/// <summary> /// 利用VS调试工具输出线程堆栈测试 http://blogs.msdn.com/b/jmstall/archive/2005/11/28/snapshot.aspx /// </summary> /// <param name="args"></param> static void Main(string[] args) { do { Console.WriteLine("pid?"); int pid; if (!int.TryParse(Console.ReadLine(), out pid)) { return; } MDbgEngine debugger = new MDbgEngine(); MDbgProcess proc = null; try { proc = debugger.Attach(pid); DrainAttach(debugger, proc); MDbgThreadCollection tc = proc.Threads; Console.WriteLine("Attached to pid:{0}", pid); foreach (MDbgThread t in tc) { Console.WriteLine("Callstack for Thread {0}", t.Id.ToString()); foreach (MDbgFrame f in t.Frames) { Console.WriteLine(" " + f); } } } finally { if (proc != null) { proc.Detach().WaitOne(); } } }while (true); }
private void GetCurrentCallStack(Dictionary <string, ThreadCounterInfo> counters, Dictionary <string, ThreadOutputInfo> threadInfos) { var debugger = new MDbgEngine(); MDbgProcess proc = null; try { Console.WriteLine($"start attack to {PID} to get call stack"); proc = debugger.Attach((int)PID); DrainAttach(debugger, proc); Console.WriteLine($"had attacked to {PID}"); var counterThreadIDList = counters.Select(p => p.Value.ThreadID).ToList(); MDbgThreadCollection tc = proc.Threads; foreach (MDbgThread t in tc) { try { // 计数器没有的线程,不拿堆栈 if (!counterThreadIDList.Contains(t.Id.ToString())) { continue; } Console.WriteLine($"start get {t.Id}'s call stack"); var tempStrs = new StringBuilder(); foreach (MDbgFrame f in t.Frames) { tempStrs.AppendFormat("<br />" + f); } ThreadOutputInfo info; if (threadInfos.TryGetValue(t.Id.ToString(), out info)) { var stack = $"{DateTime.Now.ToString()}<br/>"; stack = stack + (tempStrs.Length == 0 ? "no managment call stack" : tempStrs.ToString()); info.CallStack.Add(stack); } Console.WriteLine($"had got {t.Id}'s call stack"); } catch (Exception ee) { WriteErrorLog("获取堆栈时出错:" + ee.ToString() + Environment.NewLine); Console.WriteLine($"an exception occur when got {t.Number}'s call stack, Log file {LogFile} for detail"); } } } catch (Exception ex) { WriteErrorLog("附加到进程时出错:" + ex.ToString() + Environment.NewLine); Console.WriteLine($"an exception occur when attack to process, Log file {LogFile} for detail"); } finally { if (proc != null) { proc.Detach().WaitOne(); } } }
// Expects 1 arg, the pid as a decimal string private static void Main(string[] args) { try { Console.WriteLine("请输入pid:"); int pid = int.Parse(Console.ReadLine()); var sb = new StringBuilder(); Process process = Process.GetProcessById(pid); var counters = new Dictionary <string, MyThreadCounterInfo>(); var threadInfos = new Dictionary <string, MyThreadInfo>(); sb.AppendFormat( @"<html><head><title>{0}</title><style type=""text/css"">table, td{{border: 1px solid #000;border-collapse: collapse;}}</style></head><body>", process.ProcessName); Console.WriteLine("1、正在收集计数器"); var cate = new PerformanceCounterCategory("Thread"); string[] instances = cate.GetInstanceNames(); foreach (string instance in instances) { if (instance.StartsWith(process.ProcessName, StringComparison.CurrentCultureIgnoreCase)) { var counter1 = new PerformanceCounter("Thread", "ID Thread", instance, true); var counter2 = new PerformanceCounter("Thread", "% Processor Time", instance, true); counters.Add(instance, new MyThreadCounterInfo(counter1, counter2)); } } foreach (var pair in counters) { try { pair.Value.IdCounter.NextValue(); pair.Value.ProcessorTimeCounter.NextValue(); } catch (Exception ex) { Console.WriteLine(ex); throw; } } Thread.Sleep(1000); foreach (var pair in counters) { try { var info = new MyThreadInfo(); info.Id = pair.Value.IdCounter.NextValue().ToString(); info.ProcessorTimePercentage = pair.Value.ProcessorTimeCounter.NextValue().ToString("0.0"); threadInfos.Add(info.Id, info); } catch { } } Console.WriteLine("2、正在收集线程信息"); ProcessThreadCollection collection = process.Threads; foreach (ProcessThread thread in collection) { try { MyThreadInfo info; if (threadInfos.TryGetValue(thread.Id.ToString(), out info)) { info.UserProcessorTime = thread.UserProcessorTime.ToString(); info.StartTime = thread.StartTime.ToString(); } } catch { } } var debugger = new MDbgEngine(); MDbgProcess proc = null; try { proc = debugger.Attach(pid); DrainAttach(debugger, proc); MDbgThreadCollection tc = proc.Threads; Console.WriteLine("3、正在附加到进程{0}获取调用栈", pid); foreach (MDbgThread t in tc) { var tempStrs = new StringBuilder(); foreach (MDbgFrame f in t.Frames) { tempStrs.AppendFormat("<br />" + f); } MyThreadInfo info; if (threadInfos.TryGetValue(t.Id.ToString(), out info)) { info.CallStack = tempStrs.Length == 0 ? "no managment call stack" : tempStrs.ToString(); } } } finally { if (proc != null) { proc.Detach().WaitOne(); } } foreach (var info in threadInfos) { sb.Append(info.Value.ToString()); sb.Append("<hr />"); } sb.Append("</body></html>"); Console.WriteLine("4、正在生成报表"); using (var sw = new StreamWriter(process.ProcessName + ".htm", false, Encoding.Default)) { sw.Write(sb.ToString()); } Process.Start(process.ProcessName + ".htm"); } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine("运行完毕,按回车键关闭"); Console.ReadLine(); }