Example #1
0
        private static void Main(string[] args)
        {
            MDbgProcess proc = null;

            try
            {
                int        processId = Int32.Parse(args[0]);
                MDbgEngine debugger  = new MDbgEngine();
                proc = debugger.Attach(processId);
                InitializeMdbg(debugger, proc);
                DumpThreads(proc);
            }
            catch
            {
                PrintUsage();
            }
            finally
            {
                if (proc != null)
                {
                    // We always want to detach from target.
                    proc.Detach().WaitOne();
                }
            }
        }
Example #2
0
        private void Cleanup()
        {
            MDbgProcess active = Debugger.Processes.Active;

            active.Breakpoints.DeleteAll();

            active.CorProcess.Stop(0);
            active.Detach();
        }
Example #3
0
        /// <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);
        }
Example #4
0
        protected virtual void Dispose(bool disposing)
        {
            // 防止被多次调用
            if (disposed)
            {
                return;
            }

            if (disposing)
            {
                // 清除所有托管资源
                if (_mdbgProcess != null)
                {
                    // 确保基本进程在datach前已经终止了
                    var waithandler = _mdbgProcess.AsyncStop();
                    waithandler.WaitOne();
                    _mdbgProcess.Detach();
                }
            }

            disposed = true;
        }
Example #5
0
        protected virtual void Dispose(bool disposing)
        {
            // Protect from being called multiple times.
            if (disposed)
            {
                return;
            }

            if (disposing)
            {
                // Clean up all managed resources.
                if (_mdbgProcess != null)
                {
                    // Make sure the underlying CorProcess was stopped before
                    // detached it.
                    var waithandler = _mdbgProcess.AsyncStop();
                    waithandler.WaitOne();
                    _mdbgProcess.Detach();
                }
            }

            disposed = true;
        }
Example #6
0
        // Expects 1 arg, the pid as a decimal string
        private static void Main(string[] args)
        {
            try
            {
                int pid = int.Parse(args[0]);

                var     sb      = new StringBuilder();
                Process process = Process.GetProcessById(pid);

                //var counters = new Dictionary<string, MyThreadCounterInfo>();
                //var threadInfos = new Dictionary<string, MyThreadInfo>();


                ////zhanggangb

                //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.Message);
                //    }
                //}
                //Thread.Sleep(5000);
                //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(Exception ex)
                //    {
                //        Console.WriteLine(ex.Message);
                //    }
                //}

                //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 (Exception ex)
                //    {
                //        Console.WriteLine(ex.Message);
                //    }
                //}

                var debugger = new MDbgEngine();

                debugger.Options.StopOnException = true;

                StringBuilder sbb  = new StringBuilder();
                MDbgProcess   proc = null;
                try
                {
                    proc = debugger.Attach(pid);
                    DrainAttach(debugger, proc);

                    var 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();
                            sb.Append(info.CallStack);
                        }
                    }
                }
                finally
                {
                    if (proc != null)
                    {
                        proc.Detach().WaitOne();
                    }
                }
                Console.WriteLine("4、正在生成报表");
                using (var sw = new StreamWriter(@"D:\View\MYBLOG\CpuAnalyzer\bin\Debug\" + process.Id + ".htm", false,
                                                 Encoding.Default))
                {
                    sw.Write(sbb.ToString());
                }
                //按照cpu占用率排序
                //var result = threadInfos.Values.ToArray().OrderByDescending(item => double.Parse(item.ProcessorTimePercentage));


                //foreach (var info in result)
                //{
                //    sb.Append(info.ToString());
                //    sb.Append("<hr />");
                //}
                //sb.Append("</body></html>");

                //Console.WriteLine("4、正在生成报表");
                //using (var sw = new StreamWriter(@"D:\View\MYBLOG\CpuAnalyzer\bin\Debug\"+process.Id + ".htm", false,
                //                                 Encoding.Default))
                //{
                //    sw.Write(sb.ToString());
                //}

                Process.Start(@"D:\View\MYBLOG\CpuAnalyzer\bin\Debug\" + process.Id + ".htm");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("分析结束");
            Console.ReadKey();
        }
