/// <summary> /// Initializes a new instance of the <see cref="Process"/> class. /// </summary> /// <param name="id">The identifier.</param> internal Process(uint id) { Id = id; systemId = SimpleCache.Create(() => Context.Debugger.GetProcessSystemId(this)); upTime = SimpleCache.Create(() => Context.Debugger.GetProcessUpTime(this)); pebAddress = SimpleCache.Create(() => Context.Debugger.GetProcessEnvironmentBlockAddress(this)); executableName = SimpleCache.Create(() => Context.Debugger.GetProcessExecutableName(this)); dumpFileName = SimpleCache.Create(() => Context.Debugger.GetProcessDumpFileName(this)); actualProcessorType = SimpleCache.Create(() => Context.Debugger.GetProcessActualProcessorType(this)); effectiveProcessorType = SimpleCache.Create(() => Context.Debugger.GetProcessEffectiveProcessorType(this)); threads = SimpleCache.Create(() => Context.Debugger.GetProcessThreads(this)); modules = SimpleCache.Create(() => Context.Debugger.GetProcessModules(this)); userTypes = SimpleCache.Create(GetUserTypes); clrDataTarget = SimpleCache.Create(() => { var dataTarget = Microsoft.Diagnostics.Runtime.DataTarget.CreateFromDataReader(new CsDebugScript.CLR.DataReader(this)); dataTarget.SymbolLocator.SymbolPath += ";http://symweb"; return(dataTarget); }); clrRuntimes = SimpleCache.Create(() => { try { return(ClrDataTarget.ClrVersions.Select(clrInfo => new Runtime(this, clrInfo.CreateRuntime())).ToArray()); } catch { return(new Runtime[0]); } }); currentAppDomain = SimpleCache.Create(() => ClrRuntimes.SelectMany(r => r.AppDomains).FirstOrDefault()); ModulesByName = new DictionaryCache <string, Module>(GetModuleByName); ModulesById = new DictionaryCache <ulong, Module>(GetModuleByAddress); Variables = new DictionaryCache <Tuple <CodeType, ulong, string, string>, Variable>((tuple) => new Variable(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4)); UserTypeCastedVariables = new DictionaryCache <Variable, Variable>((variable) => Variable.CastVariableToUserType(variable)); GlobalCache.UserTypeCastedVariables.Add(UserTypeCastedVariables); ClrModuleCache = new DictionaryCache <Microsoft.Diagnostics.Runtime.ClrModule, Module>((clrModule) => { // TODO: This needs to change when ClrModule starts to be child of Module Module module = ModulesById[clrModule.ImageBase]; module.ClrModule = clrModule; module.ImageName = clrModule.Name; if (clrModule.Pdb != null && !string.IsNullOrEmpty(clrModule.Pdb.FileName)) { try { if (!module.SymbolFileName.ToLowerInvariant().EndsWith(".pdb")) { module.SymbolFileName = clrModule.Pdb.FileName; } } catch { module.SymbolFileName = clrModule.Pdb.FileName; } } module.Name = Path.GetFileNameWithoutExtension(clrModule.Name); module.LoadedImageName = clrModule.Name; module.Size = clrModule.Size; return(module); }); dumpFileMemoryReader = SimpleCache.Create(() => { try { return(string.IsNullOrEmpty(DumpFileName) ? null : new DumpFileMemoryReader(DumpFileName)); } catch (Exception) { return(null); } }); memoryRegions = SimpleCache.Create(() => { if (DumpFileMemoryReader != null) { return(DumpFileMemoryReader.GetMemoryRanges()); } else { return(Context.Debugger.GetMemoryRegions(this)); } }); memoryRegionFinder = SimpleCache.Create(() => new MemoryRegionFinder(MemoryRegions)); TypeToUserTypeDescription = new DictionaryCache <Type, UserTypeDescription[]>(GetUserTypeDescription); ansiStringCache = new DictionaryCache <Tuple <ulong, int>, string>(DoReadAnsiString); unicodeStringCache = new DictionaryCache <Tuple <ulong, int>, string>(DoReadUnicodeString); }
/// <summary> /// Initializes a new instance of the <see cref="Process"/> class. /// </summary> /// <param name="id">The identifier.</param> internal Process(uint id) { Id = id; systemId = SimpleCache.Create(() => Context.Debugger.GetProcessSystemId(this)); upTime = SimpleCache.Create(() => Context.Debugger.GetProcessUpTime(this)); pebAddress = SimpleCache.Create(() => Context.Debugger.GetProcessEnvironmentBlockAddress(this)); executableName = SimpleCache.Create(() => Context.Debugger.GetProcessExecutableName(this)); dumpFileName = SimpleCache.Create(() => Context.Debugger.GetProcessDumpFileName(this)); architectureType = SimpleCache.Create(() => Context.Debugger.GetProcessArchitectureType(this)); threads = SimpleCache.Create(() => Context.Debugger.GetProcessThreads(this)); modules = SimpleCache.Create(() => Context.Debugger.GetProcessModules(this)); userTypes = SimpleCache.Create(GetUserTypes); clrRuntimes = SimpleCache.Create(() => { try { if (Context.ClrProvider != null) { return(Context.ClrProvider.GetClrRuntimes(this)); } } catch { } return(new IClrRuntime[0]); }); currentAppDomain = SimpleCache.Create(() => ClrRuntimes.SelectMany(r => r.AppDomains).FirstOrDefault()); ModulesByName = new DictionaryCache <string, Module>(GetModuleByName); ModulesById = new DictionaryCache <ulong, Module>(GetModuleByAddress); Variables = new DictionaryCache <Tuple <CodeType, ulong, string, string>, Variable>((tuple) => new Variable(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4)); UserTypeCastedVariables = new DictionaryCache <Variable, Variable>((variable) => Variable.CastVariableToUserType(variable)); GlobalCache.UserTypeCastedVariables.Add(UserTypeCastedVariables); ClrModuleCache = new DictionaryCache <IClrModule, Module>((clrModule) => { // TODO: This needs to change when ClrModule starts to be child of Module Module module = ModulesById[clrModule.ImageBase]; module.ClrModule = clrModule; module.ImageName = clrModule.Name; if (!string.IsNullOrEmpty(clrModule.PdbFileName)) { try { if (!module.SymbolFileName.ToLowerInvariant().EndsWith(".pdb")) { module.SymbolFileName = clrModule.PdbFileName; } } catch { module.SymbolFileName = clrModule.PdbFileName; } } module.Name = Path.GetFileNameWithoutExtension(clrModule.Name); module.LoadedImageName = clrModule.Name; module.Size = clrModule.Size; return(module); }); dumpFileMemoryReader = SimpleCache.Create(() => { try { return(Context.Debugger.GetDumpFileMemoryReader(this)); } catch (Exception) { return(null); } }); memoryRegions = SimpleCache.Create(() => { if (DumpFileMemoryReader != null) { return(DumpFileMemoryReader.GetMemoryRanges()); } else { return(Context.Debugger.GetMemoryRegions(this)); } }); memoryRegionFinder = SimpleCache.Create(() => new MemoryRegionFinder(MemoryRegions)); TypeToUserTypeDescription = new DictionaryCache <Type, UserTypeDescription[]>(GetUserTypeDescription); ansiStringCache = new DictionaryCache <Tuple <ulong, int>, string>(DoReadAnsiString); unicodeStringCache = new DictionaryCache <Tuple <ulong, int>, string>(DoReadUnicodeString); wideUnicodeStringCache = new DictionaryCache <Tuple <ulong, int>, string>(DoReadWideUnicodeString); }
/// <summary> /// Gets the thread stack trace. /// </summary> /// <param name="threadIndex">Index of the thread.</param> /// <param name="dumpFileMemoryReader">The dump file memory reader.</param> /// <param name="process">Process being debugged.</param> /// <param name="symbolProvider">The symbol provider.</param> /// <returns>Array of tuples of instruction offset, stack offset and frame offset.</returns> public Tuple <ulong, ulong, ulong>[] GetThreadStackTrace(int threadIndex, DumpFileMemoryReader dumpFileMemoryReader, Process process, DwarfSymbolProvider symbolProvider) { const int pointerSize = 8; elf_prstatus prstatus = threads[threadIndex]; ulong bp = prstatus.pr_reg[X64RegisterIndex.RBP]; ulong ip = prstatus.pr_reg[X64RegisterIndex.RIP]; List <Tuple <ulong, ulong, ulong> > result = new List <Tuple <ulong, ulong, ulong> >(); ulong segmentStartAddress, segmentSize; dumpFileMemoryReader.GetMemoryRange(bp, out segmentStartAddress, out segmentSize); while (bp >= segmentStartAddress && bp < segmentStartAddress + segmentSize) { result.Add(Tuple.Create(ip, bp, bp)); ulong savedLocationForRegisters = bp; Module module = process.GetModuleByInnerAddress(ip); if (module != null) { DwarfSymbolProviderModule symbolProviderModule = symbolProvider.GetSymbolProviderModule(module) as DwarfSymbolProviderModule; if (symbolProviderModule != null) { ThreadContext frameContext = new ThreadContext(ip, bp, bp, null); ulong canonicalFrameAddress = symbolProviderModule.GetFunctionCanonicalFrameAddress(process, ip, frameContext); if (canonicalFrameAddress != 0) { savedLocationForRegisters = canonicalFrameAddress - pointerSize * 2; } } } MemoryBuffer buffer = dumpFileMemoryReader.ReadMemory(savedLocationForRegisters, pointerSize * 2); bp = UserType.ReadPointer(buffer, 0, pointerSize); ip = UserType.ReadPointer(buffer, pointerSize, pointerSize); } return(result.ToArray()); }