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;
        }
Example #2
0
        /// <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()));
        }
Example #3
0
        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);
        }
Example #4
0
        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;
        }
Example #5
0
        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;
		}
Example #7
0
        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;
 }
Example #10
0
 public MDRuntimeInfo(ClrInfo info)
 {
     m_info = info;
 }