[VisualStudio/ダンプ] ProcDumpを使ったダンプファイルの作成と解析、に関する実験

**もくじ**
→https://qiita.com/tera1707/items/4fda73d86eded283ec4f

# ダンプ関連記事

https://tera1707.com/entry/2022/02/06/144447#WindowsDump


# やったこと

ダンプファイル(.dmp)をVisualStudio2019で開くと、あたかもデバッグ実行でbreakで停止させたときのように、ダンプを出力したとき(≒アプリが落ちたとき)をデバッグできるということを知った。

ただ、どういう条件かよくわからないが、そいういう風にデバッグできるときとできないときがある。（ソースコードがありません、みたいなエラーが出るときがある）

なにがあれば何ができるのか？MSの公式ページに説明があるっぽいが呼んだだけだとよくわからないので、動かして試してみる。

# 実験内容

軽く試したところ、どうもexe、pdb、ビルド時のソースコードのファイルが、ビルド時と同じフォルダに置いてある/おいてない、で、デバッグできる/できないが変わってくるような感じがする。

そこで、[以前の記事](https://qiita.com/tera1707/items/26b7d19e7ae1b4978f9f#%E3%82%84%E3%82%8A%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8)で採取したダンプファイルについて、exe、pdb、コードを、**ビルド時と同じパスに置いた状態/置いてない状態**(削除した状態)でダンプファイルをVS2019で開いてみて、どういう表示がでるか確認した。

> 以前の記事でのprocdumpを呼ぶときのパラメータは下記の通り。
> `procdump -w -ma -e -f *Violation* WpfApp48.exe`

また、とれるダンプファイルには、procdumpに渡す引数によって、いくつか種類があるようなので、それぞれを使ったときに、できることできないことがどう変わるのか、確認した。
(今回は上のprocdumpを呼ぶときのダンプの種類のパラーメータを、`-mm`,`-ma`,`-mp`の3種類に変化させて試した。)

# とれるダンプの種類と使ったパラメータの意味

[こちら](https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2011/december/sysinternals-procdump-v4-0-writing-a-plug-in-for-sysinternals-procdump-v4-0#%E7%94%A8%E8%AA%9E)によると、取れるダンプの種類は下記の3つがありそう。

|とるダンプを指定するコマンド|説明|
|:--|:--|
|-mm|ミニダンプ。<br>プロセス環境ブロック (PEB)、スレッド環境ブロック (TEB)、スタックの一部、読み込んだモジュール、およびデータ セグメントを含む。|
|-mp|ミニプラスダンプ。<br>Mini ダンプのコンテンツに加えて (plus)、ヒューリスティックに重要と判断されるメモリを含む。|
|-ma|フルダンプ。<br>プロセスの仮想アドレス空間をすべて含む。|

また、procdumpに渡せるパラメータには様々なものがあるが、今回実験に使用したのは下記のパラメータ。([以前の記事](https://qiita.com/tera1707/items/26b7d19e7ae1b4978f9f#procdump%E5%AE%9F%E8%A1%8C%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%92%E6%B1%BA%E3%82%81%E3%82%8B)も参照。)

|その他コマンド|説明|
|:--|:--|
|-w|対象のプロセスが起動するまで待つ。<br>指定しないと、procdump起動時「そんなプロセス起動してないよ」と言ってprocdump終わってまう|
|-e|例外が起きた時にダンプファイルを取るようにする。※|
|-f <例外の名前>|ダンプをとる例外を指定する。<br>指定の際は「*」も使える。|

# 実験結果

取るダンプの種類と各種ファイルのありなしの組み合わせで、下記のようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/a0435d75-b4be-3c6b-199e-0fae6355112c.png)

×１：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/03ee312d-bd50-d589-c3a3-c7966e5b37b7.png)

×２
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/ece2c2c0-5e49-70b6-92d3-fa49cc6b31ff.png)


×３
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/cbfc0ce1-2dd5-1122-a452-2c0082ceca9d.png)

# 考察

上記検証から、

- ダンプファイル(少なくとも`-ma`でとったダンプファイル)でデバッグするときは、pdbファイルの有無は関係ないっぽい。
- `-ma`を付けてprocdumpでダンプファイルをとれば、一番デバッグしやすそう。
- ダンプファイルにはソースコードの位置まで入ってる(ビルドしたときのコードのパス＝開発者PC上でのパス)ので、開発者のPCだと、ダンプファイルを開くだけで、コードが開かれる(ただしexeもないとダメ)

