View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0004387 | Spring engine | Linux | public | 2014-05-13 13:16 | 2014-05-22 00:21 |
| Reporter | MajorBoredom | Assigned To | abma | ||
| Priority | low | Severity | major | Reproducibility | always |
| Status | closed | Resolution | unable to reproduce | ||
| Product Version | 96.0 | ||||
| Summary | 0004387: A SIGSEGV does not produce a proper stack trace | ||||
| Description | Under 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 Information | As 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. | ||||
| Tags | No tags attached. | ||||
| Checked infolog.txt for Errors | |||||
|
|
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. |
| 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 |