How do I make a thread dump in .NET ? (a la JVM thread dumps)

前端 未结 6 1737
暖寄归人
暖寄归人 2021-01-30 17:52

I have found no way of dumping the stack on all threads in .NET. Neither a signal to be send to the process nor programatic access to all the threads. I can only get access to t

6条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-30 18:17

    I wrote a dumper for a project i worked on in the past:

    void CrashHandler::WriteThreadInfo(StringWriter* sw, ArrayList* threads, String* type)
    {
        sw->WriteLine(type);
    
        IEnumerator* ie = threads->GetEnumerator();
        while(ie->MoveNext())
        {
            botNETThread* bnt = static_cast(ie->Current);
            if(!bnt->IsAlive) continue;
            sw->WriteLine(String::Concat(S"ORIGIN ASSEMBLY: ", bnt->Assembly->FullName));
            sw->WriteLine(String::Concat(S"THREAD NAME: ", (bnt->Name && bnt->Name->Length)?bnt->Name:S"Unnamed thread"));
    
            sw->Write(GetStackTrace(bnt->_thread));
            sw->WriteLine();
            sw->WriteLine();
        }
    }
    
    String* CrashHandler::GetStackTrace(Thread* t)
    {
    
        System::Diagnostics::StackTrace __gc * trace1 = __gc new System::Diagnostics::StackTrace(t, true);
    
        System::String __gc * text1 = System::Environment::NewLine;
        System::Text::StringBuilder __gc * builder1 = __gc new System::Text::StringBuilder(255);
        for (System::Int32 num1 = 0; (num1 < trace1->FrameCount); num1++)
        {
                System::Diagnostics::StackFrame __gc * frame1 = trace1->GetFrame(num1);
                builder1->Append(S"   at ");
                System::Reflection::MethodBase __gc * base1 = frame1->GetMethod();
                System::Type __gc * type1 = base1->DeclaringType;
                if (type1 != 0)
                {
                    System::String __gc * text2 = type1->Namespace;
                    if (text2 != 0)
                    {
                            builder1->Append(text2);
                            if (builder1 != 0)
                            {
                                builder1->Append(S".");
                            }
                    }
                    builder1->Append(type1->Name);
                    builder1->Append(S".");
                }
                builder1->Append(base1->Name);
                builder1->Append(S"(");
                System::Reflection::ParameterInfo __gc * infoArray1 __gc [] = base1->GetParameters();
                for (System::Int32 num2 = 0; (num2 < infoArray1->Length); num2++)
                {
                    System::String __gc * text3 = S"";
                    if (infoArray1[num2]->ParameterType != 0)
                    {
                            text3 = infoArray1[num2]->ParameterType->Name;
                    }
                    builder1->Append(System::String::Concat(((num2 != 0) ? S", " : S""), text3, S" ", infoArray1[num2]->Name));
                }
                builder1->Append(S")");
                if (frame1->GetILOffset() != -1)
                {
                    System::String __gc * text4 = 0;
                    try
                    {
                            text4 = frame1->GetFileName();
                    }
                    catch (System::Security::SecurityException*)
                    {
                    }
                    if (text4 != 0)
                    {
                            builder1->Append(System::String::Concat(S" in ", text4, S":line ", frame1->GetFileLineNumber().ToString()));
                    }
                }
                if (num1 != (trace1->FrameCount - 1))
                {
                    builder1->Append(text1);
                }
        }
        return builder1->ToString();
    
    
    
    }
    

    You can use Process.GetCurrentProcess().Threads to get threads

    And I know i spasted Managed C++ but its easy enough to follow. I take an arraylist of threads because for my purpose I had catagorized my threads. And yes i used previously written stack frame code as I was new to MC++ at the time :)

    The entire file is here. This was for a Diablo II botting engine I wrote some time ago.

提交回复
热议问题