C++调试

查看目标文件信息

查看目标文件段信息
readelf -S test | grep debug

查看文件信息,是否有调试信息等
file test

移除调试信息
strip test

gdb调试

1. 可执行文件

gcc -g test.c -o test
gdb test
(gdb)set args
(gdb)run

2. 调试已运行程序

先查看进程号ps -ef | grep pname

gdb attach pid

or

(gdb)attach pid

调试相关id进程

gdb test --pid pid

若已运行程序没有调试信息
编译出一个带调试信息的版本,在attach之前,使用file命令即可

3. 调试core文件

查看进程信息cat /proc/pid/limits

查看是否开启生成core文件

ulimit -c

or

ulimit -a
core file size (blocks, -c) 0

开启生成core文件,不限制core文件大小

ulimit -c unlimited

设置core文件大小,单位为块,一块默认512字节
ulimit -c 10

默认文件名都叫core,为了区分,添加pid到文件名后缀

echo "1" > /proc/sys/kernel/core_uses_pid

指定core文件名格式和路径

echo "/home/ubuntu/corefile/core-%e-%p" > /proc/sys/kernel/core_pattern

调试core文件

gdb <exefile> <corefile>

获取bt

获取bt文件

  1. addr2line工具
    将可执行文件中的地址转换为文件名,函数名和代码行的工具

准备一个目标文件,进行反汇编

objdump -d -l -C -S test.elf > test.elf.asm

查询文件中地址与代码行的关系

readelf -w test.elf | grep "advanced Address"

查询一个地址的文件名,函数名和代码行

addr2line 0xXXXX -e test.elf -f -s -C
  1. C库函数backtrace()backtrace_symbol()
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <signal.h>
#include <execinfo.h>

// 0: GENERATE COREDUMP FILE
// 1: PRINT STACK BY SELF
#define ADDR_MAX_NUM 100

void CallbackSignal(int iSignalNo) {
  printf ("CALLBACK: SIGNAL:%d\n", iSignalNo);
  void *pBuf[ADDR_MAX_NUM] = {0};
  int iAddrNum = backtrace(pBuf, ADDR_MAX_NUM);
  printf("BACKTRACE: NUMBER OF ADDRESSES IS:%d\n\n", iAddrNum);
  char** strSymbols = backtrace_symbols(pBuf, iAddrNum);
  if (strSymbols == NULL) {
      printf("BACKTRACE: CANNOT GET BACKTRACE SYMBOLS\n");
      return;
  }
  int ii = 0;
  for (ii = 0; ii < iAddrNum; ii++) {
      printf("%03d %s\n", iAddrNum-ii, strSymbols[ii]);
  }
  printf("\n");
  free(strSymbols);
  strSymbols = NULL;
  exit(1); // QUIT PROCESS. IF NOT, MAYBE ENDLESS LOOP.
}

void FuncBadBoy() {
  void* pBadThing = malloc(1024*1024*256);
  free (pBadThing);
  free (pBadThing);
}

void FuncBadFather() {
  FuncBadBoy();
}

int main(int argc, char **argv){
  signal(SIGSEGV, CallbackSignal);
  FuncBadFather();
  return 0;
}

编译运行gcc -rdynamic test.c

CALLBACK: SIGNAL:11
BACKTRACE: NUMBER OF ADDRESSES IS:9

009 ./a.out(CallbackSignal+0x6b) [0x5acf3e1b22d4]
008 /lib/x86_64-linux-gnu/libc.so.6(+0x42520) [0x7cbb21a42520]
007 /lib/x86_64-linux-gnu/libc.so.6(free+0x1e) [0x7cbb21aa53fe]
006 ./a.out(FuncBadBoy+0x32) [0x5acf3e1b2417]
005 ./a.out(FuncBadFather+0x12) [0x5acf3e1b242c]
004 ./a.out(main+0x31) [0x5acf3e1b2460]
003 /lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7cbb21a29d90]
002 /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7cbb21a29e40]
001 ./a.out(_start+0x25) [0x5acf3e1b21a5]
posted @ 2024-11-06 15:36  sgqmax  阅读(4)  评论(0编辑  收藏  举报