public bool Attach(Process process, string dacFile = null, uint attachTimeout = DefaultAttachTimeout) { if (process == null) { throw new ArgumentNullException("process"); } _process = process; if (_dataTarget != null) { _output.Error(String.Format("Already attached to process PID={0} Name={1}", _process.Id, _process.ProcessName)); return false; } _output.Info(String.Format("Attaching to process PID={0}", process.Id)); try { _dataTarget = DataTarget.AttachToProcess(process.Id, attachTimeout); //make sure we dont kill the process on exit } catch (Exception exception) { //TODO: Be more specific, dont catch all exceptions _output.Error("Could not attach to the process."); throw; } if (_dataTarget == null) { //TODO: Be more specific, what exactly does it mean? _output.Error("Could not attach to the process."); _process = null; return false; } _dataTarget.DebuggerInterface.SetProcessOptions(DEBUG_PROCESS.DETACH_ON_EXIT); if (_dataTarget.ClrVersions.Count == 0) { var msg = String.Format( "Process PID={0} Name={1} does not seem to have CLR loaded. Is it an unmanaged process?", _process.Id, _process.ProcessName); _output.Error(msg); Detach(); return false; } if (_dataTarget.ClrVersions.Count > 1) { //TODO: multiple CLRs found present user with choice? var msg = String.Format("Multiple CLR versions loaded. Proceeding with first version."); _output.Warning(msg); } _clrInfo = _dataTarget.ClrVersions[0]; _output.Info(String.Format("Using CLR Version={0} DACFileName={1}", _clrInfo.Version, _clrInfo.DacInfo.FileName)); string dacLocation; if(String.IsNullOrWhiteSpace(dacFile)) { dacLocation = _clrInfo.TryGetDacLocation(); } else { dacLocation = dacFile; _output.Info(String.Format("Using DacFile={0}", dacFile)); } if (String.IsNullOrWhiteSpace(dacLocation)) { //TODO: Check filepath, display meaningful message _output.Error("Could not automatically locate Data Access Component (mscordacwks.dll). This may mean that bitness or CLR versions do not match. " + "You may specify file location manually eg. ClrDiag.Attach(PID, @\"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscordacwks.dll\""); Detach(); return false; } ClrRuntime runtime = _dataTarget.CreateRuntime(dacLocation); if (runtime == null) { //TODO: add more meaningful information _output.Error("Unable to get CLR information."); Detach(); } _output.Success(String.Format("Succesfully attached to process PID={0} Name={1}", _process.Id, _process.ProcessName)); Clr = runtime; return true; }
/// <summary> /// Converts the specified information. /// </summary> /// <param name="info">The information.</param> /// <returns>IClrInfo.</returns> public IClrInfo Convert(ClrMd.ClrInfo info) { if (info == null) { return(null); } var item = new ClrInfoAdapter(this, info); return(Cache.GetOrAdd <IClrInfo>(info, () => item, () => item.Setup())); }
public LegacyRuntime(ClrInfo info, DataTargetImpl dt, DacLibrary lib, DesktopVersion version, int patch) : base(info, dt, lib) { _version = version; _patch = patch; if (!GetCommonMethodTables(ref _commonMTs)) throw new ClrDiagnosticsException("Could not request common MethodTable list.", ClrDiagnosticsException.HR.DacError); // Ensure the version of the dac API matches the one we expect. (Same for both // v2 and v4 rtm.) byte[] tmp = new byte[sizeof(int)]; if (!Request(DacRequests.VERSION, null, tmp)) throw new ClrDiagnosticsException("Failed to request dac version.", ClrDiagnosticsException.HR.DacError); int v = BitConverter.ToInt32(tmp, 0); if (v != 8) throw new ClrDiagnosticsException("Unsupported dac version.", ClrDiagnosticsException.HR.DacError); }
public RuntimeBase(ClrInfo info, DataTargetImpl dataTarget, DacLibrary lib) { Debug.Assert(lib != null); Debug.Assert(lib.DacInterface != null); ClrInfo = info; _dataTarget = dataTarget; _library = lib; _dacInterface = _library.DacInterface; InitApi(); _dacInterface.Flush(); IGCInfo data = GetGCInfo(); if (data != null) { ServerGC = data.ServerMode; HeapCount = data.HeapCount; CanWalkHeap = data.GCStructuresValid; } _dataReader = dataTarget.DataReader; }
public string FindDac(ClrInfo clrInfo) { string dac = clrInfo.TryGetDacLocation(); if (string.IsNullOrEmpty(dac)) dac = FindDac(clrInfo.DacInfo.FileName, clrInfo.DacInfo.TimeStamp, clrInfo.DacInfo.FileSize); return dac; }
public ClrInfoDecorator(ClrInfo clrInfo, ThreadDispatcher threadDispatcher) { _clrInfo = clrInfo; _threadDispatcher = threadDispatcher; }
private static string LoadCorrectDacForMemoryDump(ClrInfo version) { // First try the main location, i.e.: // C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll if (version.LocalMatchingDac != null && File.Exists(version.LocalMatchingDac)) { Console.WriteLine("\nDac already exists on the local machine at:\n{0}", version.LocalMatchingDac); return version.LocalMatchingDac; } // Location: <TEMP>\symbols\mscordacwks_amd64_amd64_4.0.30319.18444.dll\52717f9a96b000\mscordacwks_amd64_amd64_4.0.30319.18444.dll ModuleInfo dacInfo = version.DacInfo; var dacLocation = string.Format(@"{0}symbols\{1}\{2:x}{3:x}\{4}", Path.GetTempPath(), dacInfo.FileName, dacInfo.TimeStamp, dacInfo.FileSize, dacInfo.FileName); if (File.Exists(dacLocation)) { Console.WriteLine("\nDac {0} already exists in the local cache at:\n{1}", dacInfo.FileName, dacLocation); return dacLocation; } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\nUnable to find copy of the dac ({0}) on the local machine.", dacInfo); Console.WriteLine("Expected location:\n" + dacLocation); Console.WriteLine("\nIt will now be downloaded from the Microsoft Symbol Server."); Console.WriteLine("Press <ENTER> if you are okay with this, if not you can just type Ctrl-C to exit"); Console.ResetColor(); Console.ReadLine(); string downloadLocation = version.TryDownloadDac(new SymbolNotification()); Console.WriteLine("Downloaded a copy of the dac to:\n" + downloadLocation); return downloadLocation; } }
public void Detach() { var name = _process.ProcessName; var pid = _process.Id; _process = null; _clrInfo = null; Clr = null; if (_dataTarget == null) { return; } _dataTarget.DebuggerInterface.DetachProcesses(); _dataTarget.Dispose(); _dataTarget = null; _output.Success(String.Format("Successfully detached from process PID={0} Name={1}", pid, name)); }
public string FindDac(ClrInfo clrInfo) { var dac = FindDac(clrInfo.DacInfo.FileName, clrInfo.DacInfo.TimeStamp, clrInfo.DacInfo.FileSize); return dac; }
public MDRuntimeInfo(ClrInfo info) { m_info = info; }