-PR-
解決済みの質問
質問:No.1521718
困ってます
お気に入り投稿に追加する (0人が追加しました)
回答数3
閲覧数644
メモリ内をトレースログに吐きたい
自分で作成しているログファイルに、メモリ内のデータを吐き出したいんですが、やり方がわかりません。
これでは何がやりたいかがよくわからないと思うので、具体例を。
VisualStudioなんかでデバッグしたときに、メモリウィンドウが使えますよね?
そのウィンドウの表示のように吐き出したいんです。
投稿日時 - 2005-07-18 16:25:58
質問者が選んだベストアンサー
回答:No.2
所謂ダンプリストの作成方法が判らない、と言う事ですよね。
検索すればいくらでも引っ掛かると思いますが、とりあえずソースが有りそうなのを...
投稿日時 - 2005-07-18 21:20:44
この回答を支持する
(現在0人が支持しています)
この質問は役に立ちましたか?
0人が「このQ&Aが役に立った」と投票しています
ベストアンサー以外の回答
回答:No.3
「メモリダンプを行うプログラムの作成」自体が目的であれば、回答No1.と回答No.2の組み合わせでできますよね。

「デバッグのため、事後にメモリの内容を見たい」ということが目的であれば、自前でメモリを参照しダンプファイルを作成するのはあまり効率が良くありません。DbgHelpライブラリにあるMiniDumpWriteDump()でミニダンプファイルを作成すれば、Visual Studio .NETの統合環境で直接、ソースレベルで変数の内容を確認したり、実行当時のメモリ内容を確認したりできるのでお勧めです。

普段なら「詳細はヘルプを見れば分かります」と書くところなのですが、あまり馴染みのないAPIなのでプログラムを書いてテストしてみました。(インデントは全角空白なのでコピー&ペースト時は注意。)

DWORD WINAPI MinidumpThread(PVOID pv)
{
  HANDLE hFile = CreateFile(
    "c:\\tmp\\minidump.dmp",
    GENERIC_WRITE,
    0,
    NULL,
    CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    NULL
    );
  MiniDumpWriteDump(
    GetCurrentProcess(),
    GetCurrentProcessId(),
    hFile,
    MINIDUMP_TYPE(MiniDumpWithFullMemory | MiniDumpWithHandleData),
    NULL,
    NULL,
    NULL
    );
  CloseHandle(hFile);
  return 0;
}

void CreateMinidump()
{
  DWORD dw;
  HANDLE hThread = CreateThread(NULL, 0, MinidumpThread, NULL, 0, &dw);
  WaitForSingleObject(hThread, INFINITE);
  CloseHandle(hThread);
}

CreateMinidump()を呼ぶとc:\tmp\minidump.dmpを作成します。なぜこういう構造にしてあるのか、エラーチェックはどうやるのか等は、ヘルプを見て自分で考えてください。

CreateMinidump()を呼んでc:\tmp\minidump.dmpが無事に作成されたとします。そうすると、これを使って事後ソースレベルデバッグができます。やり方はこうです。

1. Visual Studio .NETを起動する。
2. ファイル(F)→開く(O)→プロジェクト(P)...でc:\tmp\minidump.dmpを開く。
3. デバッグ(D)→開始(S)でデバッグ開始。この段階で、実行中のプログラムをブレークポイントで止めたのと同じ状態になります。
4. 初回のデバッグ開始時のみソリューションファイルの保存を迫られるので、どこか適当な場所に保存。
5. スレッドペインでCreateMinidump()のスレッドを選択する。シングルスレッドアプリであればCreateMinidump()のスレッド(メインスレッド)とMinidumpThread()のスレッドの2つしかないので探しやすいはず。マルチスレッドの場合は・・・通常のライブデバッグ時と手順は同じですので、根性と常識で探しましょう。
6. 呼び出し履歴ペインでCreateMinidump()を選択する。WaitForSingleObject()で止まっているはず。
7. あとはローカル変数ペインでCreateMinidump()の中のhThreadの値を見るでも、メモリペインで適当なメモリアドレスのメモリの内容を見るでも、はたまたWinMain()まで呼び出し履歴を遡ってlpCmdLineを観察するでも、ご自由にどうぞ。デバッグ(D)→続行(C)以外は何でもできます。(えー、まぁ、「コード変更を適用」とかはできないですな。その辺は常識とヘルプで判断してください。)
8. 最後にデバッグ(D)→デバッグの停止(E)でデバッグを終了。
投稿日時 - 2005-07-18 23:07:36
この回答を支持する
(現在0人が支持しています)
回答:No.1
windowsですよね?

自プロセスのメモリ空間でしたら、直接ポインタにアドレスを書き込んで、アクセスしても大丈夫だとおもいます。(もちろん、論理的に確保されていないorアクセスが許可されていないメモリブロックにアクセスするとアクセスバイオレーションエラーが発生します。)

もっと行儀よく、自プロセスのメモリをみたい、とか、他プロセスのメモリを見たいと思うなら、
・VirtualAllocEx (WinNT以降)
・ReadProcessMemory
といったAPIを調べられるとよいです。
投稿日時 - 2005-07-18 16:45:43
この回答を支持する
(現在0人が支持しています)
補足
すいません。説明が悪かったようで。
中を見るのではなく、メモリの内容をファイルに出力して、後からそのファイルを見たいんです。
出力形式はメモリウィンドウ見たいな感じでです。
投稿日時 - 2005-07-18 17:30:22
もっと聞いてみる
関連するQ&Aはこちら
デバッグでブレークポイントを挿入した後の操作がわかりません。 1行ずつ実行していきたいのですが、普段は怪しそうな箇所にprintfを挿入してデバッグしていたのでやり方を忘れてしまいました。 調べても初...
XPの機能にシステムエラーのデバック情報を残す「完全メモリダンプ」なるものがあると思うのですが、これはいつのタイミングでどのような事態が発生した場合に吐き出されるのでしょうか?コンセントをいきなり抜く...
いつもお世話になります。  VisualStudio でコンソールプログラム(Win32 Console Application)を開発しています。  VisualStudio は、.Net ではな...
この他の関連するQ&Aをキーワードで探す
プログラミングのサブカテゴリ
カテゴリ:C・C++
RSS
-PR-
PR
-PR-