示例#1
0
        public DbgEngDataReader(int pid, AttachFlag flags, uint msecTimeout)
        {
            IDebugClient client = CreateIDebugClient();

            CreateClient(client);

            DEBUG_ATTACH attach = flags == AttachFlag.Invasive ? DEBUG_ATTACH.DEFAULT : DEBUG_ATTACH.NONINVASIVE;
            int          hr     = _control.AddEngineOptions(DEBUG_ENGOPT.INITIAL_BREAK);

            if (hr == 0)
            {
                hr = client.AttachProcess(0, (uint)pid, attach);
            }

            if (hr == 0)
            {
                hr = _control.WaitForEvent(0, msecTimeout);
            }

            if (hr == 1)
            {
                throw new TimeoutException("Break in did not occur within the allotted timeout.");
            }

            if (hr != 0)
            {
                if ((uint)hr == 0xd00000bb)
                {
                    throw new InvalidOperationException("Mismatched architecture between this process and the target process.");
                }

                throw new ClrDiagnosticsException($"Could not attach to pid {pid:X}, HRESULT: 0x{hr:x8}", ClrDiagnosticsExceptionKind.DebuggerError, hr);
            }
        }
示例#2
0
        public DbgEngDataReader(int pid, AttachFlag flags, uint msecTimeout)
        {
            IDebugClient client = CreateIDebugClient();
            CreateClient(client);

            DEBUG_ATTACH attach = (flags == AttachFlag.Invasive) ? DEBUG_ATTACH.DEFAULT : DEBUG_ATTACH.NONINVASIVE;
            int hr = _control.AddEngineOptions(DEBUG_ENGOPT.INITIAL_BREAK);

            if (hr == 0)
                hr = client.AttachProcess(0, (uint)pid, attach);

            if (hr == 0)
                hr = _control.WaitForEvent(0, msecTimeout);

            if (hr == 1)
            {
                throw new TimeoutException("Break in did not occur within the allotted timeout.");
            }
            else if (hr != 0)
            {
                if ((uint)hr == 0xd00000bb)
                    throw new InvalidOperationException("Mismatched architecture between this process and the target process.");

                throw new ClrDiagnosticsException(String.Format("Could not attach to pid {0:X}, HRESULT: 0x{1:x8}", pid, hr), ClrDiagnosticsException.HR.DebuggerError);
            }
        }
示例#3
0
        public DbgEngDataReader(int pid, AttachFlag flags, uint msecTimeout)
        {
            IDebugClient client = CreateIDebugClient();

            CreateClient(client);

            DEBUG_ATTACH attach = (flags == AttachFlag.Invasive) ? DEBUG_ATTACH.DEFAULT : DEBUG_ATTACH.NONINVASIVE;
            int          hr     = m_control.AddEngineOptions(DEBUG_ENGOPT.INITIAL_BREAK);

            if (hr == 0)
            {
                hr = client.AttachProcess(0, (uint)pid, attach);
            }

            if (hr == 0)
            {
                hr = m_control.WaitForEvent(0, msecTimeout);
            }

            if (hr == 1)
            {
                throw new TimeoutException("Break in did not occur within the allotted timeout.");
            }
            else if (hr != 0)
            {
                throw new ClrDiagnosticsException(String.Format("Could not attach to pid {0:X}, HRESULT: 0x{1:x8}", pid, hr), ClrDiagnosticsException.HR.DebuggerError);
            }
        }
示例#4
0
        public static string GetThreadDump(int pid, AttachFlag mode)
        {
            using (StringWriter writer = new StringWriter())
            {
                try {
                    using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, mode))
                    {
                        writer.WriteLine(dataTarget.ClrVersions.First().Version);
                        var runtime = dataTarget.ClrVersions.First().CreateRuntime();

                        foreach (var domain in runtime.AppDomains)
                        {
                            writer.WriteLine("Domain " + domain.Name);
                        }
                        writer.WriteLine();
                        foreach (var t in runtime.Threads)
                        {
                            if (!t.IsAlive)
                            {
                                continue;
                            }

                            if (t.StackTrace.Count == 0)
                            {
                                continue;
                            }

                            writer.WriteLine("Thread " + t.ManagedThreadId + ": ");
                            int loop_count = 0;
                            foreach (var frame in t.EnumerateStackTrace())
                            {
                                writer.WriteLine("\t" + frame.StackPointer.ToString("x16") + " " + frame.ToString());
                                loop_count++;
                                if (loop_count > 200)
                                {
                                    writer.WriteLine("\t[CORRUPTED]");
                                    break;
                                }
                            }
                            writer.WriteLine();
                        }
                    }
                    return(writer.ToString());
                } catch
                {
                    // This is mostly to catch the "invalid architecture" error.
                    // Any error that happens we want to ignore and return what we have.
                    return(writer.ToString());
                }
            }
        }
