C程序DEMO 文件 main.c
#define _GNU_SOURCE
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <stdint.h>
#include <ucontext.h>
#include <unistd.h>
#include <sys/wait.h>
#include <setjmp.h>static void *buffer[100] = {0}; // 用于存储地址列表
static int nptrs = 0;
static sigjmp_buf jmpbuf;void print_stack_trace()
{printf("Relative addresses:\n");for (int i = 0; i < nptrs; i++){Dl_info info;if (dladdr(buffer[i], &info) != 0){uintptr_t base = (uintptr_t)info.dli_fbase;printf("Frame base %p\n", info.dli_fbase);uintptr_t addr = (uintptr_t)buffer[i];printf("Frame %d: relative offset = 0x%lx\n", i, (unsigned long)(addr - base));}else{printf("Frame %d: no information available\n", i);}}
}void segv_handler(int sig)
{// 捕获调用栈nptrs = backtrace(buffer, 100);backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO);siglongjmp(jmpbuf, 1);
}void crash_function()
{int *p = NULL;*p = 42; // 故意制造一个段错误
}int main()
{int jmpid = 0;pid_t pid = fork();if (pid < 0) {perror("fork failed");exit(1);}if (pid == 0) {// 子进程pid_t cpid = getpid();printf("Child: %d \n", cpid);jmpid = setjmp(jmpbuf);if (jmpid == 0){signal(SIGSEGV, segv_handler);}else{printf("Child tag: %d \n", cpid);// print_stack_trace();signal(SIGSEGV, SIG_DFL);kill(pid, SIGSEGV);}} else {// 父进程printf("Parent: %d \n", getpid());// 等待子进程结束waitpid(pid, NULL, 0);printf("Parent end: %d \n", getpid());exit(0);}crash_function();return 0;
}
编译 -O2 优化
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ gcc -o2 main.c -o main
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ ./main
Parent: 26425
Child: 26426
./main(+0x130b)[0x55c0f8c7930b]
/lib/x86_64-linux-gnu/libc.so.6(+0x3c050)[0x7fbcc0f09050]
./main(+0x1351)[0x55c0f8c79351]
./main(+0x1483)[0x55c0f8c79483]
/lib/x86_64-linux-gnu/libc.so.6(+0x2724a)[0x7fbcc0ef424a]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85)[0x7fbcc0ef4305]
./main(+0x1141)[0x55c0f8c79141]
Child tag: 26426
Segmentation fault (core dumped)
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ addr2line -e main 0x1483
??:?
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$
-O2 优化后生成的程序 main 不能通过堆栈的相对地址查询到堆栈信息
编译 -g -O2 附加调试信息和优化
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ gcc -g -o2 main.c -o main
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ ./main
Parent: 27118
Child: 27119
./main(+0x130b)[0x5569150ce30b]
/lib/x86_64-linux-gnu/libc.so.6(+0x3c050)[0x7fa78e6d4050]
./main(+0x1351)[0x5569150ce351]
./main(+0x1483)[0x5569150ce483]
/lib/x86_64-linux-gnu/libc.so.6(+0x2724a)[0x7fa78e6bf24a]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85)[0x7fa78e6bf305]
./main(+0x1141)[0x5569150ce141]
Child tag: 27119
Segmentation fault (core dumped)
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ addr2line -e main 0x1483
/home/mestc/repos/cpp/main.c:93
剔除调试信息
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ objcopy --only-keep-debug main main.debug
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ addr2line -e main 0x1483
/home/mestc/repos/cpp/main.c:93
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ addr2line -e main.debug 0x1483
/home/mestc/repos/cpp/main.c:93
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ ./main
Parent: 27844
Child: 27845
./main(+0x130b)[0x5556cb0a430b]
/lib/x86_64-linux-gnu/libc.so.6(+0x3c050)[0x7f1e086d2050]
./main(+0x1351)[0x5556cb0a4351]
./main(+0x1483)[0x5556cb0a4483]
/lib/x86_64-linux-gnu/libc.so.6(+0x2724a)[0x7f1e086bd24a]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85)[0x7f1e086bd305]
./main(+0x1141)[0x5556cb0a4141]
Child tag: 27845
Segmentation fault (core dumped)
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ ./main.debug
bash: ./main.debug: cannot execute binary file: Exec format error
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ strip --strip-debug main
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ addr2line -e main 0x1483
??:?
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ ./main
Parent: 28082
Child: 28083
./main(+0x130b)[0x55b2ac28d30b]
/lib/x86_64-linux-gnu/libc.so.6(+0x3c050)[0x7f9f691f2050]
./main(+0x1351)[0x55b2ac28d351]
./main(+0x1483)[0x55b2ac28d483]
/lib/x86_64-linux-gnu/libc.so.6(+0x2724a)[0x7f9f691dd24a]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85)[0x7f9f691dd305]
./main(+0x1141)[0x55b2ac28d141]
Child tag: 28083
Segmentation fault (core dumped)
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ addr2line -e main.debug 0x1483
/home/mestc/repos/cpp/main.c:93
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$
还原 main 的调试信息
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ objcopy --add-gnu-debuglink=main.debug main
mestc@DESKTOP-4OJQ0ID:~/repos/cpp$ addr2line -e main 0x1483
/home/mestc/repos/cpp/main.c:93