2010年3月22日月曜日

C# プログラムをデバッグする基本的な方法

このエントリーをはてなブックマークに追加
on Mono 2.6.1


にて、gdb の基本的な使い方をシンプルにまとめていたので、同様の内容で mdb の基本的な使い方をまとめてみた。

 しかし、実際のところ、mdb の基本的な使い方は、gdb とほとんど同じであり、まるパクリな感じのする内容ではあるが、何かの参考になれば幸いである。

mdb とは

Mono に含まれている、コマンドラインで操作できるマネージドアプリ用デバッグコマンドである。どうやら、マネージドアプリだけではなく、ネイティブアプリもデバッグ実行可能らしい。

ビルドオプション

オプション -debug を指定してビルド。

$ gmcs -debug foo.cs

デバッグ実行

$ mdb foo.exe

デバッグサンプル

次のコードを使用。
using System;

namespace Example
{
  public class Factorial
  {
    public static void Main(string[] args)
    {
      int  num, j = 0;

      Console.Write("Enter the number: ");
      num = int.Parse(Console.ReadLine());

      for (int i = 1; i < num; i++)
      {
        j = j * i;
      }

      Console.WriteLine("The factorial of {0} is {1}", num, j);
    }
  }
}
/*
 * ビルド:
 *
 *   gmcs -debug factorial.cs
 *
 * 実行:
 *
 *   mono factorial.exe
 *
 * デバッグ実行:
 *
 *   mdb factorial.exe
 *
 */
以下、実行例。

$ gmcs -debug factorial.cs
$ mdb factorial.exe
Mono Debugger
(mdb) run
Starting program: factorial.exe 
Thread @1 stopped at #0: 0xb6f84207 in Example.Factorial.Main(string[])+0xf at /home/sta/src/cs/factorial.cs:9.
   9       int  num, j = 0;
(mdb) list
   8     {
   9       int  num, j = 0;
  10 
  11       Console.Write("Enter the number: ");
  12       num = int.Parse(Console.ReadLine());
  13 
  14       for (int i = 1; i < num; i++)
  15       {
  16         j = j * i;
  17       }
  18 
  19       Console.WriteLine("The factorial of {0} is {1}", num, j);
  20     }
  21   }
  22 }
  23 /*
  24  * ビルド:
  25  *
  26  *   gmcs -debug factorial.cs
  27  *
(mdb) b 16
Breakpoint 7 at Example.Factorial.Main(string[]):16
(mdb) show breakpoints
Breakpoints:
 Id   Type  En  Act  ThreadGroup  What
  1  break   y    y       global  
7 break y y global Example.Factorial.Main(string[]):16 (mdb) s Thread @1 stopped at #0: 0xb6f84209 in Example.Factorial.Main(string[])+0x11 at /home/sta/src/cs/factorial.cs:11. 11 Console.Write("Enter the number: "); (mdb) s Thread @1 stopped at #0: 0xb6f84396 in System.Console.Write(string)+0x6 at /home/sta/downloads/Mono/2.6.1/mono-2.6.1/mcs/class/corlib/System/Console.cs:300. 300 stdout.Write (value); (mdb) n Enter the number: Thread @1 stopped at #0: 0xb6f8421a in Example.Factorial.Main(string[])+0x22 at /home/sta/src/cs/factorial.cs:12. 12 num = int.Parse(Console.ReadLine()); (mdb) n 3 Thread @1 stopped at #0: 0xb6f8422d in Example.Factorial.Main(string[])+0x35 at /home/sta/src/cs/factorial.cs:14. 14 for (int i = 1; i < num; i++) (mdb) c Thread @1 hit breakpoint 7 at #0: 0xb6f84238 in Example.Factorial.Main(string[])+0x40 at /home/sta/src/cs/factorial.cs:16. 16 j = j * i; (mdb) p num (int) 3 (mdb) p i (int) 1 (mdb) p j (int) 0 (mdb) c Thread @1 hit breakpoint 7 at #0: 0xb6f84238 in Example.Factorial.Main(string[])+0x40 at /home/sta/src/cs/factorial.cs:16. 16 j = j * i; (mdb) p i (int) 2 (mdb) p j (int) 0 (mdb) c The factorial of 3 is 0 Thread @1 exited. Process #1 exited. Target exited. (mdb) quit

(list 実行時、コード内の日本語が文字化けて表示される)

以上の操作で、コードの 9 行目:j = 1、14 行目:i <= num という修正が必要なのが分かる、かもしれないwww。

mdb コマンド

mdb の基本的なコマンド 内容
run, r プログラムを実行する。
kill, k プログラムを終了する。
quit, q デバッグ操作を終了する。
list, l ソースコードを表示する。list -lines 行数 で指定した行数分の表示を行う。
break, b 行数 指定した行でプログラムの実行を停止するようにする(ブレイクポイントの設定)。また、show breakpoints でブレイクポイント一覧を表示できる。
step, s 次の 1 行を実行する。メソッドを実行する場合、そのメソッドへ飛んで、1 行ずつの処理を継続する。
next, n 次の 1 行を実行する。メソッドは一つの処理として実行する(そのメソッドへは飛ばない)。
continue, c 次のブレイクポイントまで実行する。
print, p 変数 変数の内容を出力する。

もっと学ぶ

1 件のコメント:

sta.blockhead さんのコメント...

「mdb の基本的なコマンド」の修正を行いました。

run -> run, r
kill -> kill, k
quit -> quit, q

コメントを投稿