【问题标题】:How can I get a stacktrace from C++ in WinRT?如何在 WinRT 中从 C++ 获取堆栈跟踪?
【发布时间】:2013-01-31 18:32:49
【问题描述】:

我需要从 C++ 应用程序中获取堆栈跟踪,并将其序列化为字符串,以便稍后对其进行解析。我在 Windows 上听说过的唯一 API 是 StackWalk64,它似乎不受支持。

如何在 Windows 应用商店应用程序中从 C++ 获取堆栈跟踪?

【问题讨论】:

  • 这是不可能的。 C++ 代码被过度优化以允许可靠的堆栈遍历。您使用小型转储诊断 C++ 崩溃。在商店应用中很难找到。
  • 用户可以选择让 Windows 在应用程序崩溃时发送崩溃转储。然后,您可以在仪表板中看到故障转储,以便下载并在调试器中打开它。
  • 这在 C# 代码中也是不可能的。内联和尾调用将使您的堆栈遍历完全不可靠。由于这个原因,GetCallingAssembly 及其相关的 C# 调用已从 Windows 8 .NET 配置文件中删除。 dbghelp.dll 是功能所在的位置,是的,Windows 8 应用商店应用程序不支持它。如果您愿意,请继续申请,但在我的书中有一长串优先级更高的东西:-)
  • @HansPassant 实际上在 Windows CE(C++ 应用程序)下我能够获得非常好的 .exe-s 版本的堆栈跟踪。我使用地图文件和 GetThreadCallStack 函数。

标签: c++ exception windows-runtime stack-trace windows-store-apps


【解决方案1】:

我能够调试复杂 WINRT 问题的唯一方法是使用 ETW 跟踪因果链。虽然设置起来有点乏味这篇文章(同时参考 c#)重点介绍了该方法:

这里有一些关于 C/C++ 的 ETW 的不错的介绍。

使用此方法,您应该能够创建 ETW 事件,然后在应用程序中侦听它们,并将它们作为序列化字符串包含在以后进行分析。

【讨论】:

    【解决方案2】:

    对我有用的是下面的 asm 代码。这仅适用于 x86 平台,因此仅在模拟器上调试时有用。返回的帧指针可用于反汇编窗口跳转到源代码。我认为应该可以使用地图文件来获取确切的源代码位置。

    我使用这段代码来查找内存泄漏,结合 crtdbg 它在具有大量分配的大型应用程序中运行良好。 VS 2013 内存分析器最多可以处理 1 分钟的数据记录。

      FINLINE static DWORD GetCallerFrameNum(int index) {
    #if defined(_DEBUG) && defined(_MSC_VER) && defined(_M_IX86)
    
        DWORD caller = 0;
        __asm
        {
          mov ebx, ebp
            mov ecx, index
            inc ecx
            xor eax, eax
          StackTrace_getCaller_next :
          mov eax, [ebx + 4]
            mov ebx, [ebx]
            dec ecx
            jnz StackTrace_getCaller_next
            mov caller, eax
        }
        return caller;
    
    #else
    
        return 0;
    
    #endif
      }
    
      template<class T>
      void RecordStackTrace(T& vecOut) {
        vecOut.clear();
        vecOut.reserve(32);
        for (INT iInitLevel = 1; iInitLevel < 32; ++iInitLevel) {
          DWORD dwFrameNum = GetCallerFrameNum(iInitLevel);
          if (!dwFrameNum)
            return;
          vecOut.push_back(dwFrameNum);
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2010-09-11
      • 2010-11-10
      • 1970-01-01
      • 1970-01-01
      • 2019-10-02
      • 2011-06-01
      • 2016-09-03
      • 1970-01-01
      • 2010-10-11
      相关资源
      最近更新 更多