Esempio n. 1
0
        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()
Esempio n. 2
0
 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()
Esempio n. 4
0
 internal DbgSimpleSymbol(DbgEngDebugger debugger,
                          string name,
                          DbgNamedTypeInfo type,
                          DbgRegisterInfoBase register,
                          DbgSymbol parent)
     : this(debugger, name, type, register)
 {
     Parent = parent;
 } // end constructor
Esempio n. 5
0
        } // 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
Esempio n. 7
0
        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()
Esempio n. 9
0
        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
Esempio n. 10
0
        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
Esempio n. 11
0
        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()
Esempio n. 13
0
 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()
Esempio n. 16
0
 public static IEnumerable <DbgValueConverterInfo> EnumerateAllConvertersForSymbol(DbgSymbol symbol)
 {
     return(_Singleton.EnumerateAllConvertersForSymbol(symbol));
 }
Esempio n. 17
0
        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()
Esempio n. 18
0
        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()