/// <summary> /// Gather debug information if the process was being monitored, otherwise just terminate. /// </summary> internal void OnProcessCrash(int processId) { ExecutionEventLog.RecordStatus("Process " + processId + " crash notification recieved."); try { if (Process.GetCurrentProcess().Id == processId) { //It may be possible that some strange unhandled exception is arising in a background thread, leading to a debugger being launched //and the infra Terminating itself. Somehow, it seems unlikely for this code to be reachable, but this case is a hypothetical possibility to account for. ExecutionEventLog.RecordStatus("Catastrophic Situation: Infra has recieved notification that it's own process has crashed. "); } else if (isTestRunning && pids.Contains(processId) && accumulatedDumpCost < maxDumpCost) { ExecutionEventLog.RecordStatus("Debugging Process: " + processId); FileInfo debugLogFilePath = new FileInfo(Path.Combine(executionDirectory.FullName, "TestInfraDebuggingLog_" + processId + ".log")); FileInfo debugDumpFilePath = new FileInfo(Path.Combine(executionDirectory.FullName, "TestInfraDebuggingDump_" + processId + ".dmp")); CdbUtilities.DebugProcess(processId.ToString(CultureInfo.InvariantCulture), debugLogFilePath, debugDumpFilePath); accumulatedDumpCost += debugDumpFilePath.Length; // LoggingMediator.LogFile(debugLogFilePath.FullName); LoggingMediator.LogFile(debugDumpFilePath.FullName); //Dan: Is the Recording Logger guaranteed to be explicitly aware that the given test has failed if this point is reached? //Getting here means a process the tester cares about has crashed. } else { if (accumulatedDumpCost < maxDumpCost) { ExecutionEventLog.RecordStatus("Terminating non-monitored Process:" + processId); } else { ExecutionEventLog.RecordStatus("Dump limit exceeded - Terminating process without analysis:" + processId); } Process process = Process.GetProcessById(processId); if (process != null && !process.HasExited) { process.Kill(); process.WaitForExit(); } } } //Uncaught exceptions in this event handler will ---- up the logging stack... Which would be bad. catch (Exception exception) { ExecutionEventLog.RecordException(exception); } }
/// <summary> /// Registers Jit Debugger rooted from supplied infra binaries Path and returns cleanup command. /// </summary> public static DebuggingEngineCommand Apply(DirectoryInfo infraPath, string customJitDebuggerCommand) { ExecutionEventLog.RecordStatus("Starting up DebuggingEngine."); DebuggingEngineCommand command = new DebuggingEngineCommand(); CdbUtilities.InstallCdb(); if (!String.IsNullOrEmpty(customJitDebuggerCommand)) { JitRegistrationUtilities.Register(customJitDebuggerCommand); } else { JitRegistrationUtilities.Register(GenerateJitDebuggerCommand(infraPath)); } return(command); }