X86平台挂机问题的原因查找过程
前言
运行数日,偶然出现一个coredump文件,如何查找时哪里出现了问题呢,由于不能必现,只能一步步分析。
一、先上 gdb
gdb 安装:
yum install gdb
gdb app core.1553 显示
Program terminated with signal SIGABRT, Aborted.
#0 0x00007fd60f2dbf47 in ?? ()
[Current thread is 1 (LWP 394)]
(gdb) bt
#0 0x00007fd60f2dbf47 in ?? ()
#1 0x0000000000000000 in ?? ()
PS:如果需要符号信息,则需要:
(1)SET(CMAKE_CXX_FLAGS_DEBUG “$ENV{CXXFLAGS} -O0 -Wall -g -ggdb”)
(2)no skip
(3) add_definitions(“-Wall -g”)
二、地址怎么对应堆栈呢。
(gdb) info proc map
Mapped address spaces:
gnu/libresolv-2.27.so
0x7fd60e12b000 0x7fd60e32b000 0x200000 0x17000 /lib/x86_64-linux-gnu/libresolv-2.27.so
0x7fd60e32b000 0x7fd60e32c000 0x1000 0x17000 /lib/x86_64-linux-gnu/libresolv-2.27.so
0x7fd60e32c000 0x7fd60e32d000 0x1000 0x18000 /lib/x86_64-linux-gnu/libresolv-2.27.so
0x7fd60e32f000 0x7fd60e332000 0x3000 0x0 /lib/x86_64-linux-gnu/libkeyutils.so.1.5
0x7fd60e332000 0x7fd60e531000 0x1ff000 0x3000 /lib/x86_64-linux-gnu/libkeyutils.so.1.5
0x7fd60e531000 0x7fd60e532000 0x1000 0x2000 /lib/x86_64-linux-gnu/libkeyutils.so.1.5
0x7fd60e532000 0x7fd60e533000 0x1000 0x3000 /lib/x86_64-linux-gnu/libkeyutils.so.1.5
2.找到动态库之后反汇编
objdump -tT ./app | grep 4621
4621 是计算出来的:
0x00007fd60f2dbf47 - 动态库的起始地址(举例:0x7fd60e32f000)= 偏移地址,找到相关函数。
**此时堆栈信息都能完全追踪到了。**此处是raise()函数,还是无法定位。
三、堆栈不完整,原因还是不清楚
1、(gdb) info registers 和 info threads
(gdb) info threads
(gdb) info registers
rax 0x0 0
rbx 0x7fd60d10e830 140557318940720
rcx 0x7fd60f2dbf47 140557354385223
rdx 0x0 0
rsi 0x7fd60d10e5c0 140557318940096
rdi 0x2 2
rbp 0x7fd60d10e930 0x7fd60d10e930
rsp 0x7fd60d10e5c0 0x7fd60d10e5c0
r8 0x0 0
r9 0x7fd60d10e5c0 140557318940096
r10 0x8 8
r11 0x246 582
r12 0x7fd60d10e830 140557318940720
r13 0x1000 4096
r14 0x0 0
r15 0x30 48
rip 0x7fd60f2dbf47 0x7fd60f2dbf47
eflags 0x246 [ PF ZF IF ]
通用寄存器:
AX,BX,CX,DX 称作为数据寄存器:
AX (Accumulator):累加寄存器,也称之为累加器;
BX (Base):基地址寄存器;
CX (Count):计数器寄存器;
DX (Data):数据寄存器;
SP 和 BP 又称作为指针寄存器:
SP (Stack Pointer):堆栈指针寄存器;
BP (Base Pointer):基指针寄存器;
SI 和 DI 又称作为变址寄存器:
SI (Source Index):源变址寄存器;
DI (Destination Index):目的变址寄存器;
控制寄存器:
IP (Instruction Pointer):指令指针寄存器;
FLAG:标志寄存器;
段寄存器:
CS (Code Segment):代码段寄存器;
DS (Data Segment):数据段寄存器;
SS (Stack Segment):堆栈段寄存器;
ES (Extra Segment):附加段寄存器;
2、根据rsp rbp寄存器的保存的内容查找堆栈
(gdb) info f
Stack level 0, frame at 0x7ffc4b59d670:
rip = 0x400957 in main (io1.c:16); saved rip = 0x7fc5c0d5aec5
source language c.
Arglist at 0x7ffc4b59d660, args:
Locals at 0x7ffc4b59d660, Previous frame’s sp is 0x7ffc4b59d670
Saved registers:
rbp at 0x7ffc4b59d660, rip at 0x7ffc4b59d668
(gdb) x/5i 0x400957 或者x/5i $rip
=> 0x400957 <main+26>:movl $0x0,-0x800014(%rbp)
0x400961 <main+36>:lea -0x800010(%rbp),%rax
0x400968 <main+43>:mov $0x800000,%edx
0x40096d <main+48>:mov $0x0,%esi
0x400972 <main+53>:mov %rax,%rdi
(gdb) x /200x 0x7fd60d10e400
0x7fd60d10e400: 0x08003dd0 0x00007fd6 0x04a32130 0x00000000
0x7fd60d10e410: 0x0d10ea10 0x00007fd6 0x009bddb6 0x00000000
0x7fd60d10e420: 0x98ae2b04 0x47b16805 0x0d10e4c0 0x00007fd6
0x7fd60d10e430: 0x08003dd0 0x00007fd6 0x04a2f410 0x00000000
0x7fd60d10e440: 0x08003bd0 0x00007fd6 0x0819c340 0x00007fd6
0x7fd60d10e450: 0x08012f20 0x00007fd6 0x08012f20 0x00007fd6
0x7fd60d10e460: 0x08013120 0x00007fd6 0x08012ee8 0x00007fd6
0x7fd60d10e470: 0x08012f20 0x00007fd6 0x08012f20 0x00007fd6
0x7fd60d10e480: 0x08013120 0x00007fd6 0x08012ee8 0x00007fd6
0x7fd60d10e490: 0x04a329f0 0x00000000 0x08002940 0x00007fd6
0x7fd60d10e4a0: 0x0d10fc60 0x00007fd6 0x00000000 0x00000000
0x7fd60d10e4b0: 0x00a235d0 0x00000000 0x0000002f 0x00000077
0x7fd60d10e4c0: 0x08012ed0 0x00007fd6 0x00000008 0x00000000
0x7fd60d10e4d0: 0x08012f20 0x00007fd6 0x08012f20 0x00007fd6
0x7fd60d10e4e0: 0x08013120 0x00007fd6 0x08012ee8 0x00007fd6
从上述堆栈中查找可能的函数、以及参数。 提醒的是,需要结合反汇编代码来看。