This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC 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]

segfaults in MD_FROB_UPDATE_CONTEXT and MD_FALLBACK_FRAME_STATE_FOR


Executive summary:
A call to nptl pthread_exit can cause a segfault if a function in a
dlclose'd shared lib is somewhere in the pthread_exit call chain.
Testcase attached that demonstrates the problem on powerpc64-linux.

My first reaction on seeing the bug report that complained about this
problem was "Well, don't do that!", but after properly investigating
I'm reasonably convinced this is a real bug.  At least, a target that
doesn't use MD_FROB_UPDATE_CONTEXT or MD_FALLBACK_FRAME_STATE_FOR will
quite happily work with the testcase.

Details:
nptl pthread_exit uses the .eh_frame stack unwinder to find cleanup
handlers.  The stack unwinding process uses the .eh_frame information
for a given function, with a known register state, to deduce the
register state at its caller.  The process is repeated until a handler
is found, or until we hit a function without .eh_frame information.
This last point is the simple reason that targets without the MD_*
macros mentioned above work on the testcase;  On shared lib dlclose,
__deregister_frame_info is called which tells the unwinder not to
consider .eh_frame for that shared lib (you'd get a segfault if you
tried to access it).

The problem with the two MD_* macros is that they look at .text.  In the
testcase, the backtrace from __pthread_exit looks like:

__pthread_exit (libpthread)
terminate      (main)
doSomething    (libmylib)
myThread       (main)
start_thread   (libpthread)
__clone	       (libc)

The segfault caused by MD_FROB_UPDATE_CONTEXT occurs when the unwinder
is processing .eh_frame info for "terminate".  MD_FROB_UPDATE_CONTEXT
wants to look at .text for "doSomething", which has already been
upmapped.  Of course, the frobbing that MD_FROB_UPDATE_CONTEXT does for
"terminate" isn't needed;  The unwinder won't need the register state
for "doSomething", since it won't find any .eh_frame for the unloaded
library.  This suggests a possible solution for MD_FROB_UPDATE_CONTEXT
might be to change the point at which the frobbing is done.  An
alternate simple hack is to have MD_FROB_UPDATE_CONTEXT check via
_Unwind_Find_FDE that .eh_frame info is available for the pc that it
examines.

However, MD_FALLBACK_FRAME_STATE_FOR, whose purpose is to unwind through
signal frames, is called for funtions that don't have .eh_frame info.
It too wants to examine .text.

My solution to this problem will be to install a segv handler before the
unwinder does any work, and annotate instructions that might segfault in
the MD_* macros.  Better ideas appreciated..

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

Attachment: thread_unload.tar.gz
Description: application/gunzip


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