This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

backtrace () crashes in statically linked apps


Hello,

calling backtrace () from any statically linked applications
crashes on s390(x), and probably also on the other platforms
that use DWARF-2 CFI in backtrace ().

The reason for the crash is a bit complex.  First of all,
backtrace () does a __libc_dlopen ("libgcc_s.so.1").  Since
the application is statically linked, this causes the
dynamic loader to be loaded, as well as the libgcc_s.so 
itself and also libc.so (which libgcc_s.so depends on).
Note that we now have two copies of some libc routines, the 
ones statically linked into the executable, as well as the
copies from libc.so.

Now, the _Unwind_Backtrace routine from libgcc_s.so is called.
This uses the dl_iterate_phdr routine from libc (the dynamic
copy) to find the .eh_frame sections of all dynamic objects.

The first problem right here is that (even if everything else
worked), the copy of dl_iterate_phdr is not aware at all of
the statically linked main executable's .eh_frame section.
The *static* copy of dl_iterate_phdr has special code to
enumerate that one as well, but the dynamic copy doesn't
-- and the latter is the one that's being uses.  Thus in
any case backtrace () wouldn't work properly.

However, we don't even get that far.  The first thing the
dynamic copy of dl_iterate_phdr does is to enter a critical
section using __rtld_lock_lock_recursive.  Now, if libc is
compiled with tls/nptl support, this routine simply calls
via a function pointer GL(dl_rtld_lock_recursive) in 
rtld_local (from ld.so).

That function pointer is initialized in dl_main (and might
be overwritten later on if a thread library is used).
However, in the case where a statically linked application
loads ld.so at a later time, the dl_main function is apparently
never called.  In any case, the dl_rtld_lock_recursive pointer
remains NULL, which causes the crash.

Is this supposed to work?  Or should backtrace () directly
call the glibc copies of _Unwind_Backtrace et al. if !SHARED?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]