private static void LoadDump(DumpContext context, string absoluteDumpFile) { try { var target = DataTarget.LoadCrashDump(absoluteDumpFile, CrashDumpReader.ClrMD); // attention: CLRMD needs symbol path to be ";" separated. srv*url1*url2*url3 won't work. Console.WriteLine(SYMBOL_PATH); if (!string.IsNullOrEmpty(SYMBOL_PATH)) { target.SymbolLocator.SymbolPath = SYMBOL_PATH; } context.DumpFile = absoluteDumpFile; context.DumpDirectory = Path.GetDirectoryName(absoluteDumpFile); context.SymbolLocator = target.SymbolLocator; context.SymbolLocator.SymbolPath = target.SymbolLocator.SymbolPath + ";" + context.DumpDirectory; context.SymbolPath = target.SymbolLocator.SymbolPath + ";" + context.DumpDirectory; context.Target = target; } catch (InvalidOperationException ex) { context.WriteError("wrong architecture"); context.WriteLine(ex.Message); throw; } catch (Exception ex) { context.WriteError("An exception occured while loading crash dump."); context.WriteError(ex.Message); context.WriteLine(ex.StackTrace); throw; } }
[HandleProcessCorruptedStateExceptions] // some operations out of our control (WinDbg ExecuteCommand) cause AccessViolationExceptions in some cases. Be brave and try to continute to run. This attribute allows an exception-handler to catch it. private static void RunSafe(DumpContext context, string name, Action action) { try { action(); } catch (Exception e) { context.WriteError($"WinDbgAnalyzer failed: {e}"); } }
/// <summary> /// Constructs a mixed stack trace, native and managed /// </summary> /// <param name="debugClient"></param> /// <param name="runtime"></param> public CombinedStackTrace(uint engineId, uint osId, bool isManaged, IDebugClient debugClient, DumpContext context) { this.engineId = engineId; this.osId = osId; this.isManaged = isManaged; this.debugClient = debugClient; this.context = context; this.Trace = this.GetCompleteStackTrace(); }
private static void SetupCLRRuntime(DumpContext context) { // for .NET specific try { string dac = null; context.DacLocation = dac; context.Runtime = context.Target.CreateRuntime(ref dac); context.WriteInfo("created runtime with version " + context.Runtime.ClrInfo.Version); context.Heap = context.Runtime.Heap; } catch (FileNotFoundException ex) { context.WriteError("The right dac file could not be found."); context.WriteLine(ex.Message); context.WriteLine(ex.StackTrace); context.Runtime = null; //context.Dispose(); //throw ex; } catch (Exception ex) { context.WriteError("Exception creating CLR Runtime"); context.WriteError(ex.Message); context.WriteLine(ex.StackTrace); } }
private static int Main(string[] args) { if (Environment.Is64BitProcess) { Environment.SetEnvironmentVariable("_NT_DEBUGGER_EXTENSION_PATH", @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\WINXP;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\winext;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64;"); } else { Environment.SetEnvironmentVariable("_NT_DEBUGGER_EXTENSION_PATH", @"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\WINXP;C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\winext;C:\Program Files (x86)\Windows Kits\10\Debuggers\x86;"); } using (context = new DumpContext()) { Console.WriteLine("SuperDump - Windows dump analysis tool"); Console.WriteLine("--------------------------"); //check if symbol path is set if (string.IsNullOrEmpty(SYMBOL_PATH)) { Console.WriteLine("WARNING: Environment variable _NT_SYMBOL_PATH is not set!"); } if (args.Length < 1) { Console.WriteLine("no dump file was specified! Please enter dump path: "); DUMP_LOC = Console.ReadLine(); } else { DUMP_LOC = args[0]; } if (args.Length < 2) { Console.WriteLine("no output file was specified! Please enter output file: "); OUTPUT_LOC = Console.ReadLine(); } else { OUTPUT_LOC = args[1]; } string absoluteDumpFile = Path.GetFullPath(DUMP_LOC); Console.WriteLine(absoluteDumpFile); var logfile = new FileInfo(Path.Combine(Path.GetDirectoryName(OUTPUT_LOC), "superdump.log")); context.Printer = new FilePrinter(logfile.FullName); try { if (File.Exists(absoluteDumpFile)) { LoadDump(absoluteDumpFile); // do this as early as possible, as some WinDbg commands help us get the right DAC files var windbgAnalyzer = new WinDbgAnalyzer(context, Path.Combine(context.DumpDirectory, "windbg.log")); windbgAnalyzer.Analyze(); // start analysis var analysisResult = new SDResult(); analysisResult.IsManagedProcess = context.Target.ClrVersions.Count > 0; if (analysisResult.IsManagedProcess) { SetupCLRRuntime(); } var sysInfo = new SystemAnalyzer(context); analysisResult.SystemContext = sysInfo.systemInfo; var exceptionAnalyzer = new ExceptionAnalyzer(context, analysisResult); context.WriteInfo("--- Thread analysis ---"); ThreadAnalyzer threadAnalyzer = new ThreadAnalyzer(context); analysisResult.ExceptionRecord = threadAnalyzer.exceptions; analysisResult.ThreadInformation = threadAnalyzer.threads; analysisResult.DeadlockInformation = threadAnalyzer.deadlocks; analysisResult.LastExecutedThread = threadAnalyzer.GetLastExecutedThreadOSId(); context.WriteInfo("Last executed thread (engine id): " + threadAnalyzer.GetLastExecutedThreadEngineId().ToString()); var analyzer = new MemoryAnalyzer(context); analysisResult.MemoryInformation = analyzer.memDict; analysisResult.BlockingObjects = analyzer.blockingObjects; // this analyzer runs after all others to put tags onto taggableitems var tagAnalyzer = new TagAnalyzer(analysisResult); tagAnalyzer.Analyze(); //get non loaded symbols List <string> notLoadedSymbols = new List <string>(); foreach (var item in sysInfo.systemInfo.Modules) { if (item.PdbInfo == null || string.IsNullOrEmpty(item.PdbInfo.FileName) || string.IsNullOrEmpty(item.PdbInfo.Guid)) { notLoadedSymbols.Add(item.FileName); } } analysisResult.NotLoadedSymbols = notLoadedSymbols; // print to log sysInfo.PrintArchitecture(); sysInfo.PrintCLRVersions(); sysInfo.PrintAppDomains(); sysInfo.PrintModuleList(); threadAnalyzer.PrintManagedExceptions(); threadAnalyzer.PrintCompleteStackTrace(); analyzer.PrintExceptionsObjects(); // write to json analysisResult.WriteResultToJSONFile(OUTPUT_LOC); context.WriteInfo("--- End of output ---"); Console.WriteLine("done."); } else { throw new FileNotFoundException("File can not be found!"); } } catch (Exception e) { context.WriteError($"Exception happened: {e}"); return(1); } } return(0); }
public OutputCallbacks(DumpContext context) { this.context = context; }