8

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

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

4

2 回答 2

1

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

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

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

于 2013-04-29T15:36:21.640 回答
1

对我有用的是下面的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);
    }
  }
于 2015-07-08T18:41:31.460 回答