แม้ว่าจะมีการให้คำตอบที่ถูกต้องซึ่งอธิบายถึงวิธีการใช้backtrace()ฟังก์ชันGNU libc 1และฉันได้ให้คำตอบของตัวเองที่อธิบายถึงวิธีการตรวจสอบย้อนหลังจากจุดจัดการสัญญาณไปยังตำแหน่งที่แท้จริงของความผิด2ฉันไม่เห็น การเอ่ยถึงการถอดสัญลักษณ์ C ++ ใด ๆ ออกมาจาก backtrace
เมื่อได้รับ backtraces จากโปรแกรม C ++ เอาต์พุตสามารถรันผ่านc++filt1เพื่อลดสถานะของสัญลักษณ์หรือโดยใช้1โดยตรงabi::__cxa_demangle
- 1   Linux & OS X
 โปรดสังเกตว่า
c++filtและ__cxa_demangleเฉพาะ GCC 
- 2   ลินุกซ์
 
ตัวอย่าง C ++ Linux ต่อไปนี้ใช้ตัวจัดการสัญญาณเดียวกับคำตอบอื่น ๆของฉันและแสดงให้เห็นถึงวิธีการที่c++filtสามารถนำมาใช้เพื่อลดความซับซ้อนของสัญลักษณ์
รหัส :
class foo
{
public:
    foo() { foo1(); }
private:
    void foo1() { foo2(); }
    void foo2() { foo3(); }
    void foo3() { foo4(); }
    void foo4() { crash(); }
    void crash() { char * p = NULL; *p = 0; }
};
int main(int argc, char ** argv)
{
    // Setup signal handler for SIGSEGV
    ...
    foo * f = new foo();
    return 0;
}
ผลลัพธ์ ( ./test):
signal 11 (Segmentation fault), address is (nil) from 0x8048e07
[bt]: (1) ./test(crash__3foo+0x13) [0x8048e07]
[bt]: (2) ./test(foo4__3foo+0x12) [0x8048dee]
[bt]: (3) ./test(foo3__3foo+0x12) [0x8048dd6]
[bt]: (4) ./test(foo2__3foo+0x12) [0x8048dbe]
[bt]: (5) ./test(foo1__3foo+0x12) [0x8048da6]
[bt]: (6) ./test(__3foo+0x12) [0x8048d8e]
[bt]: (7) ./test(main+0xe0) [0x8048d18]
[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]
[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]
Demangled Output ( ./test 2>&1 | c++filt):
signal 11 (Segmentation fault), address is (nil) from 0x8048e07
[bt]: (1) ./test(foo::crash(void)+0x13) [0x8048e07]
[bt]: (2) ./test(foo::foo4(void)+0x12) [0x8048dee]
[bt]: (3) ./test(foo::foo3(void)+0x12) [0x8048dd6]
[bt]: (4) ./test(foo::foo2(void)+0x12) [0x8048dbe]
[bt]: (5) ./test(foo::foo1(void)+0x12) [0x8048da6]
[bt]: (6) ./test(foo::foo(void)+0x12) [0x8048d8e]
[bt]: (7) ./test(main+0xe0) [0x8048d18]
[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]
[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]
บิลด์ต่อไปนี้สร้างขึ้นบนตัวจัดการสัญญาณจากคำตอบดั้งเดิมของฉันและสามารถแทนที่ตัวจัดการสัญญาณในตัวอย่างข้างต้นเพื่อสาธิตวิธีที่abi::__cxa_demangleสามารถใช้ในการทำให้สถานะสัญลักษณ์ลดลง ตัวจัดการสัญญาณนี้สร้างเอาต์พุต demangled เดียวกันกับตัวอย่างข้างต้น
รหัส :
void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)
{
    sig_ucontext_t * uc = (sig_ucontext_t *)ucontext;
    void * caller_address = (void *) uc->uc_mcontext.eip; // x86 specific
    std::cerr << "signal " << sig_num 
              << " (" << strsignal(sig_num) << "), address is " 
              << info->si_addr << " from " << caller_address 
              << std::endl << std::endl;
    void * array[50];
    int size = backtrace(array, 50);
    array[1] = caller_address;
    char ** messages = backtrace_symbols(array, size);    
    // skip first stack frame (points here)
    for (int i = 1; i < size && messages != NULL; ++i)
    {
        char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
        // find parantheses and +address offset surrounding mangled name
        for (char *p = messages[i]; *p; ++p)
        {
            if (*p == '(') 
            {
                mangled_name = p; 
            }
            else if (*p == '+') 
            {
                offset_begin = p;
            }
            else if (*p == ')')
            {
                offset_end = p;
                break;
            }
        }
        // if the line could be processed, attempt to demangle the symbol
        if (mangled_name && offset_begin && offset_end && 
            mangled_name < offset_begin)
        {
            *mangled_name++ = '\0';
            *offset_begin++ = '\0';
            *offset_end++ = '\0';
            int status;
            char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
            // if demangling is successful, output the demangled function name
            if (status == 0)
            {    
                std::cerr << "[bt]: (" << i << ") " << messages[i] << " : " 
                          << real_name << "+" << offset_begin << offset_end 
                          << std::endl;
            }
            // otherwise, output the mangled function name
            else
            {
                std::cerr << "[bt]: (" << i << ") " << messages[i] << " : " 
                          << mangled_name << "+" << offset_begin << offset_end 
                          << std::endl;
            }
            free(real_name);
        }
        // otherwise, print the whole line
        else
        {
            std::cerr << "[bt]: (" << i << ") " << messages[i] << std::endl;
        }
    }
    std::cerr << std::endl;
    free(messages);
    exit(EXIT_FAILURE);
}