I have a requirement of dumping stack traces when my c++ Linux application crashes. I was successfully able to do this using backtrace()
and backtrace_symbols()
. Now, additionally I would like to get the line numbers of the crash. How do it do it?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- thread_local variables initialization
- What uses more memory in c++? An 2 ints or 2 funct
It is only possible if the program has been compiled with debugging information (i.e. with
gcc -Wall -g
or withg++ -Wall -g
). Without-g
the executable does not contain any source line information. And if usinggcc
you can compile with both optimization & debugging information (e.g.g++ -Wall -g -O2
) but sometimes the line location would be "surprising".The
-Wall
flag asks GCC to show all warnings. It is very useful (hence my recommendation to use it) but unrelated to-g
or debugging information.As to how to extract the line number, the simplest way would be to fork a
gdb
process. Alternatively, you could get the debugging information (in DWARF format) and parse it, perhaps usinglibdwarf
from the ELF tool chain. I am not sure it is worth the trouble...To just get the backtrace, you might simply run your program thru
gdb
perhaps asgdb --args yourprogram itsarguments
...addenda
you could also use the libbacktrace from inside a recent GCC (actually it is Ian Taylor's libbacktrace), which is designed to solve your problem (it is "interpreting" the DWARF format of the current executable, which you would compile with
g++ -O -g
).I took help from
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l2.html and http://www.linuxjournal.com/article/6391?page=0,0 to come up with sample code which shows how you can achieve this.
Basically it is about putting a stack backtrace inside a signal handler and having the latter catch all the "bad" signals your program can receive (SIGSEGV, SIGBUS, SIGILL, SIGFPE and the like). This way, if your program unfortunately crashes and you were not running it with a debugger, you can get a stack trace and know where the fault happened. This technique also can be used to understand where your program is looping in case it stops responding...
Below code runs the external program addr2line for every address in the trace to convert it into a file name and a line number.
The source code below prints line numbers for all local functions. If a function from another library is called, you might see a couple of ??:0 instead of file names.
This code should be compiled as: gcc sighandler.c -o sighandler -rdynamic
The program outputs:
As Saqlain pointed out, addr2line can be used to get the line number.
If a library is preferred, take a look at the LPT kit. Instructions on how to install are at here. LPT relies on the bfd library.
system()
needs#include <stdlib.h>
Few other things seem missing.