【问题标题】:How can a stack trace be used to determine the cause of a crash?如何使用堆栈跟踪来确定崩溃的原因?
【发布时间】:2020-11-29 15:21:04
【问题描述】:

我了解堆栈跟踪背后的“大创意”,但实际上如何使用堆栈跟踪来确定崩溃的原因?例如,我正在编写一个 c++ 宏,而我的解释器会输出以下堆栈跟踪:

>  *** Break *** illegal instruction
> 
> 
> 
> =========================================================== There was a crash. This is the entire stack trace of all threads:
> ===========================================================
> #0  0x00007fb64ef29bbc in waitpid () from /lib64/libc.so.6
> #1  0x00007fb64eea7ea2 in do_system () from /lib64/libc.so.6
> #2  0x00007fb64ffb3d84 in TUnixSystem::StackTrace (this=0x98e960) at /cvmfs/myusername/trunk/centos7/source/root-6.16.00/core/unix/src/TUnixSystem.cxx:2413
> #3  0x00007fb64ffb64bc in TUnixSystem::DispatchSignals (this=0x98e960, sig=kSigIllegalInstruction) at
> /cvmfs/myusername/trunk/centos7/source/root-6.16.00/core/unix/src/TUnixSystem.cxx:3644
> #4  <signal handler called>
> #5  0x00007fb65057f54a in ?? ()
> #6  0x000000000146e4ec in ?? ()
> #7  0x000000000028dc9d in ?? ()
> #8  0x0028dcf80146e51c in ?? ()
> #9  0x00007ffd08a37890 in ?? ()
> #10 0x0000000000051b93 in ?? ()
> #11 0x000000000000a372 in ?? ()
> #12 0x0000a3e900051c01 in ?? ()
> #13 0x000000000000146e in ?? ()
> #14 0x00007ffd08a3788f in ?? ()
> #15 0x0000000000000000 in ?? ()
> ===========================================================
> 
> 
> The lines below might hint at the cause of the crash. You may get help
> by asking at the ROOT forum http://root.cern.ch/forum Only if you are
> really convinced it is a bug in ROOT then please submit a report at
> http://root.cern.ch/bugs Please post the ENTIRE stack trace from above
> as an attachment in addition to anything else that might help us
> fixing this issue.
> ===========================================================
> #5  0x00007fb65057f54a in ?? ()
> #6  0x000000000146e4ec in ?? ()
> #7  0x000000000028dc9d in ?? ()
> #8  0x0028dcf80146e51c in ?? ()
> #9  0x00007ffd08a37890 in ?? ()
> #10 0x0000000000051b93 in ?? ()
> #11 0x000000000000a372 in ?? ()
> #12 0x0000a3e900051c01 in ?? ()
> #13 0x000000000000146e in ?? ()
> #14 0x00007ffd08a3788f in ?? ()
> #15 0x0000000000000000 in ?? ()
> ===========================================================

【问题讨论】:

    标签: c++ crash stack interpreter root-framework


    【解决方案1】:

    堆栈跟踪背后的想法是查看崩溃时谁在调用谁。因此,您可以检查产生故障的函数并查看它是如何被调用的。
    您在示例中看到的是函数的地址,当然,如果堆栈以某种方式损坏,您也可以找到无效地址。
    要查看更多有用的信息,您应该使用调试信息编译代码,这样您不仅会看到地址,还会看到函数的名称。 例如,在 gcc 中,您可以使用“-g”启用调试信息,即:

    gcc -g test.c -o test
    

    以下是“test.c”错误代码的示例:

    void foo()
    {
        int a=1/0;
    }
    void foo1()
    {
        foo();
    }
    void foo2()
    {
        foo1();
    }
    void foo3()
    {
        foo2();
    }
    
    int main()
    {
        foo3();
    };
    
    

    这是它产生的回溯(在 gdb 中运行,信息可用,因为我使用 -g 标志进行编译)

    #0  0x0000000000401101 in foo () at test.c:3
    #1  0x0000000000401117 in foo1 () at test.c:7
    #2  0x0000000000401128 in foo2 () at test.c:11
    #3  0x0000000000401139 in foo3 () at test.c:15
    #4  0x000000000040114a in main () at test.c:20
    
    

    【讨论】:

    • 是的,用调试信息编译程序(-g)
    • 如果您将代码作为根世界中所谓的宏(root myfile.C 或根提示符.L myfile.C.x myfile.C)运行,一个选项是加载宏编译root myfile.C+/.L myfile.C+/.x myfile.C+,然后你可以通过附加一个groot myfile.C+g/.L myfile.C+g/.x myfile.C+g来添加调试信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    相关资源
    最近更新 更多