« PHP IDEでの実行結果をConsoleに表示する | トップページ | windbgを使ったデバッグ »

2006年12月 7日 (木)

drwtsn32を使ったデバッグ

Drwtsn32

最近、Windowsのネイティブアプリを作ってて、開発マシン以外でのデバッグにはまってる若い子に、

「あー、そういう時は、windbgとか、drwtsn32使うと楽だよ。」

と言って、使い方を教えてあげようとしたわけですよ。

そうしたら、さっぱり思い出せん!

もー、こんなんやってたの、4,5年前くらいだもんなー。

家に帰ってきて、昔のテキストを検索したら、使い方メモが出てきたので、今まとめ直してみようかと。

<<-- drwtsn32.logとmapファイルを使ったデバッグ -->>

とりあえず、Visual C++でメモリ破壊を起こしてアプリケーションエラーを起こすコードを書いて、ビルド、実行してみる。

#include <stdio.h>
#include <string.h>

int main()
{
    char * str;
    strcpy( str + 1024, "STRING_TEST" );

    return 0;
}

こんな感じ。

mapファイル、codファイルの作成

- VisualC++ 6.0 -

  • mapファイルの作成は、リンク->MAPファイルを生成にチェック。
  • codファイルの作成は、C/C++->C++言語のプロジェクトオプションに/FAcs追加。
         

- VisualStudio.Net -

  • mapファイルの作成は、リンク->デバッグ->マップファイルの作成。
  • codファイルの作成は、C/C++->出力ファイル->アセンブリの出力で/FAcs。

drwtsn32.logの出力先の設定

  1. コマンドプロンプトで、drwtsn32入力。drwtsn32.exeを起動。
  2. drwtsn32で出力先設定。
  3. drwtsn32.logが作成されない場合、コマンドプロンプトでdrwtsn32 - i と入力する。

mapファイルと、drwtsn32.logの比較

最初に書いたコードを実行すると、アプリケーションが落ちる。

それによって作成された、drwtsn32.logを見る。

*** WARNING: Unable to verify checksum for c:\CvsData\Study\MemoryBreak\Release\MemoryBreak.exe
ファンクション: MemoryBreak!main
        00400ff9 0000             add     [eax],al
        MemoryBreak!main <PERF> (MemoryBreak+0xffb):
        00400ffb 0000             add     [eax],al
        MemoryBreak!main <PERF> (MemoryBreak+0xffd):
        00400ffd 0000             add     [eax],al
        MemoryBreak!main <PERF> (MemoryBreak+0xfff):
        00400fff 00518b           add     [ecx-0x75],dl
        00401002 0dec504000       or      eax,0x4050ec
        00401007 8b0424           mov     eax,[esp]
        0040100a 0500040000       add     eax,0x400
フォールト ->0040100f 8908             mov     [eax],ecx         ds:0023:00000401=????????
        00401011 8b15f0504000     mov     edx,[MemoryBreak!`string'+0x4 (004050f0)]
        00401017 895004           mov     [eax+0x4],edx
        0040101a 8b0df4504000     mov     ecx,[MemoryBreak!`string'+0x8 (004050f4)]

フォールトと書かれた行が、アプリケーションを落とした命令。

で、Visual Studioが生成したmapファイルを見てみる。

  Address         Publics by Value              Rva+Base     Lib:Object

0000:00000000       __except_list              00000000     <absolute>
0000:00000002       ___safe_se_handler_count   00000002     <absolute>
0001:00000000       _main                      00401000 f   main.obj
0001:00000027       __amsg_exit                00401027 f   LIBC:crt0.obj

フォールとを起こしたアドレスが、0040100fであった。

main関数が、00401000-00401027までであるので、この中でアプリが落ちたことがわかる。

そこでcodファイルのほうを見てみる。

; 6    :     char * str;
; 7    :     strcpy( str + 1024, "STRING_TEST" );

  00001    8b 0d 00 00 00
    00         mov     ecx, DWORD PTR ??_C@_0M@FJGPBEFE@STRING_TEST?$AA@
  00007    8b 04 24     mov     eax, DWORD PTR _str$[esp+4]
  0000a    05 00 04 00 00     add     eax, 1024        ; 00000400H
  0000f    89 08         mov     DWORD PTR [eax], ecx
  00011    8b 15 04 00 00
    00         mov     edx, DWORD PTR ??_C@_0M@FJGPBEFE@STRING_TEST?$AA@+4
  00017    89 50 04     mov     DWORD PTR [eax+4], edx

codファイルを見ると、drwtsn32.logで、フォールトを起こした命令が書いてある。

これは、strcpyをコンパイルした結果の命令であることから、strcpyによって、アプリが落ちたことがわかる。

« PHP IDEでの実行結果をConsoleに表示する | トップページ | windbgを使ったデバッグ »

雑多技術メモ」カテゴリの記事

このブログについて

  • S_Ishimaru is ...

    Mac、デジカメ、音楽、楽器ガジェット、プログラミング、iPhone、ケータイなど色々興味を持ったことについて書いているブログです。


    シン石丸について

AMAZON コンピュータ・インターネット本

AMAZON 本ベストセラー

GoogleAnalytics

Google BLOG内検索

無料ブログはココログ

AMAZON エレクトロニクス

AMAZON ゲームベストセラー

2019年7月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31