mirror of
https://github.com/reactos/reactos.git
synced 2025-06-20 07:36:05 +00:00
[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 svn path=/trunk/; revision=64146
This commit is contained in:
parent
38ca96eb96
commit
dcade423c6
1 changed files with 79 additions and 74 deletions
|
@ -14,6 +14,9 @@ static HANDLE gdb_run_thread;
|
||||||
static HANDLE gdb_dbg_process;
|
static HANDLE gdb_dbg_process;
|
||||||
HANDLE gdb_dbg_thread;
|
HANDLE gdb_dbg_thread;
|
||||||
CONTEXT CurrentContext;
|
CONTEXT CurrentContext;
|
||||||
|
/* Keep track of where we are for qfThreadInfo/qsThreadInfo */
|
||||||
|
static LIST_ENTRY* CurrentProcessEntry;
|
||||||
|
static LIST_ENTRY* CurrentThreadEntry;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
static
|
static
|
||||||
|
@ -116,7 +119,11 @@ handle_gdb_thread_alive(void)
|
||||||
/* q* packets */
|
/* q* packets */
|
||||||
static
|
static
|
||||||
void
|
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)
|
if (strncmp(gdb_input, "qSupported:", 11) == 0)
|
||||||
{
|
{
|
||||||
|
@ -147,57 +154,68 @@ handle_gdb_query(_Inout_ PKD_CONTEXT KdContext)
|
||||||
return;
|
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* ProcessListHead = (LIST_ENTRY*)KdDebuggerDataBlock->PsActiveProcessHead.Pointer;
|
||||||
LIST_ENTRY* ProcessEntry;
|
BOOLEAN FirstThread = TRUE;
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
|
PETHREAD Thread;
|
||||||
KDDBGPRINT("ProcessListHead: %p.\n", ProcessListHead);
|
char gdb_out[1024];
|
||||||
|
char* ptr;
|
||||||
|
BOOLEAN Resuming = strncmp(gdb_input, "qsThreadInfo", 12) == 0;
|
||||||
|
|
||||||
/* Maybe this was not initialized yet */
|
/* Maybe this was not initialized yet */
|
||||||
if (!ProcessListHead->Flink)
|
if (!ProcessListHead->Flink)
|
||||||
{
|
{
|
||||||
char gdb_out[64];
|
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 */
|
/* Just tell GDB about the current thread */
|
||||||
sprintf(gdb_out, "mp%p.%p", PsGetCurrentProcessId(), PsGetCurrentThreadId());
|
sprintf(gdb_out, "mp%p.%p", PsGetCurrentProcessId(), PsGetCurrentThreadId());
|
||||||
send_gdb_packet(gdb_out);
|
send_gdb_packet(gdb_out);
|
||||||
|
/* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo packet */
|
||||||
gdb_receive_packet(KdContext);
|
gdb_receive_packet(KdContext);
|
||||||
if (strncmp(gdb_input, "qsThreadInfo", 12) != 0)
|
gdb_interpret_input(State, MessageData, MessageLength, KdContext);
|
||||||
{
|
return;
|
||||||
// KdAssert
|
|
||||||
KDDBGPRINT("Received %s instead of qsThreadInfo!\n", gdb_input);
|
|
||||||
while(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Resuming)
|
||||||
|
{
|
||||||
|
if (CurrentThreadEntry == NULL)
|
||||||
|
CurrentProcessEntry = CurrentProcessEntry->Flink;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentProcessEntry = ProcessListHead->Flink;
|
||||||
|
|
||||||
|
if (CurrentProcessEntry == ProcessListHead)
|
||||||
|
{
|
||||||
|
/* We're done */
|
||||||
send_gdb_packet("l");
|
send_gdb_packet("l");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* List all processes */
|
Process = CONTAINING_RECORD(CurrentProcessEntry, EPROCESS, ActiveProcessLinks);
|
||||||
for (ProcessEntry = ProcessListHead->Flink;
|
|
||||||
ProcessEntry != ProcessListHead;
|
if (Resuming && CurrentThreadEntry != NULL)
|
||||||
ProcessEntry = ProcessEntry->Flink)
|
CurrentThreadEntry = CurrentThreadEntry->Flink;
|
||||||
{
|
else
|
||||||
BOOLEAN FirstThread = TRUE;
|
CurrentThreadEntry = Process->ThreadListHead.Flink;
|
||||||
LIST_ENTRY* ThreadEntry;
|
|
||||||
PETHREAD Thread;
|
|
||||||
static char gdb_out[1024];
|
|
||||||
char* ptr;
|
|
||||||
|
|
||||||
ptr = gdb_out;
|
ptr = gdb_out;
|
||||||
Process = CONTAINING_RECORD(ProcessEntry, EPROCESS, ActiveProcessLinks);
|
|
||||||
|
|
||||||
KDDBGPRINT("gdb_out %p.\n", gdb_out);
|
|
||||||
|
|
||||||
*ptr++ = 'm';
|
*ptr++ = 'm';
|
||||||
/* List threads from this process */
|
/* List threads from this process */
|
||||||
for (ThreadEntry = Process->ThreadListHead.Flink;
|
for ( ;
|
||||||
ThreadEntry != &Process->ThreadListHead;
|
CurrentThreadEntry != &Process->ThreadListHead;
|
||||||
ThreadEntry = ThreadEntry->Flink)
|
CurrentThreadEntry = CurrentThreadEntry->Flink)
|
||||||
{
|
{
|
||||||
Thread = CONTAINING_RECORD(ThreadEntry, ETHREAD, ThreadListEntry);
|
Thread = CONTAINING_RECORD(CurrentThreadEntry, ETHREAD, ThreadListEntry);
|
||||||
|
|
||||||
KDDBGPRINT("ptr %p.\n", ptr);
|
|
||||||
|
|
||||||
/* See if we should add a comma */
|
/* See if we should add a comma */
|
||||||
if (FirstThread)
|
if (FirstThread)
|
||||||
|
@ -214,36 +232,20 @@ handle_gdb_query(_Inout_ PKD_CONTEXT KdContext)
|
||||||
if (ptr > (gdb_out + 1024))
|
if (ptr > (gdb_out + 1024))
|
||||||
{
|
{
|
||||||
/* send what we got */
|
/* send what we got */
|
||||||
KDDBGPRINT("Sending %s.\n", gdb_out);
|
|
||||||
send_gdb_packet(gdb_out);
|
send_gdb_packet(gdb_out);
|
||||||
|
/* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo packet */
|
||||||
gdb_receive_packet(KdContext);
|
gdb_receive_packet(KdContext);
|
||||||
if (strncmp(gdb_input, "qsThreadInfo", 12) != 0)
|
gdb_interpret_input(State, MessageData, MessageLength, KdContext);
|
||||||
{
|
return;
|
||||||
// KdAssert
|
|
||||||
KDDBGPRINT("Received %s instead of qsThreadInfo!\n", gdb_input);
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
/* Start anew */
|
|
||||||
ptr = gdb_out;
|
|
||||||
*ptr++ = 'm';
|
|
||||||
FirstThread = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send the list for this process */
|
/* send the list for this process */
|
||||||
KDDBGPRINT("Sending %s.\n", gdb_out);
|
|
||||||
send_gdb_packet(gdb_out);
|
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_receive_packet(KdContext);
|
||||||
if (strncmp(gdb_input, "qsThreadInfo", 12) != 0)
|
gdb_interpret_input(State, MessageData, MessageLength, KdContext);
|
||||||
{
|
|
||||||
// KdAssert
|
|
||||||
KDDBGPRINT("Received %s instead of qsThreadInfo!\n", gdb_input);
|
|
||||||
while(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We're done. Send end-of-list packet */
|
|
||||||
send_gdb_packet("l");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,6 +351,7 @@ GetCurrentContextSendHandler(
|
||||||
|
|
||||||
/* Just copy it */
|
/* Just copy it */
|
||||||
RtlCopyMemory(&CurrentContext, Context, sizeof(*Context));
|
RtlCopyMemory(&CurrentContext, Context, sizeof(*Context));
|
||||||
|
KdpSendPacketHandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -390,6 +393,8 @@ SetContextSendHandler(
|
||||||
/* Should we bugcheck ? */
|
/* Should we bugcheck ? */
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KdpSendPacketHandler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -537,7 +542,7 @@ gdb_interpret_input(
|
||||||
case 'm':
|
case 'm':
|
||||||
return handle_gdb_read_mem(State, MessageData, MessageLength);
|
return handle_gdb_read_mem(State, MessageData, MessageLength);
|
||||||
case 'q':
|
case 'q':
|
||||||
handle_gdb_query(KdContext);
|
handle_gdb_query(State, MessageData, MessageLength, KdContext);
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
handle_gdb_thread_alive();
|
handle_gdb_thread_alive();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue