如何在WinRT中从C ++获取堆栈跟踪?

时间:2013-01-31 18:32:50

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

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

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

2 个答案:

答案 0 :(得分:1)

我能够调试复杂WINRT问题的唯一方法是使用ETW来跟踪因果关系链。虽然设置繁琐但本文(同时引用c#)突出显示了方法:

以下是ETW for C / C ++的一些不错的介绍。

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

答案 1 :(得分:1)

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

我使用此代码来查找内存泄漏,结合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);
    }
  }
相关问题