はじめてのMDbgその2

プロセス列挙だけでは寂しいので、もーちょっとだけ。

こんなサンプルをデバッグ(?)してみる。

using System;

class Foo {
}

class Bar {
}

static class Program {
    static void Main () {
        object foo = new Foo ();

        try {
            Bar bar = (Bar)foo;
        }
        catch (Exception) {
        }

        try {
            int x = 10;
            int y = 0;
            Console.WriteLine (x / y);
        }
        catch (Exception) {
        }
    }
}

MDbgを使ってアセンブリのロード、スレッドの作成、例外の発生時にメッセージを出力させてみます。

using System;
using Microsoft.Samples.Debugging.MdbgEngine;

static class Program {
    static MDbgEngine dbg = new MDbgEngine ();
    static MDbgProcess proc = null;

    static void AssemblyLoaded (AssemblyLoadedStopReason r) {
        Console.WriteLine ("{0} loaded.", r.Assembly.Name);
    }

    static void ThreadCreated (ThreadCreatedStopReason r) {
        Console.WriteLine ("thread id {0} is created.", r.Thread.Id);
    }

    static void ExceptionThrown (ExceptionThrownStopReason r) {
        MDbgThread t = proc.Threads.Active;
        MDbgValue e = t.CurrentException;
        MDbgFrame f = t.CurrentFrame;
        string name = "";
        string src = "";
        string line = "";
        name = f.Function.FullName;
        if (t.CurrentSourcePosition != null) {
            src = t.CurrentSourcePosition.Path;
            line = t.CurrentSourcePosition.Line.ToString ();
        }
        Console.WriteLine ("{0} {1} - {2}({3})", e.TypeName, name, src, line);
    }

    static void Main (string[] args) {
        if (args.Length == 0) {
            return;
        }

        string path = args [0];

        dbg.Options.CreateProcessWithNewConsole = true;

        // アセンブリのロード時、スレッドの作成時、例外の発生時にブレイク
        dbg.Options.StopOnAssemblyLoad = true;
        dbg.Options.StopOnNewThread = true;
        dbg.Options.StopOnException = true;

        proc = dbg.CreateProcess (path, "", DebugModeFlag.Default, null);

        Console.WriteLine ("Start.");

        while (proc.IsAlive) {
            proc.Go().WaitOne ();
            object o = null;
            o = proc.StopReason;
            if (o is ExceptionThrownStopReason) {
                ExceptionThrownStopReason r = o as ExceptionThrownStopReason;
                ExceptionThrown (r);
            }
            else if (o is AssemblyLoadedStopReason) {
                AssemblyLoadedStopReason r = o as AssemblyLoadedStopReason;
                AssemblyLoaded (r);
            }
            else if (o is ThreadCreatedStopReason) {
                ThreadCreatedStopReason r = o as ThreadCreatedStopReason;
                ThreadCreated (r);
            }
        }

        Console.WriteLine ("End.");
    }
}

/** debug.exe sample.exe
Start.
C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll loaded.
thread id 3456 is created.
C:\Home\Projects\cs2\sample.exe loaded.
System.InvalidCastException Program.Main - c:\Home\Projects\cs2\sample.cs(14)
System.DivideByZeroException Program.Main - c:\Home\Projects\cs2\sample.cs(22)
End.
 */

これだけだと、あんま嬉しくないかな。(^^; ちゃんとしたデバッガのサンプルも公開されているので、それを調べると面白いかも。