8

C++アプリケーションからスタックトレースを取得し、後で解析できるように文字列にシリアル化する必要があります。私がWindows上でこれについて聞いた唯一のAPIはStackWalk64で、これはサポートされていないようです。WinRTのC++からスタックトレースを取得するにはどうすればよいですか?

WindowsストアアプリケーションでC++からスタックトレースを取得するにはどうすればよいですか?

+1

これはできません。 C++コードは、信頼性の高いスタックウォークを可能にするにはあまりにも大きく最適化されています。ミニダンプを使用してC++のクラッシュを診断します。 Storeアプリではやりにくい。 –

+2

ユーザーには、アプリケーションがクラッシュしたときにWindowsがクラッシュダンプを送信できるようにするオプションがあります。ダッシュボードにクラッシュダンプが表示されますので、ダウンロードしてデバッガで開くことができます。 –

+0

C#コードでもこれは不可能です。インライン展開とテールコールは、スタックの歩き方を完全に信頼できないものにします。このため、GetCallingAssemblyと関連するC#呼び出しがWindows 8 .NETプロファイルから削除されています。 dbghelp.dllは機能が存在する場所であり、はい、Windows 8 Storeアプリケーションではサポートされていません。先に進んでほしいと思ったらリクエストしてください。しかし、私の本の中で最も優先順位の高いものがあります:-) –

答えて

1

複雑なWINRTの問題をデバッグできる唯一の方法は、ETWを使用して因果関係を追跡することです。退屈な一種のセットアップにこの記事(のC#を参照しては)メソッド強調している間:ここ

をC/C++のためのETWにまともな紹介のカップルです。博士Insungパークとリッキー・ブーフにより、MSDNの記事で

を疑問視イベントは、アプリケーションでそれらをリッスンし、後で分析のためのシリアル化された文字列としてそれらを含める。

0

私のために働いたのは以下の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); 
    } 
    } 
関連する問題