GDB调试Release程序

一、gdb调试release程序

  1. 从debug版程序projectD中生成符号表projectsymbol.dbg
    objcopy --only-keep-debug projectD projectsymbol.dbg

  2. 调试release版程序projectR,同时加载符号表projectsymbol.dbg
    gdb --symbol=projectsymbol.dbg --exec=projectR

  3. 调试release版程序生成的core文件,同时加载符号表projectsymbol.dbg
    gdb --symbol=projectsymbol.dbg --exec=projectR -c core

查看core dump位置:sudo sysctl -n kernel.core_pattern
设置core dump位置:sudo sysctl -w kernel.core_pattern=/tmp

二、使用google breakpad调试dump——linux本地

测试代码:

#include "client/linux/handler/exception_handler.h"

static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context, bool succeeded) {
  printf("Dump path: %s\n", descriptor.path());
  return succeeded;
}

void crash() { volatile int* a = (int*)(NULL); *a = 1; }

int main(int argc, char* argv[]) {
  google_breakpad::MinidumpDescriptor descriptor("/tmp");
  google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);
  crash();
  return 0;
}

编译的时候注意要链接libbreakpad_client.a静态库

g++ breakpad.cpp -o breakpad -I breakpad/include/breakpad -L breakpad/lib/ -lbreakpad_client -lpthread

接下来运行breakpad,生成dump文件,程序打印出了dump文件路径

Dump path: /tmp/4d4c5bd1-6b58-4f64-89fad7b6-98585875.dmp
Segmentation fault

有两种方法:

方法1. minidump-2-core + gdb

a.使用minidump-2-core工具将dump文件转换为core

breakpad/bin/minidump-2-core /tmp/4d4c5bd1-6b58-4f64-89fad7b6-98585875.dmp > core

b.使用gdb调试core

gdb breakpad core

Core was generated by `./breakpad'.
Program terminated with signal SIGSEGV, Segmentation fault.
(gdb) bt
#0  0x00005586a6e93185 in crash() ()
#1  0x00005586a6e93235 in main ()
(gdb) 

方法2. dump_syms + minidump_stackwalk(比较麻烦)

a.从程序导出符号文件

breakpad/bin/dump_syms ./breakpad > breakpad.sym
b按照符号文件第一行内容创建指定目录结构存放符号文件

head -n1 breakpad.sym

MODULE Linux x86_64 DA1431F4146A0A08633146C746B8E5AB0 breakpad

mkdir -p ./symbols/breakpad/DA1431F4146A0A08633146C746B8E5AB0
mv breakpad.sym ./symbols/breakpad/DA1431F4146A0A08633146C746B8E5AB0/

c.使用minidump_stackwalk解析dump文件

因为stderr会输出很多冗余无用的信息,所以将其重定向到/dev/null
breakpad/bin/minidump_stackwalk /tmp/4d4c5bd1-6b58-4f64-89fad7b6-98585875.dmp ./symbols/ 2> /dev/null
输出如下:

Operating system: Linux
                  0.0.0 Linux 4.15.0-29deepin-generic #31 SMP Fri Jul 27 07:12:08 UTC 2018 x86_64
CPU: amd64
     family 6 model 78 stepping 3
     1 CPU

GPU: UNKNOWN

Crash reason:  SIGSEGV /SEGV_MAPERR
Crash address: 0x0
Process uptime: not available

Thread 0 (crashed)
 0  breakpad!crash() + 0x10
    rax = 0x0000000000000000   rdx = 0x00005557a6cc0880
    rcx = 0x0000000000000000   rbx = 0x0000000000000000
    rsi = 0x0000000000000000   rdi = 0x0000000000000000
    rbp = 0x00007ffe897de7f0   rsp = 0x00007ffe897de7f0
     r8 = 0x0000000000000000    r9 = 0x00007ffe897de410
    r10 = 0x0000000000000135   r11 = 0x00007f988d3cc3f0
    r12 = 0x00005557a6aaa030   r13 = 0x00007ffe897deab0
    r14 = 0x0000000000000000   r15 = 0x0000000000000000
    rip = 0x00005557a6aaa185
    Found by: given as instruction pointer in context
 1  breakpad!main + 0xa7
    rbx = 0x0000000000000000   rbp = 0x00007ffe897de9d0
    rsp = 0x00007ffe897de800   r12 = 0x00005557a6aaa030
    r13 = 0x00007ffe897deab0   r14 = 0x0000000000000000
    r15 = 0x0000000000000000   rip = 0x00005557a6aaa235
    Found by: call frame info
 2  libc-2.27.so + 0x21a87
    rbx = 0x0000000000000000   rbp = 0x00005557a6aba6b0
    rsp = 0x00007ffe897de9e0   r12 = 0x00005557a6aaa030
    r13 = 0x00007ffe897deab0   r14 = 0x0000000000000000
    r15 = 0x0000000000000000   rip = 0x00007f988c6fca87
    Found by: call frame info
 3  breakpad!crash() + 0x19
    rsp = 0x00007ffe897dea00   rip = 0x00005557a6aaa18e
    Found by: stack scanning

Loaded modules:
0x5557a6aa4000 - 0x5557a6abffff  breakpad  ???  (main)
0x7f988c6db000 - 0x7f988c88bfff  libc-2.27.so  ???  (WARNING: No symbols, libc-2.27.so, 97A2D08FBF581566673836BB20FFDF110)
0x7f988ca95000 - 0x7f988caabfff  libgcc_s.so.1  ???
0x7f988ccad000 - 0x7f988ce3efff  libm-2.27.so  ???
0x7f988d040000 - 0x7f988d1b1fff  libstdc++.so.6.0.25  ???
0x7f988d3c1000 - 0x7f988d3d9fff  libpthread-2.27.so  ???
0x7f988d5df000 - 0x7f988d5e1fff  libdl-2.27.so  ???
0x7f988d7e3000 - 0x7f988d807fff  ld-2.27.so  ???
0x7ffe897e4000 - 0x7ffe897e5fff  linux-gate.so  ???

1.这里的测试程序breakpad不含调试信息,如果含有调试信息,可以定位到具体的行号,显示更多出错信息
2.第一种方法可以配合debug版程序的符号表进行调试分析,一样可以定位到具体出错信息
3.第二种方法可以直接使用minidump_stackwalk得到dump信息,然后配合addr2line工具定位崩溃点

你可能感兴趣的:(gdb,breakpad)