Stacktrace trong C++

Giữ symbol names (biên dịch với -g và link với -rdynamic trên Linux), nên dùng cả 2 để có đầy đủ tên hàm + số dòng.

Debug symbol “-g” để thêm thông tin debug (file, line).

Linking flags “-rdynamic" để export symbol names để backtrace() hoặc addr2line có thể ánh xạ địa chỉ bộ nhớ → tên hàm + số dòng.

test.cpp
#include <boost/stacktrace.hpp>
#include <iostream>
#include <stdexcept>
using namespace std;

void foo()
{
    throw std::runtime_error("Something went wrong!");
}

int main() {
    try {
        foo();
    } catch (const std::exception& e) {
        std::cerr << "EXCEPTION: " << e.what() << "\n";
        std::cerr << boost::stacktrace::stacktrace() << std::endl;
    }
    return 0;
}

// 0. Không có debug symbol (strip)
[root@GIGABYTEU4 test]# g++ test.cpp -o test -s
[root@GIGABYTEU4 test]# file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=50f38c16dbad339134bb8059abb3c06feec5d3a8, for GNU/Linux 3.2.0, stripped
[root@GIGABYTEU4 test]# ./test
EXCEPTION: Something went wrong!
 0# 0x000000000040257E in ./test
 1# 0x0000791DD8A295D0 in /lib64/libc.so.6
 2# __libc_start_main in /lib64/libc.so.6
 3# 0x00000000004023C5 in ./test
[root@GIGABYTEU4 test]#
// 1. Chỉ có "-g"
[root@GIGABYTEU4 test]# g++ -g test.cpp -o test
[root@GIGABYTEU4 test]# file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=df46beba08e4aa6be11d46e71b91645ce0a94d40, for GNU/Linux 3.2.0, with debug_info, not stripped
[root@GIGABYTEU4 test]# ./test
EXCEPTION: Something went wrong!
 0# 0x000000000040257E in ./test
 1# 0x00007BFC91E295D0 in /lib64/libc.so.6
 2# __libc_start_main in /lib64/libc.so.6
 3# 0x00000000004023C5 in ./test
[root@GIGABYTEU4 test]#
// 2. Chỉ có "-rdynamic"
[root@GIGABYTEU4 test]# g++ -rdynamic test.cpp -o test
[root@GIGABYTEU4 test]# file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=ef022513dea6829d613e0a383925aa3fa1a34376, for GNU/Linux 3.2.0, not stripped
[root@GIGABYTEU4 test]# ./test
EXCEPTION: Something went wrong!
 0# main in ./test
 1# 0x00007E64F2A295D0 in /lib64/libc.so.6
 2# __libc_start_main in /lib64/libc.so.6
 3# _start in ./test
[root@GIGABYTEU4 test]#
// 3. Cả "-g" và "-rdynamic"
[root@GIGABYTEU4 test]# g++ -g -rdynamic test.cpp -o test
[root@GIGABYTEU4 test]# file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fe6dfc49e62c900a09db785f244ccd9ea24580d4, for GNU/Linux 3.2.0, with debug_info, not stripped
[root@GIGABYTEU4 test]# ./test
EXCEPTION: Something went wrong!
 0# main in ./test
 1# 0x000079EC6E8295D0 in /lib64/libc.so.6
 2# __libc_start_main in /lib64/libc.so.6
 3# _start in ./test
[root@GIGABYTEU4 test]#

Leave a Comment