PDBファイルへのアクセス。
GotDotNetを見ていたら、DIA(Debug Interface Access SDK)というキーワードが紹介されていました。うーむ、これ使うとPDBから情報引っこ抜けるのか・・・知らなかったです。と、いうことで、C#で簡単なサンプルをこさえてみました。
// ConsoleApp.cs using System; using Dia2Lib; // 今回は使用していない public enum NameSearchOptions : uint { nsNone = 0, nsfCaseSensitive = 0x1, nsfCaseInsensitive = 0x2, nsfFNameExt = 0x4, nsfRegularExpression = 0x8, nsfUndecoratedName = 0x10, nsCaseSensitive = nsfCaseSensitive, nsCaseInsensitive = nsfCaseInsensitive, nsFNameExt = nsfCaseInsensitive | nsfFNameExt, nsRegularExpression = nsfRegularExpression | nsfCaseSensitive, nsCaseInRegularExpression = nsfRegularExpression | nsfCaseInsensitive } public class ConsoleApp { public void SayHello() { Console.WriteLine("Hello World."); } static void GetSourcePosition(IDiaSession session, IDiaSymbol symbol) { if (symbol.addressSection != 0 && symbol.length > 0) { IDiaEnumLineNumbers lineNums; session.findLinesByAddr(symbol.addressSection, (uint)symbol.addressOffset, (uint)symbol.length, out lineNums); if (lineNums != null) { uint celt; IDiaLineNumber lineNum; lineNums.Next(1, out lineNum, out celt); if (celt != 1) return; // メソッド名:ソースファイル(行番号)を出力 Console.WriteLine("Method:{0} - {1}({2})", symbol.name, lineNum.sourceFile.fileName, lineNum.lineNumber); } } } [STAThread] static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("usage app.exe pdbfile"); return; } DiaSourceClass dia = new DiaSourceClass(); // pdbファイルを読み込む dia.loadDataFromPdb(args[0]); IDiaSession session; dia.openSession(out session); IDiaSymbol symbol = session.globalScope; uint id = symbol.symIndexId; if (id == 0) { return; } IDiaEnumTables tabs; session.getEnumTables(out tabs); IDiaTable symtab = tabs.Item(0); foreach (IDiaSymbol s in symtab) { // メソッドのみを対象とする if (s.symTag == (uint)SymTagEnum.SymTagFunction) { GetSourcePosition(session, s); } } } } /* 結果 Method:SayHello - c:\home\projects\consoleapp\consoleapp.cs(24) Method:GetSourcePosition - c:\home\projects\consoleapp\consoleapp.cs(29) Method:Main - c:\home\projects\consoleapp\consoleapp.cs(49) */
自分自身のPDBファイルを食わせた結果ですが、メソッドのソースファイル上での位置が取ってこれています。もっと色々出来そうですが、ちょっと疲れたのでこの辺で。
symbol.addressOffsetを渡すところをsymbol.offsetにしていて1時間くらい嵌っていました。(^^;