/// <summary> /// Initializes a new instance of the <see cref="Module" /> class. /// </summary> /// <param name="process">The process.</param> /// <param name="address">The module address.</param> internal Module(Process process, ulong address) { Address = address; Process = process; Id = uint.MaxValue; name = SimpleCache.Create(() => { string name = Context.Debugger.GetModuleName(this); Process.UpdateModuleByNameCache(this, name); return(name); }); imageName = SimpleCache.Create(() => Context.Debugger.GetModuleImageName(this)); loadedImageName = SimpleCache.Create(() => Context.Debugger.GetModuleLoadedImage(this)); symbolFileName = SimpleCache.Create(() => Context.Debugger.GetModuleSymbolFile(this)); mappedImageName = SimpleCache.Create(() => Context.Debugger.GetModuleMappedImage(this)); moduleVersion = SimpleCache.Create(() => { ModuleVersion version = new ModuleVersion(); Context.Debugger.GetModuleVersion(this, out version.Major, out version.Minor, out version.Revision, out version.Patch); return(version); }); timestampAndSize = SimpleCache.Create(() => Context.Debugger.GetModuleTimestampAndSize(this)); clrModule = SimpleCache.Create(() => Process.ClrRuntimes.SelectMany(r => r.Modules).Where(m => m.ImageBase == Address).FirstOrDefault()); pointerSize = SimpleCache.Create(() => Process.GetPointerSize()); TypesByName = new DictionaryCache <string, CodeType>(GetTypeByName); TypesById = new DictionaryCache <uint, CodeType>(GetTypeById); ClrTypes = new DictionaryCache <IClrType, CodeType>(GetClrCodeType); GlobalVariables = new DictionaryCache <string, Variable>(GetGlobalVariable); UserTypeCastedGlobalVariables = Context.UserTypeMetadataCaches.CreateDictionaryCache <string, Variable>((name) => Process.CastVariableToUserType(GlobalVariables[name])); }
/// <summary> /// Reads the simple data (1 to 8 bytes) for specified type and address to read from. /// </summary> /// <param name="codeType">Type of the code.</param> /// <param name="address">The address.</param> internal static ulong ReadSimpleData(CodeType codeType, ulong address) { Process process = codeType.Module.Process; uint size = codeType.Size; if (codeType.IsPointer) { size = process.GetPointerSize(); } byte[] buffer = ReadMemory(process, address, size).Bytes; // TODO: This doesn't work with bit fields switch (size) { case 1: return(buffer[0]); case 2: return(BitConverter.ToUInt16(buffer, 0)); case 4: return(BitConverter.ToUInt32(buffer, 0)); case 8: return(BitConverter.ToUInt64(buffer, 0)); default: throw new Exception("Unexpected data size " + size); } }
/// <summary> /// Converts the CLR values to variable collection. /// </summary> /// <param name="values">The values.</param> /// <param name="names">The names.</param> private VariableCollection ConvertClrToVariableCollection(IList <Microsoft.Diagnostics.Runtime.ClrValue> values, string[] names) { if (values.Count != names.Length) { throw new ArgumentOutOfRangeException(nameof(names)); } List <Variable> variables = new List <Variable>(values.Count); for (int i = 0; i < names.Length; i++) { if (values[i] != null) { try { var value = values[i]; ulong address = value.Address; CodeType codeType = Module.FromClrType(value.Type); Variable variable; if (codeType.IsPointer) { variable = Variable.CreatePointerNoCast(codeType, address, names[i]); } else { // TODO: This address unboxing should be part of ClrMD. if (value.ElementType == Microsoft.Diagnostics.Runtime.ClrElementType.Class) { address += Process.GetPointerSize(); } variable = Variable.CreateNoCast(codeType, address, names[i]); } variables.Add(Variable.UpcastClrVariable(variable)); } catch (Exception) { } } } return(new VariableCollection(variables.ToArray())); }