実験用のソースコードはこちら:
https://github.com/aoyama-val/gcc-gdb-separate-debug-symbols
デバッグシンボル付きでビルドする:
gcc -g a.c
デバッグシンボルを別ファイルに分離する:
objcopy --only-keep-debug a.out a.debug
a.outからデバッグシンボルを除去する:
cp a.out a.stripped
strip a.stripped
a.strippedをgdbで読み込ませてみる:
gdb a.stripped
(中略)
Reading symbols from /tmp/gdb/a.stripped...(no debugging symbols found)...done.
no debugging symbols found
と出ている通り、デバッグシンボルが読み込まれなかった。
下記の通り、ブレークポイントを張ることも出来ない。
(gdb) b a.c:21
No symbol table is loaded. Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])n
先ほど分離したシンボルファイルを読み込ませる:
(gdb) symbol-file a.debug
Reading symbols from /tmp/gdb/a.debug...done.
今度はブレークポイントを張れる:
(gdb) b a.c:21
Breakpoint 1 at 0x40058e: file a.c, line 21.
(gdb) run
Starting program: /tmp/gdb/a.stripped
Breakpoint 1, main (argc=<error reading variable: can't compute CFA for this frame>, argv=<error reading variable: can't compute CFA for this frame>) at a.c:21
21 printf("start\n");
Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.167.amzn1.x86_64
(gdb) n
start
22 ret = hoge(a, b);
(gdb) n
23 printf("ret = %d\n", ret);
(gdb) n
ret = 6
25 return 0;
--symbols=SYMFILE
manやgdb --help
によると
--symbols=SYMFILE Read symbols from SYMFILE.
というオプションがあるようだが、gdb --symbols=a.debug a.stripped
では読み込めなかった。
debug link
シンボルファイルのパスをバイナリの中に埋め込んでおく「debug link」という仕組みもあるらしい。
--with-separate-debug-dir
show debug-file-directory
objcopy --add-gnu-debuglink=foo.debug foo
参考
Debugging with GDB: 18.2 別ファイルにあるデバッグ情報
http://www.geocities.jp/harddiskdive/gdb/gdb_178.html
debugging - How to generate gcc debug symbol outside the build target? - Stack Overflow
http://stackoverflow.com/questions/866721/how-to-generate-gcc-debug-symbol-outside-the-build-target