public void SetException(ref EXCEPTION_INFO exceptionInfo) { ExceptionCategorySettings categorySettings; if (!_categoryMap.TryGetValue(exceptionInfo.guidType, out categorySettings)) { return; // not a category that we care about } var newState = ToExceptionBreakpointState(exceptionInfo.dwState); if (categorySettings.CategoryName.Equals(exceptionInfo.bstrExceptionName, StringComparison.OrdinalIgnoreCase)) { // Setting the exception category will clear all the existing rules in that category SetCategory(categorySettings, newState); } else { string exceptionName = GetExceptionId(exceptionInfo.bstrExceptionName, exceptionInfo.dwCode); if (!IsSupportedException(exceptionName)) { return; } using (var settingsUpdateHolder = categorySettings.GetSettingsUpdate()) { settingsUpdateHolder.Value.RulesToRemove.Remove(exceptionName); settingsUpdateHolder.Value.RulesToAdd[exceptionName] = newState; } } }
/// <summary> /// Process the given exception event. /// </summary> protected override void OnExceptionEvent(DebuggerLib.Events.Jdwp.Exception @event, DalvikThread thread) { base.OnExceptionEvent(@event, thread); // Get information about the exception var exceptionTypeId = Debugger.ObjectReference.ReferenceTypeAsync(@event.ExceptionObject.Object).Await(DalvikProcess.VmTimeout); var exceptionType = Process.ReferenceTypeManager[exceptionTypeId]; // Prepare VS event var info = new EXCEPTION_INFO(); info.bstrExceptionName = exceptionType.GetNameAsync().Await(DalvikProcess.VmTimeout); var caught = @event.IsCaught; info.dwState = caught ? enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE : enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; program.GetName(out info.bstrProgramName); info.pProgram = program; info.guidType = GuidList.Guids.guidDot42DebuggerId; // Send VS event var vsEvent = new ExceptionEvent(info, info.bstrExceptionName, false); Send((DebugThread)thread, vsEvent); }
/// <summary> /// Specifies how the debug engine (DE) should handle a given exception. /// </summary> public int SetException(EXCEPTION_INFO[] pException) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.SetException"); var copyToProgram = false; foreach (var info in pException) { if (info.guidType == GuidList.Guids.guidDot42DebuggerId) { if (info.bstrExceptionName == ExceptionConstants.TopLevelName) { exceptionBehaviorMap.DefaultStopOnThrow = info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE); exceptionBehaviorMap.DefaultStopUncaught = info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT); copyToProgram = true; } else { var behavior = new ExceptionBehavior( info.bstrExceptionName, info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE), info.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT)); exceptionBehaviorMap[info.bstrExceptionName] = behavior; copyToProgram = true; } } } if (copyToProgram) { CopyExceptionMapToProgram(); } return VSConstants.S_OK; }
public void ContinueInBreakMode() { var selectedThread = Substitute.For <RemoteThread>(); _process.GetSelectedThread().Returns(selectedThread); _attachedProgram.ContinueInBreakMode(); Predicate <DebugEvent> matchExceptionEvent = e => { if (!(e is ExceptionEvent exceptionEvent)) { return(false); } var info = new EXCEPTION_INFO[1]; exceptionEvent.GetException(info); return(info[0].dwState == enum_EXCEPTION_STATE.EXCEPTION_NONE); }; Received.InOrder(() => { _debugEngineHandler.SendEvent(Arg.Is <DebugEvent>(e => matchExceptionEvent(e)), _debugProgram,selectedThread); _lldbShell.AddDebugger(_debugger); _debugProgram.Received().EnumModules(out _); }); }
public void RemoveSetException(ref EXCEPTION_INFO exceptionInfo) { ExceptionCategorySettings categorySettings; if (!_categoryMap.TryGetValue(exceptionInfo.guidType, out categorySettings)) { return; // not a category that we care about } if (categorySettings.CategoryName.Equals(exceptionInfo.bstrExceptionName, StringComparison.OrdinalIgnoreCase)) { // We treat removing an exception category to be the same as setting all the exceptions in the category to break unhandled. EXCEPTION_INFO setExceptionInfo = exceptionInfo; setExceptionInfo.dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_SECOND_CHANCE; SetException(ref setExceptionInfo); } else { string exceptionName = GetExceptionId(exceptionInfo.bstrExceptionName, exceptionInfo.dwCode); if (!IsSupportedException(exceptionName)) { return; } using (var settingsUpdateHolder = categorySettings.GetSettingsUpdate()) { settingsUpdateHolder.Value.RulesToAdd.Remove(exceptionName); settingsUpdateHolder.Value.RulesToRemove.Add(exceptionName); } } }
public void SetException() { Signal firstDefaultSignal = defaultSignals.Values.ToList()[0]; Assert.True(firstDefaultSignal.stop, "Expected the stop value for the first default " + "signal to be true."); // Set an exception that would change the stop value for a signal EXCEPTION_INFO exception = new EXCEPTION_INFO { guidType = YetiConstants.DebugEngineGuid, dwCode = (uint)firstDefaultSignal.code, dwState = AD7Constants.VsExceptionContinueState, }; exceptionManager.SetExceptions(new EXCEPTION_INFO[] { exception }); // Verify that the stop value has changed. Assert.False(sbUnixSignalsStub.GetShouldStop(firstDefaultSignal.code), $"Signal {firstDefaultSignal.name} has incorrect stop state."); // Set an exception that would change the stop value for a signal back exception = new EXCEPTION_INFO { guidType = YetiConstants.DebugEngineGuid, dwCode = (uint)firstDefaultSignal.code, dwState = AD7Constants.VsExceptionStopState, }; exceptionManager.SetExceptions(new EXCEPTION_INFO[] { exception }); // Verify that the stop value has changed. Assert.True(sbUnixSignalsStub.GetShouldStop(firstDefaultSignal.code), $"Signal {firstDefaultSignal.name} has incorrect stop state."); }
public void ContinueInBreakModeWhenLldbShellIsNull() { _lldbShell = null; var selectedThread = Substitute.For <RemoteThread>(); _process.GetSelectedThread().Returns(selectedThread); _attachedProgram.ContinueInBreakMode(); Predicate <DebugEvent> matchExceptionEvent = e => { ExceptionEvent exceptionEvent = e as ExceptionEvent; if (exceptionEvent == null) { return(false); } var info = new EXCEPTION_INFO[1]; exceptionEvent.GetException(info); return(info[0].dwState == enum_EXCEPTION_STATE.EXCEPTION_NONE); }; Received.InOrder(() => { _debugEngineHandler.SendEvent(Arg.Is <DebugEvent>(e => matchExceptionEvent(e)), _debugProgram,selectedThread); }); }
public void RemoveSetException(EXCEPTION_INFO exception) { if (_breakpointManager.ContainsCatchpoint(exception.bstrExceptionName)) { _breakpointManager.Remove(_breakpointManager[exception.bstrExceptionName]); Session.Breakpoints.RemoveCatchpoint(exception.bstrExceptionName); } }
/// <summary> /// Convert EXCEPTION_INFO into Signals matching the exception code to the signal number, /// dropping any exceptions that can't be mapped to a signal. /// </summary> /// <exception cref="KeyNotFoundException">No signal matches the exception</exception> private Signal ConvertToSignal(EXCEPTION_INFO exception) { Signal signal = defaultSignals[(int)exception.dwCode]; signal.stop = exception.dwState.HasFlag(AD7Constants.ExceptionStopState); return(signal); }
private void ApplyStateToSession(ExceptionBreakState state) { const int SkippedExceptionLogLimit = 25; _logger.WriteLine("Manager: Applying {0} to debug session.", state); var stopwatch = new Stopwatch(); stopwatch.Start(); var newExceptionState = (state == ExceptionBreakState.BreakOnAll) ? (uint)VSExceptionStateStopAll : (uint)VSExceptionStateStopNotSet; var guid = Guid.Empty; var hr = Session.RemoveAllSetExceptions(ref guid); if (hr != VSConstants.S_OK) { Marshal.ThrowExceptionForHR(hr); } var updated = new EXCEPTION_INFO[1]; var skippedExceptionCount = 0; foreach (var exception in _exceptionCache) { if (_ignorePredicate(exception.bstrExceptionName)) { if (skippedExceptionCount < SkippedExceptionLogLimit) { _logger.WriteLine(" Skipped exception {0} (matches ignore rule).", exception.bstrExceptionName); } skippedExceptionCount += 1; continue; } updated[0] = new EXCEPTION_INFO { guidType = exception.guidType, bstrExceptionName = exception.bstrExceptionName, dwState = newExceptionState }; hr = Session.SetException(updated); if (hr != VSConstants.S_OK) { Marshal.ThrowExceptionForHR(hr); } } if (skippedExceptionCount > SkippedExceptionLogLimit) { _logger.WriteLine(" Skipped {0} more exceptions (match ignore rule).", skippedExceptionCount - SkippedExceptionLogLimit); } stopwatch.Stop(); _logger.WriteLine(" Finished in {0}ms.", stopwatch.ElapsedMilliseconds); }
void AssertExceptionEvent(ExceptionEvent e, uint signalNumber) { EXCEPTION_INFO[] infos = new EXCEPTION_INFO[1]; e.GetException(infos); (string name, string description) = SignalMap.Map[signalNumber]; Assert.AreEqual(signalNumber, infos[0].dwCode); Assert.AreEqual(name, infos[0].bstrExceptionName); e.GetExceptionDescription(out string exceptionDescription); Assert.AreEqual(name + ": " + description, exceptionDescription); }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { EXCEPTION_INFO ex = new EXCEPTION_INFO(); ex.bstrExceptionName = _name; ex.dwCode = _code; ex.dwState = _state; ex.guidType = _category; pExceptionInfo[0] = ex; return(Constants.S_OK); }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { EXCEPTION_INFO ex = new EXCEPTION_INFO(); ex.bstrExceptionName = _name; ex.dwCode = _code; ex.dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_ALL; ex.guidType = new Guid(EngineConstants.EngineId); // use the engine guid - should we be using a shared guid for POSIX signals? pExceptionInfo[0] = ex; return(Constants.S_OK); }
public void SetException(EXCEPTION_INFO exception) { if (exception.dwState.HasFlag(enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE)) { var catchpoint = Session.Breakpoints.AddCatchpoint(exception.bstrExceptionName); _breakpointManager.Add(catchpoint); } else { RemoveSetException(exception); } }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { EXCEPTION_INFO info = new EXCEPTION_INFO(); info.pProgram = _engine; info.bstrExceptionName = _info.Type; info.dwState = (uint)enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE; pExceptionInfo[0] = info; return(S_OK); }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { if (pExceptionInfo.Length == 0) { return(VSConstants.E_INVALIDARG); } pExceptionInfo[0] = new EXCEPTION_INFO { bstrExceptionName = _exceptionName, dwCode = _code, dwState = _state, guidType = Iid }; return(VSConstants.S_OK); }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { if (pExceptionInfo == null) throw new ArgumentNullException("pExceptionInfo"); if (pExceptionInfo.Length == 0) throw new ArgumentException(); pExceptionInfo[0].bstrExceptionName = _exceptionObject.GetReferenceType().GetName(); pExceptionInfo[0].bstrProgramName = _program.GetName(); pExceptionInfo[0].dwCode = 0; pExceptionInfo[0].dwState = _catchLocation != null ? enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE : enum_EXCEPTION_STATE.EXCEPTION_STOP_SECOND_CHANCE; pExceptionInfo[0].guidType = JavaDebuggerConstants.JavaDebugEngineGuid; pExceptionInfo[0].pProgram = _program; return VSConstants.S_OK; }
int IDebugExceptionEvent150.GetException(EXCEPTION_INFO150[] pExceptionInfo) { var info = new EXCEPTION_INFO[1]; int hr = ((IDebugExceptionEvent2)this).GetException(info); if (hr != VSConstants.S_OK) { return hr; } pExceptionInfo[0].guidType = info[0].guidType; pExceptionInfo[0].bstrExceptionName = info[0].bstrExceptionName; pExceptionInfo[0].bstrProgramName = info[0].bstrProgramName; pExceptionInfo[0].dwCode = info[0].dwCode; pExceptionInfo[0].dwState = (uint)info[0].dwState; pExceptionInfo[0].pProgram = info[0].pProgram; return VSConstants.S_OK; }
public void SetExceptionsWrongSignal() { const int invalidSignal = 5000; // Set an exception that would change the stop value for a signal EXCEPTION_INFO exception = new EXCEPTION_INFO { guidType = YetiConstants.DebugEngineGuid, dwCode = invalidSignal }; exceptionManager.SetExceptions(new EXCEPTION_INFO[] { exception }); // Since the GUID type was not one we want to handle, verify the stop value hasn't // changed. Assert.False(sbUnixSignalsStub.HasShouldStop(invalidSignal), "Expected no stop " + "information to be available for the invalid signal."); }
int IDebugExceptionEvent150.GetException(EXCEPTION_INFO150[] pExceptionInfo) { var info = new EXCEPTION_INFO[1]; int hr = ((IDebugExceptionEvent2)this).GetException(info); if (hr != VSConstants.S_OK) { return(hr); } pExceptionInfo[0].guidType = info[0].guidType; pExceptionInfo[0].bstrExceptionName = info[0].bstrExceptionName; pExceptionInfo[0].bstrProgramName = info[0].bstrProgramName; pExceptionInfo[0].dwCode = info[0].dwCode; pExceptionInfo[0].dwState = (uint)info[0].dwState; pExceptionInfo[0].pProgram = info[0].pProgram; return(VSConstants.S_OK); }
int IDebugExceptionEvent2.GetException(EXCEPTION_INFO[] pExceptionInfo) { if (pExceptionInfo == null || pExceptionInfo.Length == 0) { return VSConstants.E_POINTER; } pExceptionInfo[0].guidType = AD7Engine.DebugEngineGuid; pExceptionInfo[0].bstrExceptionName = _exception.TypeName; pExceptionInfo[0].pProgram = _engine; if (_exception.UserUnhandled) { pExceptionInfo[0].dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; } else { pExceptionInfo[0].dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE; } if (_exception.HResult != 0) { pExceptionInfo[0].dwState |= enum_EXCEPTION_STATE.EXCEPTION_CODE_SUPPORTED | enum_EXCEPTION_STATE.EXCEPTION_CODE_DISPLAY_IN_HEX; } return VSConstants.S_OK; }
public void SetExceptionsWrongGuid() { Signal firstDefaultSignal = defaultSignals.Values.ToList()[0]; Assert.True(firstDefaultSignal.stop, "Expected the stop value for the first default " + "signal to be true."); // Set an exception that would change the stop value for a signal EXCEPTION_INFO exception = new EXCEPTION_INFO { guidType = new Guid("0123456789abcdef0123456789abcedf"), dwCode = (uint)firstDefaultSignal.code, dwState = AD7Constants.VsExceptionContinueState, }; exceptionManager.SetExceptions(new EXCEPTION_INFO[] { exception }); // Since the GUID type was not one we want to handle, verify the stop value hasn't // changed. Assert.AreEqual(firstDefaultSignal.stop, sbUnixSignalsStub.GetShouldStop(firstDefaultSignal.code), $"Signal {firstDefaultSignal.name} has incorrect stop state."); }
private ExceptionBreakState GetStateFromSession() { var inferredState = ExceptionBreakState.Unknown; var exceptionThatCausedChangeFromUnknown = new EXCEPTION_INFO(); foreach (var exception in GetSetManagedExceptions()) { if (_ignorePredicate(exception.bstrExceptionName)) { continue; } var @break = (((enum_EXCEPTION_STATE)exception.dwState & VSExceptionStateStopAllInfer) == VSExceptionStateStopAllInfer); var stateFromException = @break ? ExceptionBreakState.BreakOnAll : ExceptionBreakState.BreakOnNone; if (inferredState == ExceptionBreakState.Unknown) { inferredState = stateFromException; exceptionThatCausedChangeFromUnknown = exception; continue; } if (inferredState != stateFromException) { _logger.WriteLine("Manager: inconclusive state diagnostic."); _logger.WriteLine(" Previous state: {0}.", inferredState); _logger.WriteLine(" Previous exception: {0}; {1}.", exceptionThatCausedChangeFromUnknown.bstrExceptionName, (enum_EXCEPTION_STATE)exceptionThatCausedChangeFromUnknown.dwState); _logger.WriteLine(" Conflicting state: {0}.", stateFromException); _logger.WriteLine(" Conflicting exception: {0}; {1}.", exception.bstrExceptionName, (enum_EXCEPTION_STATE)exception.dwState); inferredState = ExceptionBreakState.Inconclusive; break; } } _logger.WriteLine("Manager: inferred state is {0}.", inferredState); return(inferredState); }
public void ContinueInBreakModeSignal() { var selectedThread = Substitute.For <RemoteThread>(); _process.GetSelectedThread().Returns(selectedThread); selectedThread.GetStopReason().Returns(StopReason.SIGNAL); selectedThread.GetStopReasonDataCount().Returns <uint>(1); ulong sigAbort = 6; selectedThread.GetStopReasonDataAtIndex(0).Returns(sigAbort); _attachedProgram.ContinueInBreakMode(); EXCEPTION_INFO[] info = null; Predicate <DebugEvent> matchExceptionEvent = e => { if (!(e is ExceptionEvent exceptionEvent)) { return(false); } info = new EXCEPTION_INFO[1]; exceptionEvent.GetException(info); return(true); }; Received.InOrder(() => { _debugEngineHandler.SendEvent(Arg.Is <DebugEvent>(e => matchExceptionEvent(e)), _debugProgram,selectedThread); _lldbShell.AddDebugger(_debugger); _debugProgram.Received().EnumModules(out _); }); Assert.That(info[0].dwState, Is.EqualTo(enum_EXCEPTION_STATE.EXCEPTION_STOP_ALL | enum_EXCEPTION_STATE.EXCEPTION_CANNOT_BE_CONTINUED)); Assert.That(info[0].bstrExceptionName,Is.EqualTo("SIGABRT")); }
/// <summary> /// Process the given exception event. /// </summary> protected override void OnExceptionEvent(DebuggerLib.Events.Jdwp.Exception @event, DalvikThread thread) { base.OnExceptionEvent(@event, thread); // Get information about the exception var exceptionTypeId = Debugger.ObjectReference.ReferenceTypeAsync(@event.ExceptionObject.Object).Await(DalvikProcess.VmTimeout); var exceptionType = Process.ReferenceTypeManager[exceptionTypeId]; // Prepare VS event var info = new EXCEPTION_INFO(); info.bstrExceptionName = exceptionType.GetNameAsync().Await(DalvikProcess.VmTimeout); var caught = @event.IsCaught; info.dwState = caught ? enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE : enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; program.GetName(out info.bstrProgramName); info.pProgram = program; info.guidType = GuidList.Guids.guidDot42DebuggerId; // Send VS event var vsEvent = new ExceptionEvent(info, info.bstrExceptionName, false); Send((DebugThread) thread, vsEvent); }
private void ExtractExceptionDetails(IDebugEvent2 pEvent) { IDebugExceptionEvent2 dBevent = (IDebugExceptionEvent2)pEvent; if (dBevent != null) { string x = string.Empty; EXCEPTION_INFO[] exception = new EXCEPTION_INFO[1]; bool result = dBevent.GetException(exception) == VSConstants.S_OK && dBevent.GetExceptionDescription(out x) == VSConstants.S_OK; if (result) { _properties.Remove("VSException"); _properties.Remove("VSExceptionDetail"); _properties.Add("VSException", exception[0].bstrExceptionName); _properties.Add("VSExceptionDetail", x.Replace(_properties["OutputFileName"], "")); IFeed stackoverflowfeed = FeedFactory.GetFeedInstance(FeedType.StackOverflow); stackoverflowfeed.Execute(_properties); } } }
private static EXCEPTION_INFO[] GetExceptionsFromEnumerator(int enumHResult, IEnumDebugExceptionInfo2 enumerator) { if (enumHResult == VSConstants.S_FALSE) { return(new EXCEPTION_INFO[0]); } if (enumHResult != VSConstants.S_OK) { Marshal.ThrowExceptionForHR(enumHResult); } uint count; var hr = enumerator.GetCount(out count); if (hr != VSConstants.S_OK) { Marshal.ThrowExceptionForHR(hr); } if (count == 0) { return(new EXCEPTION_INFO[0]); } var buffer = new EXCEPTION_INFO[count]; var countFetched = 0U; hr = enumerator.Next(count, buffer, ref countFetched); if (hr != VSConstants.S_OK) { Marshal.ThrowExceptionForHR(hr); } return(buffer); }
/// <summary> /// Specifies how the debug engine (DE) should handle a given exception. /// </summary> /// <param name="pException">[in] An EXCEPTION_INFO structure that describes the exception and how to debug it.</param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> /// <remarks>A DE could be instructed to stop the program generating an exception at first chance, second chance, or not at all.</remarks> public int SetException(EXCEPTION_INFO[] pException) { if (pException == null) throw new ArgumentNullException("pException"); if (pException.Length != 1) throw new ArgumentException(); if (pException[0].guidType != JavaDebuggerConstants.JavaDebugEngineGuid) return VSConstants.E_INVALIDARG; _exceptions[pException[0].bstrExceptionName] = pException[0]; return VSConstants.S_OK; }
public bool TryGetException(string exceptionName, out EXCEPTION_INFO exceptionInfo) { return(_exceptions.TryGetValue(exceptionName, out exceptionInfo)); }
// Specifies how the DE should handle a given exception. // The sample engine does not support exceptions in the debuggee so this method is not actually implemented. int IDebugEngine2.SetException(EXCEPTION_INFO[] pException) { return VSConstants.S_OK; }
/// <summary> /// Specifies how the debug DebugEngine (DE) should handle a given exception. /// </summary> /// <param name="pException">An EXCEPTION_INFO structure that describes the exception and how to debug it.</param> /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns> /// <remarks>A DE could be instructed to stop the program generating an exception at first chance, second chance, or not at all.</remarks> public virtual int SetException( EXCEPTION_INFO[] pException ) { Logger.Debug( string.Empty ); return VSConstants.E_NOTIMPL; }
public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib) { try { string threadName = null; if (pThread != null && pEvent != null) { uint attributes; pEvent.GetAttributes(out attributes); if ((uint)enum_EVENTATTRIBUTES.EVENT_SYNC_STOP == attributes) { //HandleException.PrintFrames(pThread); } pThread.GetName(out threadName); //ExtractFrameContent(pThread); //IEnumDebugFrameInfo2 ppEnum = null; } Trace.WriteLine(string.Format("Event {0} Thread {1}", riidEvent, threadName)); if (typeof(IDebugInterceptExceptionCompleteEvent2).GUID == riidEvent) { var interactionEvent = pEvent as IDebugInterceptExceptionCompleteEvent2; ulong cookie; interactionEvent.GetInterceptCookie(out cookie); // another way to get code path: //pProgram.EnumCodePaths( var exceptionInfo = HandleException.PrintFrames(pThread); if (exceptionInfo != null) { if (exceptionInfo.ExceptionKind == null) { exceptionInfo.ExceptionKind = LastExceptionType; } if (exceptionInfo.ExceptionMessage == null) { exceptionInfo.ExceptionMessage = LastExceptionMessage; } SaveToDb(exceptionInfo); } } //HandleException.ProcessEvent(riidEvent, pThread); if (typeof(IDebugProgramCreateEvent2).GUID == riidEvent) { // Add handle } //if (typeof(IDebugBreakEvent2).GUID == riidEvent) if (typeof(IDebugBreakpointEvent2).GUID == riidEvent) { // Might be interesting to get the statement line number here and emit. //var ev = pEvent as IDebugBreakEvent2; var ev = pEvent as IDebugBreakpointEvent2; var info = HandleException.ProcessEvent(riidEvent, pThread); if (info != null) { SaveToDb(info); } } if (riidEvent == typeof(IDebugEntryPointEvent2).GUID) { // This is when execution is just about to the start. // I can't get the reference to the engine, pEngine is always null, and // there doesn't seem to be an interface to fetch it (there is a query interface in docs, but not in dll!) //string engineStr; Guid engineGuid; //pProgram.GetEngineInfo(out engineStr, out engineGuid); //var superEngine = pEngine as IDebugEngine3; //if (superEngine != null) //{ // superEngine.SetAllExceptions(enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE); //} } else if (riidEvent == typeof(IDebugMessageEvent2).GUID) { var ev = pEvent as IDebugMessageEvent2; var str = ""; uint type; string helpFile; uint helpId; var suc = ev.GetMessage(new enum_MESSAGETYPE[] { enum_MESSAGETYPE.MT_REASON_EXCEPTION }, out str, out type, out helpFile, out helpId); //uint messageType; //var suc = ev.GetMessage( out messageType, out str, out type, out helpFile, out helpId); if (suc == VSConstants.S_OK) { if (str.StartsWith("A first chance exception of type")) { if (pThread != null) { //ExtractFrameContent(pThread); //HandleException.PrintFrames(pThread); LastExceptionMessage = str; LastExceptionType = str; } // First chance exception thrown...but can't figure out how to get stack trace :( } } } // This interface is sent by the debug engine (DE) to the session debug manager (SDM) when a thread is created in a program being debugged. //if (riidEvent == Guid.Parse("{2090ccfc-70c5-491d-a5e8-bad2dd9ee3ea}")) { if (pThread != null) { // ExtractFrameContent(pThread); } } // Process of exception handling. // http://msdn.microsoft.com/es-es/library/bb146610.aspx if (riidEvent == typeof(IDebugExceptionEvent2).GUID || riidEvent == Guid.Parse("{51A94113-8788-4A54-AE15-08B74FF922D0}") ) { IDebugExceptionEvent2 ev = pEvent as IDebugExceptionEvent2; if (ev != null) { var info = new EXCEPTION_INFO[1]; ev.GetException(info); var name = info[0].bstrExceptionName; var state = info[0].dwState; //state == enum_EXCEPTION_STATE.EXCEPTION_STOP_SECOND_CHANCE //ExtractFrameContent(pThread); } } } catch (Exception ex) { Trace.WriteLine(ex.Message); } if (pEngine != null) { Marshal.ReleaseComObject(pEngine); } if (pProcess != null) { Marshal.ReleaseComObject(pProcess); } if (pProgram != null) { Marshal.ReleaseComObject(pProgram); } if (pThread != null) { Marshal.ReleaseComObject(pThread); } if (pEvent != null) { Marshal.ReleaseComObject(pEvent); } return(VSConstants.S_OK); }
public bool TryGetException(string exceptionName, out EXCEPTION_INFO exceptionInfo) { return _exceptions.TryGetValue(exceptionName, out exceptionInfo); }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { pExceptionInfo[0].pProgram = _engine; pExceptionInfo[0].guidType = AD7Engine.DebugEngineGuid; pExceptionInfo[0].bstrExceptionName = _exception; if (_isUnhandled) { pExceptionInfo[0].dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; } else { pExceptionInfo[0].dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE; } return VSConstants.S_OK; }
/// <summary> /// Gets full list of child exceptions under given <paramref name="parent" />. /// The exceptions will not have a specific state set. /// </summary> private EXCEPTION_INFO[] GetDefaultExceptions(EXCEPTION_INFO? parent = null) { IEnumDebugExceptionInfo2 enumerator; var hr = Session.EnumDefaultExceptions(parent != null ? new[] { parent.Value } : null, out enumerator); return GetExceptionsFromEnumerator(hr, enumerator); }
private static EXCEPTION_INFO[] GetExceptionsFromEnumerator(int enumHResult, IEnumDebugExceptionInfo2 enumerator) { if (enumHResult == VSConstants.S_FALSE) return new EXCEPTION_INFO[0]; if (enumHResult != VSConstants.S_OK) Marshal.ThrowExceptionForHR(enumHResult); uint count; var hr = enumerator.GetCount(out count); if (hr != VSConstants.S_OK) Marshal.ThrowExceptionForHR(hr); if (count == 0) return new EXCEPTION_INFO[0]; var buffer = new EXCEPTION_INFO[count]; var countFetched = 0U; hr = enumerator.Next(count, buffer, ref countFetched); if (hr != VSConstants.S_OK) Marshal.ThrowExceptionForHR(hr); return buffer; }
private ExceptionBreakState GetStateFromSession() { var inferredState = ExceptionBreakState.Unknown; var exceptionThatCausedChangeFromUnknown = new EXCEPTION_INFO(); foreach (var exception in GetSetManagedExceptions()) { if (_ignorePredicate(exception.bstrExceptionName)) continue; var @break = (((enum_EXCEPTION_STATE)exception.dwState & VSExceptionStateStopAllInfer) == VSExceptionStateStopAllInfer); var stateFromException = @break ? ExceptionBreakState.BreakOnAll : ExceptionBreakState.BreakOnNone; if (inferredState == ExceptionBreakState.Unknown) { inferredState = stateFromException; exceptionThatCausedChangeFromUnknown = exception; continue; } if (inferredState != stateFromException) { _logger.WriteLine("Manager: inconclusive state diagnostic."); _logger.WriteLine(" Previous state: {0}.", inferredState); _logger.WriteLine(" Previous exception: {0}; {1}.", exceptionThatCausedChangeFromUnknown.bstrExceptionName, (enum_EXCEPTION_STATE)exceptionThatCausedChangeFromUnknown.dwState); _logger.WriteLine(" Conflicting state: {0}.", stateFromException); _logger.WriteLine(" Conflicting exception: {0}; {1}.", exception.bstrExceptionName, (enum_EXCEPTION_STATE)exception.dwState); inferredState = ExceptionBreakState.Inconclusive; break; } } _logger.WriteLine("Manager: inferred state is {0}.", inferredState); return inferredState; }
private void ApplyStateToSession(ExceptionBreakState state) { const int SkippedExceptionLogLimit = 25; _logger.WriteLine("Manager: Applying {0} to debug session.", state); var stopwatch = new Stopwatch(); stopwatch.Start(); var newExceptionState = (state == ExceptionBreakState.BreakOnAll) ? (uint)VSExceptionStateStopAll : (uint)VSExceptionStateStopNotSet; var guid = Guid.Empty; var hr = Session.RemoveAllSetExceptions(ref guid); if (hr != VSConstants.S_OK) Marshal.ThrowExceptionForHR(hr); var updated = new EXCEPTION_INFO[1]; var skippedExceptionCount = 0; foreach (var exception in _exceptionCache) { if (_ignorePredicate(exception.bstrExceptionName)) { if (skippedExceptionCount < SkippedExceptionLogLimit) _logger.WriteLine(" Skipped exception {0} (matches ignore rule).", exception.bstrExceptionName); skippedExceptionCount += 1; continue; } updated[0] = new EXCEPTION_INFO { guidType = exception.guidType, bstrExceptionName = exception.bstrExceptionName, dwState = newExceptionState }; hr = Session.SetException(updated); if (hr != VSConstants.S_OK) Marshal.ThrowExceptionForHR(hr); } if (skippedExceptionCount > SkippedExceptionLogLimit) _logger.WriteLine(" Skipped {0} more exceptions (match ignore rule).", skippedExceptionCount - SkippedExceptionLogLimit); stopwatch.Stop(); _logger.WriteLine(" Finished in {0}ms.", stopwatch.ElapsedMilliseconds); }
int IDebugExceptionEvent2.GetException (EXCEPTION_INFO [] pExceptionInfo) { LoggingUtils.PrintFunction (); try { pExceptionInfo [0] = new EXCEPTION_INFO (); pExceptionInfo [0].bstrExceptionName = m_exceptionName; pExceptionInfo [0].pProgram = m_debugProgram as IDebugProgram2; LoggingUtils.RequireOk (m_debugProgram.DebugProcess.GetName (enum_GETNAME_TYPE.GN_NAME, out pExceptionInfo [0].bstrProgramName)); pExceptionInfo [0].dwCode = m_exceptionCode; pExceptionInfo [0].dwState = enum_EXCEPTION_STATE.EXCEPTION_NONE; pExceptionInfo [0].dwState |= enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE; if (!m_canContinue) { pExceptionInfo [0].dwState |= enum_EXCEPTION_STATE.EXCEPTION_CANNOT_BE_CONTINUED; } return Constants.S_OK; } catch (System.Exception e) { LoggingUtils.HandleException (e); return Constants.E_FAIL; } }
int IDebugEngine2.RemoveSetException(EXCEPTION_INFO[] pException) { bool sendUpdate = false; for (int i = 0; i < pException.Length; i++) { if (pException[i].guidType == DebugEngineGuid) { sendUpdate = true; if (pException[i].bstrExceptionName == "J Exceptions") { _defaultBreakOnExceptionMode = (int)enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; } else { _breakOnException.Remove(pException[i].bstrExceptionName); } } } if (sendUpdate) { _process.SetExceptionInfo(_defaultBreakOnExceptionMode, _breakOnException); } return VSConstants.S_OK; }
int IDebugEngine2.SetException(EXCEPTION_INFO[] pException) { DebugWriteCommand("SetException"); UpdateExceptionTreatment(pException, _process.SetExceptionTreatment); return VSConstants.S_OK; }
/// <summary> /// Default ctor /// </summary> public ExceptionEvent(EXCEPTION_INFO info, string description, bool canPassToDebuggee) { this.info = info; this.description = description; this.canPassToDebuggee = canPassToDebuggee; }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { EXCEPTION_INFO ex = new EXCEPTION_INFO(); ex.bstrExceptionName = _name; ex.dwCode = _code; ex.dwState = _state; ex.guidType = _category; pExceptionInfo[0] = ex; return Constants.S_OK; }
/// <summary> /// Removes the specified exception so it is no longer handled by the debug engine. /// </summary> public int RemoveSetException(EXCEPTION_INFO[] pException) { DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.RemoveSetException"); var copyToProgram = false; foreach (var info in pException) { if (info.guidType == GuidList.Guids.guidDot42DebuggerId) { if (info.bstrExceptionName == ExceptionConstants.TopLevelName) { exceptionBehaviorMap.ResetDefaults(); copyToProgram = true; } else { exceptionBehaviorMap[info.bstrExceptionName] = null; copyToProgram = true; } } } if (copyToProgram) { CopyExceptionMapToProgram(); } return VSConstants.S_OK; }
public int GetException(EXCEPTION_INFO[] pExceptionInfo) { pExceptionInfo[0].bstrExceptionName = _exception; if (_isUnhandled) { pExceptionInfo[0].dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; } else { pExceptionInfo[0].dwState = enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE; } return VSConstants.S_OK; }
public int RemoveSetException(EXCEPTION_INFO[] pException) { DebugHelper.TraceEnteringMethod(); return VSConstants.S_OK; }
int IDebugEngine2.SetException(EXCEPTION_INFO[] pException) { if (_mixedMode) { return VSConstants.E_NOTIMPL; } bool sendUpdate = false; for (int i = 0; i < pException.Length; i++) { if (pException[i].guidType == DebugEngineGuid) { sendUpdate = true; if (pException[i].bstrExceptionName == "Python Exceptions") { _defaultBreakOnExceptionMode = (int)(pException[i].dwState & (enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE | enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT)); } else { _breakOnException[pException[i].bstrExceptionName] = (int)(pException[i].dwState & (enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE | enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT)); } } } if (sendUpdate) { SetExceptionInfo(_defaultBreakOnExceptionMode, _breakOnException); } return VSConstants.S_OK; }
// Removes the specified exception so it is no longer handled by the debug engine. // The sample engine does not support exceptions in the debuggee so this method is not actually implemented. int IDebugEngine2.RemoveSetException(EXCEPTION_INFO[] pException) { // The sample engine will always stop on all exceptions. return VSConstants.S_OK; }
public void SetException(ref EXCEPTION_INFO exceptionInfo) { ExceptionCategorySettings categorySettings; if (!_categoryMap.TryGetValue(exceptionInfo.guidType, out categorySettings)) { return; // not a category that we care about } var newState = ToExceptionBreakpointState(exceptionInfo.dwState); if (categorySettings.CategoryName.Equals(exceptionInfo.bstrExceptionName, StringComparison.OrdinalIgnoreCase)) { // Setting the exception category will clear all the existing rules in that category using (var settingsUpdateHolder = categorySettings.GetSettingsUpdate()) { settingsUpdateHolder.Value.NewCategoryState = newState; settingsUpdateHolder.Value.RulesToAdd.Clear(); settingsUpdateHolder.Value.RulesToRemove.Clear(); } } else { string exceptionName = GetExceptionId(exceptionInfo.bstrExceptionName, exceptionInfo.dwCode); if (!IsSupportedException(exceptionName)) { return; } using (var settingsUpdateHolder = categorySettings.GetSettingsUpdate()) { settingsUpdateHolder.Value.RulesToRemove.Remove(exceptionName); settingsUpdateHolder.Value.RulesToAdd[exceptionName] = newState; } } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int SetException (EXCEPTION_INFO [] pException) { // // Specifies how the DebugEngine should handle a given exception. // LoggingUtils.PrintFunction (); try { // // Filter exceptions to those targeted at this debug engine. // List<EXCEPTION_INFO> filtedExceptions = new List<EXCEPTION_INFO> (pException.Length); for (int i = 0; i < pException.Length; ++i) { if (DebugEngineGuids.guidDebugEngineID.Equals (pException [i].guidType)) { filtedExceptions.Add (pException [i]); } } if (filtedExceptions.Count > 0) { NativeDebugger.RunInterruptOperation (delegate (CLangDebugger debugger) { for (int i = 0; i < pException.Length; ++i) { string exceptionName = filtedExceptions [i].bstrExceptionName; exceptionName = exceptionName.Substring (0, exceptionName.IndexOf (' ')); // pick out 'SIG*' identifier. GdbClient.Signal signal = debugger.GdbClient.GetClientSignal (exceptionName); bool shouldStop = ((filtedExceptions [i].dwState & enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE) != 0); signal.SetShouldStop (shouldStop); } }); } return Constants.S_OK; } catch (NotImplementedException e) { LoggingUtils.HandleException (e); return Constants.E_NOTIMPL; } }
/// <summary> /// Return true for an exception that came from our debug engine, false otherwise. /// </summary> /// <param name="exception">Exception to inspect.</param> private bool IsStadiaException(EXCEPTION_INFO exception) { return(exception.guidType == YetiConstants.DebugEngineGuid || exception.guidType == YetiConstants.ExceptionEventGuid); }
/// <summary> /// Process the given exception event. /// </summary> protected override void OnExceptionEvent(Exception @event, DalvikThread thread) { var prev = Interlocked.CompareExchange(ref processing, @event, null); if (prev != null) { if (@event.ExceptionObject.Equals(prev.ExceptionObject) && @event.ThreadId.Equals(prev.ThreadId)) { // the same exception is reported multiple times. just ignore. Debugger.VirtualMachine.ResumeAsync(); return; } DLog.Error(DContext.VSDebuggerMessage, "Multiple exceptions in debuggee or exceptions while retrieving exception information. " + "Current Exception/Thread: {0}/{1}; previous Exception/Thread: {2}/{3} ", @event.ThreadId, @event.ExceptionObject, prev.ThreadId, prev.ExceptionObject); Debugger.VirtualMachine.ResumeAsync(); return; // This cancelling might not be neccessary any more; check this. //// I have no idea why we have to resume twice, but if we dont, the debuggee will hang. //Debugger.Process.ResumeAsync(); //if(cancelProcessing != null) // cancelProcessing.Cancel(); } cancelProcessing = new CancellationTokenSource(); var cancelToken = cancelProcessing.Token; bool wasThreadNull = thread == null; bool caught; string exceptionName = "(unknown)"; string catchingClass = "(unknown)"; string exceptionMessage = null; try { // Get information about the exception var exceptionTypeId = Debugger.ObjectReference.ReferenceTypeAsync(@event.ExceptionObject.Object) .Await(DalvikProcess.VmTimeout, cancelToken); var exceptionType = Process.ReferenceTypeManager[exceptionTypeId]; exceptionName = exceptionType.GetNameAsync() .Await(DalvikProcess.VmTimeout, cancelToken); caught = @event.IsCaught; if (!ShouldHandle(exceptionName, caught)) { DLog.Debug(DContext.VSDebuggerMessage, "not handling exception {0}", exceptionName); Debugger.VirtualMachine.ResumeAsync(); return; } if (caught && @event.CatchLocation != null) { // filter out internal exceptions, that are used for control flow. catchingClass = Process.ReferenceTypeManager[@event.CatchLocation.Class].GetNameAsync() .Await(DalvikProcess.VmTimeout, cancelToken); if (CaughtExceptionLocationExcludePattern.IsMatch(catchingClass)) { DLog.Debug(DContext.VSDebuggerMessage, "not handling exception {0}, catching class={1}", exceptionName, catchingClass); Debugger.VirtualMachine.ResumeAsync(); return; } } if (wasThreadNull) { thread = Debugger.Process.ThreadManager.Threads.First(); } base.OnExceptionEvent(@event, thread); exceptionMessage = GetExceptionMessageAsync(@event.ExceptionObject).Await(DalvikProcess.VmTimeout); } catch (System.Exception ex) { DLog.Error(DContext.VSDebuggerMessage, "Exception in debugger while processing exception: {0}. involved thread: {1}; exception.object={2}; exception type: {3}; ccatching class: {4}", ex.Message, GetThreadId(thread), @event.ExceptionObject.Object, exceptionName, catchingClass); Debugger.VirtualMachine.ResumeAsync(); return; } finally { Interlocked.Exchange(ref processing, null); } // Prepare VS event var info = new EXCEPTION_INFO(); info.bstrExceptionName = exceptionName; info.dwState = caught ? enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE : enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; program.GetName(out info.bstrProgramName); info.pProgram = program; info.guidType = GuidList.Guids.guidDot42DebuggerId; string description = info.bstrExceptionName; if (exceptionMessage != null) { description += ": \"" + exceptionMessage + "\""; } if (caught) { description += "\n(first chance, caught by debuggee)"; } else { description += "\n(not caught by debugee)"; } if (thread == null) { DLog.Warning(DContext.VSDebuggerEvent, "Exception without a thread: {0}. Original thread id: {1}.", exceptionName, @event.ThreadId); description += "\n The exceptions thread has already died, the VS call stack window has no meaning. The exception was raised on thread " + @event.ThreadId; } // Send VS event var vsEvent = new ExceptionEvent(info, description, false); Send((DebugThread)thread, vsEvent); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int RemoveSetException (EXCEPTION_INFO [] pException) { // // Removes the specified exception so it is no longer handled by the DebugEngine. // LoggingUtils.PrintFunction (); try { throw new NotImplementedException (); } catch (NotImplementedException e) { LoggingUtils.HandleException (e); return Constants.E_NOTIMPL; } }
int IDebugEngine2.SetException(EXCEPTION_INFO[] pException) { // TODO return VSConstants.E_NOTIMPL; }
public ExceptionInfo(ExceptionType exceptionType, EXCEPTION_INFO info) { exceptionInfoKey = new ExceptionInfoKey(exceptionType, info.Name); BreakOnFirstChance = (info.State & ExceptionState.EXCEPTION_STOP_FIRST_CHANCE) != 0; IsOtherExceptions = false; }
/// <summary> /// Process the given exception event. /// </summary> protected override void OnExceptionEvent(Exception @event, DalvikThread thread) { var prev = Interlocked.CompareExchange(ref processing, @event, null); if (prev != null) { if (@event.ExceptionObject.Equals(prev.ExceptionObject) && @event.ThreadId.Equals(prev.ThreadId)) { // the same exception is reported multiple times. just ignore. Debugger.VirtualMachine.ResumeAsync(); return; } DLog.Error(DContext.VSDebuggerMessage, "Multiple exceptions in debuggee or exceptions while retrieving exception information. " +"Current Exception/Thread: {0}/{1}; previous Exception/Thread: {2}/{3} ", @event.ThreadId, @event.ExceptionObject, prev.ThreadId, prev.ExceptionObject); Debugger.VirtualMachine.ResumeAsync(); return; // This cancelling might not be neccessary any more; check this. //// I have no idea why we have to resume twice, but if we dont, the debuggee will hang. //Debugger.Process.ResumeAsync(); //if(cancelProcessing != null) // cancelProcessing.Cancel(); } cancelProcessing = new CancellationTokenSource(); var cancelToken = cancelProcessing.Token; bool wasThreadNull = thread == null; bool caught; string exceptionName = "(unknown)"; string catchingClass = "(unknown)"; string exceptionMessage = null; try { // Get information about the exception var exceptionTypeId = Debugger.ObjectReference.ReferenceTypeAsync(@event.ExceptionObject.Object) .Await(DalvikProcess.VmTimeout, cancelToken); var exceptionType = Process.ReferenceTypeManager[exceptionTypeId]; exceptionName = exceptionType.GetNameAsync() .Await(DalvikProcess.VmTimeout, cancelToken); caught = @event.IsCaught; if (!ShouldHandle(exceptionName, caught)) { DLog.Debug(DContext.VSDebuggerMessage, "not handling exception {0}", exceptionName); Debugger.VirtualMachine.ResumeAsync(); return; } if (caught && @event.CatchLocation != null) { // filter out internal exceptions, that are used for control flow. catchingClass = Process.ReferenceTypeManager[@event.CatchLocation.Class].GetNameAsync() .Await(DalvikProcess.VmTimeout, cancelToken); if (CaughtExceptionLocationExcludePattern.IsMatch(catchingClass)) { DLog.Debug(DContext.VSDebuggerMessage, "not handling exception {0}, catching class={1}", exceptionName, catchingClass); Debugger.VirtualMachine.ResumeAsync(); return; } } if (wasThreadNull) thread = Debugger.Process.ThreadManager.Threads.First(); base.OnExceptionEvent(@event, thread); exceptionMessage = GetExceptionMessageAsync(@event.ExceptionObject).Await(DalvikProcess.VmTimeout); } catch(System.Exception ex) { DLog.Error(DContext.VSDebuggerMessage, "Exception in debugger while processing exception: {0}. involved thread: {1}; exception.object={2}; exception type: {3}; ccatching class: {4}", ex.Message, GetThreadId(thread), @event.ExceptionObject.Object, exceptionName, catchingClass); Debugger.VirtualMachine.ResumeAsync(); return; } finally { Interlocked.Exchange(ref processing, null); } // Prepare VS event var info = new EXCEPTION_INFO(); info.bstrExceptionName = exceptionName; info.dwState = caught ? enum_EXCEPTION_STATE.EXCEPTION_STOP_FIRST_CHANCE : enum_EXCEPTION_STATE.EXCEPTION_STOP_USER_UNCAUGHT; program.GetName(out info.bstrProgramName); info.pProgram = program; info.guidType = GuidList.Guids.guidDot42DebuggerId; string description = info.bstrExceptionName; if (exceptionMessage != null) description += ": \"" + exceptionMessage + "\""; if (caught) description += "\n(first chance, caught by debuggee)"; else description += "\n(not caught by debugee)"; if (thread == null) { DLog.Warning(DContext.VSDebuggerEvent, "Exception without a thread: {0}. Original thread id: {1}.", exceptionName, @event.ThreadId); description += "\n The exceptions thread has already died, the VS call stack window has no meaning. The exception was raised on thread "+ @event.ThreadId; } // Send VS event var vsEvent = new ExceptionEvent(info, description, false); Send((DebugThread)thread, vsEvent); }
// Specifies how the DE should handle a given exception. // The sample engine does not support exceptions in the debuggee so this method is not actually implemented. int IDebugEngine2.SetException(EXCEPTION_INFO[] pException) { _debuggedProcess?.ExceptionManager.SetException(ref pException[0]); return Constants.S_OK; }
/// <summary> /// Return true for an exception that represents a signal, false otherwise. /// </summary> /// <param name="exception">Exception to inspect.</param> private bool IsSignal(EXCEPTION_INFO exception) { return(defaultSignals.ContainsKey((int)exception.dwCode)); }