上代码
///////////////////////////
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/time.h> #include <unistd.h> #include <execinfo.h> #define MAX_STACK_DEPTH 16 volatile int sample_count = 0; void collect_call_stack() { void* buffer[MAX_STACK_DEPTH]; int depth = backtrace(buffer, MAX_STACK_DEPTH); printf("\n[采样 #%d] 调用栈深度: %d\n", ++sample_count, depth); // 关键修改:用 backtrace_symbols 解析成可读的符号 char** symbols = backtrace_symbols(buffer, depth); if (symbols) { for (int i = 0; i < depth && i < 8; i++) { printf(" %s\n", symbols[i]); } if (depth > 8) { printf(" ... 还有 %d 帧\n", depth - 8); } free(symbols); // 别忘了释放 } } void profiling_handler(int sig) { collect_call_stack(); } void function_c() { for (volatile long i = 0; i < 100000000; i++); } void function_b() { for (int i = 0; i < 3; i++) { function_c(); } } void function_a() { for (int i = 0; i < 3; i++) { function_b(); } } int main() { signal(SIGPROF, profiling_handler); struct itimerval timer; timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 10000; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 10000; if (setitimer(ITIMER_PROF, &timer, NULL) == -1) { perror("setitimer 失败"); return 1; } printf("=== 性能采样器已启动 (每10ms CPU时间采样一次) ===\n"); printf("程序正在执行计算,采样器会周期性记录调用栈...\n\n"); function_a(); printf("\n=== 采样完成 ===\n"); printf("总共采集了 %d 个样本\n", sample_count); return 0; }编译
g++ b.cpp -rdynamic
./a.out
ubuntu22@NYX:~/test$ ./a.out === 性能采样器已启动 (每10ms CPU时间采样一次) === 程序正在执行计算,采样器会周期性记录调用栈... [采样 #1] 调用栈深度: 10 ./a.out(_Z18collect_call_stackv+0x32) [0x62c8211fe27b] ./a.out(_Z17profiling_handleri+0x14) [0x62c8211fe398] /lib/x86_64-linux-gnu/libc.so.6(+0x42520) [0x7984c7c42520] ./a.out(_Z10function_cv+0x2b) [0x62c8211fe3c6] ./a.out(_Z10function_bv+0x1a) [0x62c8211fe3e8] ./a.out(_Z10function_av+0x1a) [0x62c8211fe410] ./a.out(main+0xa8) [0x62c8211fe4c6] /lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7984c7c29d90] ... 还有 2 帧