Monday, July 5, 2010

How to generate g++ symbol file

To generate g++ debug symbol for the build target, -g option could be used. However, the debug symbol is embedded in the target. A different approach is taken on Windows -- PDB file, not the module self, contains the debug symbol. In the field, WinDGB could load the PDB file for the release build without copying over debug build of the module.

The link here provides some information on how to strip g++ debug symbol from the build target into a symbol file.

Create the shared libraries containing the debug symbol.

$ g++ -g -c -fPIC lib1.cpp -o lib1.o
$ g++ -shared -o liblib1.so lib1.o

$ g++ -g -c -fPIC lib2.cpp -o lib2.o
$ g++ -shared -o liblib2.so lib2.o

Extract the debug symbol from the shared libraries into symbol files.

$ ./xsym.sh liblib1.so debug lib1.sym
$ ./xsym.sh liblib2.so debug lib2.sym

Link to the shared libraries.
 $ g++ -g main.cpp -o main -L. liblib1.so liblib2.so

Extract the debug symbol from the executable into a symbol files.
$ ./xsym.sh main.exe debug main.sym

A bash script -- xsym.sh is used to extract the debug symbol into a file.

#!/bin/bash
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
    echo Usage: tostripfile debugdir debugfile
    exit
fi
tostripfile=$1
debugdir=$2
debugfile=$3
if [ ! -d "$debugdir" ]; then
    echo creating directory: $debugdir
    mkdir -p $debugdir
fi
objcopy --only-keep-debug $tostripfile $debugdir/$debugfile
strip --strip-debug --strip-unneeded $tostripfile
objcopy --add-gnu-debuglink=$debugdir/$debugfile $tostripfile

Now the debug symbol files are in the debug folder.

Generate the release version of shared libraries and executable.
$ g++ -c -fPIC lib1.cpp -o lib1.o
$ g++ -c -fPIC lib2.cpp -o lib2.o
$ g++ -shared -o liblib1.so lib1.o
$ g++ -shared -o liblib2.so lib2.o
$ g++ main.cpp -o main -L. liblib1.so liblib2.so

Run the release version of executable through GDB using the debug symbol files
...
(no debugging symbols found)
(gdb) symbol-file debug/main.sym
Reading symbols from /xxx/debug/main.sym...done.
(gdb) break main
Breakpoint 1 at 0x401065: file main.cpp, line 6.
(gdb) r
Starting program: /xxx/main.exe
[New thread 4676.0x35fc]
[New thread 4676.0x4d50]

Breakpoint 1, main (argc=1, argv=0x1004a4e0) at main.cpp:6
(gdb) info shared
From        To          Syms Read   Shared Object Library
0x7c901000  0x7c9b1eb4  Yes         /c/WINDOWS/system32/ntdll.dll
0x7c801000  0x7c8f4c10  Yes         /c/WINDOWS/system32/kernel32.dll
0x61001000  0x61300000  Yes         /usr/bin/cygwin1.dll
0x77dd1000  0x77e6ab14  Yes         /c/WINDOWS/system32/advapi32.dll
0x77e71000  0x77f01464  Yes         /c/WINDOWS/system32/rpcrt4.dll
0x77fe1000  0x77ff0880  Yes         /c/WINDOWS/system32/secur32.dll
0x10001000  0x100060f4  Yes         /xxx/liblib2.so
0x003e1000  0x003e60f4  Yes         /xxx/liblib1.so
(gdb) add-symbol-file debug/lib1.sym 0x003e1000
add symbol table from file "debug/lib1.sym" at
    .text_addr = 0x3e1000
(y or n) y
Reading symbols from /xxx/debug/lib1.sym...done.
(gdb) add-symbol-file debug/lib2.sym 0x10001000
add symbol table from file "debug/lib2.sym" at
    .text_addr = 0x10001000
(y or n) y
Reading symbols from /xxx/debug/lib2.sym...done.
(gdb) s
(gdb) s
print1 () at lib1.cpp:5
(gdb) s
This is a message from lib1
(gdb) s
main (argc=1, argv=0x1004a4e0) at main.cpp:8
(gdb) s
print2 () at lib2.cpp:5
(gdb) s
This is a message from lib2
(gdb) s
main (argc=1, argv=0x1004a4e0) at main.cpp:9
(gdb)

After loading the debug symbol files, we could step into the code in the executable and shared libraries.

0 comments:

Post a Comment