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工具定位崩溃点

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GDB是一种功能强大的调试器,用于帮助开发人员在软件开发过程中定位和修复程序中的错误。GDB有两个不同的版本:开发版本和发布版本。开发版本通常包含最新的功能和修复,而发布版本是为了稳定性和可靠性而经过测试和验证的版本。 发布版本的GDB是为了满足用户的需求而推出的。它经过详细的测试和验证,确保可以在各种操作系统和硬件平台上正常工作。发布版本通常是根据开发版本中的一些特定功能和修复进行选择和打包的。 发布版本的主要目的是向用户提供一个稳定可靠的调试器,以帮助用户更好地调试和优化他们的程序。这是通过从开发版本中选择和集成一些已经验证和稳定的功能和修复来实现的。此外,发布版本还提供了一些额外的文档,如用户手册和常见问题解答,以帮助用户更好地使用GDB。 发布版本的GDB通常以二进制形式提供,用户只需下载并安装即可使用。用户可以通过向开发者提供反馈来改善发布版本,并在后续的更新中获取新的功能和修复。发布版本的GDB可用于各种软件开发项目,包括嵌入式系统、服务器应用程序和桌面应用程序等。 总之,发布版本的GDB是一个经过测试和验证的稳定版本,旨在为用户提供一个可靠且功能丰富的调试器,以帮助他们调试和优化程序。用户可以下载并安装发布版本,然后从开发者那里获取反馈和更新,以进一步改进GDB的性能和功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值