public static bool TryCreateFunction(DbgEngDebugger debugger, DbgEngContext context, DEBUG_STACK_FRAME_EX nativeStackFrame, out DbgFunction function, out ulong displacement) { function = null; displacement = 0; DbgSymbol sym = null; try { SymbolInfo si = DbgHelp.SymFromInlineContext(debugger.DebuggerInterface, nativeStackFrame.InstructionOffset, nativeStackFrame.InlineFrameContext, out displacement); sym = new DbgPublicSymbol(debugger, si, debugger.GetCurrentTarget()); function = new DbgNativeFunction(debugger, context, sym); return(true); } catch (DbgProviderException dpe) { // Sometimes the debugger doesn't know. E.g., frame 'e' here (from ntsd): // 0:000> kn // # Child-SP RetAddr Call Site // 00 00000000`0058dff8 00000000`76c02ef8 ntdll!NtRequestWaitReplyPort+0xa // 01 00000000`0058e000 00000000`76c352d1 kernel32!GetConsoleMode+0xf8 // 02 00000000`0058e030 00000000`76c4a60c kernel32!VerifyConsoleIoHandle+0x281 // 03 00000000`0058e180 000007fe`fae30fe1 kernel32!ReadConsoleW+0xbc // 04 00000000`0058e260 000007fe`fae1eb88 Microsoft_PowerShell_ConsoleHost_ni+0x70fe1 // 05 00000000`0058e390 000007fe`fae2a7e2 Microsoft_PowerShell_ConsoleHost_ni+0x5eb88 // 06 00000000`0058e410 000007fe`fae29fae Microsoft_PowerShell_ConsoleHost_ni+0x6a7e2 // 07 00000000`0058e4c0 000007fe`fae32bd1 Microsoft_PowerShell_ConsoleHost_ni+0x69fae // 08 00000000`0058e5b0 000007fe`fae235c6 Microsoft_PowerShell_ConsoleHost_ni+0x72bd1 // 09 00000000`0058e670 000007fe`fae23f27 Microsoft_PowerShell_ConsoleHost_ni+0x635c6 // 0a 00000000`0058e6d0 000007fe`fade5006 Microsoft_PowerShell_ConsoleHost_ni+0x63f27 // 0b 00000000`0058e760 000007fe`fade2c1a Microsoft_PowerShell_ConsoleHost_ni+0x25006 // 0c 00000000`0058e7e0 000007fe`fae33588 Microsoft_PowerShell_ConsoleHost_ni+0x22c1a // 0d 00000000`0058e890 000007fe`97f805de Microsoft_PowerShell_ConsoleHost_ni+0x73588 // 0e 00000000`0058e8f0 000007fe`f777dad3 0x000007fe`97f805de // 0f 00000000`0058ea80 000007fe`f777d7ae clr!PreBindAssemblyEx+0x13e07 // 10 00000000`0058eac0 000007fe`f777d830 clr!PreBindAssemblyEx+0x13ae2 // 11 00000000`0058eb00 000007fe`f76d0f3b clr!PreBindAssemblyEx+0x13b64 // 12 00000000`0058ecb0 000007fe`f76a9e5a clr!GetHistoryFileDirectory+0x945b // 13 00000000`0058ee80 000007fe`f76a9d54 clr!InitializeFusion+0x8b12 // 14 00000000`0058f170 000007fe`f76a98ce clr!InitializeFusion+0x8a0c // 15 00000000`0058f730 000007fe`f76a9826 clr!InitializeFusion+0x8586 // 16 00000000`0058f7a0 000007fe`f76aa078 clr!InitializeFusion+0x84de // 17 00000000`0058f830 000007fe`f8247b95 clr!CorExeMain+0x14 // 18 00000000`0058f870 000007fe`f82e5b21 mscoreei!CorExeMain+0x5d // 19 00000000`0058f8c0 00000000`76bf652d mscoree!CorExeMain+0x69 // 1a 00000000`0058f8f0 00000000`772ec521 kernel32!BaseThreadInitThunk+0xd // 1b 00000000`0058f920 00000000`00000000 ntdll!RtlUserThreadStart+0x21 LogManager.Trace("Could not get symbol for stack frame {0} on thread index {1}. Error: {2}", nativeStackFrame.FrameNumber, context.ThreadIndexOrAddress, Util.GetExceptionMessages(dpe)); } return(false); } // end TryCreateFunction()
public DbgNativeFunction(DbgEngDebugger debugger, DbgEngContext context, DbgSymbol symbol) : base(debugger, context, symbol.Address, symbol.Name) { m_sym = symbol; } // end constructor()
/// <summary> /// Gets a (possibly cached) DbgSymbol representing this static member. /// </summary> public DbgSymbol GetSymbol() { if (null == m_cachedSymbol) { // Note that we don't pass a "Parent" symbol, as we want to share this // symbol between any instances of the owning type. if (ConstantValue != null) { Util.Assert(Address == 0); Util.Assert(AddressOffset == 0); m_cachedSymbol = new DbgSimpleSymbol(Debugger, Name, DataType, ConstantValue); } else { m_cachedSymbol = new DbgSimpleSymbol(Debugger, Name, DataType, Address); } } else { m_cachedSymbol.DumpCachedValueIfCookieIsStale(); } return(m_cachedSymbol); } // end GetSymbol()
internal DbgSimpleSymbol(DbgEngDebugger debugger, string name, DbgNamedTypeInfo type, DbgRegisterInfoBase register, DbgSymbol parent) : this(debugger, name, type, register) { Parent = parent; } // end constructor
} // end constructor internal DbgSimpleSymbol(DbgEngDebugger debugger, string name, DbgNamedTypeInfo type, ulong address, DbgSymbol parent) : this(debugger, name, type, address) { Parent = parent; }
} // end constructor internal DbgSimpleSymbol(DbgEngDebugger debugger, string name, DbgNamedTypeInfo type, object constantValue, DbgSymbol parent) : this(debugger, name, type, constantValue) { Parent = parent; } // end constructor
private static DbgTarget _GetTargetFromParent(DbgSymbol parent) { if (null == parent) { throw new ArgumentNullException("parent"); } return(parent.Target); }
} // end GetOrCreateValue() /// <summary> /// Picks a converter for a given DbgSymbol. /// </summary> internal DbgValueConverterInfo ChooseConverterForSymbol(DbgSymbol symbol) { if (null == symbol) { throw new ArgumentNullException("symbol"); } var converter = _ChooseConverter(symbol.Type.Module.Name, symbol); if (null != converter) { return(converter); } return(_ChooseConverter(c_NoModule, symbol)); } // end ChooseConverterForSymbol()
internal DbgMemberSymbol(DbgEngDebugger debugger, DbgSymbol parent, DbgDataMemberTypeInfo memberInfo) : base(debugger, _GetName(memberInfo), _GetTargetFromParent(parent)) { Parent = parent; MemberInfo = memberInfo; if (Parent.IsValueInRegister) { m_addr = 0; } else { m_addr = Parent.Address + memberInfo.Offset; } } // end constructor
internal SymbolIdentity(DbgSymbol sgi) { Name = sgi.Name; ModuleBase = null != sgi.Module ? sgi.Module.BaseAddress : 0; if (sgi.IsValueUnavailable) { Offset = DebuggerObject.InvalidAddress; } else { Offset = sgi.Address; } Type = sgi.Type; _SetContext(sgi.Target.Context); } // end constructor
public DbgNearSymbol(ulong baseAddress, long displacement, DbgSymbol symbol) { if (null == symbol) { throw new ArgumentNullException("symbol"); } BaseAddress = baseAddress; Displacement = displacement; Symbol = symbol; if ((ulong)((long)baseAddress + displacement) != symbol.Address) { // This can be caused by optimization tools (like BBT) which operate on // already-built binaries, because they might move stuff around, but // offsets in the PDB are not adjusted. DoesNotMakeMathematicalSense = true; // if( (ulong) ((long) baseAddress - displacement) == symbol.Address ) // Util.Fail( "We got the displacement backwards!" ); } } // end constructor
} // end ChooseConverterForSymbol() private DbgValueConverterInfo _ChooseConverter(string modName, DbgSymbol symbol) { return(_EnumerateAllConvertersForSymbol(modName, symbol).FirstOrDefault()); } // end _ChooseConverter()
public static DbgValueConverterInfo ChooseConverterForSymbol(DbgSymbol symbol) { return(_Singleton.ChooseConverterForSymbol(symbol)); }
} // end _ChooseConverter() internal IEnumerable <DbgValueConverterInfo> EnumerateAllConvertersForSymbol(DbgSymbol symbol) { if (symbol.Module.BaseAddress != 0) { Util.Assert(!String.IsNullOrEmpty(symbol.Module.Name)); foreach (var converter in _EnumerateAllConvertersForSymbol(symbol.Module.Name, symbol)) { yield return(converter); } } foreach (var converter in _EnumerateAllConvertersForSymbol(c_NoModule, symbol)) { yield return(converter); } } // end EnumerateAllConvertersForSymbol()
} // end EnumerateAllConvertersForSymbol() private IEnumerable <DbgValueConverterInfo> _EnumerateAllConvertersForSymbol(string modName, DbgSymbol symbol) { if (null == symbol) { throw new ArgumentNullException("symbol"); } var templateMap = TryGetNonNullValue(m_moduleMap, modName); if (null == templateMap) { yield break; } foreach (var typeNameTemplate in symbol.GetTemplateNodes()) { var matchList = TryGetNonNullValue(templateMap, typeNameTemplate.TemplateName); if (null != matchList) { var converter = matchList.TryFindMatchingItem(typeNameTemplate); if (null != converter) { yield return(converter); } } } } // end _EnumerateAllConvertersForSymbol()
public static IEnumerable <DbgValueConverterInfo> EnumerateAllConvertersForSymbol(DbgSymbol symbol) { return(_Singleton.EnumerateAllConvertersForSymbol(symbol)); }
public bool TryConvertToPrimitive(DbgSymbol symbol, out object primitive, out bool isBitfield) { if (null == symbol) { throw new ArgumentNullException("symbol"); } isBitfield = false; primitive = null; if (symbol.IsConstant) { // Is this really the right place for this code? primitive = symbol.GetConstantValue(); } else { switch (BaseType) { case BasicType.btChar: Util.Assert(1 == Size); primitive = symbol.ReadAs_sbyte(); break; case BasicType.btWChar: Util.Assert(2 == Size); primitive = symbol.ReadAs_WCHAR(); break; case BasicType.btInt: case BasicType.btLong: switch (Size) { case 1: primitive = symbol.ReadAs_sbyte(); break; case 2: primitive = symbol.ReadAs_short(); break; case 4: primitive = symbol.ReadAs_Int32(); break; case 8: primitive = symbol.ReadAs_Int64(); break; default: Util.Fail("strangely-sized int"); return(false); } break; case BasicType.btUInt: case BasicType.btULong: switch (Size) { case 1: primitive = symbol.ReadAs_byte(); break; case 2: primitive = symbol.ReadAs_ushort(); break; case 4: primitive = symbol.ReadAs_UInt32(); break; case 8: primitive = symbol.ReadAs_UInt64(); break; default: Util.Fail("strangely-sized uint"); return(false); } break; case BasicType.btBool: switch (Size) { case 1: primitive = symbol.ReadAs_CPlusPlusBool(); break; case 2: Util.Fail("Does this happen?"); primitive = symbol.ReadAs_short() == 0 ? false : true; break; case 4: Util.Fail("Does this happen?"); primitive = symbol.ReadAs_Int32() == 0 ? false : true; break; case 8: Util.Fail("Does this happen?"); primitive = symbol.ReadAs_Int64() == 0 ? false : true; break; default: Util.Fail("strangely-sized bool"); return(false); } break; case BasicType.btFloat: switch (Size) { case 4: primitive = symbol.ReadAs_float(); break; case 8: primitive = symbol.ReadAs_double(); break; case 10: primitive = new LongDouble(Debugger.ReadMem(symbol.Address, 10)); break; default: Util.Fail("strangely-sized float"); return(false); } break; case BasicType.btHresult: Util.Assert(4 == Size); primitive = symbol.ReadAs_UInt32(); break; // TODO // case BasicType.btBSTR: // TODO // case BasicType.btVariant // TODO: other types } // end switch( BaseType ) } DbgMemberSymbol memberSym = symbol as DbgMemberSymbol; if (null != memberSym) { if (memberSym.MemberInfo.IsBitfield) { isBitfield = true; Util.Assert(BaseType == BasicType.btInt || BaseType == BasicType.btLong || BaseType == BasicType.btUInt || BaseType == BasicType.btULong || BaseType == BasicType.btBool); // We'll use 'dynamic' to get runtime dynamic dispatch (so the correct // overload will get chosen at runtime). try { if (BasicType.btBool == BaseType) { Util.Assert(1 == Size); // Oops; we've already converted to true/false. Need to read // the full byte value again. primitive = BitHelper.ExtractBitfield((dynamic)symbol.ReadAs_byte(), memberSym.MemberInfo.BitfieldPosition, memberSym.MemberInfo.BitfieldLength); primitive = ((byte)primitive) != 0; } else { primitive = BitHelper.ExtractBitfield((dynamic)primitive, memberSym.MemberInfo.BitfieldPosition, memberSym.MemberInfo.BitfieldLength); } } catch (Exception e) { LogManager.Trace("Failure trying to extract bitfield from a {0}: {1}", primitive.GetType().FullName, Util.GetExceptionMessages(e)); throw; } } // end if( isBitfield ) } // end if( null != memberSym ) return(null != primitive); } // end TryConvertToPrimitive()
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()