Example #7
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Usage();
                return;
            }

            int samples        = 10;
            int sampleInterval = 1000;


            var state = ParseState.Unknown;

            foreach (var arg in args.Skip(1))
            {
                switch (state)
                {
                case ParseState.Unknown:
                    if (arg.ToLower() == "/s")
                    {
                        state = ParseState.Samples;
                    }
                    else if (arg.ToLower() == "/i")
                    {
                        state = ParseState.Interval;
                    }
                    else
                    {
                        Usage();
                        return;
                    }
                    break;

                case ParseState.Samples:
                    if (!Int32.TryParse(arg, out samples))
                    {
                        Usage();
                        return;
                    }
                    state = ParseState.Unknown;
                    break;

                case ParseState.Interval:
                    if (!Int32.TryParse(arg, out sampleInterval))
                    {
                        Usage();
                        return;
                    }
                    state = ParseState.Unknown;
                    break;

                default:
                    break;
                }
            }

            string pidOrProcess = args[0];


            var stats    = new Dictionary <int, List <ThreadSnapshot> >();
            var debugger = new MDbgEngine();
            int pid      = -1;

            var processes = Process.GetProcessesByName(pidOrProcess);

            if (processes.Length < 1)
            {
                try {
                    pid = Int32.Parse(pidOrProcess);
                } catch {
                    Console.WriteLine("Error: could not find any processes with that name or pid");
                    return;
                }
            }
            else
            {
                if (processes.Length > 1)
                {
                    Console.WriteLine("Warning: multiple processes share that name, attaching to the first");
                }
                pid = processes[0].Id;
            }


            MDbgProcess attached = null;

            try {
                attached = debugger.Attach(pid);
            } catch (Exception e) {
                Console.WriteLine("Error: failed to attach to process: " + e);
                return;
            }

            attached.Go().WaitOne();

            for (int i = 0; i < samples; i++)
            {
                foreach (MDbgThread thread in attached.Threads)
                {
                    var snapshot = ThreadSnapshot.GetThreadSnapshot(thread);
                    List <ThreadSnapshot> snapshots;
                    if (!stats.TryGetValue(snapshot.Id, out snapshots))
                    {
                        snapshots          = new List <ThreadSnapshot>();
                        stats[snapshot.Id] = snapshots;
                    }

                    snapshots.Add(snapshot);
                }

                attached.Go();
                Thread.Sleep(sampleInterval);
                attached.AsyncStop().WaitOne();
            }

            attached.Detach().WaitOne();

            // perform basic analysis to see which are the top N stack traces observed,
            //  weighted on cost

            Dictionary <Guid, long>   costs  = new Dictionary <Guid, long>();
            Dictionary <Guid, string> stacks = new Dictionary <Guid, string>();

            foreach (var stat in stats.Values)
            {
                long prevTime = -1;
                foreach (var snapshot in stat)
                {
                    long time = snapshot.KernelTime + snapshot.UserTime;
                    if (prevTime != -1)
                    {
                        foreach (var tuple in snapshot.StackHashes)
                        {
                            if (costs.ContainsKey(tuple.Item1))
                            {
                                costs[tuple.Item1] += time - prevTime;
                            }
                            else
                            {
                                costs[tuple.Item1]  = time - prevTime;
                                stacks[tuple.Item1] = tuple.Item2;
                            }
                        }
                    }
                    prevTime = time;
                }
            }

            Console.WriteLine("Most expensive stacks");
            Console.WriteLine("------------------------------------");
            foreach (var group in costs.OrderByDescending(p => p.Value).GroupBy(p => p.Value))
            {
                List <string> stacksToShow = new List <string>();

                foreach (var pair in group.OrderByDescending(p => stacks[p.Key].Length))
                {
                    if (!stacksToShow.Any(s => s.Contains(stacks[pair.Key])))
                    {
                        stacksToShow.Add(stacks[pair.Key]);
                    }
                }

                foreach (var stack in stacksToShow)
                {
                    Console.WriteLine(stack);
                    Console.WriteLine("===> Cost ({0})", group.Key);
                    Console.WriteLine();
                }
            }


            var offenders = stats.Values
                            .Select(_ => ThreadSnapshotStats.FromSnapshots(_))
                            .OrderBy(stat => stat.TotalKernelTime + stat.TotalUserTime)
                            .Reverse();

            foreach (var stat in offenders)
            {
                Console.WriteLine("------------------------------------");
                Console.WriteLine(stat.ThreadId);
                Console.WriteLine("Kernel: {0} User: {1}", stat.TotalKernelTime, stat.TotalUserTime);
                foreach (var method in stat.CommonStack)
                {
                    Console.WriteLine(method);
                }
                Console.WriteLine("Other Stacks:");
                var prev = new List <string>();
                foreach (var trace in stats[stat.ThreadId].Select(_ => _.StackTrace))
                {
                    if (!prev.SequenceEqual(trace))
                    {
                        Console.WriteLine();
                        foreach (var method in trace)
                        {
                            Console.WriteLine(method);
                        }
                    }
                    else
                    {
                        Console.WriteLine("<skipped>");
                    }
                    prev = trace;
                }
                Console.WriteLine("------------------------------------");
            }
        }
        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();
                }
            }
        }
