} // end GetPipelineCallback() // protected void EnsureLiveTarget( DbgEngDebugger debugger ) // { // if( !debugger.IsLive ) // { // DbgProviderException dpe = new DbgProviderException( "Target is not live.", // "TargetNotLive", // ErrorCategory.InvalidOperation ); // try { throw dpe; } catch( Exception ) { } // give it a stack trace // ThrowTerminatingError( dpe ); // } // } // end EnsureLiveTarget() protected void EnsureTargetCanStep(DbgEngDebugger debugger) { if (!debugger.CanStep) { DbgProviderException dpe = new DbgProviderException("Target is not live (cannot step).", "TargetNotLiveAndCantStep", ErrorCategory.InvalidOperation); try { throw dpe; } catch (Exception) { } // give it a stack trace ThrowTerminatingError(dpe); } } // end EnsureTargetCanStep()
/// <summary> /// This method is "best effort"--it probably won't screen out all possible /// invalid breakpoints. But it should hopefully catch some obviously bad ones. /// </summary> private void _TryValidateBp(ref DbgBreakpointInfo bp) { bool bpIsActuallyBogus = false; if (bp.IsEnabled) { if (bp.IsDeferred) { try { Util.Assert(!String.IsNullOrEmpty(Expression)); // TODO: What if the expression is not a symbol?? string mod, bareSym; ulong offset; DbgProvider.ParseSymbolName(Expression, out mod, out bareSym, out offset); if ("*" == mod) { bpIsActuallyBogus = true; } else { var modInfos = Debugger.GetModuleByName(mod).ToArray(); if (modInfos.Length > 0) { // The module is loaded and yet the bp is deferred... the // expression is no good. // // Or there is more than one module with that name. bpIsActuallyBogus = true; } } } catch (ArgumentException ae) { LogManager.Trace("Failed to parse expression as a symbol: {0}", Util.GetExceptionMessages(ae)); } } // end if( bp is deferred ) else if (0 != bp.Offset) { // The address shouldn't be invalid, because that would indicate the // bp is deferred, but we already checked for that. Util.Assert(bp.Offset != DebuggerObject.InvalidAddress); MEMORY_BASIC_INFORMATION64 mbi; int hr = Debugger.TryQueryVirtual(bp.Offset, out mbi); if (hr != 0) { // iDNA targets don't yet handle QueryVirtual. if (hr != DebuggerObject.E_NOTIMPL) { LogManager.Trace("_TryValidateBp: TryQueryVirtual failed: {0}", Util.FormatErrorCode(hr)); bpIsActuallyBogus = true; } } else { if ((mbi.Protect != PAGE.EXECUTE) && (mbi.Protect != PAGE.EXECUTE_READ) && // <-- (mbi.Protect != PAGE.EXECUTE_READWRITE) && // <-- I don't actually know what these are (mbi.Protect != PAGE.EXECUTE_WRITECOPY)) // <-- { bpIsActuallyBogus = true; } } } } // end if( bp is enabled ) if (bpIsActuallyBogus) { ulong addr = 0; if ((bp.Offset != 0) && (bp.Offset != DebuggerObject.InvalidAddress)) { addr = bp.Offset; } Debugger.RemoveBreakpoint(ref bp); var dpe = new DbgProviderException(Util.Sprintf("Failed to set breakpoint at {0}.", addr != 0 ? DbgProvider.FormatAddress(addr, Debugger.TargetIs32Bit, true).ToString(false) : Expression), "BpEnabledButDeferredAndOrBad", ErrorCategory.InvalidArgument, addr != 0 ? (object)addr : (object)Expression); try { throw dpe; } catch { } // give it a stack WriteError(dpe); } } // end _TryValidateBp()
} // end ProcessRecord() private IList <ulong> _TryResolveExpression() { // We need to parse this here for further examination of the modName and // so that we'll have the offset (which isn't returned from FindSymbol). string modName; string bareSym; ulong offset; DbgProvider.ParseSymbolName(Expression, out modName, out bareSym, out offset); if (!WildcardPattern.ContainsWildcardCharacters(modName)) { var mods = Debugger.GetModuleByName(modName, CancelTS.Token).ToArray(); if (0 == mods.Length) { // The module not loaded yet; it will have to become a deferred // breakpoint if it's not obviously bad. // DbgEng won't like wildcards for a deferred breakpoint. if (WildcardPattern.ContainsWildcardCharacters(Expression)) { var dpe = new DbgProviderException(Util.Sprintf("Can't use a wildcard for a deferred bp: {0}", Expression), "BpNoWildcardsHere", ErrorCategory.InvalidOperation, Expression); try { throw dpe; } catch { } // give it a stack SafeWriteError(dpe); return(null); } return(new ulong[0]); // signals that we need a deferred breakpoint } } GlobalSymbolCategory category; if (_IsDataBreakpoint) { category = GlobalSymbolCategory.All; } else { category = GlobalSymbolCategory.Function; } var syms = Debugger.FindSymbol_Enum(Expression, category, CancelTS.Token).ToArray(); if (0 == syms.Length) { var dpe = new DbgProviderException(Util.Sprintf("Could not resolve expression: {0}", Expression), "BpCouldNotFindSymbol", ErrorCategory.ObjectNotFound, Expression); try { throw dpe; } catch { } // give it a stack SafeWriteError(dpe); return(null); } if (syms.Length > 1) { // // Did the user obviously intend to have multiple breakpoints? // if (!WildcardPattern.ContainsWildcardCharacters(modName) && !WildcardPattern.ContainsWildcardCharacters(bareSym) && !Multiple) { SafeWriteWarning("The expression matched multiple symbols. If this is intended, you can use -Multiple to suppress this warning."); } // If the user specified -Multiple, we'll assume they know what they are doing with an offset. if ((offset != 0) && !Multiple) { SafeWriteWarning("Is it safe to use an offset with an expression that matches multiple symbols?"); } } ulong[] addrs = new ulong[syms.Length]; for (int i = 0; i < syms.Length; i++) { addrs[i] = syms[i].Address + offset; } return(addrs); } // end _TryResolveExpression()
protected override void ProcessRecord() { base.ProcessRecord(); Func <uint, DbgUModeThreadInfo> getThreadFunc; uint[] ids; string idType; if (0 == Util.Strcmp_OI(ParameterSetName, c_IdParamSetName)) { idType = "debugger id"; getThreadFunc = Debugger.GetUModeThreadByDebuggerId; ids = DebuggerId; } else if (0 == Util.Strcmp_OI(ParameterSetName, c_TidParamSetName)) { idType = "system id (tid)"; getThreadFunc = Debugger.GetThreadBySystemTid; ids = SystemId; } else if (Current) { idType = "id [current]"; getThreadFunc = (x) => Debugger.GetCurrentThread(); ids = sm_dummyIds; } else { Util.Assert(LastEvent); idType = "id [lastEvent]"; getThreadFunc = (x) => Debugger.GetEventThread(); ids = sm_dummyIds; } if (null == ids) { if (null == DebuggerId) // Just get 'em all { foreach (var ti in Debugger.EnumerateThreads()) { if (Stopping) { break; } SafeWriteObject(ti); } } } // end if( no specific id; get them all ) else { foreach (uint id in ids) { if (Stopping) { break; } try { SafeWriteObject(getThreadFunc(id)); } catch (DbgEngException dee) { DbgProviderException dpe = new DbgProviderException( Util.Sprintf("Could not get thread with {0} {1}. No such thread?", idType, id), "BadThreadId", ErrorCategory.InvalidArgument, dee, id); try { throw dpe; } catch (DbgProviderException) { } // give it a stack SafeWriteError(dpe); } } } // end else( by id ) } // end ProcessRecord()
protected override void ProcessRecord() { base.ProcessRecord(); if (null == Thread) { Func <uint, DbgUModeThreadInfo> getThreadFunc; uint id; string idType; if (0 == Util.Strcmp_OI(ParameterSetName, c_IdParamSetName)) { idType = "debugger id"; getThreadFunc = Debugger.GetUModeThreadByDebuggerId; id = DebuggerId; } else { Util.Assert(0 == Util.Strcmp_OI(ParameterSetName, c_TidParamSetName)); idType = "system id (tid)"; getThreadFunc = Debugger.GetThreadBySystemTid; id = SystemId; } try { Thread = getThreadFunc(id); } catch (DbgEngException dee) { DbgProviderException dpe = new DbgProviderException( Util.Sprintf("Could not get thread with {0} {1}. No such thread?", idType, id), "BadThreadId", ErrorCategory.InvalidArgument, dee, id); // If switching threads fails, subsequent commands might be in the wrong // context, so we'll make this a terminating error. try { throw dpe; } catch (DbgProviderException) { } // give it a stack ThrowTerminatingError(dpe); } } // end if( no Thread ) try { Util.Assert(null != Thread); Thread.SetContext(); } catch (DbgEngException dee) { DbgProviderException dpe = new DbgProviderException( Util.Sprintf("Could not switch to thread {0}: {1}", Thread.DebuggerId, Util.GetExceptionMessages(dee)), "ThreadSwitchFailed", ErrorCategory.NotSpecified, dee, Thread); // If switching threads fails, subsequent commands might be in the wrong // context, so we'll make this a terminating error. try { throw dpe; } catch (DbgProviderException) { } // give it a stack ThrowTerminatingError(dpe); } finally { RebuildNamespaceAndSetLocationBasedOnDebuggerContext(!Quiet); } } // end ProcessRecord()
} // end constructor public void AddLine(string s) { switch (m_state) { case WfdState.ExpectingBlockId: if ((s.Length > 0) && (s[s.Length - 1] != ':')) { // It's not a block ID... this can happen when "Flow // analysis was incomplete". m_currentBlockId = new ColorString(ConsoleColor.DarkGray, "<unknown>").MakeReadOnly(); m_pipeline.WriteObject(_ParseDisassembly(0, // will get parsed out of s s, m_currentBlockId, m_hasCodeBytes)); } else { m_currentBlockId = DbgProvider.ColorizeSymbol(s).MakeReadOnly(); } m_state = WfdState.ExpectingInstructionOrBlankLine; break; case WfdState.ExpectingInstructionOrBlankLine: if (String.IsNullOrEmpty(s)) { m_state = WfdState.ExpectingBlockId; m_currentBlockId = null; } else { m_pipeline.WriteObject(_ParseDisassembly(0, // will get parsed out of s s, m_currentBlockId, m_hasCodeBytes)); } break; // This is a horrible state. But sometimes we see it, like // sometimes after a flow analysis error. case WfdState.DontKnow: if (s.StartsWith("Flow analysis", StringComparison.OrdinalIgnoreCase)) { //m_flowAnalysisWarning = true; m_pipeline.WriteWarning(s); m_state = WfdState.DontKnow; break; } else if (s.StartsWith("*** WARNING: ", StringComparison.OrdinalIgnoreCase)) { m_pipeline.WriteWarning(s.Substring(13)); // trim off what will become redundant "WARNING" label. m_state = WfdState.DontKnow; break; } else if (s.StartsWith("*** ERROR: ", StringComparison.OrdinalIgnoreCase)) { s = s.Substring(11); // trim off what will become redundant "ERROR" label. var dpe = new DbgProviderException(s, "ErrorDuringUnassemble", ErrorCategory.ReadError); try { throw dpe; } catch (Exception) { } // give it a stack. m_pipeline.WriteError(dpe); m_state = WfdState.DontKnow; break; } else if (s.StartsWith("No code found, aborting", StringComparison.OrdinalIgnoreCase)) { var dpe = new DbgProviderException(s, "NoCodeFound", ErrorCategory.ReadError); try { throw dpe; } catch (Exception) { } // give it a stack. m_pipeline.WriteError(dpe); m_state = WfdState.DontKnow; // actually, we should be done now. break; } else if ((s.Length > 0) && (s[s.Length - 1] == ':')) { // Looks like a block ID... m_state = WfdState.ExpectingBlockId; AddLine(s); } else if (String.IsNullOrEmpty(s)) { m_state = WfdState.ExpectingBlockId; m_currentBlockId = null; } else { m_state = WfdState.ExpectingInstructionOrBlankLine; AddLine(s); } break; default: Util.Fail("Invalid parse state."); throw new Exception("Invalid parse state."); } } // end AddLine()
protected void SafeWriteError(DbgProviderException dpe) { SafeWriteError(dpe.ErrorRecord); }
protected void ThrowTerminatingError(DbgProviderException dpe) { ThrowTerminatingError(dpe.ErrorRecord); }