Author: jgardou
Date: Sun Sep 14 14:28:05 2014
New Revision: 64146
URL:
http://svn.reactos.org/svn/reactos?rev=64146&view=rev
Log:
[KDGDB]
- It can happen that GDB issues something else than qsThreadInfo after qfThreadInfo
- Properly clean up the callbacks after handling a custom Send/ManipulateState loop
Modified:
trunk/reactos/drivers/base/kdgdb/gdb_input.c
Modified: trunk/reactos/drivers/base/kdgdb/gdb_input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/gdb_inp…
==============================================================================
--- trunk/reactos/drivers/base/kdgdb/gdb_input.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/base/kdgdb/gdb_input.c [iso-8859-1] Sun Sep 14 14:28:05 2014
@@ -14,6 +14,9 @@
static HANDLE gdb_dbg_process;
HANDLE gdb_dbg_thread;
CONTEXT CurrentContext;
+/* Keep track of where we are for qfThreadInfo/qsThreadInfo */
+static LIST_ENTRY* CurrentProcessEntry;
+static LIST_ENTRY* CurrentThreadEntry;
/* PRIVATE FUNCTIONS **********************************************************/
static
@@ -116,7 +119,11 @@
/* q* packets */
static
void
-handle_gdb_query(_Inout_ PKD_CONTEXT KdContext)
+handle_gdb_query(
+ _Out_ DBGKD_MANIPULATE_STATE64* State,
+ _Out_ PSTRING MessageData,
+ _Out_ PULONG MessageLength,
+ _Inout_ PKD_CONTEXT KdContext)
{
if (strncmp(gdb_input, "qSupported:", 11) == 0)
{
@@ -147,103 +154,98 @@
return;
}
- if (strncmp(gdb_input, "qfThreadInfo", 12) == 0)
+ if ((strncmp(gdb_input, "qfThreadInfo", 12) == 0)
+ || (strncmp(gdb_input, "qsThreadInfo", 12) == 0))
{
LIST_ENTRY* ProcessListHead =
(LIST_ENTRY*)KdDebuggerDataBlock->PsActiveProcessHead.Pointer;
- LIST_ENTRY* ProcessEntry;
+ BOOLEAN FirstThread = TRUE;
PEPROCESS Process;
-
- KDDBGPRINT("ProcessListHead: %p.\n", ProcessListHead);
+ PETHREAD Thread;
+ char gdb_out[1024];
+ char* ptr;
+ BOOLEAN Resuming = strncmp(gdb_input, "qsThreadInfo", 12) == 0;
/* Maybe this was not initialized yet */
if (!ProcessListHead->Flink)
{
char gdb_out[64];
+
+ if (Resuming)
+ {
+ /* there is only one thread to tell about */
+ send_gdb_packet("l");
+ return;
+ }
/* Just tell GDB about the current thread */
sprintf(gdb_out, "mp%p.%p", PsGetCurrentProcessId(),
PsGetCurrentThreadId());
send_gdb_packet(gdb_out);
+ /* GDB can ask anything at this point, it isn't necessarily a
qsThreadInfo packet */
gdb_receive_packet(KdContext);
- if (strncmp(gdb_input, "qsThreadInfo", 12) != 0)
- {
- // KdAssert
- KDDBGPRINT("Received %s instead of qsThreadInfo!\n",
gdb_input);
- while(1);
- }
+ gdb_interpret_input(State, MessageData, MessageLength, KdContext);
+ return;
+ }
+
+ if (Resuming)
+ {
+ if (CurrentThreadEntry == NULL)
+ CurrentProcessEntry = CurrentProcessEntry->Flink;
+ }
+ else
+ CurrentProcessEntry = ProcessListHead->Flink;
+
+ if (CurrentProcessEntry == ProcessListHead)
+ {
+ /* We're done */
send_gdb_packet("l");
return;
}
- /* List all processes */
- for (ProcessEntry = ProcessListHead->Flink;
- ProcessEntry != ProcessListHead;
- ProcessEntry = ProcessEntry->Flink)
- {
- BOOLEAN FirstThread = TRUE;
- LIST_ENTRY* ThreadEntry;
- PETHREAD Thread;
- static char gdb_out[1024];
- char* ptr;
-
- ptr = gdb_out;
- Process = CONTAINING_RECORD(ProcessEntry, EPROCESS, ActiveProcessLinks);
-
- KDDBGPRINT("gdb_out %p.\n", gdb_out);
-
- *ptr++ = 'm';
- /* List threads from this process */
- for (ThreadEntry = Process->ThreadListHead.Flink;
- ThreadEntry != &Process->ThreadListHead;
- ThreadEntry = ThreadEntry->Flink)
+ Process = CONTAINING_RECORD(CurrentProcessEntry, EPROCESS, ActiveProcessLinks);
+
+ if (Resuming && CurrentThreadEntry != NULL)
+ CurrentThreadEntry = CurrentThreadEntry->Flink;
+ else
+ CurrentThreadEntry = Process->ThreadListHead.Flink;
+
+ ptr = gdb_out;
+
+ *ptr++ = 'm';
+ /* List threads from this process */
+ for ( ;
+ CurrentThreadEntry != &Process->ThreadListHead;
+ CurrentThreadEntry = CurrentThreadEntry->Flink)
+ {
+ Thread = CONTAINING_RECORD(CurrentThreadEntry, ETHREAD, ThreadListEntry);
+
+ /* See if we should add a comma */
+ if (FirstThread)
{
- Thread = CONTAINING_RECORD(ThreadEntry, ETHREAD, ThreadListEntry);
-
- KDDBGPRINT("ptr %p.\n", ptr);
-
- /* See if we should add a comma */
- if (FirstThread)
- {
- FirstThread = FALSE;
- }
- else
- {
- *ptr++ = ',';
- }
-
- ptr += _snprintf(ptr, 1024 - (ptr - gdb_out),
- "p%p.%p", PsGetProcessId(Process), PsGetThreadId(Thread));
- if (ptr > (gdb_out + 1024))
- {
- /* send what we got */
- KDDBGPRINT("Sending %s.\n", gdb_out);
- send_gdb_packet(gdb_out);
- gdb_receive_packet(KdContext);
- if (strncmp(gdb_input, "qsThreadInfo", 12) != 0)
- {
- // KdAssert
- KDDBGPRINT("Received %s instead of qsThreadInfo!\n",
gdb_input);
- while(1);
- }
- /* Start anew */
- ptr = gdb_out;
- *ptr++ = 'm';
- FirstThread = TRUE;
- }
+ FirstThread = FALSE;
}
-
- /* send the list for this process */
- KDDBGPRINT("Sending %s.\n", gdb_out);
- send_gdb_packet(gdb_out);
- gdb_receive_packet(KdContext);
- if (strncmp(gdb_input, "qsThreadInfo", 12) != 0)
+ else
{
- // KdAssert
- KDDBGPRINT("Received %s instead of qsThreadInfo!\n",
gdb_input);
- while(1);
+ *ptr++ = ',';
}
- }
-
- /* We're done. Send end-of-list packet */
- send_gdb_packet("l");
+
+ ptr += _snprintf(ptr, 1024 - (ptr - gdb_out),
+ "p%p.%p", PsGetProcessId(Process), PsGetThreadId(Thread));
+ if (ptr > (gdb_out + 1024))
+ {
+ /* send what we got */
+ send_gdb_packet(gdb_out);
+ /* GDB can ask anything at this point, it isn't necessarily a
qsThreadInfo packet */
+ gdb_receive_packet(KdContext);
+ gdb_interpret_input(State, MessageData, MessageLength, KdContext);
+ return;
+ }
+ }
+
+ /* send the list for this process */
+ send_gdb_packet(gdb_out);
+ CurrentThreadEntry = NULL;
+ /* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo
packet */
+ gdb_receive_packet(KdContext);
+ gdb_interpret_input(State, MessageData, MessageLength, KdContext);
return;
}
@@ -349,6 +351,7 @@
/* Just copy it */
RtlCopyMemory(&CurrentContext, Context, sizeof(*Context));
+ KdpSendPacketHandler = NULL;
}
static
@@ -390,6 +393,8 @@
/* Should we bugcheck ? */
while (1);
}
+
+ KdpSendPacketHandler = NULL;
}
static
@@ -537,7 +542,7 @@
case 'm':
return handle_gdb_read_mem(State, MessageData, MessageLength);
case 'q':
- handle_gdb_query(KdContext);
+ handle_gdb_query(State, MessageData, MessageLength, KdContext);
break;
case 'T':
handle_gdb_thread_alive();