View Issue Details

IDProjectCategoryView StatusLast Update
0004387Spring engineLinuxpublic2014-05-22 00:21
ReporterMajorBoredom Assigned Toabma  
PrioritylowSeveritymajorReproducibilityalways
Status closedResolutionunable to reproduce 
Product Version96.0 
Summary0004387: A SIGSEGV does not produce a proper stack trace
DescriptionUnder Linux, the signal handler for SIGSEGV, SIGFPE, SIGILL, etc is not guaranteed to be run in the thread that executed the fault. For example, it is very common for the main thread to be sleeping inside its NetProtocol.cpp update loop at the time of such a fault.

When the signal handler is invoked, it calls Stacktrace() and subsequently the linux function backtrace(). This function reads stack frames from the signal handler's stack, which is called inside an arbitrary thread. (It is not guaranteed to be called inside the thread that issued the faulting instruction).

The backtrace() output under such circumstances would include the site of the sleep() call inside the NetProtocol.cpp update loop, but may also erroneously print garbage frames above that as it does not have adequate symbol information for the frames inside sleep() etc. And the entire trace in this case is useless anyway since it is the wrong thread.
Additional InformationAs far as I have been able to uncover, in order to fix this, the sigaction() calls that are made when the CrashHandler is installed must be converted to the new signal handler format (see bits/sigaction.h and bits/siginfo.h)

void signal_handler_func (int signal)

to

void sigaction_handler_func (int signal, siginfo_t*, void *)

There are two possibilities for thread-specific action to be taken within this signal handler. First, the siginfo_t structure contains an instruction address which could be decoded. Second and more viable, the (void*) parameter to the handler is a pointer to a ucontext_t structure (as is produced by getcontext()). This structure contains a stack pointer. It is also conveniently the same format as required by libunwind (see libunwind-ARCH.h) and so it can be used by this library to unwind the stack and produce proper traces.

I could fix this on the libunwind feature branch but the fix is more lengthy and so I figured I would explain it here and perhaps push it to a later patch for the develop branch.
TagsNo tags attached.
Checked infolog.txt for Errors

Relationships

related to 0004375 closedabma integrate libunwind patch (linux only, maybe osx, too) 
related to 0004394 closedabma TranslateStacktrace provides inappropriate values to addr2line 

Activities

MajorBoredom

2014-05-16 03:21

reporter   ~0013102

Last edited: 2014-05-16 03:22

I have looked at conflicting information on the net which says that the signal handler is (or is not) invoked in the thread that issued the faulting instruction. It seems that if you use the new signal handler format (sa_sigaction instead of sa_handler in sigaction_t) the handler is invoked in the appropriate thread. I saw otherwise before when using sa_handler.

In any case, you do not have to rely on the signal handler's ucontext_t* parameter as I thought before. The solution is to use libunwind's unw_getcontext() (really just aliased to getcontext() on my x86_64 system) inside the signal handler. After that, it is just a matter of ignoring the signal handler's frames which are placed on top of the faulting thread's frames.

This is fixed in my libunwind integration fork.

Issue History

Date Modified Username Field Change
2014-05-13 13:16 MajorBoredom New Issue
2014-05-14 00:01 abma Relationship added related to 0004375
2014-05-16 03:18 Kloot Relationship added related to 0004394
2014-05-16 03:21 MajorBoredom Note Added: 0013102
2014-05-16 03:22 MajorBoredom Note Edited: 0013102
2014-05-22 00:21 abma Status new => closed
2014-05-22 00:21 abma Assigned To => abma
2014-05-22 00:21 abma Resolution open => unable to reproduce