Windows堆栈跟踪中的函数名称

问题描述:

如何恢复堆栈跟踪函数名称而不是<UNKNOWN>Windows堆栈跟踪中的函数名称

 
    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) 
+2

这是什么意思?“不是真正的问题”? – 2010-01-11 16:08:04

+1

@尼尔,我怀疑在编辑之前,人们在阅读所要求的内容时有困难。 – 2010-01-11 17:15:59

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

至少这是它在Delphi中的工作原理。我也知道Visual Studio中的这种可能性。

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

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

+0

我在VS 2005中加载了exe文件,输入这个地址0xE06D7363到地址下拉菜单中,它显示???在显示屏上,请帮忙? – Sanjiv 2010-01-11 17:16:18

+0

在VS 2005中启动应用程序,在调试模式下运行它。在断点处停下来。右键单击任何源代码行,然后单击“转到Dissasembly”。你会找到Adresses。 – 2010-01-11 19:53:10

获得程序,objdump它完全相同的构建,并看看是在地址什么功能。如果符号名已从可执行文件中删除,这可能有点困难。

如果程序代码以任何方式动态的,你可能有它碰上一个调试器找到函数的地址。

如果程序被故意混淆和讨厌,并且它在运行时以某种方式随机分配了它的函数地址(像病毒这样的逃避东西,或者防拷贝代码有时会这样做),那么所有的投注都关闭。

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

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

我用StackWalker - 只是把它编译成你的程序的源代码,如果它崩溃,你可以在那时产生一个堆栈跟踪,包括函数名。

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

这可能不是这里的情况:“77E4BEF7”是非常高的概率在Windows DLL,并006DFAC7在你的模块中的地址。你不需要这样的PDB文件:Windows应该总是知道模块名称(.EXE或.DLL) - 事实上,它首先需要该模块名称才能找到正确的PDB文件。

现在,剩下的问题是为什么你没有模块信息。这我从上面的信息不能告诉。您需要有关实际系统的信息。例如,如果有DEP吗?您的流程是否启用了DEP?