C++ アプリケーションからスタック トレースを取得し、後で解析できるように文字列にシリアル化する必要があります。Windows でこれについて私が聞いた唯一の API は StackWalk64 ですが、これはサポートされていないようです。
Windows ストア アプリで C++ からスタック トレースを取得するにはどうすればよいですか?
C++ アプリケーションからスタック トレースを取得し、後で解析できるように文字列にシリアル化する必要があります。Windows でこれについて私が聞いた唯一の API は StackWalk64 ですが、これはサポートされていないようです。
Windows ストア アプリで C++ からスタック トレースを取得するにはどうすればよいですか?
私にとってうまくいったのは、以下の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);
}
}
複雑な WINRT の問題をデバッグできた唯一の方法は、ETW を使用して因果関係の連鎖を追跡することです。この記事では (c# を参照しながら)、次の方法を強調しています。
C/C++ の ETW の適切な紹介をいくつか紹介します。
このメソッドを使用すると、ETW イベントを作成してアプリでリッスンし、後で分析するためにシリアル化された文字列として含めることができます。