[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