private static extern int SymEnumLines( int hProcess, Int64 BaseOfDll, int obj, int File, PSYM_ENUMLINES_CALLBACK lpCallback, int UserContext);
/// <summary> /// Retrieve symbols and line numbers and write them to a memory stream /// </summary> /// <param name="FileName"></param> /// <returns></returns> private Internals.AssemblyLineMap GetAssemblyLineMap(string FileName) { // create a new map to capture symbols and line info with _alm = Internals.Bookkeeping.AssemblyLineMaps.Add(FileName); if (!System.IO.File.Exists(FileName)) { throw new FileNotFoundException("The file could not be found.", FileName); } var hProcess = System.Diagnostics.Process.GetCurrentProcess().Id; Int64 dwModuleBase = 0; // clear the map _alm.Clear(); try { if (SymInitialize(hProcess, "", false) != 0) { dwModuleBase = SymLoadModuleEx(hProcess, 0, FileName, 0, 0, 0, 0, 0); if (dwModuleBase != 0) { // this apparently is required in some cases where the module info load may be deferred IMAGEHLP_MODULE64 moduleInfo = IMAGEHLP_MODULE64.Create(); var r = SymGetModuleInfo(hProcess, 0, ref moduleInfo); // Enumerate all the symbol names var rEnumSymbolsDelegate = new PSYM_ENUMSYMBOLS_CALLBACK(SymEnumSymbolsCallback_proc); if (SymEnumSymbols(hProcess, dwModuleBase, 0, rEnumSymbolsDelegate, 0) == 0) { // unable to retrieve the symbol list throw new UnableToEnumerateSymbolsException(); } // now enumerate all the source lines and their respective addresses var pSymEnumLinesCallback_proc = new PSYM_ENUMLINES_CALLBACK(SymEnumLinesCallback_proc); if (SymEnumSourceLines(hProcess, dwModuleBase, 0, 0, 0, 0, pSymEnumLinesCallback_proc, 0) == 0) { // unable to retrieve the line number list throw new UnableToEnumLinesException(); } } } } catch (Exception ex) { // return vars Log.LogError(ex, "Unable to retrieve symbols."); _alm.Clear(); // and rethrow throw; } finally { Log.LogMessage("Retrieved {0} symbols", _alm.Symbols.Count); Log.LogMessage("Retrieved {0} lines", _alm.AddressToLineMap.Count); Log.LogMessage("Retrieved {0} strings", _alm.Names.Count); // release the module if (dwModuleBase != 0) { SymUnloadModule64(hProcess, dwModuleBase); } // can clean up the dbghelp system SymCleanup(hProcess); } return(_alm); }