public void GetExceptionInfo(ExceptionInfo exceptionInfo, ThreadParser threadParser) { if (threadNum < 0) { threadNum = GetFaultingThreadNum(threadParser); } if (threadNum >= 0 && address > 0 && (frame == null || module == null)) { // Get the frame in the faulting thread with that address FrameInfo frameInfo = threadParser.GetFrameInfoByAddress(threadNum, address); if (frameInfo != null) { if (frame == null) { frame = frameInfo.function; } if (module == null) { module = frameInfo.module; } } } // Copy the internal info exceptionInfo.description = description; exceptionInfo.address = address; exceptionInfo.module = module; exceptionInfo.frame = frame; exceptionInfo.threadNum = threadNum; }
public void GetExceptionInfo(ExceptionInfo exceptionInfo, ThreadParser threadParser) { exceptionInfo.description = "Heap corruption (" + errorType + "). " + errorDetails.Replace(".", ". "); // Finds out the thread number that corresponds to the extracted call stack List <ThreadInfo> threads = threadParser.GetThreadsByStack(stack); if (threads.Count == 1) // Only one thread is expected { exceptionInfo.threadNum = threads[0].threadNum; } }
// Returns the index of the faulting thread int GetFaultingThreadNum(ThreadParser threadParser) { // Get all threads containing the exception address int threadNum = -1; List <ThreadInfo> threads = threadParser.GetThreadsByAddress(address); if (threads.Count == 1) { threadNum = threads[0].threadNum; } else if (threads.Count > 1) { threadNum = threadParser.GuessFaultingThread(threads); } return(threadNum); }
ThreadInfo exceptionThread; // The thread that generated the exception public override void Parse() { addressHex = null; frame = null; description = null; module = null; threadNum = -1; Debug.Assert(lines.Count > 0); for (int idx = 0; idx < lines.Count; idx++) { if (lines[idx].Contains("ExceptionAddress:")) { pattern = @"ExceptionAddress:\s(?<excep_addr>[\w]+)"; matches = Regex.Matches(lines[idx], pattern); if (matches.Count == 1) { addressHex = matches[0].Groups["excep_addr"].Value; address = Utils.StrHexToUInt64(addressHex); if (address == 0) // This exception record is not valid { return; } // Find exception frame if (lines[idx].Contains("(")) { pattern = @"\s\((?<excep_frame>.+)\)"; matches = Regex.Matches(lines[idx], pattern); if (matches.Count == 1) { frame = matches[0].Groups["excep_frame"].Value; if (frame.Contains("!")) { string[] parts = frame.Split('!'); if (parts.Length >= 2) { module = parts[0]; } } } } } } else if (lines[idx].Contains("ExceptionCode:")) { pattern = @"ExceptionCode: (?<exception>.+)"; matches = Regex.Matches(lines[idx], pattern); if (matches.Count == 1) { description = matches[0].Groups["exception"].Value; if (description.Contains("CLR exception")) { isClrException = true; } } } else if (lines[idx].Contains("EXCEPTION CALL STACK:")) { ThreadParser threadParser = new ThreadParser(); // Used to extract the exception thread's call stack while (++idx < lines.Count) { threadParser.AddLine(lines[idx]); } threadParser.Parse(); if (threadParser.Threads.Count > 0) { exceptionThread = threadParser.Threads[0]; threadNum = exceptionThread.threadNum; } } else if (lines[idx].Contains("Unable to get exception context")) { return; // The exception info is not useful. } } }