とりあえず今回のケース([今回のケースとはこちら](https://qiita.com/tera1707/items/26b7d19e7ae1b4978f9f#%E5%89%8D%E6%8F%90))で行くと、デバッグのしやすさだけで行くと、テスターの方にお願いして`-ma`でダンプを取ってもらって、開発した人の(=exeやコードがビルド時の場所に一式そろっている)PCでデバッグするのが一番速そう。(あたりまえ？)


# 追記（VisualStudio2022）

VS2022のVersion 17.9.6 で、同じことができるかを試した。


結果、上でやった、VS2019のときと同じことができた。

ただ、しばらく、pdbはあるけどソースコードが見つからないときに出てくる下図の「ソースファイルの検索」画面がでるはずが出てこないという現象が起きていた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/5749719b-9066-82fc-31f1-72227b029951.png)

ただこれは、pdbの「シンボルキャッシュを空にする」をしてやると、改善された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/6939f046-bad2-4c1b-6153-9967b08ca0e9.png)

同じアプリを何度も繰り返し、長期間にわたってダンプのデバッグをするような場合に、pdbのキャッシュがなにか悪さをするのかもしれない。何かあった場合は、キャッシュをけすとよいかもしれない。

# 参考／今後調べたいこと／その他メモ

procdumpの仕様（コマンドのパラメータなど）
https://docs.microsoft.com/ja-jp/sysinternals/downloads/procdump

VisualStudioでのダンプについて
https://docs.microsoft.com/ja-jp/visualstudio/debugger/using-dump-files?view=vs-2019

-mm、-ma、-mpの違い
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2011/december/sysinternals-procdump-v4-0-writing-a-plug-in-for-sysinternals-procdump-v4-0#%E7%94%A8%E8%AA%9E

ダンプの取り方
.NET Framework4.0以降は、VSにダンプを解析する機能がある？
https://social.msdn.microsoft.com/Forums/ja-JP/5c17740c-ad57-4ae7-a250-edd4bb0aee2c/net-framework?forum=netfxgeneralja

ワトソンに変わってWERという機能で、ユーザーダンプを作成できる？
→これが、前から知ってたレジスト履の設定変えたらcrash時にダンプができるやり方っぽい
https://support.citrix.com/article/CTX119302

ユーザーダンプ(アプリのクラッシュ時のダンプなど)を取りたい場合は、
User Mode Process Dumperというソフトを使う→しかしこれはXPまで？？
→本([これ](https://www.amazon.co.jp/Windows%E3%83%80%E3%83%B3%E3%83%97%E3%81%AE%E6%A5%B5%E6%84%8F-%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%97%E3%81%9F%E3%82%89%E3%80%81%E3%81%BE%E3%81%9A%E3%83%80%E3%83%B3%E3%83%97%E8%A7%A3%E6%9E%90-%E4%B8%8A%E5%8E%9F-%E7%A5%A5%E5%B8%82/dp/4048675095/ref=sr_1_1?adgrpid=107112967151&dchild=1&gclid=Cj0KCQjw7ZL6BRCmARIsAH6XFDIu5mneezT6Ig1ac167LyA1RElVclFsfYcdOEKP1esuV858UxYPYmQaAsRcEALw_wcB&hvadid=448369384768&hvdev=c&hvlocphy=1009547&hvnetw=g&hvqmt=b&hvrand=3313211882923015156&hvtargid=kwd-333741928731&hydadcr=15816_11177322&jp-ad-ap=0&keywords=%E3%83%80%E3%83%B3%E3%83%97%E3%81%AE%E6%A5%B5%E6%84%8F&qid=1598363834&sr=8-1&tag=googhydr-22))のP54に載ってる

今どきは、ProcDump を使う？？
https://docs.microsoft.com/ja-jp/sysinternals/downloads/procdump
https://troushoo.blog.fc2.com/blog-entry-99.html
https://troushoo.blog.fc2.com/blog-entry-100.html

・ダンプファイルをprocdumpでとるときに、ヒープを含めるようにしていると、別にpdbが無くても停止箇所のダンプのデバッグができる。ヒープを含めないようにしていると、pdbがないと、それができない？？
⇒https://devblogs.microsoft.com/devops/understanding-symbol-files-and-visual-studios-symbol-settings/
＞なぜシンボルが必要なのですか？ のところ。
⇒procdumpで、-ma(mp?)をつけてないと、pdbが必要になる？？？

VSでのダンプを使ったデバッグ
https://docs.microsoft.com/ja-jp/visualstudio/debugger/using-dump-files?view=vs-2019
- ダンプは主に、開発者がアクセスできないマシンからの問題をデバッグするために使用されます
- 注意
    - 最適化されたコードのデバッグ(≒Releaseビルド)は、制約アリ。(⇒最適化されたコードのダンプファイルのデバッグは・・・のところ)

シンボルとは？
https://devblogs.microsoft.com/devops/understanding-symbol-files-and-visual-studios-symbol-settings/

pdbonlyとは？
https://docs.microsoft.com/ja-jp/visualstudio/debugger/specify-symbol-dot-pdb-and-source-files-in-the-visual-studio-debugger?view=vs-2019#net-options