[Interest] Creating a debug log with a stacktrace on Linux

Thiago Macieira thiago.macieira at intel.com
Fri Jun 27 00:56:42 CEST 2014


Em qui 26 jun 2014, às 19:50:28, Rogers Nate escreveu:
> Works great, thanks Thiago!!
> 
> On 06/26/2014 12:11 PM, Thiago Macieira wrote:
> > Em qui 26 jun 2014, às 08:45:34, Thiago Macieira escreveu:
> >> Em qui 26 jun 2014, às 14:29:15, Rogers Nate escreveu:
> >>> I built it as a debug build.
> >> 
> >> You need one extra flag:
> >> 
> >> QMAKE_LFLAGS_APP += -Wl,-rdynamic
> > 
> > Sorry, without the -Wl,. This is a GCC flag:
> > 
> > QMAKE_LFLAGS_APP += -rdynamic

Quick explanation:

The backtrace() function uses dladdr(), which in turn uses the dynamic symbol 
table from the ELF headers. Without the -rdynamic option, the linker will not 
export symbols from the main executable into that table. That is, the dynamic 
symbol table would contain only the symbol imports (the "undefined" symbols).

And a bit of background:

In an ELF-based system, there are three separate symbol tables:

1) the dynamic symbol table (section .dynsym, referencing .dynstr), which 
contains stuff that the dynamic linker needs for performing the run-time 
operations. All ELF modules linking to anything contain such a table, with the 
symbols that they import. Additionally, ELF libraries place their symbols they 
define in this table, so other modules can refer to them. Both of these 
sections are read-only, shareable parts of the program memory, which is why 
there are several techniques to limit the number of symbols exported. This 
table can be listed with nm -D, objdump -T, readelf -Ds.

2) the "static" symbol table (no ELF section), which contains stuff that the 
traditional linker requires for creating binaries. This is important in .o 
files, but not so much in final ELF modules, which is why this data is stripped 
by most distributions (/usr/bin/strip). Even when present, this data is never 
loaded into a running executable. It can be displayed with nm without -D, 
objdump -t, readelf -s without -D.

3) the debug symbols (ELF sections starting with .debug), which are generated 
by the compiler and linker and only used by the debugger. The /usr/bin/strip 
command will also remove these sections, which is why Linux distributions 
often use objcopy --only-keep-debug to create .debug files. They are never 
loaded under normal conditions, but they are loaded by the debugger.

The debugger will prefer using the debug symbols if they are present, falling 
back to the two symbol tables if they are not. That's why often backtraces 
contain a mix of information: full functions with their parameters, just 
function names without argument data, or the name of the library.
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Interest mailing list