private static DbgTypeInfo _LoadTypeInfo(DbgEngDebugger debugger, DbgModuleInfo module, uint typeId) { if (null == debugger) { throw new ArgumentNullException("debugger"); } if (IsDbgGeneratedType(typeId) && !DbgHelp.PeekSyntheticTypeExists(debugger.DebuggerInterface, module.BaseAddress, typeId)) { return(new DbgGeneratedTypeInfo(debugger, module, typeId)); } return(debugger.ExecuteOnDbgEngThread(() => { var symTag = DbgHelp.GetSymTag(debugger.DebuggerInterface, module.BaseAddress, typeId); return _LoadTypeInfo(debugger, module, typeId, symTag); })); }
private static DbgTypeInfo _LoadTypeInfo(DbgEngDebugger debugger, DbgModuleInfo module, uint typeId, SymTag symTag) { if (null == debugger) { throw new ArgumentNullException("debugger"); } if (IsDbgGeneratedType(typeId) && !DbgHelp.PeekSyntheticTypeExists(debugger.DebuggerInterface, module.BaseAddress, typeId)) { return(new DbgGeneratedTypeInfo(debugger, module, typeId, symTag)); } return(debugger.ExecuteOnDbgEngThread(() => { if (((int)symTag) > sm_factories.Length) { // In case they extend the SymTag enum and I don't get updated. Util.Fail("Need to update SymTag enum."); return _DefaultFactory(debugger, module, typeId, symTag); } return sm_factories[(int)symTag](debugger, module, typeId); })); } // end _LoadTypeInfo()
private static void _GenerateSyntheticTypeToMatchDbgEngGeneratedType(string localSymName, DbgEngDebugger debugger, DEBUG_SYMBOL_ENTRY dse) { if (dse.Tag != SymTag.PointerType) { LogManager.Trace("It's a dbgeng-generated type that isn't a pointer! It's a {0} (id 0x{1:x}).", dse.Tag, dse.TypeId); return; } if (DbgHelp.PeekSyntheticTypeExists(debugger.DebuggerInterface, dse.ModuleBase, dse.TypeId)) { return; } // We'll run a command like this: // // dv /t "varname" // // And here's some sample output: // // struct Microsoft::CoreUI::Support::BufferInfo * message = 0x0000006f`81edd570 // string output = String.Empty; using (debugger.HandleDbgEngOutput( (x) => { x = x.Trim(); if (!String.IsNullOrEmpty(x)) { Util.Assert(String.IsNullOrEmpty(output)); output = x; } })) { debugger.InvokeDbgEngCommand(Util.Sprintf("dv /t \"{0}\"", localSymName), DEBUG_OUTCTL.THIS_CLIENT); } int matchCount = 0; foreach (Match match in sm_vartypeRegex.Matches(output)) { matchCount++; string typename = match.Groups["typename"].Value; // Console.WriteLine( "output: {0}", output ); // Console.WriteLine( "typename: {0}", typename ); // Console.WriteLine( "varname: {0}", match.Groups[ "varname" ].Value ); LogManager.Trace("DbgEng-generated type is a pointer, pointing to type: {0}", typename); var mod = debugger.GetModuleByAddress(dse.ModuleBase); DbgTypeInfo ti = debugger.GetTypeInfoByName(mod.Name + "!" + typename).FirstOrDefault(); if (null != ti) { Util.Assert(ti is DbgNamedTypeInfo); var nti = ti as DbgNamedTypeInfo; Util.Assert(nti.Module.BaseAddress == dse.ModuleBase); // We don't need to TryGetSynthPointerTypeIdByPointeeTypeId, because // we already know it's not there (because we did // PeekSyntheticTypeExists earlier). DbgHelp.AddSyntheticPointerTypeInfo(debugger.DebuggerInterface, nti.Module.BaseAddress, nti.TypeId, //debugger.TargetIs32Bit ? 4UL : 8UL, dse.Size, dse.TypeId); } // end if( we found the pointee type ) else { LogManager.Trace("(but we couldn't find the type!)"); } } // end foreach( match ) Util.Assert(matchCount <= 1); if (0 == matchCount) { LogManager.Trace("Failed to parse out type name from: {0}", output); } } // end _GenerateSyntheticTypeToMatchDbgEngGeneratedType()