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文件
- 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
- 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]