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"