public ColorString ToColorString() { // return DbgProvider.FormatAddress( BaseAddress, // Debugger.TargetIs32Bit, // true ) // .Append( " " ) // .Append( DbgProvider.FormatAddress( BaseAddress + Size, // Debugger.TargetIs32Bit, // true ) ) // .Append( " " ) // .AppendPushPopFgBg( ConsoleColor.Black, // ConsoleColor.DarkYellow, // Name ) // .Append( Name.Length < 20 ? new String( ' ', 20 - Name.Length ) : String.Empty ) // .Append( SymbolStatus ); return(DbgProvider.ColorizeModuleName(Name) .Append(" ") .Append(DbgProvider.FormatAddress(BaseAddress, Debugger.TargetIs32Bit, true)) .Append(" ") .Append(DbgProvider.FormatAddress(BaseAddress + Size, Debugger.TargetIs32Bit, true))); } // end ToColorString()
// TODO: Is this sufficient? I wonder what a function pointer that returns // a function pointer looks like... protected override ColorString GetColorName() { if (null == m_colorName) { var cs = new ColorString(); cs.Append(DbgProvider.ColorizeTypeName(ReturnType.Name)); cs.Append(" (*fn)( "); if (0 == Arguments.Count) { cs.Append(DbgProvider.ColorizeTypeName("void")); cs.Append(" "); } else { for (int i = 0; i < Arguments.Count; i++) { cs.Append(DbgProvider.ColorizeTypeName(Arguments[i].ArgType.Name)); if (i < (Arguments.Count - 1)) { cs.Append(","); } cs.Append(" "); } } m_colorName = cs.Append(")").MakeReadOnly(); } return(m_colorName); } // end GetColorName()
private DateTimeOffset _GetDbgEngLastEventTimestamp() { // Example: // // Last event: ac8.2f8: Break instruction exception - code 80000003 (first/second chance not available) // debugger time: Mon Oct 20 06:41:19.392 2014 (UTC - 7:00) DateTimeOffset timestamp = DateTimeOffset.MinValue; using (m_debugger.HandleDbgEngOutput((x) => { x = x.Trim(); const string debuggerTime = "debugger time: "; if (x.StartsWith(debuggerTime, StringComparison.OrdinalIgnoreCase)) { var tsStr = x.Substring(debuggerTime.Length); if (!DbgProvider.TryParseDebuggerTimestamp(tsStr, out timestamp)) { var msg = Util.Sprintf("Huh... unable to parse dbgeng timestamp: {0}", tsStr); LogManager.Trace(msg); Util.Fail(msg); } } })) { m_debugger.InvokeDbgEngCommand(".lastevent", false); } return(timestamp); } // end _GetDbgEngLastEventTimestamp()
public override ColorString ToColorString() { var cs = new ColorString().Append(DbgProvider.ColorizeModuleName(m_sym.Module.Name)) .Append("!") .Append(DbgProvider.ColorizeTypeName(m_sym.Name)); return(cs); }
public ColorString ToColorString() { if (null == m_cs) { m_cs = new ColorString(); m_cs.Append(DbgProvider.ColorizeModuleName(m_udt.Module.Name)) .Append("!") .Append(m_udt.ColorName) .Append(" (size 0x") .Append(m_udt.Size.ToString("x")) .Append(")"); int widest = 16; foreach (var item in Items) { var ddti = item.Item as DbgDataTypeInfo; if (null != ddti) { widest = Math.Max(widest, ddti.Name.Length); } } widest = Math.Min(widest, 40); foreach (var item in Items) { m_cs.AppendLine() .Append(" +0x") .Append(item.Offset.ToString("x3")) .Append(" "); var ddti = item.Item as DbgDataTypeInfo; if (null != ddti) { m_cs.Append(ColorString.MakeFixedWidth(ddti.Name, widest)) .Append(" : ") .Append(ddti.DataType.ColorName); } else { VTableLayoutItem vli = (VTableLayoutItem)item; var dvti = (DbgVTableTypeInfo)item.Item; m_cs.AppendPushFg(ConsoleColor.DarkGray); if (vli.VTablePath.Count > 1) { m_cs.Append(vli.VTablePath[1].ColorName).Append(": "); } m_cs.Append(dvti.ToColorString()) .AppendPop(); } } m_cs.MakeReadOnly(); } // end if( !m_cs ) return(m_cs); } // end ToColorString()
} // end _FormatBlocks() private ColorString _FormatCharsOnly(uint numColumns, uint bytesPerChar, Func <char, char> toDisplay) { if (0 == numColumns) { numColumns = 32; // documentation says it should be 48, but windbg seems to do 32 instead. } ColorString cs = new ColorString(); StringBuilder sbChars = new StringBuilder((int)numColumns + 8); ulong addr = StartAddress; for (int idx = 0; idx < Count; idx++) { if (0 == (idx % numColumns)) { // This is the beginning of a new line. // First finish off the last line if necessary: if (sbChars.Length > 1) { sbChars.Append('"'); cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } sbChars.Clear(); sbChars.Append('"'); if (0 != idx) { cs.AppendLine(); } cs.Append(DbgProvider.FormatAddress(addr, m_is32Bit, true, true)).Append(" "); addr += (ulong)numColumns * bytesPerChar; } // end start of new line // Widen to ulong to accommodate largest possible item. ulong val = (ulong)this[idx]; if (0 == val) { break; } sbChars.Append(toDisplay((char)val)); } // end for( idx = 0 .. length ) // Finish off last line. if (sbChars.Length > 1) { sbChars.Append('"'); cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } return(cs.MakeReadOnly()); } // end _FormatCharsOnly()
public override ColorString ToColorString() { // TODO: This is the same as the DbgNativeFunction... factor out? // Or factor Module "in"? (Because maybe not all functions would have a // module?) var cs = new ColorString().Append(DbgProvider.ColorizeModuleName(Module.Name)) .Append("!") .Append(DbgProvider.ColorizeTypeName(Name)); return(cs); }
} // end Module public override ColorString ToColorString() { ColorString cs = new ColorString(); if (null != Module) { cs.Append(DbgProvider.ColorizeModuleName(Module.Name)).Append("!"); } cs.Append(DbgProvider.ColorizeTypeName(Name)); return(cs); }
} // end constructor() public static DbgUnknownFunction Create(DbgEngDebugger debugger, DbgEngContext context, DEBUG_STACK_FRAME_EX nativeFrame) { ulong address = nativeFrame.InstructionOffset; string modName = null; string funcName = null; ulong offset = 0; string fullname = null; // If our dbgeng has managed support (or support for whatever this is), let's // try that: if (0 != nativeFrame.InstructionOffset) { fullname = debugger.TryGetInfoFromFrame(nativeFrame, out modName, out funcName, out offset); if (String.IsNullOrEmpty(fullname)) { LogManager.Trace("DbgUnknownFunction.Create: dbgeng doesn't know, either."); } } else { LogManager.Trace("DbgUnknownFunction.Create: we have no chance with an InstructionOffset of zero."); } if (String.IsNullOrEmpty(fullname)) { funcName = DbgProvider.FormatUInt64(address, useTick: true); } else { address = address - offset; } return(new DbgUnknownFunction(debugger, context, nativeFrame, address, modName, funcName)); } // end static Create() factory
} // end _FormatBits() private static ColorString _DefaultSymLookup(DbgEngDebugger debugger, ulong addr) { ulong disp; string symName; if (debugger.TryGetNameByOffset(addr, out symName, out disp)) { ColorString cs = DbgProvider.ColorizeSymbol(symName); if (disp != 0) { cs.AppendPushPopFg(ConsoleColor.Gray, "+" + disp.ToString("x")); } return(cs); } return(ColorString.Empty); } // end _DefaultSymLookup()
} // end property Displacement public override string ToString() { if (null == Function) { // Let's see if dbgeng can do any better. try { Util.Fail("We don't have a Function."); ulong displacement; string fullname = GetNameByInlineContext(InstructionPointer, NativeFrameEx.InlineFrameContext, out displacement); string modName, funcName; ulong dontCare; DbgProvider.ParseSymbolName(fullname, out modName, out funcName, out dontCare); if (displacement == 0) { return(fullname); } else { return(Util.Sprintf("{0}+0x{1:x}", fullname, displacement)); } } catch (DbgProviderException dpe) { LogManager.Trace("Still couldn't get symbolic name: {0}", Util.GetExceptionMessages(dpe)); } } // end if( !Function ) if (Displacement == 0) { return(SymbolName); } else { return(Util.Sprintf("{0}+0x{1:x}", SymbolName, Displacement)); } } // end ToString()
} // end _FormatCharsOnly() private ColorString _FormatBits() { ColorString cs = new ColorString(); uint bytesPerValue = sizeof(uint); uint bitsPerValue = bytesPerValue * 8; ulong addr = StartAddress; for (int idx = 0; idx < Count; idx++) { if (0 != idx) { cs.AppendLine(); } cs.Append(DbgProvider.FormatAddress(addr, m_is32Bit, true, true)).Append(" "); addr += (ulong)bytesPerValue; uint val = this[idx]; for (int i = 0; i < bitsPerValue; i++) { if (i % 8 == 0) { cs.Append(" "); } uint mask = 0x80000000 >> i; if ((mask & val) == mask) { cs.AppendPushPopFg(ConsoleColor.Green, "1"); } else { cs.AppendPushPopFg(ConsoleColor.DarkGreen, "0"); } } cs.Append(" " + val.ToString("x").PadLeft(8, '0')); } // end for( idx = 0 .. length ) return(cs.MakeReadOnly()); } // end _FormatBits()
private static ColorString _SummarizeModuleList(bool loadedMods, List <object> modObjList, int maxWidth) { ColorString cs = new ColorString(); if (0 == modObjList.Count) { cs.AppendPushPopFg(ConsoleColor.DarkGray, "(0 modules)"); } else { cs.Append(Util.Sprintf("{0} modules: ", modObjList.Count)); for (int i = 0; i < Math.Min(modObjList.Count, 3); i++) { if (i > 0) { cs.Append(", "); } DbgModuleInfo dmi = (DbgModuleInfo)modObjList[i]; if (loadedMods) { cs.Append(DbgProvider.ColorizeModuleName(dmi.Name)); } else { cs.Append(dmi.ImageName); } } if (modObjList.Count > 3) { cs.Append(", ..."); } } return(CaStringUtil.Truncate(cs.ToString(DbgProvider.HostSupportsColor), maxWidth)); } // end _SummarizeModuleList()
public DbgValueScriptConverter(string typeName, ScriptBlock script, bool captureContext) { if (String.IsNullOrEmpty(typeName)) { throw new ArgumentException("You must supply a type name.", "typeName"); } if (null == script) { throw new ArgumentNullException("script"); } TypeName = typeName; Script = script; if (captureContext) { Context = DbgProvider.CapturePsContext(); } else { Context = new PsContext(); } } // end constructor
} // end ToString() public ColorString ToColorString() { ColorString cs; if (0 == InstructionPointer) { cs = new ColorString(ConsoleColor.Red, "0") .Append(" ") .AppendPushFg(ConsoleColor.Yellow) .Append("WARNING: Frame IP not in any known module. Following frames may be wrong.") .AppendPop(); } else { cs = DbgProvider.ColorizeSymbol(ToString()); if ((null != Module) && (Module.SymbolType == DEBUG_SYMTYPE.EXPORT)) { // If we only have export symbols, let's give a visual clue: cs = new ColorString().AppendPushBg(ConsoleColor.DarkRed).Append(cs).AppendPop(); } } return(cs); } // end ToColorString()
public PsContextHelper(ScriptBlock scriptBlock, PsContext withContext, bool saveContext) { if (null == scriptBlock) { throw new ArgumentNullException("scriptBlock"); } m_withContext = withContext; if (!saveContext) { m_scriptBlock = scriptBlock; return; } if (null == m_withContext) { m_withContext = new PsContext(); } m_savedContext = new PSVariable(c_SavedContextVarName, null); m_withContext.Vars[m_savedContext.Name] = m_savedContext; m_ctxMarker = DbgProvider.SetContextStartMarker(); // Hacking the scriptBlock and smuggling the context out like this is // pretty ugly. I don't know a better way, though--I'm open to // suggestions. m_scriptBlock = ScriptBlock.Create(Util.Sprintf(@"{0} . ""{1}\\GetPsContextFunc.ps1"" ${2} = Get-PsContext", scriptBlock.ToString(), DbgProvider.PsScriptRoot, c_SavedContextVarName)); } // end constructor
} // end _ZeroPad() private ColorString _FormatBlocks(int elemSize, int charsPerBlock, uint numColumns, AddtlInfo addtlInfo) { if (0 == numColumns) { numColumns = (uint)(16 / elemSize); } if (addtlInfo.HasFlag(AddtlInfo.Symbols)) { numColumns = 1; } int desiredLen = elemSize * 2; ColorString cs = new ColorString(); StringBuilder sbChars = new StringBuilder(20); ulong addr = StartAddress; cs.AppendPushFg(ConsoleColor.DarkGreen); for (int idx = 0; idx < Count; idx++) { if (0 == (idx % numColumns)) { // This is the beginning of a new line. // First finish off the last line if necessary: if (addtlInfo.HasFlag(AddtlInfo.Ascii)) { if (sbChars.Length > 2) { cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } sbChars.Clear(); sbChars.Append(" "); } if (0 != idx) { cs.AppendLine(); } cs.Append(DbgProvider.FormatAddress(addr, m_is32Bit, true, true)).Append(" "); addr += (ulong)(numColumns * elemSize); } // end start of new line else { cs.Append(" "); } // Widen to ulong to accommodate largest possible item. ulong val = (ulong)this[idx]; // This highlights the non-zero portion in [bright] green. cs.Append(_ZeroPad(val, desiredLen)); if (addtlInfo.HasFlag(AddtlInfo.Symbols)) { ColorString csSym = ColorString.Empty; if (val > 4096) // don't even bother trying if it's too low. { csSym = m_lookupSymbol(val); if (csSym.Length > 0) { cs.Append(" ").Append(csSym); } } if (addtlInfo.HasFlag(AddtlInfo.Ascii)) { if (0 == csSym.Length) { cs.Append(" "); _AppendChars(sbChars, idx * elemSize, elemSize); } } } // end if( symbols ) else if (addtlInfo.HasFlag(AddtlInfo.Ascii)) { _AppendChars(sbChars, idx * elemSize, elemSize); } // end else if( Ascii ) } // end for( idx = 0 .. length ) // Finish off last line. if (sbChars.Length > 2) { // It could be a partial line, so we may need to adjust for that. int numMissing = (int)numColumns - ((sbChars.Length - 2) / elemSize); Util.Assert(numMissing >= 0); if (numMissing > 0) { cs.Append(new String(' ', numMissing * charsPerBlock)); } cs.AppendPushPopFg(ConsoleColor.Cyan, sbChars.ToString()); } cs.AppendPop(); // pop DarkGreen return(cs.MakeReadOnly()); } // end _FormatBlocks()
public ColorString ToColorString(ConsoleColor color) => DbgProvider.FormatAddress(Value, Is32Bit, true, true, color);
public ColorString ToColorString() => DbgProvider.FormatAddress(Value, Is32Bit, true, true);
} // end property OwningClass protected override ColorString GetColorName() { return(DbgProvider.ColorizeFunctionName(Name)); } // end GetColorName()
public ColorString ToColorString() { if (DEBUG_EVENT.NONE == EventType) { return(ColorString.Empty); } ColorString csThreadId; if (0xffffffff == ThreadId) { csThreadId = new ColorString(ConsoleColor.Red, "ffffffff"); } else { csThreadId = new ColorString(m_debugger.GetUModeThreadByDebuggerId(ThreadId).Tid.ToString("x")); } ColorString cs = new ColorString(ConsoleColor.Black, ConsoleColor.White, " Last event:") .Append(" ") .Append(m_debugger.GetProcessSystemId(ProcessId).ToString("x")) .Append(".") .Append(csThreadId) .Append(": "); DbgModuleInfo mod = null; string tmp = null; string[] lines = null; switch (EventType) { case DEBUG_EVENT.NONE: Util.Fail("can't get here"); // we returned ColorString.Empty above break; case DEBUG_EVENT.BREAKPOINT: cs.Append(Description); break; case DEBUG_EVENT.EXCEPTION: tmp = ExceptionEventArgs._CreateMessage(m_debugger, ExtraInformation.Exception.ExceptionRecord, ExtraInformation.Exception.FirstChance != 0, 0, null, false).ToString(DbgProvider.HostSupportsColor); lines = tmp.Split(sm_newline, StringSplitOptions.None); cs.AppendLine(lines[0]); for (int i = 1; i < lines.Length; i++) { cs.AppendPushPopFgBg(ConsoleColor.Black, ConsoleColor.White, " ") .Append(" ") .Append(lines[i]); if (i != lines.Length - 1) { cs.AppendLine(); } } break; case DEBUG_EVENT.CREATE_THREAD: cs.Append(Description); break; case DEBUG_EVENT.EXIT_THREAD: cs.Append(Description); break; case DEBUG_EVENT.CREATE_PROCESS: cs.Append(Description); break; case DEBUG_EVENT.EXIT_PROCESS: cs.Append(Description); break; case DEBUG_EVENT.LOAD_MODULE: // // Last event: 9c84.3984: Load module C:\WINDOWS\system32\ADVAPI32.dll at 00007ffb`b0cd0000 // debugger time: Mon Oct 20 19:30:56.164 2014 (UTC - 7:00) mod = m_debugger.GetModuleByAddress(ExtraInformation.LoadModule.Base); cs.Append("Loaded module ") .AppendPushPopFg(ConsoleColor.White, mod.ImageName) .Append(" at ") .Append(DbgProvider.FormatAddress(ExtraInformation.LoadModule.Base, m_debugger.TargetIs32Bit, true)); break; case DEBUG_EVENT.UNLOAD_MODULE: // TODO: test this! mod = m_debugger.GetModuleByAddress(ExtraInformation.UnloadModule.Base); cs.AppendPushPopFg(ConsoleColor.DarkRed, "Unloaded module ") .AppendPushPopFg(ConsoleColor.White, mod.ImageName) .Append(" at ") .Append(DbgProvider.FormatAddress(ExtraInformation.UnloadModule.Base, m_debugger.TargetIs32Bit, true)); break; case DEBUG_EVENT.SYSTEM_ERROR: // TODO: test this! cs.AppendPushPopFgBg(ConsoleColor.White, ConsoleColor.Red, "System error:") .Append(" ") .AppendPushPopFg(ConsoleColor.Red, Util.FormatErrorCode(ExtraInformation.SystemError.Error)) .Append(".") .AppendPushPopFg(ConsoleColor.Red, Util.FormatErrorCode(ExtraInformation.SystemError.Level)); // TODO: This is a hack. var w32e = new System.ComponentModel.Win32Exception((int)ExtraInformation.SystemError.Error); cs.AppendLine(); cs.AppendPushPopFg(ConsoleColor.Red, w32e.Message).Append("."); break; case DEBUG_EVENT.SESSION_STATUS: // DbgEng doesn't save these as "last events". Util.Fail(Util.Sprintf("Unexpected last event type: {0}", EventType)); break; case DEBUG_EVENT.CHANGE_DEBUGGEE_STATE: // DbgEng doesn't save these as "last events". Util.Fail(Util.Sprintf("Unexpected last event type: {0}", EventType)); break; case DEBUG_EVENT.CHANGE_ENGINE_STATE: // DbgEng doesn't save these as "last events". Util.Fail(Util.Sprintf("Unexpected last event type: {0}", EventType)); break; case DEBUG_EVENT.CHANGE_SYMBOL_STATE: // DbgEng doesn't save these as "last events". Util.Fail(Util.Sprintf("Unexpected last event type: {0}", EventType)); break; default: Util.Fail(Util.Sprintf("Unexpected event type: {0}", EventType)); throw new Exception(Util.Sprintf("Unexpected event type: {0}", EventType)); } // end switch( event type ) cs.AppendLine() .AppendPushPopFgBg(ConsoleColor.Black, ConsoleColor.White, " Debugger time:") .Append(" ") .Append(DbgProvider.FormatTimestamp(_GetDbgEngLastEventTimestamp(), true)); return(cs); } // end ToColorString()
public DbgMemoryAccessException(ulong address, bool is32bit) : this(address, Util.Sprintf("Could not access memory: {0}", DbgProvider.FormatAddress(address, is32bit, true))) { }
public override void WriteError(ErrorRecord er) { ThrowIfDisposed(); DbgProvider.LogError(er); //m_errors.Add( er ); }
} // end property Displacement public override string ToString() { if (null == Function) { // Let's see if dbgeng can do any better. try { Util.Fail("We don't have a Function."); ulong displacement; string fullname = GetNameByInlineContext(InstructionPointer, NativeFrameEx.InlineFrameContext, out displacement); string modName, funcName; ulong dontCare; DbgProvider.ParseSymbolName(fullname, out modName, out funcName, out dontCare); if (displacement == 0) { return(fullname); } else { return(Util.Sprintf("{0}+0x{1:x}", fullname, displacement)); } } catch (DbgProviderException dpe) { LogManager.Trace("Still couldn't get symbolic name: {0}", Util.GetExceptionMessages(dpe)); } } // end if( !Function ) try { string disp = String.Empty; if (Displacement != 0) { disp = "+0x" + Displacement.ToString("x"); } if (null != ManagedFrame) { // TODO: Ideally we wouldn't deal with this at this layer; we would // synthesize a DbgModuleInfo instead. But for now this is a handy // workaround. // https://github.com/Microsoft/DbgShell/issues/35 // It seems like dbgeng likes to replace dots in module names with // underbars... why? I guess I should do the same? return(ManagedFrame.ModuleName.Replace('.', '_') + "!" + ManagedFrame.Method.GetFullSignature() + disp); } return(SymbolName + disp); } catch (DbgProviderException dpe) { LogManager.Trace("Could not get symbol name: {0}", Util.GetExceptionMessages(dpe)); } return(DbgProvider.FormatAddress(InstructionPointer, Debugger.TargetIs32Bit, useTick: true)); } // end ToString()
// Example: // // 0:009> r // r0=00000000 r1=00000000 r2=00000000 r3=76fdcf09 r4=00000000 r5=028df6e0 // r6=028df730 r7=00000000 r8=00000001 r9=01507858 r10=015156a8 r11=028df8e8 // r12=00000000 sp=028df6c8 lr=00000000 pc=76ccce24 psr=600f0030 -ZC-- Thumb // KERNELBASE!RaiseFailFastException+0x60: // 76ccce24 f000f846 bl KERNELBASE!SignalStartWerSvc (76ccceb4) // public override ColorString ToColorString() { if (null == m_colorString) { ConsoleColor color; ColorString cs = new ColorString(" r0="); color = GetColorForDiffAgainstBaseline("r0"); cs.Append(R0.GetColorizedValueString(color)); cs.Append(" r1="); color = GetColorForDiffAgainstBaseline("r1"); cs.Append(R1.GetColorizedValueString(color)); cs.Append(" r2="); color = GetColorForDiffAgainstBaseline("r2"); cs.Append(R2.GetColorizedValueString(color)); cs.Append(" r3="); color = GetColorForDiffAgainstBaseline("r3"); cs.Append(R3.GetColorizedValueString(color)); cs.Append(" r4="); color = GetColorForDiffAgainstBaseline("r4"); cs.Append(R4.GetColorizedValueString(color)); cs.Append(" r5="); color = GetColorForDiffAgainstBaseline("r5"); cs.Append(R5.GetColorizedValueString(color)); cs.AppendLine(); cs.Append(" r6="); color = GetColorForDiffAgainstBaseline("r6"); cs.Append(R6.GetColorizedValueString(color)); cs.Append(" r7="); color = GetColorForDiffAgainstBaseline("r7"); cs.Append(R7.GetColorizedValueString(color)); cs.Append(" r8="); color = GetColorForDiffAgainstBaseline("r8"); cs.Append(R8.GetColorizedValueString(color)); cs.Append(" r9="); color = GetColorForDiffAgainstBaseline("r9"); cs.Append(R9.GetColorizedValueString(color)); cs.Append(" r10="); color = GetColorForDiffAgainstBaseline("r10"); cs.Append(R10.GetColorizedValueString(color)); cs.Append(" r11="); color = GetColorForDiffAgainstBaseline("r11"); cs.Append(R11.GetColorizedValueString(color)); cs.AppendLine(); cs.Append("r12="); color = GetColorForDiffAgainstBaseline("r12"); cs.Append(R12.GetColorizedValueString(color)); cs.Append(" sp="); color = GetColorForDiffAgainstBaseline("sp"); cs.Append(Sp.GetColorizedValueString(color)); cs.Append(" lr="); color = GetColorForDiffAgainstBaseline("lr"); cs.Append(Lr.GetColorizedValueString(color)); cs.Append(" pc="); color = GetColorForDiffAgainstBaseline("pc"); cs.Append(Pc.GetColorizedValueString(color)); cs.Append(" psr="); color = GetColorForDiffAgainstBaseline("psr"); cs.Append(Psr.GetColorizedValueString(color)); // TODO: cs.AppendLine(" TBD: flags and mode"); cs.Append(DbgProvider.ColorizeSymbol(StackFrame.SymbolName)); if (0 != StackFrame.Displacement) { cs.Append("+0x"); cs.Append(StackFrame.Displacement.ToString("x")); } cs.AppendLine(":"); cs.Append(Disasm(Pc.ValueAsPointer)); m_colorString = cs; } return(m_colorString); } // end ToString()
} // end property Frames public IEnumerable <DbgStackFrameInfo> EnumerateStackFrames() { if (null != m_frames) { return(m_frames); } m_frames = new List <DbgStackFrameInfo>(); bool noException = false; try { return(Debugger.ExecuteOnDbgEngThread(() => { using (new DbgEngContextSaver(Debugger, Context)) { WDebugControl dc = (WDebugControl)Debugger.DebuggerInterface; /* TODO: I guess frameOffset doesn't do what I think it does... or maybe I need to file a bug. * //int stride = 64; * int stride = 3; * ulong frameOffset = 0; * int hr = 0; * DEBUG_STACK_FRAME_EX[] frames = new DEBUG_STACK_FRAME_EX[ stride ]; * while( true ) * { * uint framesFilled = 0; * hr = dc.GetStackTraceEx( frameOffset, 0, 0, frames, frames.Length, out framesFilled ); * * CheckHr( hr ); * * if( 0 == framesFilled ) * break; * * for( int i = 0; i < framesFilled; i++ ) * { * var newFrame = new StackFrameInfo( Debugger, frames[ i ] ); * m_frames.Add( newFrame ); * //yield return newFrame; hmm, can't mix an iterator with the straight 'return' above * } * * frameOffset += 3; * } // while( keep requesting more frames ) */ DEBUG_STACK_FRAME_EX[] frames; int hr = dc.GetStackTraceEx(0, // frameOffset 0, // stackOffset 0, // instructionOffset MaxFrameCount, out frames); CheckHr(hr); int[] managedFrameIndices; try { managedFrameIndices = new int[Thread.ManagedThreads.Count]; } catch (InvalidOperationException ioe) { // // Likely "Mismatched architecture between this process // and the dac." No managed code information for you, sir. // DbgProvider.RequestExecuteBeforeNextPrompt( Util.Sprintf("Write-Warning 'Could not get managed thread/frame information: {0}'", System.Management.Automation.Language.CodeGeneration.EscapeSingleQuotedStringContent(Util.GetExceptionMessages(ioe)))); managedFrameIndices = new int[0]; // (and remember not to keep trying to get managed info) Debugger.ClrMdDisabled = true; } foreach (var nativeFrame in frames) { ClrStackFrame managedFrame = null; for (int i = 0; i < managedFrameIndices.Length; i++) { var mThread = Thread.ManagedThreads[i]; int mFrameIdx = managedFrameIndices[i]; // It's possible that a thread is marked as a managed // thread, but has no stack frames. (I've seen this, // for instance, at the final breakpoint of a managed // app.) if (0 == mThread.StackTrace.Count) { continue; } if (mFrameIdx >= mThread.StackTrace.Count) { // We've exhausted the managed frames for this // particular managed thread. continue; } var mFrame = mThread.StackTrace[mFrameIdx]; while ((0 == mFrame.InstructionPointer) && (mFrameIdx < (mThread.StackTrace.Count - 1))) // still at least one more frame below? { // It's some sort of "helper" or GC frame or // something, which we need to skip. mFrameIdx++; managedFrameIndices[i] = mFrameIdx; mFrame = mThread.StackTrace[mFrameIdx]; } if (nativeFrame.InstructionOffset == mFrame.InstructionPointer) { managedFrame = mFrame; managedFrameIndices[i] += 1; break; } } var newFrame = new DbgStackFrameInfo(Debugger, m_thread, nativeFrame, managedFrame); m_frames.Add(newFrame); } noException = true; return m_frames; } // end using( context saver ) })); } finally { if (!noException) { m_frames = null; // so we can try again (handy for debugging) } } } // end EnumerateStackFrames()
} // end ChangeDebuggeeState() public int ChangeEngineState(DEBUG_CES Flags, ulong Argument) { LogManager.Trace("ChangeEngineState: {0}, 0x{1:x}", Flags, Argument); try { var eventArgs = new EngineStateChangedEventArgs(m_debugger, Flags, Argument); if (eventArgs.Flags.HasFlag(DEBUG_CES.EVENT_FILTERS)) { // Need to refresh our filters. if (eventArgs.Argument == DbgEventArgs.DEBUG_ANY_ID) { m_debugger._ResetFilters(); } else { m_debugger._RefreshSingleFilter((uint)eventArgs.Argument); } } if (eventArgs.Flags.HasFlag(DEBUG_CES.BREAKPOINTS)) { // Need to refresh our breakpoints. m_debugger.FixupBpStuff(eventArgs.Argument); } if ((eventArgs.Flags.HasFlag(DEBUG_CES.SYSTEMS))) { // DbgEng doesn't seem to set up its symbol path until you first // attach to something, but it doesn't raise the event saying that // the symbol path has changed when that happens. As a workaround, // we'll dump our cached symbol path here. m_debugger.m_sympath = null; // Another oddity with the symbol path: before attaching to any // system, dbgeng will say that the symbol path is blank. Then, // once it gets attached to something, it will append the value of // the environment variable _NT_SYMBOL_PATH to it. if ((DEBUG_ANY_ID != (uint)eventArgs.Argument)) { // We're adding a system. This might be a handy spot to do // something, so I'm leaving the condition here even though I'm // not currently using it. // (this gets traced by the eventArgs constructor) } else { // Removing a system. (this gets traced by the eventArgs // constructor) } } if (eventArgs.Flags.HasFlag(DEBUG_CES.EFFECTIVE_PROCESSOR)) { //DbgProvider.ForceRebuildNamespace(); LogManager.Trace("Effective processor changed; queueing request to rebuild namespace."); DbgProvider.RequestExecuteBeforeNextPrompt("[MS.Dbg.DbgProvider]::ForceRebuildNamespace()"); } if (eventArgs.Flags.HasFlag(DEBUG_CES.EXECUTION_STATUS)) { m_executionStatusCookie++; } int retVal = _RaiseEvent(m_debugger.EngineStateChanged, eventArgs); if (_ShouldOutput(retVal, eventArgs)) { _PsPipe.WriteObject(eventArgs); } if (DEBUG_CES.EXECUTION_STATUS == Flags) { var status = (DEBUG_STATUS)(Argument & (ulong)DEBUG_STATUS.MASK); bool insideWait = false; bool waitTimedOut = false; if (status != (DEBUG_STATUS)Argument) { insideWait = 0 != (Argument & (ulong)DEBUG_STATUS_FLAGS.INSIDE_WAIT); waitTimedOut = 0 != (Argument & (ulong)DEBUG_STATUS_FLAGS.WAIT_TIMEOUT); } LogManager.Trace("EXECUTION_STATUS changed. Argument: 0x{0:x} ({1}{2}{3})", Argument, status, insideWait ? " + INSIDE_WAIT" : "", waitTimedOut ? " + WAIT_TIMEOUT" : ""); DbgEngDebugger._GlobalDebugger.DbgEngCookie++; if (0 == ((ulong)DEBUG_STATUS_FLAGS.INSIDE_WAIT & Argument)) { // Formerly, we would use this code to signal the currently- // running cmdlet to exit its message loop. The idea was that // there had been problems with more notification events arriving // /after/ WaitForEvent returned. But I can't currently repro // that. (There /are/ some notifications that occur after // WaitForEvent returns, but they are caused by my own actions-- // setting assembly options and text aliases.) // // There is also the difference that now I call WaitForEvent on // the dbgeng thread, whereas originally I had been calling it on // a threadpool thread. I'm not sure how that would have made a // difference, though. // // For now, I'm going to get rid of this stuff. It seems fragile // and horribly complicated--I really hope I don't have to bring // it back. // // // TODO: This seems terribly fragile. But I don't see how else to make // // sure we process all callbacks before exiting ProcessRecord. I'm probably // // going to have to add more cases... :( // if( DEBUG_STATUS.BREAK == (DEBUG_STATUS) Argument ) // { // if( _SignalPipeOnBreak ) // { // LogManager.Trace( "EXECUTION_STATUS is BREAK; signaling pipeline." ); // _PsPipe.SignalDone(); // } // else // { // LogManager.Trace( "EXECUTION_STATUS is BREAK, but we're ignoring it." ); // } // } if (DEBUG_STATUS.NO_DEBUGGEE == (DEBUG_STATUS)Argument) { // We have no target. This might be a handy spot to do // something, so I'm leaving the condition here even // though I'm not currently using it. LogManager.Trace("No debuggee."); } } // end if( inside wait ) } // end if( exec status ) return(retVal); } catch (Exception e) { Util.FailFast("Unexpected exception during event callback.", e); return(0); } } // end ChangeEngineState()
public object Convert(DbgSymbol symbol) // TODO: plumb a CancellationToken through here. { if (null == m_currentlyProcessingAddresses) { m_currentlyProcessingAddresses = new HashSet <ulong>(); } if (!m_currentlyProcessingAddresses.Add(symbol.Address)) // TODO: Do we need to worry about enregistered things? { LogManager.Trace("Detected re-entrant conversion of type {0}; bailing out.", TypeName); return(null); } PowerShell shell; var lease = DbgProvider.LeaseShell(out shell); try { Util.Assert(null != Context); Context.Vars["_"] = new PSVariable("_", symbol); Context.Vars["PSItem"] = new PSVariable("PSItem", symbol); // Note that StrictMode will be enforced for value converters, because // they execute in the scope of Debugger.psm1, which sets StrictMode. // // The problem with just calling Script.InvokeWithContext directly is that // non-terminating errors are hidden from us. shell.AddScript(@"$args[ 0 ].InvokeWithContext( $args[ 1 ].Funcs, $args[ 1 ].VarList )", true) .AddArgument(Script) .AddArgument(Context); Collection <PSObject> results = shell.Invoke(); // // For some reason, sometimes shell.HadErrors returns true when // // shell.Streams.Error.Count is 0, when the pipeline is stopping. // if( Stopping ) // return; // INT2d518c4b: shell.HadErrors is clueless. //if( shell.HadErrors ) if (shell.Streams.Error.Count > 0) { // TODO TODO: handle more than one // if( 1 == shell.Streams.Error.Count ) // { var e = shell.Streams.Error[0]; // TODO: tailored exception throw new DbgProviderException(Util.Sprintf("Symbol value conversion for type name {0} failed: {1}", TypeName, Util.GetExceptionMessages(e.Exception)), e); // } // else // { // } } if (0 == results.Count) { return(null); // I guess it didn't work. } if (1 == results.Count) { return(results[0]); } else { // TODO: Hmm... not sure what's the best thing to do here. Return just the // last thing? For now I'll return the collection. LogManager.Trace("Warning: Symbol value conversion for type name {0} yielded multiple results (symbol {1}).", TypeName, symbol); return(results); } } finally { m_currentlyProcessingAddresses.Remove(symbol.Address); if (null != lease) { lease.Dispose(); } // Let's not keep the input object rooted. Context.Vars.Remove("_"); Context.Vars.Remove("PSItem"); } } // end Convert()
protected virtual ColorString GetColorName() { return(DbgProvider.ColorizeTypeName(Name)); } // end GetColorName()
// Example: // // eax=7ffdb000 ebx=00000000 ecx=00000000 edx=7785f17d esi=00000000 edi=00000000 // eip=777f410c esp=040ef770 ebp=040ef79c iopl=0 nv up ei pl zr na pe nc // cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 // ntdll!DbgBreakPoint: // public override ColorString ToColorString() { if (null == m_colorString) { ConsoleColor color; ColorString cs = new ColorString("eax="); color = GetColorForDiffAgainstBaseline("eax"); cs.Append(Eax.GetColorizedValueString(color)); cs.Append(" ebx="); color = GetColorForDiffAgainstBaseline("ebx"); cs.Append(Ebx.GetColorizedValueString(color)); cs.Append(" ecx="); color = GetColorForDiffAgainstBaseline("ecx"); cs.Append(Ecx.GetColorizedValueString(color)); cs.Append(" edx="); color = GetColorForDiffAgainstBaseline("edx"); cs.Append(Edx.GetColorizedValueString(color)); cs.Append(" esi="); color = GetColorForDiffAgainstBaseline("esi"); cs.Append(Esi.GetColorizedValueString(color)); cs.Append(" edi="); color = GetColorForDiffAgainstBaseline("edi"); cs.Append(Edi.GetColorizedValueString(color)); cs.AppendLine(); cs.Append("eip="); color = GetColorForDiffAgainstBaseline("eip"); cs.Append(Eip.GetColorizedValueString(color)); cs.Append(" esp="); color = GetColorForDiffAgainstBaseline("esp"); cs.Append(Esp.GetColorizedValueString(color)); cs.Append(" ebp="); color = GetColorForDiffAgainstBaseline("ebp"); cs.Append(Ebp.GetColorizedValueString(color)); cs.Append(" iopl="); color = GetColorForDiffAgainstBaseline("iopl"); cs.AppendPushPopFg(color, ((uint)Iopl.Value).ToString("x")); // TODO: cs.AppendLine(" TBD: flags"); cs.Append("cs="); color = GetColorForDiffAgainstBaseline("cs"); cs.AppendPushPopFg(color, ((uint)Cs.Value).ToString("x4")); cs.Append(" ss="); color = GetColorForDiffAgainstBaseline("ss"); cs.AppendPushPopFg(color, ((uint)Ss.Value).ToString("x4")); cs.Append(" ds="); color = GetColorForDiffAgainstBaseline("ds"); cs.AppendPushPopFg(color, ((uint)Ds.Value).ToString("x4")); cs.Append(" es="); color = GetColorForDiffAgainstBaseline("es"); cs.AppendPushPopFg(color, ((uint)Es.Value).ToString("x4")); cs.Append(" fs="); color = GetColorForDiffAgainstBaseline("fs"); cs.AppendPushPopFg(color, ((uint)Fs.Value).ToString("x4")); cs.Append(" gs="); color = GetColorForDiffAgainstBaseline("gs"); cs.AppendPushPopFg(color, ((uint)Gs.Value).ToString("x4")); cs.Append(" efl="); color = GetColorForDiffAgainstBaseline("efl"); cs.Append(Efl.GetColorizedValueString(color)); cs.AppendLine(); cs.Append(DbgProvider.ColorizeSymbol(StackFrame.SymbolName)); if (0 != StackFrame.Displacement) { cs.Append("+0x"); cs.Append(StackFrame.Displacement.ToString("x")); } cs.AppendLine(":"); cs.Append(Disasm(Eip.ValueAsPointer)); m_colorString = cs; } return(m_colorString); } // end ToString()