public static void Main(string[] args) { var pid = 0; //TODO var seconds = 100; //TODO var sw = new Stopwatch(); var tree = new CallTree("Process"); using (var dt = DataTarget.AttachToProcess(pid, 10, AttachFlag.Passive)) { var runtime = dt.ClrVersions[0].CreateRuntime(); if (dt.PointerSize != IntPtr.Size) { throw new Exception(); } sw.Start(); while (sw.Elapsed < TimeSpan.FromSeconds(seconds)) { foreach (var thread in runtime.Threads) { tree.Add(thread.StackTrace); } Thread.Sleep(10); runtime.Flush(); ClrRuntimePatcher.Flush(runtime); } } tree.Print(); }
private static void AttachToLiveProcess(int pid) { using (var target = DataTarget.AttachToProcess(pid, 2000)) { AnalyzeApplication(target); } }
/// <summary> /// Refresh all assemblies in given TreeView. /// </summary> /// <param name="tvAssemblies">Current TreeView.</param> public static void RefreshAssemblies(TreeView tvAssemblies) { tvAssemblies.Nodes.Clear(); int pid = Process.GetCurrentProcess().Id; DT = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive); foreach (ClrInfo clrVersion in DT.ClrVersions) { TreeElement clrNode = new TreeElement("CLR", clrVersion); tvAssemblies.Nodes.Add(clrNode); ClrInfo clrInfo = (ClrInfo)clrNode.Object; ClrRuntime runtime = clrInfo.CreateRuntime(); foreach (ClrModule module in runtime.Modules) { TreeElement moduleNode = new TreeElement("Module", module); clrNode.Nodes.Add(moduleNode); foreach (ClrType clrType in module.EnumerateTypes()) { TreeElement typeNode = new TreeElement("Type", clrType); moduleNode.Nodes.Add(typeNode); } } } }
public int DumpProcess(string directoryPath) { DataTarget dataTarget; int result = 0; using (dataTarget = DataTarget.AttachToProcess((int)_processId, 10000, AttachFlag.Passive)) foreach (ClrInfo clrInfo in dataTarget.ClrVersions) { foreach (ClrModule clrModule in clrInfo.CreateRuntime().Modules) { try { string moduleName; moduleName = clrModule.Name ?? "EmptyName"; moduleName = clrModule.IsDynamic ? moduleName.Split(',')[0] : Path.GetFileName(moduleName); if (DumpModule((IntPtr)clrModule.ImageBase, Path.Combine(directoryPath, moduleName))) { result++; } } catch { } } } return(result); }
/// <summary> /// Walks the heap and checks all objects for string type. /// </summary> /// <returns>The number of found strings.</returns> public static int GetStringCount() { int numberOfStrings = 0; Process currentProcess = Process.GetCurrentProcess(); using (DataTarget dataTarget = DataTarget.AttachToProcess(currentProcess.Id, 10000, AttachFlag.Passive)) { ClrInfo clrVersion = dataTarget.ClrVersions.First(); ClrRuntime runtime = clrVersion.CreateRuntime(); ClrHeap heap = runtime.Heap; if (!heap.CanWalkHeap) { return(0); } foreach (ulong ptr in heap.EnumerateObjectAddresses()) { ClrType type = heap.GetObjectType(ptr); if (type == null || type.IsString == false) { continue; } numberOfStrings++; } } return(numberOfStrings); }
public string DumpASM() { TextWriter asmWriter = new StringWriter(); using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive)) { foreach (ClrInfo clrInfo in target.ClrVersions) { this.engine.UpdateLog("Found CLR Version:" + clrInfo.Version.ToString()); // This is the data needed to request the dac from the symbol server: ModuleInfo dacInfo = clrInfo.DacInfo; this.engine.UpdateLog($"Filesize: {dacInfo.FileSize:X}"); this.engine.UpdateLog($"Timestamp: {dacInfo.TimeStamp:X}"); this.engine.UpdateLog($"Dac File: {dacInfo.FileName}"); ClrRuntime runtime = target.ClrVersions.Single().CreateRuntime(); var appDomain = runtime.AppDomains[0]; var module = appDomain.Modules.LastOrDefault(m => m.AssemblyName != null && m.AssemblyName.StartsWith(assemblyName)); asmWriter.WriteLine( $"; {clrInfo.ModuleInfo.ToString()} ({clrInfo.Flavor} {clrInfo.Version})"); asmWriter.WriteLine( $"; {clrInfo.DacInfo.FileName} ({clrInfo.DacInfo.TargetArchitecture} {clrInfo.DacInfo.Version})"); asmWriter.WriteLine(); foreach (var typeClr in module.EnumerateTypes()) { asmWriter.WriteLine($"; Type {typeClr.Name}"); ClrHeap heap = runtime.Heap; ClrType @object = heap.GetTypeByMethodTable(typeClr.MethodTable); foreach (ClrMethod method in @object.Methods) { MethodCompilationType compileType = method.CompilationType; ArchitectureMode mode = clrInfo.DacInfo.TargetArchitecture == Architecture.X86 ? ArchitectureMode.x86_32 : ArchitectureMode.x86_64; this.currentMethodAddress = 0; var translator = new IntelTranslator { SymbolResolver = (Instruction instruction, long addr, ref long offset) => ResolveSymbol(runtime, instruction, addr, ref currentMethodAddress) }; // This not work even ClrMd says opposite... //ulong startAddress = method.NativeCode; //ulong endAddress = method.ILOffsetMap.Select(entry => entry.EndAddress).Max(); DisassembleAndWrite(method, mode, translator, ref currentMethodAddress, asmWriter); this.engine.UpdateLog($"Method {method.Name} disassembled to ASM."); asmWriter.WriteLine(); } } break; } } return(asmWriter.ToString()); }
static void Handle(Settings settings) { using (var dataTarget = DataTarget.AttachToProcess( settings.ProcessId, (uint)TimeSpan.FromMilliseconds(5000).TotalMilliseconds, AttachFlag.Invasive)) { var runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ConfigureSymbols(dataTarget); var state = new State(runtime, (IDebugControl)dataTarget.DebuggerInterface); var disasembledMethods = Disassemble(settings, runtime, state); // we don't want to export the disassembler entry point method which is just an artificial method added to get generic types working var methodsToExport = disasembledMethods.Where(method => disasembledMethods.Count == 1 || // if there is only one method we want to return it (most probably benchmark got inlined) !method.Name.Contains(DisassemblerConstants.DiassemblerEntryMethodName)).ToArray(); using (var stream = new FileStream(settings.ResultsPath, FileMode.Append, FileAccess.Write)) using (var writer = XmlWriter.Create(stream)) { var serializer = new XmlSerializer(typeof(DisassemblyResult)); serializer.Serialize(writer, new DisassemblyResult { Methods = methodsToExport }); } } }
public string ResolveSymbol(ulong address) { using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive)) { foreach (ClrInfo version in target.ClrVersions) { ClrRuntime runtime = target.ClrVersions.Single().CreateRuntime(); string methodSignature = runtime.GetMethodByAddress(address) ?.GetFullSignature(); if (!string.IsNullOrWhiteSpace(methodSignature)) { return(methodSignature); } } } Symbol symbol = this.nativeTarget.ResolveSymbol((ulong)address); if (!string.IsNullOrWhiteSpace(symbol.MethodName)) { return(symbol.ToString()); } return(null); }
static void Handle(Settings settings) { using (var dataTarget = DataTarget.AttachToProcess( settings.ProcessId, (uint)TimeSpan.FromMilliseconds(5000).TotalMilliseconds, AttachFlag.Invasive)) { var runtime = dataTarget.ClrVersions.Single().CreateRuntime(); ConfigureSymbols(dataTarget); var state = new State(runtime, (IDebugControl)dataTarget.DebuggerInterface); var disasembledMethods = Disassemble(settings, runtime, state); using (var stream = new FileStream(settings.ResultsPath, FileMode.Append, FileAccess.Write)) using (var writer = XmlWriter.Create(stream)) { var serializer = new XmlSerializer(typeof(DisassemblyResult)); serializer.Serialize(writer, new DisassemblyResult { Methods = disasembledMethods.ToArray() }); } } }
protected override void Load(ContainerBuilder builder) { builder.RegisterInstance(ApiPolicySetup.CreatePolicy()) .AsSelf() .SingleInstance(); builder.Register(_ => { var dataTarget = DataTarget.AttachToProcess(Current.ProcessId, suspend: false); return(dataTarget.ClrVersions.Single(c => c.Flavor == ClrFlavor.Core).CreateRuntime()); }).SingleInstance(); builder.RegisterType <Pool <ClrRuntime> >() .AsSelf() .SingleInstance(); builder.RegisterType <ExecutionResultSerializer>() .AsSelf() .SingleInstance(); builder.RegisterType <FlowReportingRewriter>() .As <IAssemblyRewriter>() .SingleInstance(); builder.RegisterType <MemoryGraphArgumentNamesRewriter>() .As <IAssemblyRewriter>() .SingleInstance(); builder.RegisterType <FSharpEntryPointRewriter>() .As <IAssemblyRewriter>() .As <IContainerAssemblyRewriter>() .SingleInstance(); builder.RegisterType <Executor>() .As <IExecutor>() .SingleInstance(); var containerHostUrl = Environment.GetEnvironmentVariable("SHARPLAB_CONTAINER_HOST_URL") ?? throw new Exception("Required environment variable SHARPLAB_CONTAINER_HOST_URL was not provided."); builder.RegisterType <ContainerFlowReportingRewriter>() .As <IContainerAssemblyRewriter>() .SingleInstance(); builder.Register(c => { var secretsClient = c.Resolve <ISecretsClient>(); var containerAuthorizationToken = secretsClient.GetSecret("ContainerHostAuthorizationToken"); return(new ContainerClientSettings(new Uri(containerHostUrl), containerAuthorizationToken)); }).SingleInstance() .AsSelf(); builder.RegisterType <ContainerClient>() .As <IContainerClient>() .SingleInstance(); builder.RegisterType <ContainerExecutor>() .As <IContainerExecutor>() .SingleInstance(); RegisterRuntime(builder); }
private DataTarget GetDataTarget(ILogger logger) { if (_commandLineOptions.ProcessId == null && _commandLineOptions.Dump == null) { throw new CommandLineException("Please specify process id or dump file"); } if (_commandLineOptions.ProcessId != null && _commandLineOptions.Dump != null) { throw new CommandLineException("Please specify either process id or dump file"); } if (_commandLineOptions.Dump != null) { logger.LogInformation($"Processing file {_commandLineOptions.Dump.FullName}"); return(DataTarget.LoadDump(_commandLineOptions.Dump.FullName)); } if (_commandLineOptions.ProcessId != null) { logger.LogInformation($"Processing process {_commandLineOptions.ProcessId}"); return(DataTarget.AttachToProcess(_commandLineOptions.ProcessId.Value, false)); } throw new NotSupportedException(); }
public void Decompile(CompilationStreamPair streams, TextWriter codeWriter) { Argument.NotNull(nameof(streams), streams); Argument.NotNull(nameof(codeWriter), codeWriter); using (var loadContext = new CustomAssemblyLoadContext(shouldShareAssembly: _ => true)) using (var dataTarget = DataTarget.AttachToProcess(Current.ProcessId, uint.MaxValue, AttachFlag.Passive)) { var assembly = loadContext.LoadFromStream(streams.AssemblyStream); ValidateStaticConstructors(assembly); var runtime = dataTarget.ClrVersions.Single(v => v.Flavor == ClrFlavor.Core).CreateRuntime(); var context = new JitWriteContext(codeWriter, runtime); context.Translator = new IntelTranslator { SymbolResolver = (Instruction instruction, long addr, ref long offset) => ResolveSymbol(runtime, instruction, addr, context.CurrentMethodAddress) }; WriteJitInfo(runtime.ClrInfo, codeWriter); WriteProfilerState(codeWriter); var architecture = MapArchitecture(runtime.ClrInfo.DacInfo.TargetArchitecture); foreach (var type in assembly.DefinedTypes) { if (type.IsNested) { continue; // it's easier to handle nested generic types recursively, so we suppress all nested for consistency } DisassembleAndWriteMembers(context, type); } } }
private static void PrintObjectsWithClrMD() { var pid = Process.GetCurrentProcess().Id; using (var dt = DataTarget.AttachToProcess(pid, 3000, AttachFlag.Passive)) { if (dt.PointerSize != IntPtr.Size) { throw new Exception(); } var runtime = dt.ClrVersions[0].CreateRuntime(); var heap = runtime.Heap; Console.WriteLine(heap); var printers = new IClrObjectPrinter[] { new DictionaryPrinter(), new ConcurrentDictionaryPrinter(), new ListPrinter(), new ImmutableListPrinter() }; ClrObjectPrinter.Print(heap, printers); } }
/// <summary> /// 全スレッドのスタックトレースを取得します。 /// </summary> public static List <string> GetAllThreadStackTrace() { try { var pid = Process.GetCurrentProcess().Id; using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive)) { var clrInfo = dataTarget.ClrVersions[0]; var dacFile = clrInfo.TryGetDacLocation(); var runtime = clrInfo.CreateRuntime(dacFile); var list = new List <string>(); foreach (var thread in runtime.Threads) { var trace = MakeStackTrace(thread); if (!trace.Any()) { continue; } list.Add($" thread {thread.ManagedThreadId}:"); trace.ForEach(_ => list.Add(_)); } return(list); } } catch { return(new List <string>()); } }
public void Decompile(Stream assemblyStream, TextWriter codeWriter) { var currentSetup = AppDomain.CurrentDomain.SetupInformation; using (var dataTarget = DataTarget.AttachToProcess(CurrentProcess.Id, UInt32.MaxValue, AttachFlag.Passive)) using (var context = AppDomainContext.Create(new AppDomainSetup { ApplicationBase = currentSetup.ApplicationBase, PrivateBinPath = currentSetup.PrivateBinPath })) { context.LoadAssembly(LoadMethod.LoadFrom, Assembly.GetExecutingAssembly().GetAssemblyFile().FullName); var results = RemoteFunc.Invoke(context.Domain, assemblyStream, Remote.GetCompiledMethods); var currentMethodAddressRef = new Reference <ulong>(); var runtime = dataTarget.ClrVersions.Single().CreateRuntime(); var translator = new IntelTranslator { SymbolResolver = (Instruction instruction, long addr, ref long offset) => ResolveSymbol(runtime, instruction, addr, currentMethodAddressRef.Value) }; WriteJitInfo(runtime.ClrInfo, codeWriter); var architecture = MapArchitecture(runtime.ClrInfo.DacInfo.TargetArchitecture); foreach (var result in results) { DisassembleAndWrite(result, runtime, architecture, translator, currentMethodAddressRef, codeWriter); codeWriter.WriteLine(); } } }
public static void ShowStackTrace( int processId, uint attachTimeout, string outputPath, CommandLineApplication cmd, HashSet <uint> threadIds = null, bool includeStackObjects = false) { List <ThreadInfo> threadInfos; var stackTracesByThread = GetStackTracesByThreadId(processId); using (var dataTarget = DataTarget.AttachToProcess(processId, attachTimeout, AttachFlag.Passive)) threadInfos = CreateThreadInfos(dataTarget, stackTracesByThread, threadIds, includeStackObjects); if (threadIds != null || includeStackObjects) { using (GetOutputWriter(outputPath, cmd, out var outputWriter)) OutputResult(outputWriter, threadInfos); return; } var mergedStackTraces = MergeStackTraces(threadInfos); using (GetOutputWriter(outputPath, cmd, out var outputWriter)) OutputResult(outputWriter, mergedStackTraces);
public Boolean RefreshHeap(Int32 ProcessId) { // Clear all variables on a heap read this.Heap = null; this.Roots = new Dictionary <UInt64, ClrRoot>(); this.Fields = new Dictionary <UInt64, ClrField>(); try { DataTarget dataTarget = DataTarget.AttachToProcess(ProcessId, AttachTimeout, AttachFlag.Passive); if (dataTarget.ClrVersions.Count <= 0) { return(false); } ClrInfo version = dataTarget.ClrVersions[0]; ClrRuntime runtime = version.CreateRuntime(); this.Heap = runtime.GetHeap(); } catch { } return(this.Heap == null ? false : true); }
public void Decompile(CompilationStreamPair streams, TextWriter codeWriter) { Argument.NotNull(nameof(streams), streams); Argument.NotNull(nameof(codeWriter), codeWriter); using (var resultScope = JitCompileAndGetMethods(streams.AssemblyStream)) using (var dataTarget = DataTarget.AttachToProcess(Current.ProcessId, uint.MaxValue, AttachFlag.Passive)) { var currentMethodAddressRef = new Reference <ulong>(); var runtime = dataTarget.ClrVersions.Single(v => v.Flavor == ClrFlavor).CreateRuntime(); var translator = new IntelTranslator { SymbolResolver = (Instruction instruction, long addr, ref long offset) => ResolveSymbol(runtime, instruction, addr, currentMethodAddressRef.Value) }; WriteJitInfo(runtime.ClrInfo, codeWriter); WriteProfilerState(codeWriter); codeWriter.WriteLine(); var architecture = MapArchitecture(runtime.ClrInfo.DacInfo.TargetArchitecture); foreach (var result in resultScope.Results) { DisassembleAndWrite(result, runtime, architecture, translator, currentMethodAddressRef, codeWriter); codeWriter.WriteLine(); } } }
public static void ShowStackTrace( int processId, uint attachTimeout, string outputPath, CommandLineApplication cmd, HashSet <uint> threadIds = null, bool includeStackObjects = false) { if (processId == -1) { throw new InvalidOperationException("Uninitialized process id parameter"); } List <ThreadInfo> threadInfos; using (var dataTarget = DataTarget.AttachToProcess(processId, attachTimeout, AttachFlag.Passive)) threadInfos = CreateThreadInfos(dataTarget, threadIds, includeStackObjects); if (threadIds != null || includeStackObjects) { using (GetOutputWriter(outputPath, cmd, out var outputWriter)) OutputResult(outputWriter, threadInfos); return; } var mergedStackTraces = MergeStackTraces(threadInfos); using (GetOutputWriter(outputPath, cmd, out var outputWriter)) OutputResult(outputWriter, mergedStackTraces);
public static ClrMDSession AttachToProcess(Process p, uint millisecondsTimeout = 5000, AttachFlag attachFlag = AttachFlag.Invasive) { if (s_currentSession != null && s_lastProcessId == p.Id) { TestInvalidComObjectException(); return(s_currentSession); } Detach(); DataTarget target = DataTarget.AttachToProcess(p.Id, millisecondsTimeout, attachFlag); string dacFile; try { dacFile = target.ClrVersions[0].TryGetDacLocation(); if (dacFile == null) { throw new InvalidOperationException("Unable to find dac file. This may be caused by mismatched architecture between this process and the target process."); } } catch { target.Dispose(); throw; } s_lastProcessId = p.Id; return(new ClrMDSession(target, dacFile)); }
public IEnumerable <ModuleInfo> EnumerateModules() { using var process = NativeProcess.Open(processId); if (process.IsInvalid) { throw new InvalidOperationException(); } using var dataTarget = DataTarget.AttachToProcess((int)processId, 1000, AttachFlag.Passive); dataTarget.SymbolLocator = DummySymbolLocator.Instance; foreach (var runtime in dataTarget.ClrVersions.Select(t => t.CreateRuntime())) { var clrVersion = runtime.ClrInfo.Version.ToString(); foreach (var domain in runtime.AppDomains) { var domainName = domain.Name; foreach (var module in domain.Modules) { if (module.ImageBase == 0) { continue; } if (!IsValidPEMagic(module, process)) { continue; } // .NET 3.5有nlp文件,但是被认为是.NET模块 GetModuleFileInfo(module, out var name, out var path); uint size = GetModuleSize(module, process); yield return(new DotNetModuleInfo(name, (nuint)module.ImageBase, size, path, domainName, clrVersion)); } } } }
/// <summary> /// Get all used threads in calling assembly. Function ignore current thread Id /// </summary> /// <param name="callingAssembly">Calling assembly</param> private void GetUsedThreads(Assembly callingAssembly) { var mainThreadId = Thread.CurrentThread.ManagedThreadId; using (DataTarget target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 5000, AttachFlag.Passive)) { ClrRuntime runtime = target.ClrVersions.First().CreateRuntime(); foreach (ClrThread thread in runtime.Threads) { if (thread.ManagedThreadId == mainThreadId) { //main thread catched continue; } //ClrThread doesn't have any information about thread string threadName = thread.OSThreadId.ToString(); if (string.IsNullOrEmpty(threadName)) { threadName = thread.ManagedThreadId.ToString(); } var frames = ExceptionStack.Convert(thread.StackTrace); ThreadInformations.Add(threadName, new ThreadInformation(threadName, false, frames)); } } }
/// <summary> /// Disassemble the method. /// </summary> /// <param name="method">A method to disassemble</param> /// <param name="builder">The builder to receive the method ASM</param> /// <param name="formatter">A Iced Formatter to use instead of the default <see cref="NasmFormatter"/></param> public static void ToAsm(this MethodInfo method, StringBuilder builder, Formatter formatter = null) { if (method == null) { throw new ArgumentNullException(nameof(method)); } using (var dataTarget = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, UInt32.MaxValue, AttachFlag.Passive)) { var clrVersion = dataTarget.ClrVersions.First(); var runtime = clrVersion.CreateRuntime(); // Make sure the method is being Jitted RuntimeHelpers.PrepareMethod(method.MethodHandle); // Get the handle from clrmd var clrmdMethodHandle = runtime.GetMethodByHandle((ulong)method.MethodHandle.Value.ToInt64()); if (clrmdMethodHandle.NativeCode == 0) { throw new InvalidOperationException($"Unable to disassemble method `{method}`"); } //var check = clrmdMethodHandle.NativeCode; //var offsets = clrmdMethodHandle.ILOffsetMap; var codePtr = clrmdMethodHandle.HotColdInfo.HotStart; var codeSize = clrmdMethodHandle.HotColdInfo.HotSize; // Disassemble with Iced DecodeMethod(new IntPtr((long)codePtr), codeSize, builder, formatter); } }
public static void Start(Options options, Process process, IWriter outWriter) { Dictionary <ClrType, HeapStatsEntry> stats = null; IEnumerable <ThreadData> threads = null; using (var dataTarget = DataTarget.AttachToProcess(process.Id, 5000, AttachFlag.Invasive)) { ClrInfo version = dataTarget.ClrVersions.FirstOrDefault(); if (version != null) { var runtime = version.CreateRuntime(); if (options.DumpThreads) { threads = ThreadsDump(runtime); } if (options.DumpStats) { stats = HeapDump(runtime); } if (!string.IsNullOrEmpty(options.DumpHeapByType)) { DumpHeapByType(runtime, options.DumpHeapByType, outWriter); } } if (options.FullDump) { IDebugClient client = dataTarget.DebuggerInterface; var fileName = Path.Combine(options.OutputFolder ?? Environment.CurrentDirectory, GetDumpFileName(process)); outWriter.WriteHint($"Writing memory dump to: {fileName}"); client.WriteDumpFile(fileName, DEBUG_DUMP.DEFAULT); } } if (threads != null) { outWriter.WriteHint("Thread dump:"); foreach (var thread in threads) { outWriter.WriteLine(thread.ToString(), "thread"); } outWriter.WriteHint("Thread dump finished."); } if (stats != null) { outWriter.WriteHint("Heap stats:"); StringBuilder sb = new StringBuilder(); sb.AppendLine(string.Format("{0,12} {1,12} {2}", "Size", "Count", "Type")); foreach (var entry in from entry in stats.Values orderby entry.Size select entry) { sb.AppendLine(string.Format("{0,12:n0} {1,12:n0} {2}", entry.Size, entry.Count, entry.Name)); } outWriter.WriteLine(sb.ToString(), "Heap"); outWriter.WriteHint("Heap stats finished."); } }
private void RefreshModuleList() { IntPtr snapshotHandle; MODULEENTRY32 moduleEntry32; ListViewItem listViewItem; DataTarget dataTarget; lvwModules.Items.Clear(); if (!mnuOnlyDotNetModule.Checked) { moduleEntry32 = MODULEENTRY32.Default; snapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, _processId); if (snapshotHandle == INVALID_HANDLE_VALUE) { return; } if (!Module32First(snapshotHandle, ref moduleEntry32)) { return; } if (!_isDotNetProcess) { //如果是.Net进程,这里获取的主模块信息会与通过ClrMD获取的信息重复 listViewItem = new ListViewItem(moduleEntry32.szModule); listViewItem.SubItems.Add("0x" + moduleEntry32.modBaseAddr.ToString(Cache.Is64BitOperatingSystem ? "X16" : "X8")); listViewItem.SubItems.Add("0x" + moduleEntry32.modBaseSize.ToString("X8")); listViewItem.SubItems.Add(moduleEntry32.szExePath); lvwModules.Items.Add(listViewItem); } while (Module32Next(snapshotHandle, ref moduleEntry32)) { listViewItem = new ListViewItem(moduleEntry32.szModule); listViewItem.SubItems.Add("0x" + moduleEntry32.modBaseAddr.ToString(Cache.Is64BitOperatingSystem ? "X16" : "X8")); listViewItem.SubItems.Add("0x" + moduleEntry32.modBaseSize.ToString("X8")); listViewItem.SubItems.Add(moduleEntry32.szExePath); lvwModules.Items.Add(listViewItem); } } if (_isDotNetProcess) { using (dataTarget = DataTarget.AttachToProcess((int)_processId, 10000, AttachFlag.Passive)) foreach (ClrInfo clrInfo in dataTarget.ClrVersions) { foreach (ClrModule clrModule in clrInfo.CreateRuntime().Modules) { string moduleName; moduleName = clrModule.Name ?? "<<EmptyName>>"; listViewItem = new ListViewItem(clrModule.IsDynamic ? moduleName.Split(',')[0] : Path.GetFileName(moduleName)); listViewItem.SubItems.Add("0x" + clrModule.ImageBase.ToString(Cache.Is64BitOperatingSystem ? "X16" : "X8")); listViewItem.SubItems.Add("0x" + clrModule.Size.ToString("X8")); listViewItem.SubItems.Add(clrModule.IsDynamic ? "模块仅在内存中" : clrModule.FileName); listViewItem.BackColor = Cache.DotNetColor; lvwModules.Items.Add(listViewItem); } } } lvwModules.AutoResizeColumns(false); }
private static string GetStackTrace(Thread src) { var target = DataTarget.AttachToProcess(Process.GetCurrentProcess().Id, 10000, AttachFlag.Passive); var runtime = target.ClrVersions[0].CreateRuntime(); return(runtime.Threads.First(x => x.ManagedThreadId == src.ManagedThreadId) .StackTrace.Implode(x => x.DisplayString, Environment.NewLine)); }
public ManagedTarget(int processID) { // TODO This can only be done from a process with the same bitness, so we might want to move this out _dataTarget = DataTarget.AttachToProcess(processID, 1000, AttachFlag.Passive); _runtimes = _dataTarget.ClrVersions.Select(clr => clr.CreateRuntime()).ToList(); _modules = _dataTarget.EnumerateModules().ToList(); }
//https://github.com/Microsoft/dotnet-samples/tree/master/Microsoft.Diagnostics.Runtime/CLRMD private void objectOverviewToolStripMenuItem_Click(object sender, EventArgs e) { if (Process == null) { return; } saveFileDialogObjects.FileName = String.Format("clrmd_{0:yyyyMMdd_HHmmss}_FieldInfo", DateTime.Now); if (saveFileDialogObjects.ShowDialog() != DialogResult.OK) { return; } if (File.Exists(saveFileDialogObjects.FileName)) { File.Delete(saveFileDialogObjects.FileName); } Cursor.Current = Cursors.WaitCursor; using (DataTarget dataTarget = DataTarget.AttachToProcess(Process.Id, dataTargetTimeOut, dataTargetAttachFlag)) { ClrInfo clrVersion = dataTarget.ClrVersions.First(); ClrRuntime runtime = clrVersion.CreateRuntime(); if (runtime.Heap.CanWalkHeap) { using (StreamWriter writer = new StreamWriter(saveFileDialogObjects.FileName, true, Encoding.UTF8)) { foreach (DataGridViewRow row in dataGridViewMain.SelectedRows) { int cnt = 0; ManagedObject m = row.DataBoundItem as ManagedObject; writer.WriteLine("*********************** {0} ************************", m.ObjectName); writer.WriteLine(); foreach (ulong ptr in runtime.Heap.EnumerateObjectAddresses()) { ClrType type = runtime.Heap.GetObjectType(ptr); if (type == null || type.Name != m.ObjectName) { continue; } writer.WriteLine(ClrMdHelper.GetInfoOfObject(runtime, ptr, type)); writer.WriteLine(); cnt++; } writer.WriteLine("{0}x found in Heap {1}", cnt, m.ObjectName); writer.WriteLine(); writer.WriteLine(); } } } } Cursor.Current = Cursors.Default; }
public async Task Process([Option('i', Description = "Input process id to run.")] int pid, bool showobj = false) { // ## HANDLE DUMP // REF: https://github.com/microsoft/clrmd/blob/master/doc/GettingStarted.md // **load existing dump** using var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive); await Core(dataTarget, showobj); }
private DataTarget GetDataTarget() { if (myFile != null) { return(DataTarget.LoadCrashDump(myFile)); } return(DataTarget.AttachToProcess(myPid, 5000, AttachFlag.NonInvasive)); }