Can I catch SIGSEGV and other signals in a multi-threaded (pthreads) app and print a backtrace of the thread that caused it, or all threads?
I saw Getting a backtrace of other thread but it didn't contain a lot of practical information.
What I want is to be able to catch SIGSEGV in a C multi-threaded app using POSIX threads running on Linux (CentOS, 2.6 kernel), and print the stack trace of the thread that caused it. Of course, not knowing which thread caused it, it's Good Enough For Me (tm) that the main thread that caught the signal to enumerate over all the threads and just print the stack trace of all of them.
It was noted over there that perhaps libunwind can be used for this, but its documentation is rather lacking and I couldn't find a good example of how to go abo开发者_如何学运维ut using it for this purpose. Also, I wondered if it has any significant performance overhead or other impact, and whether it is battle-tested and used in production code, or if it's mostly only used in debugging and development, and not in production systems.
Does anyone have sample code using libunwind or another reasonably straightforward (like not writing it in assembly) way to do this?
Getting the backtrace of the thread that caused the exception is easy, more or less:
Pass the -rdynamic flag to the linker
Then, in your coderegister signal handler, extract the EIP of the fault from the signal handler parameters and then use it and the backtrace() function to get an array of the addresses.
Find some way to pass the data in the array outside your app (to a different process over a pipe for exeample) and there you can use backtrace_symbols() to translate the backtrace to symbol names.
Make sure not to use any thread async non safe function in the signal handler, don't take any locks, allocate memory or call any function that does.
Here are the slides to a presentation I gave on the subject: http://www.scribd.com/doc/3726406/Crash-N-Burn-Writing-Linux-application-fault-handlers
The video is also available somewhere of the talk but I can't find it now...
Extending this to get the backtrace of multiple threads is possible but quite tricky - you need to keep tab of your various threads and send signals to them at the event of a crash
精彩评论