示例#5
0
        public static DataTarget LoadOrAttach(string target, AttachFlag attachFlag, uint msecTimeout)
        {
            if (File.Exists(target))
            {
                return(DataTarget.LoadCrashDump(target));
            }

            Process process = null;

            Int32 processId;

            if (Int32.TryParse(target, out processId))
            {
                process = Process.GetProcessById(processId);
            }
            else
            {
                var processes = Process.GetProcesses();
                var found     = new List <Process>();
                // TODO: Access denied workaround

                foreach (var process1 in processes)
                {
                    if (process1.ProcessName.StartsWith(target))
                    {
                        found.Add(process1);
                    }
                }

                if (found.Count > 1)
                {
                    throw new ProcessNotFoundException("Multiple processes match the specified name.");
                }
                if (found.Count == 0)
                {
                    throw new ProcessNotFoundException("No process matching the specified name can be found. Try elevating the command prompt.");
                }

                process = found[0];
            }

            if (process == null)
            {
                throw new ProcessNotFoundException("No process matching the specified name can be found. Try elevating the command prompt.");
            }

            //Console.WriteLine($"Using {process.MainModule.FileName}");

            return(DataTarget.AttachToProcess(process.Id, msecTimeout, attachFlag));
        }
示例#6
0
        /// <summary>
        /// Attaches to a live process.
        /// </summary>
        /// <param name="pid">The process ID of the process to attach to.</param>
        /// <param name="msecTimeout">Timeout in milliseconds.</param>
        /// <param name="attachFlag">The type of attach requested for the target process.</param>
        /// <returns>A DataTarget instance.</returns>
        public static DataTarget AttachToProcess(int pid, uint msecTimeout, AttachFlag attachFlag)
        {
            IDebugClient client = null;
            IDataReader  reader;

            if (attachFlag == AttachFlag.Passive)
            {
#if NET45
                reader = new LiveDataReader(pid, false);
#else
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    reader = new LiveDataReader(pid, false);
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    reader = new Linux.LinuxLiveDataReader((uint)pid);
                }
                else
                {
                    throw new NotSupportedException("Passive attach is not supported on OSX.s");
                }
#endif
            }
            else
            {
#if !NET45
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    throw new PlatformNotSupportedException("Currently only AttachFlag.Passive is supported for AttachToProcess");
                }
#endif

                DbgEngDataReader dbgeng = new DbgEngDataReader(pid, attachFlag, msecTimeout);
                reader = dbgeng;
                client = dbgeng.DebuggerInterface;
            }

            DataTargetImpl dataTarget = new DataTargetImpl(reader, client);
#if !NET45
            if (reader is Linux.LinuxLiveDataReader)
            {
                // TODO: discuss this design of
                // 1) add a method to IDataReader2 to return the list of module full path
                // 2) make DefaultSymbolLocator use that list as hint to load binaries
                dataTarget.SymbolLocator = new Linux.LinuxDefaultSymbolLocator(((Linux.LinuxLiveDataReader)reader).GetModulesFullPath());
            }
#endif
            return(dataTarget);
        }
示例#7
0
        /// <summary>
        /// Attaches to a live process.
        /// </summary>
        /// <param name="pid">The process ID of the process to attach to.</param>
        /// <param name="msecTimeout">Timeout in milliseconds.</param>
        /// <param name="attachFlag">The type of attach requested for the target process.</param>
        /// <returns>A DataTarget instance.</returns>
        public static DataTarget AttachToProcess(int pid, uint msecTimeout, AttachFlag attachFlag)
        {
            IDebugClient client = null;
            IDataReader  reader;

            if (attachFlag == AttachFlag.Passive)
            {
                reader = new LiveDataReader(pid, false);
            }
            else
            {
                DbgEngDataReader dbgeng = new DbgEngDataReader(pid, attachFlag, msecTimeout);
                reader = dbgeng;
                client = dbgeng.DebuggerInterface;
            }

            DataTargetImpl dataTarget = new DataTargetImpl(reader, client);

            return(dataTarget);
        }
示例#8
0
        public static ClrMDSession AttachToProcess(string processName, uint millisecondsTimeout = 5000, AttachFlag attachFlag = AttachFlag.Invasive)
        {
            Process p = Process.GetProcessesByName(processName).FirstOrDefault();

            if (p == null)
            {
                throw new ArgumentException("Process not found", "processName");
            }

            return(AttachToProcess(p, millisecondsTimeout, attachFlag));
        }
示例#9
0
        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);
        }
