【问题标题】:Function name from Windows stack traceWindows 堆栈跟踪中的函数名称
【发布时间】:2011-01-03 19:39:15
【问题描述】:

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

事件类型:错误 事件来源:abcd 事件类别:无 事件编号:16 日期:2010 年 1 月 3 日 时间:晚上 10:24:10 用户:不适用 电脑:CMS01 描述: Server.exe 在 2CA001B:77E4BEF7 处导致一个 in 模块 构建 6.0.0.334 工作集大小:1291071488 字节 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)

【问题讨论】:

  • 在什么意义上这个“不是一个真正的问题”?
  • @Neil,我怀疑在编辑之前人们很难阅读所询问的内容。

标签: c++ windows stack stack-trace


【解决方案1】:

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

如果程序代码是动态的,您可能必须将其运行到调试器中才能找到函数的地址。

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      尝试从您的 IDE 运行相同的构建,暂停它并跳转到汇编中的地址。然后你可以切换到源代码,看看那里的功能。

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

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

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

      【讨论】:

      • 我在VS 2005中加载了exe,在地址下拉列表中输入了这个地址0xE06D7363,它显示???在显示中,请帮忙?
      • 在 VS 2005 中启动应用程序,在调试模式下运行它。在断点处停止。右键单击任何源代码行,然后单击“Go To Dissasembly”。在那里你会找到地址。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

        现在,剩下的问题是为什么您没有模块信息。从上面的信息中我无法判断。您需要有关实际系统的信息。例如,是否有 DEP?您的流程是否启用了 DEP?

        【讨论】:

          猜你喜欢
          • 2017-04-01
          • 1970-01-01
          • 2018-07-13
          • 2018-09-26
          • 2015-10-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-06
          • 1970-01-01
          相关资源
          最近更新 更多