- Turn this thing into something useful
   - Pretend we are only one process to GDB (making it a kernel-only debugger...) until the GDB team sorts this out
   - This is a kernel debugger stub you know. You didn't seriously pretend that recursive functions would be fine, did you ?
[NTOS:KD64]
 - Fix build
Pix or it din't happen : https://jira.reactos.org/secure/attachment/36322/source_level_debugging_ros.png

svn path=/trunk/; revision=72077
This commit is contained in:
Jérôme Gardou 2016-08-01 22:16:58 +00:00
parent 0f196e05cc
commit 9bb0e5a772
9 changed files with 373 additions and 182 deletions

View file

@ -9,9 +9,7 @@
/* LOCALS *********************************************************************/
static ULONG_PTR gdb_run_tid;
/* Keep track of where we are for qfThreadInfo/qsThreadInfo */
static LIST_ENTRY* CurrentProcessEntry;
static LIST_ENTRY* CurrentThreadEntry;
/* GLOBALS ********************************************************************/
UINT_PTR gdb_dbg_pid;
@ -69,6 +67,17 @@ handle_gdb_set_thread(void)
break;
case 'g':
KDDBGPRINT("Setting debug thread: %s.\n", gdb_input);
#if MONOPROCESS
gdb_dbg_pid = 0;
if (strncmp(&gdb_input[2], "-1", 2) == 0)
{
gdb_dbg_tid = (UINT_PTR)-1;
}
else
{
gdb_dbg_tid = hex_to_tid(&gdb_input[2]);
}
#else
if (strncmp(&gdb_input[2], "p-1", 3) == 0)
{
gdb_dbg_pid = (UINT_PTR)-1;
@ -83,6 +92,7 @@ handle_gdb_set_thread(void)
else
gdb_dbg_tid = hex_to_tid(ptr);
}
#endif
send_gdb_packet("OK");
break;
default:
@ -91,20 +101,6 @@ handle_gdb_set_thread(void)
}
}
KDSTATUS
gdb_receive_and_interpret_packet(
_Out_ DBGKD_MANIPULATE_STATE64* State,
_Out_ PSTRING MessageData,
_Out_ PULONG MessageLength,
_Inout_ PKD_CONTEXT KdContext)
{
KDSTATUS Status = gdb_receive_packet(KdContext);
if (Status != KdPacketReceived)
return Status;
return gdb_interpret_input(State, MessageData, MessageLength, KdContext);
}
static
void
handle_gdb_thread_alive(void)
@ -112,12 +108,20 @@ handle_gdb_thread_alive(void)
ULONG_PTR Pid, Tid;
PETHREAD Thread;
#if MONOPROCESS
Pid = 0;
Tid = hex_to_tid(&gdb_input[1]);
KDDBGPRINT("Checking if %p is alive.\n", Tid);
#else
Pid = hex_to_pid(&gdb_input[2]);
Tid = hex_to_tid(strstr(gdb_input, ".") + 1);
/* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL.
* So loop. */
KDDBGPRINT("Checking if p%p.%p is alive.\n", Pid, Tid);
#endif
Thread = find_thread(Pid, Tid);
@ -129,40 +133,53 @@ handle_gdb_thread_alive(void)
/* q* packets */
static
KDSTATUS
handle_gdb_query(
_Out_ DBGKD_MANIPULATE_STATE64* State,
_Out_ PSTRING MessageData,
_Out_ PULONG MessageLength,
_Inout_ PKD_CONTEXT KdContext)
void
handle_gdb_query(void)
{
if (strncmp(gdb_input, "qSupported:", 11) == 0)
{
send_gdb_packet("PacketSize=4096;multiprocess+;");
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
#if MONOPROCESS
send_gdb_packet("PacketSize=1000;");
#else
send_gdb_packet("PacketSize=1000;multiprocess+;");
#endif
return;
}
if (strncmp(gdb_input, "qAttached", 9) == 0)
{
/* Say no: We didn't attach, we create the process! */
send_gdb_packet("0");
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
#if MONOPROCESS
send_gdb_packet("1");
#else
UINT_PTR queried_pid = hex_to_pid(&gdb_input[10]);
/* Let's say we created system process */
if (gdb_pid_to_handle(queried_pid) == NULL)
send_gdb_packet("0");
else
send_gdb_packet("1");
#endif
return;
}
if (strncmp(gdb_input, "qRcmd,", 6) == 0)
{
send_gdb_packet("OK");
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
return;
}
if (strcmp(gdb_input, "qC") == 0)
{
char gdb_out[64];
#if MONOPROCESS
sprintf(gdb_out, "QC:%"PRIxPTR";",
handle_to_gdb_tid(PsGetThreadId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread)));
#else
sprintf(gdb_out, "QC:p%"PRIxPTR".%"PRIxPTR";",
handle_to_gdb_pid(PsGetThreadProcessId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread)),
handle_to_gdb_tid(PsGetThreadId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread)));
#endif
send_gdb_packet(gdb_out);
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
return;
}
if ((strncmp(gdb_input, "qfThreadInfo", 12) == 0)
@ -174,82 +191,162 @@ handle_gdb_query(
char gdb_out[1024];
char* ptr = gdb_out;
BOOLEAN Resuming = strncmp(gdb_input, "qsThreadInfo", 12) == 0;
if (Resuming)
{
if (CurrentProcessEntry == (LIST_ENTRY*)1)
{
/* We're done */
send_gdb_packet("l");
CurrentProcessEntry = NULL;
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
}
if (CurrentThreadEntry == NULL)
CurrentProcessEntry = CurrentProcessEntry->Flink;
}
else
CurrentProcessEntry = ProcessListHead->Flink;
if ((CurrentProcessEntry == ProcessListHead) ||
(CurrentProcessEntry == NULL)) /* Ps is not initialized */
{
/* We're almost done. Tell GDB about the idle thread */
send_gdb_packet("mp1.1");
CurrentProcessEntry = (LIST_ENTRY*)1;
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
}
Process = CONTAINING_RECORD(CurrentProcessEntry, EPROCESS, ActiveProcessLinks);
if (Resuming && CurrentThreadEntry != NULL)
CurrentThreadEntry = CurrentThreadEntry->Flink;
else
CurrentThreadEntry = Process->ThreadListHead.Flink;
/* Keep track of where we are. */
static LIST_ENTRY* CurrentProcessEntry;
static LIST_ENTRY* CurrentThreadEntry;
ptr = gdb_out;
*ptr++ = 'm';
/* List threads from this process */
for ( ;
CurrentThreadEntry != &Process->ThreadListHead;
CurrentThreadEntry = CurrentThreadEntry->Flink)
/* NULL terminate in case we got nothing more to iterate */
*ptr = '\0';
if (!Resuming)
{
Thread = CONTAINING_RECORD(CurrentThreadEntry, ETHREAD, ThreadListEntry);
/* Initialize the entries */
CurrentProcessEntry = ProcessListHead->Flink;
CurrentThreadEntry = NULL;
/* See if we should add a comma */
if (FirstThread)
{
FirstThread = FALSE;
}
else
{
*ptr++ = ',';
}
ptr += _snprintf(ptr, 1024 - (ptr - gdb_out),
"p%p.%p",
handle_to_gdb_pid(Process->UniqueProcessId),
handle_to_gdb_tid(Thread->Cid.UniqueThread));
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 */
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
}
/* Start with idle thread */
#if MONOPROCESS
ptr = gdb_out + sprintf(gdb_out, "m1");
#else
ptr = gdb_out + sprintf(gdb_out, "mp1.1");
#endif
FirstThread = FALSE;
}
/* send the list for this process */
send_gdb_packet(gdb_out);
CurrentThreadEntry = NULL;
if (CurrentProcessEntry == NULL) /* Ps is not initialized */
{
send_gdb_packet(Resuming ? "l" : gdb_out);
return;
}
/* List all the processes */
for ( ;
CurrentProcessEntry != ProcessListHead;
CurrentProcessEntry = CurrentProcessEntry->Flink)
{
Process = CONTAINING_RECORD(CurrentProcessEntry, EPROCESS, ActiveProcessLinks);
if (CurrentThreadEntry != NULL)
CurrentThreadEntry = CurrentThreadEntry->Flink;
else
CurrentThreadEntry = Process->ThreadListHead.Flink;
/* 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)
{
FirstThread = FALSE;
}
else
{
*ptr++ = ',';
}
#if MONOPROCESS
ptr += _snprintf(ptr, 1024 - (ptr - gdb_out),
"%p",
handle_to_gdb_tid(Thread->Cid.UniqueThread));
#else
ptr += _snprintf(ptr, 1024 - (ptr - gdb_out),
"p%p.%p",
handle_to_gdb_pid(Process->UniqueProcessId),
handle_to_gdb_tid(Thread->Cid.UniqueThread));
#endif
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 */
return;
}
}
/* We're done for this process */
CurrentThreadEntry = NULL;
}
if (gdb_out[1] == '\0')
{
/* We didn't iterate over anything, meaning we were already done */
send_gdb_packet("l");
}
else
{
send_gdb_packet(gdb_out);
}
/* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo packet */
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
return;
}
if (strncmp(gdb_input, "qThreadExtraInfo,", 17) == 0)
{
ULONG_PTR Pid, Tid;
PETHREAD Thread;
PEPROCESS Process;
char out_string[64];
STRING String = {0, 64, out_string};
KDDBGPRINT("Giving extra info for");
#if MONOPROCESS
Pid = 0;
Tid = hex_to_tid(&gdb_input[17]);
KDDBGPRINT(" %p.\n", Tid);
Thread = find_thread(Pid, Tid);
Process = CONTAINING_RECORD(Thread->Tcb.Process, EPROCESS, Pcb);
#else
Pid = hex_to_pid(&gdb_input[2]);
Tid = hex_to_tid(strstr(gdb_input, ".") + 1);
/* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL.
* So loop. */
KDDBGPRINT(" p%p.%p.\n", Pid, Tid);
Process = find_process(Pid);
Thread = find_thread(Pid, Tid);
#endif
if (PsGetThreadProcessId(Thread) == 0)
{
String.Length = sprintf(out_string, "SYSTEM");
}
else
{
String.Length = sprintf(out_string, "%.*s", 16, Process->ImageFileName);
}
gdb_send_debug_io(&String, FALSE);
return;
}
if (strncmp(gdb_input, "qOffsets", 8) == 0)
{
/* We load ntoskrnl at 0x80800000 while compiling it at 0x00800000 base adress */
send_gdb_packet("TextSeg=80000000");
return;
}
if (strcmp(gdb_input, "qTStatus") == 0)
{
/* No tracepoint support */
send_gdb_packet("T0");
return;
}
KDDBGPRINT("KDGDB: Unknown query: %s\n", gdb_input);
send_gdb_packet("");
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
return;
}
#if 0
@ -305,11 +402,13 @@ ReadMemorySendHandler(
KdpSendPacketHandler = NULL;
KdpManipulateStateHandler = NULL;
#if !MONOPROCESS
/* Reset the TLB */
if ((gdb_dbg_pid != 0) && gdb_pid_to_handle(gdb_dbg_pid) != PsGetCurrentProcessId())
{
__writecr3(PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]);
}
#endif
}
static
@ -328,6 +427,7 @@ handle_gdb_read_mem(
MessageData->Length = 0;
*MessageLength = 0;
#if !MONOPROCESS
/* Set the TLB according to the process being read. Pid 0 means any process. */
if ((gdb_dbg_pid != 0) && gdb_pid_to_handle(gdb_dbg_pid) != PsGetCurrentProcessId())
{
@ -340,6 +440,7 @@ handle_gdb_read_mem(
}
__writecr3(AttachedProcess->Pcb.DirectoryTableBase[0]);
}
#endif
State->u.ReadMemory.TargetBaseAddress = hex_to_address(&gdb_input[1]);
State->u.ReadMemory.TransferCount = hex_to_address(strstr(&gdb_input[1], ",") + 1);
@ -362,16 +463,12 @@ handle_gdb_v(
{
if (gdb_input[5] == '?')
{
KDSTATUS Status;
/* Report what we support */
send_gdb_packet("vCont;c;C;s;S");
Status = gdb_receive_packet(KdContext);
if (Status != KdPacketReceived)
return Status;
return gdb_interpret_input(State, MessageData, MessageLength, KdContext);
return (KDSTATUS)-1;
}
if (strcmp(gdb_input, "vCont;c") == 0)
if (strncmp(gdb_input, "vCont;c", 7) == 0)
{
DBGKM_EXCEPTION64* Exception = NULL;
@ -404,41 +501,63 @@ handle_gdb_v(
return KdPacketReceived;
}
/* GLOBAL FUNCTIONS ***********************************************************/
KDSTATUS
gdb_interpret_input(
gdb_receive_and_interpret_packet(
_Out_ DBGKD_MANIPULATE_STATE64* State,
_Out_ PSTRING MessageData,
_Out_ PULONG MessageLength,
_Inout_ PKD_CONTEXT KdContext)
{
switch (gdb_input[0])
KDSTATUS Status;
do
{
case '?':
/* Send the Status */
gdb_send_exception();
break;
case 'g':
return gdb_send_registers(State, MessageData, MessageLength, KdContext);
case 'H':
handle_gdb_set_thread();
break;
case 'm':
return handle_gdb_read_mem(State, MessageData, MessageLength, KdContext);
case 'p':
return gdb_send_register(State, MessageData, MessageLength, KdContext);
case 'q':
return handle_gdb_query(State, MessageData, MessageLength, KdContext);
case 'T':
handle_gdb_thread_alive();
break;
case 'v':
return handle_gdb_v(State, MessageData, MessageLength, KdContext);
default:
/* We don't know how to handle this request. Maybe this is something for KD */
State->ReturnStatus = STATUS_NOT_SUPPORTED;
KDDBGPRINT("Unsupported GDB command: %s.\n", gdb_input);
return KdPacketReceived;
}
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
Status = gdb_receive_packet(KdContext);
KDDBGPRINT("KDGBD: Packet received with status %u\n", Status);
if (Status != KdPacketReceived)
return Status;
Status = (KDSTATUS)-1;
switch (gdb_input[0])
{
case '?':
/* Send the Status */
gdb_send_exception(TRUE);
break;
case '!':
send_gdb_packet("OK");
break;
case 'g':
gdb_send_registers();
break;
case 'H':
handle_gdb_set_thread();
break;
case 'm':
Status = handle_gdb_read_mem(State, MessageData, MessageLength, KdContext);
break;
case 'p':
gdb_send_register();
break;
case 'q':
handle_gdb_query();
break;
case 'T':
handle_gdb_thread_alive();
break;
case 'v':
Status = handle_gdb_v(State, MessageData, MessageLength, KdContext);
break;
default:
/* We don't know how to handle this request. Maybe this is something for KD */
State->ReturnStatus = STATUS_NOT_SUPPORTED;
KDDBGPRINT("Unsupported GDB command: %s.\n", gdb_input);
return KdPacketReceived;
}
} while (Status == (KDSTATUS)-1);
return Status;
}

View file

@ -42,6 +42,7 @@ gdb_receive_packet(_Inout_ PKD_CONTEXT KdContext)
return Status;
if (Byte == 0x03)
{
KDDBGPRINT("BREAK!");
KdContext->KdpControlCPending = TRUE;
return KdPacketNeedsResend;
}

View file

@ -123,22 +123,26 @@ send_gdb_memory(
void
gdb_send_debug_io(
_In_ PSTRING String)
_In_ PSTRING String,
_In_ BOOLEAN WithPrefix)
{
UCHAR ack;
do {
CHAR* ptr = String->Buffer;
CHAR check_sum;
CHAR check_sum = 0;
USHORT Length = String->Length;
CHAR Byte;
KdpSendByte('$');
KdpSendByte('O');
if (WithPrefix)
{
KdpSendByte('O');
check_sum = 'O';
}
/* Send the data */
check_sum = 'O';
while (Length--)
{
Byte = hex_chars[(*ptr >> 4) & 0xf];
@ -164,7 +168,7 @@ gdb_send_debug_io(
}
void
gdb_send_exception(void)
gdb_send_exception(BOOLEAN WithThread)
{
char gdb_out[1024];
char* ptr = gdb_out;
@ -180,11 +184,20 @@ gdb_send_exception(void)
}
else
ptr += sprintf(ptr, "05");
ptr += sprintf(ptr, "thread:p%" PRIxPTR ".%" PRIxPTR ";",
handle_to_gdb_pid(PsGetThreadProcessId(Thread)),
handle_to_gdb_tid(PsGetThreadId(Thread)));
if (WithThread)
{
#if MONOPROCESS
ptr += sprintf(ptr, "thread:%" PRIxPTR ";",
handle_to_gdb_tid(PsGetThreadId(Thread)));
#else
ptr += sprintf(ptr, "thread:p%" PRIxPTR ".%" PRIxPTR ";",
handle_to_gdb_pid(PsGetThreadProcessId(Thread)),
handle_to_gdb_tid(PsGetThreadId(Thread)));
#endif
}
ptr += sprintf(ptr, "core:%x;", CurrentStateChange.Processor);
/* Add program counter */
gdb_append_pc_to_exception(Thread, ptr);
send_gdb_packet(gdb_out);
}

View file

@ -93,6 +93,7 @@ thread_to_reg(PETHREAD Thread, enum reg_name reg_name, unsigned short* size)
case ESP:
case EBP:
case EIP:
KDDBGPRINT("Returning NULL for register %d.\n", reg_name);
*size = 4;
return &NullValue;
default:
@ -143,12 +144,8 @@ thread_to_reg(PETHREAD Thread, enum reg_name reg_name, unsigned short* size)
return NULL;
}
KDSTATUS
gdb_send_registers(
_Out_ DBGKD_MANIPULATE_STATE64* State,
_Out_ PSTRING MessageData,
_Out_ PULONG MessageLength,
_Inout_ PKD_CONTEXT KdContext)
void
gdb_send_registers(void)
{
CHAR Registers[16*8 + 1];
UCHAR* RegisterPtr;
@ -184,7 +181,7 @@ gdb_send_registers(
{
/* Thread is dead */
send_gdb_packet("E03");
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
return;
}
for(i=0; i < 16; i++)
@ -209,15 +206,10 @@ gdb_send_registers(
}
*ptr = '\0';
send_gdb_packet(Registers);
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
}
KDSTATUS
gdb_send_register(
_Out_ DBGKD_MANIPULATE_STATE64* State,
_Out_ PSTRING MessageData,
_Out_ PULONG MessageLength,
_Inout_ PKD_CONTEXT KdContext)
void
gdb_send_register(void)
{
enum reg_name reg_name;
void *ptr;
@ -242,7 +234,7 @@ gdb_send_register(
{
/* Thread is dead */
send_gdb_packet("E03");
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
return;
}
ptr = thread_to_reg(DbgThread, reg_name, &size);
@ -257,6 +249,30 @@ gdb_send_register(
{
send_gdb_memory(ptr, size);
}
return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
}
char*
gdb_append_pc_to_exception(
_In_ PETHREAD Thread,
_Inout_ char* ptr)
{
/* Get EIP */
unsigned short ptrSize;
unsigned char* EipPtr = thread_to_reg(Thread, EIP, &ptrSize);
/* Print it */
ptr += sprintf(ptr, "08:");
*ptr++ = hex_chars[EipPtr[0] >> 4];
*ptr++ = hex_chars[EipPtr[0] & 0xF];
*ptr++ = hex_chars[EipPtr[1] >> 4];
*ptr++ = hex_chars[EipPtr[1] & 0xF];
*ptr++ = hex_chars[EipPtr[2] >> 4];
*ptr++ = hex_chars[EipPtr[2] & 0xF];
*ptr++ = hex_chars[EipPtr[3] >> 4];
*ptr++ = hex_chars[EipPtr[3] & 0xF];
*ptr++ = ';';
*ptr++ = '\0';
return ptr;
}

View file

@ -296,15 +296,15 @@ KDSTATUS
NTAPI
KdpReceiveByte(_Out_ PUCHAR OutByte)
{
USHORT CpStatus = CpGetByte(&KdComPort, OutByte, TRUE, FALSE);
/* Get the byte */
if (CpGetByte(&KdComPort, OutByte, TRUE, FALSE) == CP_GET_SUCCESS)
if (CpStatus == CP_GET_SUCCESS)
{
return KdPacketReceived;
}
else
{
return KdPacketTimedOut;
}
KDDBGPRINT("CpGetByte returned %u.\n", CpStatus);
return KdPacketTimedOut;
}
KDSTATUS
@ -319,6 +319,7 @@ KdpPollBreakIn(VOID)
{
if (Byte == 0x03)
{
KDDBGPRINT("BreakIn Polled.\n");
return KdPacketReceived;
}
else if (Byte == '$')

View file

@ -21,6 +21,9 @@
#define KDDEBUG /* uncomment to enable debugging this dll */
/* To undefine once https://sourceware.org/bugzilla/show_bug.cgi?id=17397 is resolved */
#define MONOPROCESS 1
#ifndef KDDEBUG
#define KDDBGPRINT(...)
#else
@ -34,6 +37,7 @@ FORCEINLINE HANDLE gdb_tid_to_handle(UINT_PTR Tid)
return (HANDLE)(Tid - 1);
}
#define gdb_pid_to_handle gdb_tid_to_handle
FORCEINLINE UINT_PTR handle_to_gdb_tid(HANDLE Handle)
{
return (UINT_PTR)Handle + 1;
@ -68,7 +72,6 @@ typedef KDSTATUS (*KDP_MANIPULATESTATE_HANDLER)(
/* gdb_input.c */
extern UINT_PTR gdb_dbg_tid;
extern UINT_PTR gdb_dbg_pid;
extern KDSTATUS gdb_interpret_input(_Out_ DBGKD_MANIPULATE_STATE64* State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext);
extern KDSTATUS gdb_receive_and_interpret_packet(_Out_ DBGKD_MANIPULATE_STATE64* State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext);
/* gdb_receive.c */
@ -79,8 +82,8 @@ char hex_value(char ch);
/* gdb_send.c */
void send_gdb_packet(_In_ CHAR* Buffer);
void send_gdb_memory(_In_ VOID* Buffer, size_t Length);
void gdb_send_debug_io(_In_ PSTRING String);
void gdb_send_exception(void);
void gdb_send_debug_io(_In_ PSTRING String, _In_ BOOLEAN WithPrefix);
void gdb_send_exception(BOOLEAN WithThread);
void send_gdb_ntstatus(_In_ NTSTATUS Status);
extern const char hex_chars[];
@ -108,8 +111,9 @@ extern PEPROCESS find_process( _In_ UINT_PTR Pid);
extern PETHREAD find_thread(_In_ UINT_PTR Pid, _In_ UINT_PTR Tid);
/* arch_sup.c */
extern KDSTATUS gdb_send_register(_Out_ DBGKD_MANIPULATE_STATE64* State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext);
extern KDSTATUS gdb_send_registers(_Out_ DBGKD_MANIPULATE_STATE64* State, _Out_ PSTRING MessageData, _Out_ PULONG MessageLength, _Inout_ PKD_CONTEXT KdContext);
extern void gdb_send_register(void);
extern void gdb_send_registers(void);
extern char* gdb_append_pc_to_exception(_In_ PETHREAD Thread, _Inout_ char* ptr);
/* Architecture specific defines. See ntoskrnl/include/internal/arch/ke.h */
#ifdef _M_IX86

View file

@ -94,6 +94,7 @@ SetContextSendHandler(
|| (State->ReturnStatus != STATUS_SUCCESS))
{
/* Should we bugcheck ? */
KDDBGPRINT("BAD BAD BAD not manipulating state for sending context.\n");
while (1);
}
@ -116,6 +117,7 @@ SetContextManipulateHandler(
if (MessageData->MaximumLength < sizeof(CurrentContext))
{
KDDBGPRINT("Wrong message length %u.\n", MessageData->MaximumLength);
while (1);
}
@ -153,14 +155,18 @@ send_kd_state_change(DBGKD_ANY_WAIT_STATE_CHANGE* StateChange)
PsGetThreadId(Thread));
/* Set the current debugged process/thread accordingly */
gdb_dbg_tid = handle_to_gdb_tid(PsGetThreadId(Thread));
#if MONOPROCESS
gdb_dbg_pid = 0;
#else
gdb_dbg_pid = handle_to_gdb_pid(PsGetThreadProcessId(Thread));
gdb_send_exception();
#endif
gdb_send_exception(FALSE);
/* Next receive call will ask for the context */
KdpManipulateStateHandler = GetContextManipulateHandler;
break;
}
default:
/* FIXME */
KDDBGPRINT("Unknown StateChange %u.\n", StateChange->NewState);
while (1);
}
}
@ -177,10 +183,10 @@ send_kd_debug_io(
switch (DebugIO->ApiNumber)
{
case DbgKdPrintStringApi:
gdb_send_debug_io(String);
gdb_send_debug_io(String, TRUE);
break;
default:
/* FIXME */
KDDBGPRINT("Unknown ApiNumber %u.\n", DebugIO->ApiNumber);
while (1);
}
}
@ -200,7 +206,7 @@ send_kd_state_manipulate(
return;
#endif
default:
/* FIXME */
KDDBGPRINT("Unknown ApiNumber %u.\n", State->ApiNumber);
while (1);
}
}
@ -314,7 +320,11 @@ FirstSendHandler(
/* Set up the current state */
CurrentStateChange = *StateChange;
gdb_dbg_tid = handle_to_gdb_tid(PsGetThreadId(Thread));
#if MONOPROCESS
gdb_dbg_pid = 0;
#else
gdb_dbg_pid = handle_to_gdb_pid(PsGetThreadProcessId(Thread));
#endif
/* This is the idle process. Save it! */
TheIdleThread = Thread;
TheIdleProcess = (PEPROCESS)Thread->Tcb.ApcState.Process;
@ -352,7 +362,6 @@ KdReceivePacket(
_Out_ PULONG DataLength,
_Inout_ PKD_CONTEXT KdContext)
{
KDSTATUS Status;
DBGKD_MANIPULATE_STATE64* State;
/* Special handling for breakin packet */
@ -373,13 +382,8 @@ KdReceivePacket(
if (KdpManipulateStateHandler != NULL)
return KdpManipulateStateHandler(State, MessageData, DataLength, KdContext);
/* Receive data from GDB */
Status = gdb_receive_packet(KdContext);
if (Status != KdPacketReceived)
return Status;
/* Interpret it */
return gdb_interpret_input(State, MessageData, DataLength, KdContext);
/* Receive data from GDB and interpret it */
return gdb_receive_and_interpret_packet(State, MessageData, DataLength, KdContext);
}
VOID
@ -409,7 +413,7 @@ KdSendPacket(
send_kd_state_manipulate((DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer, MessageData);
break;
default:
/* FIXME */
KDDBGPRINT("Unknown packet type %u.\n", PacketType);
while (1);
}
}

View file

@ -21,7 +21,7 @@ find_process(
PEPROCESS Process;
/* Special case for idle process */
if (Pid == 1)
if (ProcessId == NULL)
return TheIdleProcess;
for (ProcessEntry = ProcessListHead->Flink;
@ -46,15 +46,44 @@ find_thread(
PETHREAD Thread;
PEPROCESS Process;
LIST_ENTRY* ThreadEntry;
#if MONOPROCESS
LIST_ENTRY* ProcessEntry;
#endif
if (
#if !MONOPROCESS
(Pid == 0) &&
#endif
(Tid == 0))
{
/* Zero means any, so use the current one */
return (PETHREAD)(ULONG_PTR)CurrentStateChange.Thread;
}
#if MONOPROCESS
/* Special case for the idle thread */
if ((Pid == 1) && (Tid == 1))
if (Tid == 1)
return TheIdleThread;
for (ProcessEntry = ProcessListHead->Flink;
ProcessEntry != ProcessListHead;
ProcessEntry = ProcessEntry->Flink)
{
Process = CONTAINING_RECORD(ProcessEntry, EPROCESS, ActiveProcessLinks);
#else
Process = find_process(Pid);
/* Special case for the idle thread */
if ((Process == TheIdleProcess) && (Tid == 1))
return TheIdleThread;
if (!Process)
return NULL;
#endif
for (ThreadEntry = Process->ThreadListHead.Flink;
ThreadEntry != &Process->ThreadListHead;
ThreadEntry = ThreadEntry->Flink)
@ -67,5 +96,9 @@ find_thread(
}
}
#if MONOPROCESS
}
#endif
return NULL;
}

View file

@ -113,7 +113,7 @@ KdpCopyMemoryChunks(IN ULONG64 Address,
/*
* We may have modified executable code, flush the instruction cache
*/
KeSweepICache((PVOID)Address, TotalSize);
KeSweepICache((PVOID)(ULONG_PTR)Address, TotalSize);
/*
* Return the size we managed to copy