目的
別環境で採取した core ファイルを解析する。
環境
- OS: Oracle Enterprise Linux 5.8
- GDB: GNU gdb 7.0.1-42.el5
解析に必要なファイル
別環境で発生した core ファイルを解析するためには以下のファイルが必要。
- core ファイル
- 実行ファイル
- 共有ライブラリ
例えば、以下のように abort()
でわざと core を吐かせて試してみる。
$ cat hello.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
printf("hello, world\n");
abort();
return 0;
}
$ gcc -o hello hello.c
$ ./hello
hello, world
Aborted (core dumped)
$ ls -ltr | tail -1
-rw------- 1 oracle oinstall 184320 Oct 10 20:59 core.7441
core.7441 という core ファイルが吐かれた。
実行ファイルは core ファイルに対して file
コマンドを実行すれば確認できる。
$ file core.7441
core.7441: ELF 64-bit LSB core file AMD x86-64, version 1 (SYSV), SVR4-style, from 'hello'
hello
という実行ファイルによってこの core が吐かれたことが分かる。
共有ライブラリは GDB で core を読み込んで info share
で確認できる。
$ gdb ./hello ./core.7441
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-42.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/hello...(no debugging symbols found)...done.
[New Thread 7441]
Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `./hello'.
Program terminated with signal 6, Aborted.
#0 0x00000037be430265 in raise () from /lib64/libc.so.6
(gdb) info share
From To Syms Read Shared Object Library
0x00000037be41d780 0x00000037be50ad68 Yes (*) /lib64/libc.so.6
0x00000037be000a70 0x00000037be01682e Yes (*) /lib64/ld-linux-x86-64.so.2
(*): Shared library is missing debugging information.
共有ライブラリとしては以下が読み込まれていることが分かる。
- /lib64/libc.so.6
- /lib64/ld-linux-x86-64.so.2
なお、実行中に動的リンクを行うようなプログラムでなければ、共有ライブラリは ldd
コマンドでも確認できる。
$ ldd ./hello
linux-vdso.so.1 => (0x00007fffcd1ff000)
libc.so.6 => /lib64/libc.so.6 (0x00000037be400000)
/lib64/ld-linux-x86-64.so.2 (0x00000037be000000)
以上より、この例では他の環境でこの core ファイルを解析するためには次のファイルを採取する必要がある。
- core ファイル => core.7441
- 実行ファイル => hello
- 共有ライブラリ => /lib64/libc.so.6, /lib64/ld-linux-x86-64.so.2
別環境での core の解析
別環境に先ほど採取したファイルを展開する。 今回は以下のように配置した。
/tmp/core.7441
/tmp/bin/hello
/tmp/lib/libc.so.6
/tmp/lib/ld-linux-x86-64.so.2
GDB でこの core を解析するためには、採取した共有ライブラリを読み込むために以下のように solib-absolute-prefix
, solib-search-path
を設定する。
$ cd /tmp
$ gdb
(gdb) set solib-absolute-prefix /tmp/lib
(gdb) set solib-search-path /tmp/lib
(gdb) file ./bin/hello
(gdb) core-file ./core.7441
実際の実行例は以下。
$ gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-42.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) set solib-absolute-prefix /tmp/lib
(gdb) set solib-search-path /tmp/lib
(gdb) file ./bin/hello
Reading symbols from /tmp/bin/hello...(no debugging symbols found)...done.
(gdb) core-file ./core.7441
[New Thread 7441]
Reading symbols from /tmp/lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /tmp/lib/libc.so.6
Reading symbols from /tmp/lib/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /tmp/lib/ld-linux-x86-64.so.2
Core was generated by `./hello'.
Program terminated with signal 6, Aborted.
#0 0x00000037be430265 in raise () from /tmp/lib/libc.so.6
(gdb) bt
#0 0x00000037be430265 in raise () from /tmp/lib/libc.so.6
#1 0x00000037be431d10 in abort () from /tmp/lib/libc.so.6
#2 0x00000000004004f6 in main ()
ソースファイル
デバックオプション(-g オプション)付きでコンパイルされている場合は、ソースファイルがあればソースコードを使用した調査ができる。
コンパイルした環境と別の環境で core 解析する場合、ソースコードを入手して、GDB の directory
にてソースファイルを展開したディレクトリを指定する。
実行例は以下。(実行ファイルはデバックオプション付きでコンパイルしたものを使用)
(gdb) bt
#0 0x00000030ea830265 in raise () from /tmp/lib/libc.so.6
#1 0x00000030ea831d10 in abort () from /tmp/lib/libc.so.6
#2 0x00000000004004f6 in main (argc=1, argv=0x7fff9d995df8) at hello.c:7
(gdb) frame 2
#2 0x00000000004004f6 in main (argc=1, argv=0x7fff9d995df8) at hello.c:7
7 hello.c: No such file or directory.
in hello.c
(gdb) list
2 in hello.c
ソースファイルが見つからないと上記のようにソースコードが必要な調査ができない。
directory
にてソースファイルを展開したディレクトリを指定すると、ソースコードを元にした調査ができる。
(ディレクトリが複数ある場合は:
で区切って複数指定するか、directory
をディレクトリの分だけ実行すれば追加される)
(gdb) directory /tmp/src
Source directories searched: /tmp/src:$cdir:$cwd
(gdb) frame 2
#2 0x00000000004004f6 in main (argc=1, argv=0x7fff9d995df8) at hello.c:7
7 abort();
(gdb) list
2 #include <stdlib.h>
3
4 int main(int argc, char *argv[])
5 {
6 printf("hello, world\n");
7 abort();
8 return 0;
9 }