mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 18:43:30 +00:00
[KDGDB]
- Add support for the qfThreadInfo GDB request svn path=/trunk/; revision=64144
This commit is contained in:
parent
7d06aab495
commit
50d072fe6a
4 changed files with 147 additions and 48 deletions
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "kdgdb.h"
|
||||
|
||||
#include <pstypes.h>
|
||||
|
||||
/* LOCALS *********************************************************************/
|
||||
static HANDLE gdb_run_thread;
|
||||
static HANDLE gdb_dbg_process;
|
||||
|
@ -114,7 +116,7 @@ handle_gdb_thread_alive(void)
|
|||
/* q* packets */
|
||||
static
|
||||
void
|
||||
handle_gdb_query(void)
|
||||
handle_gdb_query(_Inout_ PKD_CONTEXT KdContext)
|
||||
{
|
||||
if (strncmp(gdb_input, "qSupported:", 11) == 0)
|
||||
{
|
||||
|
@ -145,10 +147,103 @@ handle_gdb_query(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (strncmp(gdb_input, "qTStatus", 8) == 0)
|
||||
if (strncmp(gdb_input, "qfThreadInfo", 12) == 0)
|
||||
{
|
||||
/* We don't support tracepoints. */
|
||||
send_gdb_packet("T0");
|
||||
LIST_ENTRY* ProcessListHead = (LIST_ENTRY*)KdDebuggerDataBlock->PsActiveProcessHead.Pointer;
|
||||
LIST_ENTRY* ProcessEntry;
|
||||
PEPROCESS Process;
|
||||
|
||||
KDDBGPRINT("ProcessListHead: %p.\n", ProcessListHead);
|
||||
|
||||
/* Maybe this was not initialized yet */
|
||||
if (!ProcessListHead->Flink)
|
||||
{
|
||||
char gdb_out[64];
|
||||
/* Just tell GDB about the current thread */
|
||||
sprintf(gdb_out, "mp%p.%p", PsGetCurrentProcessId(), PsGetCurrentThreadId());
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -409,7 +504,7 @@ gdb_interpret_input(
|
|||
case 'm':
|
||||
return handle_gdb_read_mem(State, MessageData, MessageLength);
|
||||
case 'q':
|
||||
handle_gdb_query();
|
||||
handle_gdb_query(KdContext);
|
||||
break;
|
||||
case 'T':
|
||||
handle_gdb_thread_alive();
|
||||
|
|
|
@ -185,36 +185,3 @@ gdb_send_exception(void)
|
|||
ptr += sprintf(ptr, "core:%x;", CurrentStateChange.Processor);
|
||||
send_gdb_packet(gdb_out);
|
||||
}
|
||||
|
||||
#ifdef KDDEBUG
|
||||
ULONG KdpDbgPrint(const char* Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
CHAR Buffer[512];
|
||||
struct _STRING Str;
|
||||
int Length;
|
||||
|
||||
va_start(ap, Format);
|
||||
Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* Check if we went past the buffer */
|
||||
if (Length == -1)
|
||||
{
|
||||
/* Terminate it if we went over-board */
|
||||
Buffer[sizeof(Buffer) - 1] = '\n';
|
||||
|
||||
/* Put maximum */
|
||||
Length = sizeof(Buffer);
|
||||
}
|
||||
|
||||
Str.Buffer = Buffer;
|
||||
Str.Length = Length;
|
||||
Str.MaximumLength = sizeof(Buffer);
|
||||
|
||||
gdb_send_debug_io(&Str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -34,8 +34,11 @@ const ULONG BaseArray[] = {0, 0xF1012000};
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
CPPORT KdComPort;
|
||||
ULONG KdComPortIrq = 0; // Not used at the moment.
|
||||
#ifdef KDDEBUG
|
||||
CPPORT KdDebugComPort;
|
||||
ULONG KdDebugComPortIrq = 0; // Not used at the moment.
|
||||
#endif
|
||||
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
@ -77,7 +80,7 @@ KdpPortInitialize(IN ULONG ComPortNumber,
|
|||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = CpInitialize(&KdDebugComPort,
|
||||
Status = CpInitialize(&KdComPort,
|
||||
UlongToPtr(BaseArray[ComPortNumber]),
|
||||
ComPortBaudRate);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -86,7 +89,7 @@ KdpPortInitialize(IN ULONG ComPortNumber,
|
|||
}
|
||||
else
|
||||
{
|
||||
KdComPortInUse = KdDebugComPort.Address;
|
||||
KdComPortInUse = KdComPort.Address;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -107,10 +110,9 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
|||
PCHAR CommandLine, PortString, BaudString, IrqString;
|
||||
ULONG Value;
|
||||
|
||||
/* Check if e have a LoaderBlock */
|
||||
/* Check if we have a LoaderBlock */
|
||||
if (LoaderBlock)
|
||||
{
|
||||
|
||||
/* Get the Command Line */
|
||||
CommandLine = LoaderBlock->LoadOptions;
|
||||
|
||||
|
@ -182,11 +184,16 @@ KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
|||
{
|
||||
/* Read and set it */
|
||||
Value = atol(IrqString + 1);
|
||||
if (Value) KdDebugComPortIrq = Value;
|
||||
if (Value) KdComPortIrq = Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KDDEBUG
|
||||
/* Use DEBUGPORT=COM1 if you want to debug KDGDB, as we use COM2 for debugging it */
|
||||
CpInitialize(&KdDebugComPort, UlongToPtr(BaseArray[2]), DEFAULT_BAUD_RATE);
|
||||
#endif
|
||||
|
||||
/* Initialize the port */
|
||||
return KdpPortInitialize(ComPortNumber, ComPortBaudRate);
|
||||
}
|
||||
|
@ -210,7 +217,7 @@ NTAPI
|
|||
KdpSendByte(_In_ UCHAR Byte)
|
||||
{
|
||||
/* Send the byte */
|
||||
CpPutByte(&KdDebugComPort, Byte);
|
||||
CpPutByte(&KdComPort, Byte);
|
||||
}
|
||||
|
||||
KDSTATUS
|
||||
|
@ -218,7 +225,7 @@ NTAPI
|
|||
KdpPollByte(OUT PUCHAR OutByte)
|
||||
{
|
||||
/* Poll the byte */
|
||||
if (CpGetByte(&KdDebugComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
|
||||
if (CpGetByte(&KdComPort, OutByte, FALSE, FALSE) == CP_GET_SUCCESS)
|
||||
{
|
||||
return KdPacketReceived;
|
||||
}
|
||||
|
@ -233,7 +240,7 @@ NTAPI
|
|||
KdpReceiveByte(_Out_ PUCHAR OutByte)
|
||||
{
|
||||
/* Get the byte */
|
||||
if (CpGetByte(&KdDebugComPort, OutByte, TRUE, FALSE) == CP_GET_SUCCESS)
|
||||
if (CpGetByte(&KdComPort, OutByte, TRUE, FALSE) == CP_GET_SUCCESS)
|
||||
{
|
||||
return KdPacketReceived;
|
||||
}
|
||||
|
@ -266,4 +273,34 @@ KdpPollBreakIn(VOID)
|
|||
return KdPacketTimedOut;
|
||||
}
|
||||
|
||||
#ifdef KDDEBUG
|
||||
ULONG KdpDbgPrint(const char* Format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
static CHAR Buffer[512];
|
||||
char* ptr;
|
||||
int Length;
|
||||
|
||||
va_start(ap, Format);
|
||||
Length = _vsnprintf(Buffer, sizeof(Buffer), Format, ap);
|
||||
va_end(ap);
|
||||
|
||||
/* Check if we went past the buffer */
|
||||
if (Length == -1)
|
||||
{
|
||||
/* Terminate it if we went over-board */
|
||||
Buffer[sizeof(Buffer) - 1] = '\n';
|
||||
|
||||
/* Put maximum */
|
||||
Length = sizeof(Buffer);
|
||||
}
|
||||
|
||||
ptr = Buffer;
|
||||
while (Length--)
|
||||
CpPutByte(&KdDebugComPort, *ptr++);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <windbgkd.h>
|
||||
#include <kddll.h>
|
||||
|
||||
// #define KDDEBUG /* uncomment to enable debugging this dll */
|
||||
#define KDDEBUG /* uncomment to enable debugging this dll */
|
||||
|
||||
#ifndef KDDEBUG
|
||||
#define KDDBGPRINT(...)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue