diff --git a/src/plugins/dbg/library.cpp b/src/plugins/dbg/library.cpp index c7c72c1dc4..fdda7b3ab3 100644 --- a/src/plugins/dbg/library.cpp +++ b/src/plugins/dbg/library.cpp @@ -45,9 +45,10 @@ EXT_COMMAND( } Registration Registration = Registration::FromLink(LinkAddr); - Dml("\t0x%I64X\t\"%s\"\n", + Dml("\t0x%I64X\t%s\t\t\"%s\"\n", Registration.Addr, Registration.Addr, + Registration.GetWorkersState(), Registration.GetAppName().Data); HasAtLeastOne = true; } diff --git a/src/plugins/dbg/quictypes.h b/src/plugins/dbg/quictypes.h index 7ec2c3b870..5db0588746 100644 --- a/src/plugins/dbg/quictypes.h +++ b/src/plugins/dbg/quictypes.h @@ -1303,6 +1303,28 @@ struct Listener : Struct { } }; +struct CxPlatWorker : Struct { + + CxPlatWorker(ULONG64 Addr) : Struct("msquic!CXPLAT_WORKER", Addr) { } + + ULONG64 Thread() { + return ReadPointer("Thread"); + } +}; + +struct CxPlatExecutionContext : Struct { + + CxPlatExecutionContext(ULONG64 Addr) : Struct("msquic!CXPLAT_EXECUTION_CONTEXT", Addr) { } + + ULONG64 CxPlatContext() { + return ReadPointer("CxPlatContext"); + } + + CxPlatWorker GetCxPlatWorker() { + return CxPlatWorker(CxPlatContext()); + } +}; + struct Worker : Struct { Worker(ULONG64 Addr) : Struct("msquic!QUIC_WORKER", Addr) { } @@ -1315,12 +1337,15 @@ struct Worker : Struct { return ReadType("IsActive"); } + bool HasWorkQueue() { + return !GetConnections().IsEmpty() || !GetOperations().IsEmpty(); + } + PSTR StateStr() { - bool HasWorkQueue = !GetConnections().IsEmpty() || !GetOperations().IsEmpty(); if (IsActive()) { - return HasWorkQueue ? "ACTIVE (+queue)" : "ACTIVE"; + return HasWorkQueue() ? "ACTIVE (+queue)" : "ACTIVE (no queue)"; } else { - return HasWorkQueue ? "QUEUE" : "IDLE"; + return HasWorkQueue() ? "QUEUE" : "IDLE (no queue)"; } } @@ -1328,12 +1353,16 @@ struct Worker : Struct { return ReadType("PartitionIndex"); } - UINT32 ThreadID() { - return ReadType("ThreadID"); + CxPlatExecutionContext GetCxPlatExecutionContext() { + return CxPlatExecutionContext(AddrOf("ExecutionContext")); } ULONG64 Thread() { - return ReadPointer("Thread"); + ULONG64 thread = ReadPointer("Thread"); + if (!thread) { + thread = GetCxPlatExecutionContext().GetCxPlatWorker().Thread(); + } + return thread; } LinkedList GetConnections() { @@ -1429,6 +1458,21 @@ struct Registration : Struct { String GetAppName() { return String(AddrOf("AppName")); } + + PSTR GetWorkersState() { + auto Workers = GetWorkerPool(); + UCHAR WorkerCount = Workers.WorkerCount(); + bool HasQueuedWorker = false; + for (UCHAR i = 0; i < WorkerCount; i++) { + if (Workers.GetWorker(i).IsActive()) { + return "ACTIVE"; + } + if (Workers.GetWorker(i).HasWorkQueue()) { + HasQueuedWorker = true; + } + } + return HasQueuedWorker ? "QUEUED" : " IDLE"; + } }; struct LookupHashTable : Struct { diff --git a/src/plugins/dbg/worker.cpp b/src/plugins/dbg/worker.cpp index 2311063093..e8440a9706 100644 --- a/src/plugins/dbg/worker.cpp +++ b/src/plugins/dbg/worker.cpp @@ -24,12 +24,11 @@ EXT_COMMAND( "\n" "\tState %s\n" "\tPartition %u\n" - "\tThread 0x%X (UM/KM)\n", + "\tThread 0x%X\n", Work.Addr, Work.StateStr(), Work.PartitionIndex(), - Work.ThreadID(), - Work.ThreadID(), + Work.Thread(), Work.Thread()); Dml("\nQUEUE\n"