Windows堆栈跟踪中的函数名称

时间:2010-01-11 16:00:18

标签: c++ windows stack stack-trace

如何恢复堆栈跟踪功能名称而不是<UNKNOWN>

    Event Type: Error
    Event Source:   abcd
    Event Category: None
    Event ID:   16
    Date:       1/3/2010
    Time:       10:24:10 PM
    User:       N/A
    Computer:   CMS01
    Description:
    Server.exe caused a  in module  at 2CA001B:77E4BEF7

    Build 6.0.0.334

    WorkingSetSize: 1291071488 bytes

    EAX=02CAF420  EBX=00402C88  ECX=00000000  EDX=7C82860C  ESI=02CAF4A8
    EDI=02CAFB68  EBP=02CAF470  ESP=02CAF41C  EIP=77E4BEF7  FLG=00000206
    CS=2CA001B   DS=2CA0023  SS=7C820023  ES=2CA0023   FS=7C82003B  GS=2CA0000

    2CA001B:77E4BEF7 (0xE06D7363 0x00000001 0x00000003 0x02CAF49C) 
    2CA001B:006DFAC7 (0x02CAF4B8 0x00807F50 0x00760D50 0x007D951C) 
    2CA001B:006DFC87 (0x00003561 0x7F6A0F38 0x008E7290 0x00021A6F) 
    2CA001B:0067E4C3 (0x00003561 0x00000000 0x02CAFBB8 0x02CAFB74) 
    2CA001B:00674CB2 (0x00003561 0x006EBAC7 0x02CAFB68 0x02CAFA64) 
    2CA001B:00402CA4 (0x00003560 0x00000000 0x00000000 0x02CAFBB8) 
    2CA001B:00402B29 (0x00003560 0x00000001 0x02CAFBB8 0x00000000) 
    2CA001B:00683096 (0x00003560 0x563DDDB6 0x00000000 0x02CAFC18) 
    2CA001B:00688E32 (0x02CAFC58 0x7C7BE590 0x00000000 0x00000000) 
    2CA001B:00689F0C (0x02CAFC58 0x7C7BE590 0x00000000 0x00650930) 
    2CA001B:0042E8EA (0x7F677648 0x7F677648 0x00CAFD6C 0x02CAFD6C) 
    2CA001B:004100CA (0x563DDB3E 0x00000000 0x00000000 0x008E7290) 
    2CA001B:0063AC39 (0x7F677648 0x02CAFD94 0x02CAFD88 0x77B5B540) 
    2CA001B:0064CB51 (0x7F660288 0x563DD9FE 0x00000000 0x00000000) 
    2CA001B:0063A648 (0x00000000 0x02CAFFEC 0x77E6482F 0x008E7290) 
    2CA001B:0063A74D (0x008E7290 0x00000000 0x00000000 0x008E7290) 
    2CA001B:77E6482F (0x0063A740 0x008E7290 0x00000000 0x00000000) 

5 个答案:

答案 0 :(得分:1)

获取完全相同的程序版本objdump,然后查看该地址的函数。如果符号名称已从可执行文件中删除,则可能有点困难。

如果程序代码以任何方式动态化,您可能必须将其运行到调试器中以查找函数的地址。

如果程序被故意混淆和讨厌,并且它在运行时以某种方式随机化其功能地址(像病毒这样的回避或复制保护代码有时会这样做)那么所有的赌注都会关闭。

一般来说: 找出导致崩溃的原因的最简单方法是遵循在调试器中运行的应用程序实例中重现它所需的步骤。所有其他方法都困难得多。这就是为什么开发人员通常不会花时间尝试解决没有已知方法来重现的错误。

答案 1 :(得分:0)

尝试从IDE运行相同的构建,暂停它并跳转到程序集中的地址。然后你可以切换到源代码并查看那里的函数。

至少它是如何在Delphi中运行的。我也在Visual Studio中了解这种可能性。

如果您没有内置IDE,则必须使用类似OllyDbg的调试器。运行导致错误的exe并在OllyDbg中暂停应用程序。从堆栈跟踪转到地址。 在IDE中打开一个类似的应用程序项目,运行它并暂停它。搜索您在OllyDbg中看到的相同二进制模式,然后切换到源代码。

我知道的最后一种可能性是分析地图文件,如果你在构建过程中构建它。

答案 2 :(得分:0)

发生崩溃时,您需要在exe旁边有调试信息文件(.pdb) 然后,希望您的崩溃转储代码可以加载它并使用其中的信息。

答案 3 :(得分:0)

我使用StackWalker - 只需将其编译到程序源中,如果崩溃,您可以在此时生成堆栈跟踪,包括函数名称。

答案 4 :(得分:0)

最常见的原因是您实际上没有指定地址的模块。这可能发生在例如当您取消引用未初始化的函数指针,或使用无效的this指针调用虚函数时。

这可能不是这种情况:“77E4BEF7”很可能是一个Windows DLL,006DFAC7是一个模块中的地址。您不需要PDB文件:Windows应始终知道模块名称(.EXE或.DLL) - 实际上,它首先需要该模块名称才能找到正确的PDB文件。

现在,剩下的问题是你没有模块信息的原因。我从上面的信息中无法分辨出来。您需要有关实际系统的信息。例如,如果有DEP?是否为您的流程启用了DEP?