} // end _CreateBp() private void _SetOtherBpProperties(DbgBreakpointInfo bp) { bp.IsEnabled = true; if (OneShot) { bp.IsOneShot = true; } if (0 != PassCount) { bp.PassCount = PassCount; } if (null != Command) { bp.ScriptBlockCommand = Command; } else if (!String.IsNullOrEmpty(DbgEngCommand)) { bp.DbgEngCommand = DbgEngCommand; } if (null != MatchThread) { bp.MatchThread = MatchThread.DebuggerId; } if (0 != DataSize) { bp.DataAccessType = DataAccessType; bp.DataSize = DataSize; } }
} // end _TryResolveExpression() private DbgBreakpointInfo _CreateBaseBp(ulong addr) { DbgBreakpointInfo bp = Debugger.TryFindMatchingBreakpoint(Expression, addr); uint oldId = DebuggerObject.DEBUG_ANY_ID; if (null != bp) { oldId = bp.Id; SafeWriteWarning("Redefining existing breakpoint {0}.", oldId); Debugger.RemoveBreakpoint(ref bp); } DEBUG_BREAKPOINT_TYPE bpType; if (_IsDataBreakpoint) { bpType = DEBUG_BREAKPOINT_TYPE.DATA; } else { bpType = DEBUG_BREAKPOINT_TYPE.CODE; } bp = Debugger.NewBreakpoint(bpType, oldId); return(bp); } // end _CreateBaseBp()
private void _CreateBp(ulong addr) { DbgBreakpointInfo bp = _CreateBaseBp(addr); if (0 != addr) { bp.Offset = addr; } else { bp.OffsetExpression = Expression; } _SetOtherBpProperties(bp); // // DbgEng will let you set breakpoints that are not valid. // // Subsequently trying to step (after setting a bogus breakpoint) will fail. // // It would be much nicer to give an error about the breakpoint up front. // _TryValidateBp(ref bp); // will null it out if bogus if (null != bp) { SafeWriteObject(bp); } } // end _CreateBp()
protected override void ProcessRecord() { foreach (var bp in _EnumBreakpointsToOperateOn()) { DbgBreakpointInfo tmpBp = bp; // because we can't pass a "foreach variable" as "ref" SafeWriteVerbose("Deleting breakpoint {0} ({1}).", tmpBp.Id, tmpBp.SymbolicName); Debugger.RemoveBreakpoint(ref tmpBp); } } // end ProcessRecord()
/// <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()