7.4. glibc Debugging SupportThe usual way to examine a back trace of a program is to use an external debugger such as GDB. Sometimes, however, it is useful to obtain back-trace information from within a running program for logging or debugging purposes. The GNU glibc provides support that enables the developer to produce back-trace printouts from within the application. Example 7-4 shows how to use backtrace inside a signal handler and outside a signal handler. The API prototypes for back trace are declared in the header file execinfo.h and should be included in the application. Example 7-4. Code Listing of sample_backtrace.c
Compile the code listing sample_backtrace.c with the _handler_ macro defined to simulate an application program that aborts in the middle of its run: $ gcc sample_backtrace.c -o sample_backtrace -g -rdynamic -D_handler_ $./sample_backtrace ########## start backtrace ########## Number of elements in backtrace: 9 ./main1(handler+0x2d) [0x8048829] [0xffffe440] /lib/tls/libc.so.6(abort+0x129) [0x40051f79] ./main1(g+0) [0x80488d2] ./main1(g+0xb) [0x80488dd] ./main1(foo+0xb) [0x80488ea] ./main1(main+0x6a) [0x8048956] /lib/tls/libc.so.6(__libc_start_main+0xe0) [0x4003e500] ./main1 [0x8048761] ########## end backtrace ########## Aborted In the preceding example, back-trace information is produced through the abort signal handler routine called handler(). The same method can be implemented for other signals caught by the application. In the following, Example 7-4 is compiled without the _handler_ macro defined. In this example, the handler() function is called explicitly by the application to produce a back-trace printout. This method can be used to create back-trace information at certain points of the application for debugging or monitoring reasons. $ gcc sample_backtrace.c -o sample_backtrace -g -rdynamic $ ./sample_backtrace ########## start backtrace ########## Number of elements in backtrace: 7 ./main1(handler+0x2d) [0x80487f9] ./main1(h+0xb) [0x80488a2] ./main1(g+0xb) [0x80488af] ./main1(foo+0xb) [0x80488bc] ./main1(main+0x6a) [0x8048928] /lib/tls/libc.so.6(__libc_start_main+0xe0) [0x4003e500] ./main1 [0x8048731] ########## end backtrace ########## When compiling, notice that the rdynamic flag is used. The rdynamic flag is passed on to the linker to force inclusion of global symbol tables in the final executable. |