예제 #1
0
        private void DumpRunningThreadpoolThreads(ClrMDHelper helper)
        {
            Dictionary <string, ThreadDistributionItem> distribution = new Dictionary <string, ThreadDistributionItem>(8 * 1024);

            StringBuilder sb = new StringBuilder(8 * 1024 * 1024);

            _host.WriteLine("\r\n  ID ThreadOBJ        Locks  Details");
            _host.WriteLine("-----------------------------------------------------------------------------------");
            foreach (var thread in _host.Session.Clr.Threads
                     .Where(t => t.IsThreadpoolWorker)
                     .OrderBy(t => (t.LockCount > 0) ? -1 : (!t.IsAlive ? t.ManagedThreadId + 10000 : t.ManagedThreadId)))
            {
                string details = GetCallStackInfo(helper, thread);
                sb.AppendFormat("{0,4} {1}  {2}  {3}\r\n",
                                thread.ManagedThreadId.ToString(),
                                thread.Address.ToString("X16"),
                                ((thread.LockCount > 0) ? thread.LockCount.ToString("D4") : "    "),
                                details
                                );

                // the details might have different forms
                // 155 000000CC08EF5030        Thread
                //                                  + [method signature]
                //                                  => WaitHandle.WaitOneNative(0x000000CFC388EBA0 : SafeWaitHandle)
                // 156 000000CC08EFD050        Task | [method signature]
                //                                  + [method signature]
                //                                  => WaitHandle.WaitOneNative(0x000000CF40B7F480 : SafeWaitHandle)
                // but we just want to group by the first TWO lines (not the "=> ..." that contains pointers values that will break the grouping
                // so the key is computed up to "=>"
                string key = details;
                int    pos = details.IndexOf("=>");
                if (pos == -1)
                {
                    key = string.Intern(details);
                }
                else
                {
                    int lastLineMarkerPos = details.IndexOf("\r\n");
                    if (lastLineMarkerPos == -1)
                    {
                        Debug.Fail("unexpected item format" + details);
                        lastLineMarkerPos = pos;
                    }
                    key = string.Intern(details.Substring(0, lastLineMarkerPos + "\r\n".Length));
                }

                ThreadDistributionItem state;
                if (distribution.ContainsKey(key))
                {
                    state = distribution[key];
                }
                else
                {
                    state = new ThreadDistributionItem()
                    {
                        Key   = key,
                        Count = 0
                    };
                    distribution[key] = state;
                }
                state.Count++;
            }
            _host.WriteLine(sb.ToString());

            // build a summary
            if (distribution.Values.Count > 0)
            {
                sb.Clear();
                sb.AppendLine("\r\n____________________________________________________________________________________________________\r\nCount Details\r\n----------------------------------------------------------------------------------------------------");
                int total = 0;
                foreach (var item in distribution.Values.OrderBy(t => t.Count))
                {
                    sb.AppendLine(string.Format(" {0,4} {1}", item.Count.ToString(), item.Key));
                    total += item.Count;
                }
                sb.AppendLine(" ----");
                sb.AppendLine(string.Format(" {0,4}\r\n", total.ToString()));

                _host.WriteLine(sb.ToString());
            }
        }
        private static void DumpRunningThreadpoolThreads(ClrMDHelper helper)
        {
            Dictionary <string, ThreadDistributionItem> distribution = new Dictionary <string, ThreadDistributionItem>(8 * 1024);

            Console.WriteLine("\r\n  ID ThreadOBJ        Locks  Details");
            Console.WriteLine("-----------------------------------------------------------------------------------");
            foreach (var thread in Runtime.Threads.Where(t => t.IsThreadpoolWorker).OrderBy(t => (t.LockCount > 0) ? -1 : (!t.IsAlive ? t.ManagedThreadId + 10000 : t.ManagedThreadId)))
            {
                string details = string.Intern(GetCallStackInfo(helper, thread));

                if (thread.IsAlive)
                {
                    Console.WriteLine(string.Format(
                                          "{0,4} <link cmd=\"~~[{1}]e!ClrStack\">{2}</link>  {3}  {4}",
                                          thread.ManagedThreadId.ToString(),
                                          thread.OSThreadId.ToString("X"),
                                          thread.Address.ToString("X16"),
                                          ((thread.LockCount > 0) ? thread.LockCount.ToString("D4") : "    "),
                                          details
                                          ));
                }
                else
                {
                    Console.WriteLine(string.Format(
                                          "{0,4} {1}  {2}  {3}",
                                          thread.ManagedThreadId.ToString(),
                                          thread.Address.ToString("X16"),
                                          ((thread.LockCount > 0) ? thread.LockCount.ToString("D4") : "    "),
                                          details
                                          ));
                }

                ThreadDistributionItem state;
                if (distribution.ContainsKey(details))
                {
                    state = distribution[details];
                }
                else
                {
                    state = new ThreadDistributionItem()
                    {
                        Key   = details,
                        Count = 0
                    };
                    distribution[details] = state;
                }
                state.Count++;
            }

            // build a summary
            if (distribution.Values.Count > 0)
            {
                Console.WriteLine("\r\n____________________________________________________________________________________________________\r\nCount Details\r\n----------------------------------------------------------------------------------------------------");
                int total = 0;
                foreach (var item in distribution.Values.OrderBy(t => t.Count))
                {
                    Console.WriteLine(string.Format(" {0,4} {1}", item.Count.ToString(), item.Key));
                    total += item.Count;
                }
                Console.WriteLine(" ----");
                Console.WriteLine(string.Format(" {0,4}\r\n", total.ToString()));
            }
        }