Example #9
0
    // 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();
    }
Example #10
0
        // Expects 1 arg, the pid as a decimal string
        public void Analyse(int pid)
        {
            try
            {
                var stopwt = new Stopwatch();

                var sb          = new StringBuilder();
                var 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();
                Console.WriteLine("instances总数:{0}", instances.Length);
                stopwt.Start();
                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));
                    }
                }

                var i = 0;
                Console.WriteLine("counters总数:{0} {1}ms", counters.Count, stopwt.ElapsedMilliseconds);
                stopwt.Restart();
                foreach (var pair in counters)
                {
                    try
                    {
                        pair.Value.IdCounter.NextValue();
                        pair.Value.ProcessorTimeCounter.NextValue();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("#{0} {1}", i, ex.Message);
                    }
                    i++;
                }
                Console.WriteLine("counters foreach {0}ms", stopwt.ElapsedMilliseconds);
                Thread.Sleep(5000);
                stopwt.Restart();
                i = 0;
                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 (Exception ex)
                    {
                        Console.WriteLine("#{0} {1}", i, ex.Message);
                    }
                    i++;
                }
                i = 0;
                Console.WriteLine("counters foreach 2 {0}ms", stopwt.ElapsedMilliseconds);
                stopwt.Restart();

                Console.WriteLine("2、正在收集线程信息");
                ProcessThreadCollection collection = process.Threads;
                Console.WriteLine("Threads总数:{0}", collection.Count);
                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 (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
                Console.WriteLine("完成收集线程信息 {0}ms", stopwt.ElapsedMilliseconds);
                stopwt.Restart();

                var         debugger = new MDbgEngine();
                MDbgProcess proc     = null;
                try
                {
                    Console.WriteLine("3、正在附加到进程{0}获取调用栈", pid);
                    proc = debugger.Attach(pid);
                    DrainAttach(debugger, proc);

                    var tc = proc.Threads;
                    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();
                    }
                }

                //修改成按照cpu占用率排序
                var result = threadInfos.Values.ToArray().OrderByDescending(item => double.Parse(item.ProcessorTimePercentage));

                Console.WriteLine("4、正在生成报表");
                foreach (var info in result)
                {
                    sb.Append(info.ToString());
                    sb.Append("<hr />");
                }
                sb.Append("</body></html>");
                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.Message);
            }

            Console.WriteLine("分析结束");
            //Console.ReadKey();
        }
Example #11
0
        private void ExectueCmdForMdbg()
        {
            int pid = Process.GetCurrentProcess().Id;

            result = "内部调用栈测试!";
            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);

            //收集计数器
            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)
                {
                    //throw;
                    //todo 写到日志 zhanggangb
                }
            }

            Thread.Sleep(5000);
            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 (Exception ex)
                {
                    // throw;
                }
            }

            //收到线程信息
            ProcessThreadCollection collection = process.Threads;

            foreach (ProcessThread thread in collection)
            {
                try
                {
                    MyThreadInfo info;
                    if (threadInfos.TryGetValue(thread.Id.ToString(), out info))
                    {
                        info.UserProcessorTime = thread.Id.ToString();
                        info.StartTime         = thread.StartTime.ToString();
                    }
                }
                catch (Exception)
                {
                    //throw;
                }
            }


            var debugger = new MDbgEngine();

            debugger.Options.StopOnException = true;
            MDbgProcess proc = null;

            try
            {
                proc = debugger.Attach(pid);
                DrainAttach(debugger, proc);

                var tc = proc.Threads;
                //附加到进程获取调用栈
                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 ? "没有托管调用栈" : tempStrs.ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                //throw;
            }
            finally
            {
                if (proc != null)
                {
                    proc.Detach().WaitOne();
                }
            }

            //按照CPU占用率排序
            var threadresult = threadInfos.Values.ToArray().OrderByDescending(item => double.Parse(item.ProcessorTimePercentage));

            foreach (var info in threadresult)
            {
                sb.Append(info.ToString());
                sb.Append("<hr />");
            }
            //sb.Append("</body></html>")
            //Utility.Logger.Log(message);

            //生成报表
            //using (var sw = new StreamWriter(process.ProcessName+".html",false,Encoding.Default))
            //{
            //    sw.Write(sb.ToString());
            //}

            //process.Start(process.ProcessName + ".html");

            result = sb.ToString();
        }