示例#10
0
        static void Main(string[] args)
        {
            string     process_set_id = "all";
            AttachFlag mode           = AttachFlag.Passive;
            int        interval       = 0;

            // command line parsing
            int i = 0;

            while (i < args.Length)
            {
                switch (args[i])
                {
                case "-Passive":
                    mode = AttachFlag.Passive;
                    i++;
                    continue;

                case "-NonInvasive":
                    mode = AttachFlag.NonInvasive;
                    i++;
                    continue;

                case "-Invasive":
                    mode = AttachFlag.Invasive;
                    i++;
                    continue;

                case "-Interval":
                    i++;
                    if (args.Length < i)
                    {
                        Console.WriteLine("Interval takes at least one argument");
                        return;
                    }
                    interval = Int32.Parse(args[i]);
                    i++;
                    continue;
                }
                process_set_id = args[i];
                i++;
            }

            if (!process_sets.ContainsKey(process_set_id))
            {
                Console.WriteLine("Must specify valid process set: all iis services");
                return;
            }

            List <string> process_set = process_sets[process_set_id];

            do
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                using (TextWriter writer = new StreamWriter(File.Create("threads_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".log")))
                {
                    writer.WriteLine(DateTime.Now.ToString());

                    foreach (var p in Process.GetProcesses())
                    {
                        string filename = GetProcessFilename(p);
                        if (process_set.Any(f => filename.EndsWith(f)))
                        {
                            writer.WriteLine(p.Id + " " + p.ProcessName + " " + filename);
                            writer.WriteLine(GetThreadDump(p.Id, mode));
                        }
                    }
                }
                sw.Stop();
                // wait at least twice as long as it took to process
                // try to keep up with the defined interval
                Thread.Sleep(Math.Max(interval * 1000 - (int)sw.ElapsedMilliseconds, 2 * (int)sw.ElapsedMilliseconds));
            } while (interval > 0);
        }
示例#11
0
        public static ClrMDSession AttachToProcess(string processName, uint millisecondsTimeout = 5000, AttachFlag attachFlag = AttachFlag.Invasive)
        {
            Process p = Process.GetProcessesByName(processName).FirstOrDefault();

            if (p == null)
                throw new ArgumentException("Process not found", "processName");

            return AttachToProcess(p, millisecondsTimeout, attachFlag);
        }
示例#12
0
        /// <summary>
        /// Attaches to a live process.
        /// </summary>
        /// <param name="pid">The process ID of the process to attach to.</param>
        /// <param name="msecTimeout">Timeout in milliseconds.</param>
        /// <param name="attachFlag">The type of attach requested for the target process.</param>
        /// <returns>A DataTarget instance.</returns>
        public static DataTarget AttachToProcess(int pid, uint msecTimeout, AttachFlag attachFlag)
        {
            Microsoft.Diagnostics.Runtime.Interop.IDebugClient client = null;
            IDataReader reader;
            if (attachFlag == AttachFlag.Passive)
            {
                reader = new LiveDataReader(pid);
            }
            else
            {
                var dbgeng = new DbgEngDataReader(pid, attachFlag, msecTimeout);
                reader = dbgeng;
                client = dbgeng.DebuggerInterface;
            }

            DataTargetImpl dataTarget = new DataTargetImpl(reader, client);
            return dataTarget;
        }
示例#13
0
        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);

            s_lastProcessId = p.Id;
            return(new ClrMDSession(target, null));
        }
 public ThreadDumpCollector(uint attachTimeoutInMillis, AttachFlag mode)
 {
     AttachTimeoutInMillis = attachTimeoutInMillis;
     Mode = mode;
 }
示例#15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DebugSession"/> class.
 /// </summary>
 /// <param name="processId">The process identifier.</param>
 /// <param name="milliSeconds">The milli seconds.</param>
 /// <param name="flag">The flag.</param>
 public DebugSession(int processId, uint milliSeconds, AttachFlag flag)
     : this()
 {
     AttachedTarget = DataTarget.AttachToProcess(processId, milliSeconds, flag);
     Initialize();
 }
示例#16
0
        public static ClrMDSession AttachToProcess(int pid, uint millisecondsTimeout = 5000, AttachFlag attachFlag = AttachFlag.Invasive)
        {
            Process p = Process.GetProcessById(pid);

            if (p == null)
            {
                throw new ArgumentException("Process not found", "pid");
            }

            return(AttachToProcess(p, millisecondsTimeout, attachFlag));
        }
示例#17
0
        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));
        }
示例#18
0
        public static ClrMDSession AttachToProcess(int pid, uint millisecondsTimeout = 5000, AttachFlag attachFlag = AttachFlag.Invasive)
        {
            Process p = Process.GetProcessById(pid);

            if (p == null)
                throw new ArgumentException("Process not found", "pid");

            return AttachToProcess(p, millisecondsTimeout, attachFlag);
        }