[ros-dev] [ros-diffs] [jgardou] 72435: [KDGDB] - Implement setting and removing breakpoints - Implement single-stepping - Only get past the breakpoint instruction when it comes from RtlpBreakWithStatus - Implement writi...
Pierre Schweitzer
pierre at reactos.org
Tue Aug 23 19:31:44 UTC 2016
Hi Jérome,
First of all, amazing work. Thanks for it!
Is this page still relevant regarding debugging with GDB?
https://www.reactos.org/wiki/GDB
Or is there a new way to configure ReactOS/client side (Linux, ideally :-p).
Cheers,
Pierre
Le 23/08/2016 à 00:24, jgardou at svn.reactos.org a écrit :
> Author: jgardou
> Date: Mon Aug 22 22:24:30 2016
> New Revision: 72435
>
> URL: http://svn.reactos.org/svn/reactos?rev=72435&view=rev
> Log:
> [KDGDB]
> - Implement setting and removing breakpoints
> - Implement single-stepping
> - Only get past the breakpoint instruction when it comes from RtlpBreakWithStatus
> - Implement writing to memory
> - Always send the thread raising the exception to GDB to avoid confusing it
> - Let GDB find the program counter alone by querying the registers (support was already there before.)
> - Properly escape special characters on input
> Ladies and gentlemen : the almost-fully functional GDB stub. (still no real multi-process support :-( )
> To enable , in CMakeCache.txt :
> - Set GDB:BOOL=TRUE
> - Set _WINKD_:BOOL=TRUE
> - Set KDBG:BOOL=FALSE
> To do : give GDB the list of loaded drivers. Loading ntoskrnl.exe symbols at 0x80801000 already does a good enough job.
> Default output is on COM1. Can be configure to any othe COM port with usual kernel options.
> Hope you'll like it as much as I do ;-)
>
> Modified:
> trunk/reactos/drivers/base/kdgdb/gdb_input.c
> trunk/reactos/drivers/base/kdgdb/gdb_receive.c
> trunk/reactos/drivers/base/kdgdb/gdb_send.c
> trunk/reactos/drivers/base/kdgdb/i386_sup.c
> trunk/reactos/drivers/base/kdgdb/kdcom.c
> trunk/reactos/drivers/base/kdgdb/kdgdb.h
> trunk/reactos/drivers/base/kdgdb/kdpacket.c
>
> Modified: trunk/reactos/drivers/base/kdgdb/gdb_input.c
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/gdb_input.c?rev=72435&r1=72434&r2=72435&view=diff
> ==============================================================================
> --- trunk/reactos/drivers/base/kdgdb/gdb_input.c [iso-8859-1] (original)
> +++ trunk/reactos/drivers/base/kdgdb/gdb_input.c [iso-8859-1] Mon Aug 22 22:24:30 2016
> @@ -9,6 +9,11 @@
>
> /* LOCALS *********************************************************************/
> static ULONG_PTR gdb_run_tid;
> +static struct
> +{
> + ULONG_PTR Address;
> + ULONG Handle;
> +} BreakPointHandles[32];
>
>
> /* GLOBALS ********************************************************************/
> @@ -203,16 +208,15 @@
>
> if (!Resuming)
> {
> + /* Report the idle thread */
> +#if MONOPROCESS
> + ptr += sprintf(ptr, "1");
> +#else
> + ptr += sprintf(gdb, "p1.1");
> +#endif
> /* Initialize the entries */
> CurrentProcessEntry = ProcessListHead->Flink;
> CurrentThreadEntry = NULL;
> -
> - /* 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;
> }
>
> @@ -306,8 +310,8 @@
> 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);
> + Pid = hex_to_pid(&gdb_input[18]);
> + Tid = hex_to_tid(strstr(&gdb_input[18], ".") + 1);
>
> /* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL.
> * So loop. */
> @@ -394,21 +398,23 @@
> KDDBGPRINT("Wrong API number (%lu) after DbgKdReadVirtualMemoryApi request.\n", State->ApiNumber);
> }
>
> - /* Check status */
> - if (!NT_SUCCESS(State->ReturnStatus))
> + /* Check status. Allow to send partial data. */
> + if (!MessageData->Length && !NT_SUCCESS(State->ReturnStatus))
> send_gdb_ntstatus(State->ReturnStatus);
> else
> send_gdb_memory(MessageData->Buffer, MessageData->Length);
> KdpSendPacketHandler = NULL;
> KdpManipulateStateHandler = NULL;
>
> -#if !MONOPROCESS
> +#if MONOPROCESS
> + if (gdb_dbg_tid != 0)
> /* Reset the TLB */
> +#else
> if ((gdb_dbg_pid != 0) && gdb_pid_to_handle(gdb_dbg_pid) != PsGetCurrentProcessId())
> +#endif
> {
> __writecr3(PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]);
> }
> -#endif
> }
>
> static
> @@ -427,8 +433,29 @@
> MessageData->Length = 0;
> *MessageLength = 0;
>
> -#if !MONOPROCESS
> /* Set the TLB according to the process being read. Pid 0 means any process. */
> +#if MONOPROCESS
> + if ((gdb_dbg_tid != 0) && gdb_tid_to_handle(gdb_dbg_tid) != PsGetCurrentThreadId())
> + {
> + PETHREAD AttachedThread = find_thread(0, gdb_dbg_tid);
> + PKPROCESS AttachedProcess;
> + if (AttachedThread == NULL)
> + {
> + KDDBGPRINT("The current GDB debug thread is invalid!");
> + send_gdb_packet("E03");
> + return (KDSTATUS)-1;
> + }
> +
> + AttachedProcess = AttachedThread->Tcb.Process;
> + if (AttachedProcess == NULL)
> + {
> + KDDBGPRINT("The current GDB debug thread is invalid!");
> + send_gdb_packet("E03");
> + return (KDSTATUS)-1;
> + }
> + __writecr3(AttachedProcess->DirectoryTableBase[0]);
> + }
> +#else
> if ((gdb_dbg_pid != 0) && gdb_pid_to_handle(gdb_dbg_pid) != PsGetCurrentProcessId())
> {
> PEPROCESS AttachedProcess = find_process(gdb_dbg_pid);
> @@ -436,7 +463,7 @@
> {
> KDDBGPRINT("The current GDB debug thread is invalid!");
> send_gdb_packet("E03");
> - return gdb_receive_and_interpret_packet(State, MessageData, MessageLength, KdContext);
> + return (KDSTATUS)-1;
> }
> __writecr3(AttachedProcess->Pcb.DirectoryTableBase[0]);
> }
> @@ -448,6 +475,388 @@
> /* KD will reply with KdSendPacket. Catch it */
> KdpSendPacketHandler = ReadMemorySendHandler;
>
> + return KdPacketReceived;
> +}
> +
> +static
> +void
> +WriteMemorySendHandler(
> + _In_ ULONG PacketType,
> + _In_ PSTRING MessageHeader,
> + _In_ PSTRING MessageData)
> +{
> + DBGKD_MANIPULATE_STATE64* State = (DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer;
> +
> + if (PacketType != PACKET_TYPE_KD_STATE_MANIPULATE)
> + {
> + // KdAssert
> + KDDBGPRINT("Wrong packet type (%lu) received after DbgKdWriteVirtualMemoryApi request.\n", PacketType);
> + while (1);
> + }
> +
> + if (State->ApiNumber != DbgKdWriteVirtualMemoryApi)
> + {
> + KDDBGPRINT("Wrong API number (%lu) after DbgKdWriteVirtualMemoryApi request.\n", State->ApiNumber);
> + }
> +
> + /* Check status */
> + if (!NT_SUCCESS(State->ReturnStatus))
> + send_gdb_ntstatus(State->ReturnStatus);
> + else
> + send_gdb_packet("OK");
> + KdpSendPacketHandler = NULL;
> + KdpManipulateStateHandler = NULL;
> +
> +#if MONOPROCESS
> + if (gdb_dbg_tid != 0)
> + /* Reset the TLB */
> +#else
> + if ((gdb_dbg_pid != 0) && gdb_pid_to_handle(gdb_dbg_pid) != PsGetCurrentProcessId())
> +#endif
> + {
> + __writecr3(PsGetCurrentProcess()->Pcb.DirectoryTableBase[0]);
> + }
> +}
> +
> +static
> +KDSTATUS
> +handle_gdb_write_mem(
> + _Out_ DBGKD_MANIPULATE_STATE64* State,
> + _Out_ PSTRING MessageData,
> + _Out_ PULONG MessageLength,
> + _Inout_ PKD_CONTEXT KdContext)
> +{
> + /* Maximal input buffer is 0x1000. Each byte is encoded on two bytes by GDB */
> + static UCHAR OutBuffer[0x800];
> + ULONG BufferLength;
> + char* blob_ptr;
> + UCHAR* OutPtr;
> +
> + State->ApiNumber = DbgKdWriteVirtualMemoryApi;
> + State->ReturnStatus = STATUS_SUCCESS; /* ? */
> + State->Processor = CurrentStateChange.Processor;
> + State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
> +
> + /* Set the TLB according to the process being read. Pid 0 means any process. */
> +#if MONOPROCESS
> + if ((gdb_dbg_tid != 0) && gdb_tid_to_handle(gdb_dbg_tid) != PsGetCurrentThreadId())
> + {
> + PETHREAD AttachedThread = find_thread(0, gdb_dbg_tid);
> + PKPROCESS AttachedProcess;
> + if (AttachedThread == NULL)
> + {
> + KDDBGPRINT("The current GDB debug thread is invalid!");
> + send_gdb_packet("E03");
> + return (KDSTATUS)-1;
> + }
> +
> + AttachedProcess = AttachedThread->Tcb.Process;
> + if (AttachedProcess == NULL)
> + {
> + KDDBGPRINT("The current GDB debug thread is invalid!");
> + send_gdb_packet("E03");
> + return (KDSTATUS)-1;
> + }
> + __writecr3(AttachedProcess->DirectoryTableBase[0]);
> + }
> +#else
> + if ((gdb_dbg_pid != 0) && gdb_pid_to_handle(gdb_dbg_pid) != PsGetCurrentProcessId())
> + {
> + PEPROCESS AttachedProcess = find_process(gdb_dbg_pid);
> + if (AttachedProcess == NULL)
> + {
> + KDDBGPRINT("The current GDB debug thread is invalid!");
> + send_gdb_packet("E03");
> + return (KDSTATUS)-1;
> + }
> + __writecr3(AttachedProcess->Pcb.DirectoryTableBase[0]);
> + }
> +#endif
> +
> + State->u.WriteMemory.TargetBaseAddress = hex_to_address(&gdb_input[1]);
> + BufferLength = hex_to_address(strstr(&gdb_input[1], ",") + 1);
> + if (BufferLength == 0)
> + {
> + /* Nothing to do */
> + send_gdb_packet("OK");
> + return (KDSTATUS)-1;
> + }
> +
> + State->u.WriteMemory.TransferCount = BufferLength;
> + MessageData->Length = BufferLength;
> + MessageData->Buffer = (CHAR*)OutBuffer;
> +
> + OutPtr = OutBuffer;
> + blob_ptr = strstr(strstr(&gdb_input[1], ",") + 1, ":") + 1;
> + while (BufferLength)
> + {
> + if (BufferLength >= 4)
> + {
> + *((ULONG*)OutPtr) = *((ULONG*)blob_ptr);
> + OutPtr += 4;
> + blob_ptr += 4;
> + BufferLength -= 4;
> + }
> + else if (BufferLength >= 2)
> + {
> + *((USHORT*)OutPtr) = *((USHORT*)blob_ptr);
> + OutPtr += 2;
> + blob_ptr += 2;
> + BufferLength -= 2;
> + }
> + else
> + {
> + *OutPtr++ = *blob_ptr++;
> + BufferLength--;
> + }
> + }
> +
> + /* KD will reply with KdSendPacket. Catch it */
> + KdpSendPacketHandler = WriteMemorySendHandler;
> +
> + return KdPacketReceived;
> +}
> +
> +static
> +void
> +WriteBreakPointSendHandler(
> + _In_ ULONG PacketType,
> + _In_ PSTRING MessageHeader,
> + _In_ PSTRING MessageData)
> +{
> + DBGKD_MANIPULATE_STATE64* State = (DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer;
> +
> + if (PacketType != PACKET_TYPE_KD_STATE_MANIPULATE)
> + {
> + // KdAssert
> + KDDBGPRINT("Wrong packet type (%lu) received after DbgKdWriteBreakPointApi request.\n", PacketType);
> + while (1);
> + }
> +
> + if (State->ApiNumber != DbgKdWriteBreakPointApi)
> + {
> + KDDBGPRINT("Wrong API number (%lu) after DbgKdWriteBreakPointApi request.\n", State->ApiNumber);
> + }
> +
> + /* Check status */
> + if (!NT_SUCCESS(State->ReturnStatus))
> + {
> + KDDBGPRINT("Inserting breakpoint failed!\n");
> + send_gdb_ntstatus(State->ReturnStatus);
> + }
> + else
> + {
> + /* Keep track of the address+handle couple */
> + ULONG i;
> + for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
> + {
> + if (BreakPointHandles[i].Address == 0)
> + {
> + BreakPointHandles[i].Address = (ULONG_PTR)State->u.WriteBreakPoint.BreakPointAddress;
> + BreakPointHandles[i].Handle = State->u.WriteBreakPoint.BreakPointHandle;
> + break;
> + }
> + }
> + send_gdb_packet("OK");
> + }
> + KdpSendPacketHandler = NULL;
> + KdpManipulateStateHandler = NULL;
> +}
> +
> +static
> +KDSTATUS
> +handle_gdb_insert_breakpoint(
> + _Out_ DBGKD_MANIPULATE_STATE64* State,
> + _Out_ PSTRING MessageData,
> + _Out_ PULONG MessageLength,
> + _Inout_ PKD_CONTEXT KdContext)
> +{
> + State->ReturnStatus = STATUS_SUCCESS; /* ? */
> + State->Processor = CurrentStateChange.Processor;
> + State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
> + if (MessageData)
> + MessageData->Length = 0;
> + *MessageLength = 0;
> +
> + switch (gdb_input[1])
> + {
> + case '0':
> + {
> + ULONG_PTR Address = hex_to_address(&gdb_input[3]);
> + ULONG i;
> + BOOLEAN HasFreeSlot = FALSE;
> +
> + KDDBGPRINT("Inserting breakpoint at %p.\n", (void*)Address);
> +
> + for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
> + {
> + if (BreakPointHandles[i].Address == 0)
> + HasFreeSlot = TRUE;
> + }
> +
> + if (!HasFreeSlot)
> + {
> + /* We don't have a way to keep track of this break point. Fail. */
> + KDDBGPRINT("No breakpoint slot available!\n");
> + send_gdb_packet("E01");
> + return (KDSTATUS)-1;
> + }
> +
> + State->ApiNumber = DbgKdWriteBreakPointApi;
> + State->u.WriteBreakPoint.BreakPointAddress = Address;
> + /* FIXME : ignoring all other Z0 arguments */
> +
> + /* KD will reply with KdSendPacket. Catch it */
> + KdpSendPacketHandler = WriteBreakPointSendHandler;
> + return KdPacketReceived;
> + }
> + }
> +
> + KDDBGPRINT("Unhandled 'Z' packet: %s\n", gdb_input);
> + send_gdb_packet("E01");
> + return (KDSTATUS)-1;
> +}
> +
> +static
> +void
> +RestoreBreakPointSendHandler(
> + _In_ ULONG PacketType,
> + _In_ PSTRING MessageHeader,
> + _In_ PSTRING MessageData)
> +{
> + DBGKD_MANIPULATE_STATE64* State = (DBGKD_MANIPULATE_STATE64*)MessageHeader->Buffer;
> + ULONG i;
> +
> + if (PacketType != PACKET_TYPE_KD_STATE_MANIPULATE)
> + {
> + // KdAssert
> + KDDBGPRINT("Wrong packet type (%lu) received after DbgKdRestoreBreakPointApi request.\n", PacketType);
> + while (1);
> + }
> +
> + if (State->ApiNumber != DbgKdRestoreBreakPointApi)
> + {
> + KDDBGPRINT("Wrong API number (%lu) after DbgKdRestoreBreakPointApi request.\n", State->ApiNumber);
> + }
> +
> + /* We ignore failure here. If DbgKdRestoreBreakPointApi fails,
> + * this means that the breakpoint was already invalid for KD. So clean it up on our side. */
> + for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
> + {
> + if (BreakPointHandles[i].Handle == State->u.RestoreBreakPoint.BreakPointHandle)
> + {
> + BreakPointHandles[i].Address = 0;
> + BreakPointHandles[i].Handle = 0;
> + break;
> + }
> + }
> +
> + send_gdb_packet("OK");
> +
> + KdpSendPacketHandler = NULL;
> + KdpManipulateStateHandler = NULL;
> +}
> +
> +static
> +KDSTATUS
> +handle_gdb_remove_breakpoint(
> + _Out_ DBGKD_MANIPULATE_STATE64* State,
> + _Out_ PSTRING MessageData,
> + _Out_ PULONG MessageLength,
> + _Inout_ PKD_CONTEXT KdContext)
> +{
> + State->ReturnStatus = STATUS_SUCCESS; /* ? */
> + State->Processor = CurrentStateChange.Processor;
> + State->ProcessorLevel = CurrentStateChange.ProcessorLevel;
> + if (MessageData)
> + MessageData->Length = 0;
> + *MessageLength = 0;
> +
> + switch (gdb_input[1])
> + {
> + case '0':
> + {
> + ULONG_PTR Address = hex_to_address(&gdb_input[3]);
> + ULONG i, Handle = 0;
> +
> + KDDBGPRINT("Removing breakpoint on %p.\n", (void*)Address);
> +
> + for (i = 0; i < (sizeof(BreakPointHandles) / sizeof(BreakPointHandles[0])); i++)
> + {
> + if (BreakPointHandles[i].Address == Address)
> + {
> + Handle = BreakPointHandles[i].Handle;
> + break;
> + }
> + }
> +
> + if (Handle == 0)
> + {
> + KDDBGPRINT("Received %s, but breakpoint was never inserted ?!\n", gdb_input);
> + send_gdb_packet("E01");
> + return (KDSTATUS)-1;
> + }
> +
> + State->ApiNumber = DbgKdRestoreBreakPointApi;
> + State->u.RestoreBreakPoint.BreakPointHandle = Handle;
> + /* FIXME : ignoring all other z0 arguments */
> +
> + /* KD will reply with KdSendPacket. Catch it */
> + KdpSendPacketHandler = RestoreBreakPointSendHandler;
> + return KdPacketReceived;
> + }
> + }
> +
> + KDDBGPRINT("Unhandled 'Z' packet: %s\n", gdb_input);
> + send_gdb_packet("E01");
> + return (KDSTATUS)-1;
> +}
> +
> +static
> +KDSTATUS
> +handle_gdb_c(
> + _Out_ DBGKD_MANIPULATE_STATE64* State,
> + _Out_ PSTRING MessageData,
> + _Out_ PULONG MessageLength,
> + _Inout_ PKD_CONTEXT KdContext)
> +{
> + /* Tell GDB everything is fine, we will handle it */
> + send_gdb_packet("OK");
> +
> + if (CurrentStateChange.NewState == DbgKdExceptionStateChange)
> + {
> + DBGKM_EXCEPTION64* Exception = &CurrentStateChange.u.Exception;
> + ULONG_PTR ProgramCounter = KdpGetContextPc(&CurrentContext);
> +
> + /* See if we should update the program counter */
> + if (Exception && (Exception->ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT)
> + && ProgramCounter == KdDebuggerDataBlock->BreakpointWithStatus.Pointer)
> + {
> + /* We must get past the breakpoint instruction */
> + KdpSetContextPc(&CurrentContext, ProgramCounter + KD_BREAKPOINT_SIZE);
> +
> + SetContextManipulateHandler(State, MessageData, MessageLength, KdContext);
> + KdpManipulateStateHandler = ContinueManipulateStateHandler;
> + return KdPacketReceived;
> + }
> + }
> +
> + return ContinueManipulateStateHandler(State, MessageData, MessageLength, KdContext);
> +}
> +
> +static
> +KDSTATUS
> +handle_gdb_s(
> + _Out_ DBGKD_MANIPULATE_STATE64* State,
> + _Out_ PSTRING MessageData,
> + _Out_ PULONG MessageLength,
> + _Inout_ PKD_CONTEXT KdContext)
> +{
> + KDDBGPRINT("Single stepping.\n");
> + /* Set CPU single step mode and continue */
> + KdpSetSingleStep(&CurrentContext);
> + SetContextManipulateHandler(State, MessageData, MessageLength, KdContext);
> + KdpManipulateStateHandler = ContinueManipulateStateHandler;
> return KdPacketReceived;
> }
>
> @@ -464,36 +873,19 @@
> if (gdb_input[5] == '?')
> {
> /* Report what we support */
> - send_gdb_packet("vCont;c;C;s;S");
> + send_gdb_packet("vCont;c;s");
> return (KDSTATUS)-1;
> }
>
> if (strncmp(gdb_input, "vCont;c", 7) == 0)
> {
> - DBGKM_EXCEPTION64* Exception = NULL;
> -
> - /* Tell GDB everything is fine, we will handle it */
> - send_gdb_packet("OK");
> -
> - if (CurrentStateChange.NewState == DbgKdExceptionStateChange)
> - Exception = &CurrentStateChange.u.Exception;
> -
> - /* See if we should update the program counter (unlike windbg, gdb doesn't do it for us) */
> - if (Exception && (Exception->ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT)
> - && (Exception->ExceptionRecord.ExceptionInformation[0] == 0))
> - {
> - ULONG_PTR ProgramCounter;
> -
> - /* So we must get past the breakpoint instruction */
> - ProgramCounter = KdpGetContextPc(&CurrentContext);
> - KdpSetContextPc(&CurrentContext, ProgramCounter + KD_BREAKPOINT_SIZE);
> -
> - SetContextManipulateHandler(State, MessageData, MessageLength, KdContext);
> - KdpManipulateStateHandler = ContinueManipulateStateHandler;
> - return KdPacketReceived;
> - }
> -
> - return ContinueManipulateStateHandler(State, MessageData, MessageLength, KdContext);
> + return handle_gdb_c(State, MessageData, MessageLength, KdContext);
> + }
> +
> + if (strncmp(gdb_input, "vCont;s", 7) == 0)
> + {
> +
> + return handle_gdb_s(State, MessageData, MessageLength, KdContext);
> }
> }
>
> @@ -524,11 +916,14 @@
> {
> case '?':
> /* Send the Status */
> - gdb_send_exception(TRUE);
> + gdb_send_exception();
> break;
> case '!':
> send_gdb_packet("OK");
> break;
> + case 'c':
> + Status = handle_gdb_c(State, MessageData, MessageLength, KdContext);
> + break;
> case 'g':
> gdb_send_registers();
> break;
> @@ -544,17 +939,28 @@
> case 'q':
> handle_gdb_query();
> break;
> + case 's':
> + Status = handle_gdb_s(State, MessageData, MessageLength, KdContext);
> + break;
> case 'T':
> handle_gdb_thread_alive();
> break;
> case 'v':
> Status = handle_gdb_v(State, MessageData, MessageLength, KdContext);
> break;
> + case 'X':
> + Status = handle_gdb_write_mem(State, MessageData, MessageLength, KdContext);
> + break;
> + case 'z':
> + Status = handle_gdb_remove_breakpoint(State, MessageData, MessageLength, KdContext);
> + break;
> + case 'Z':
> + Status = handle_gdb_insert_breakpoint(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;
> + /* We don't know how to handle this request. */
> KDDBGPRINT("Unsupported GDB command: %s.\n", gdb_input);
> - return KdPacketReceived;
> + send_gdb_packet("");
> }
> } while (Status == (KDSTATUS)-1);
>
>
> Modified: trunk/reactos/drivers/base/kdgdb/gdb_receive.c
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/gdb_receive.c?rev=72435&r1=72434&r2=72435&view=diff
> ==============================================================================
> --- trunk/reactos/drivers/base/kdgdb/gdb_receive.c [iso-8859-1] (original)
> +++ trunk/reactos/drivers/base/kdgdb/gdb_receive.c [iso-8859-1] Mon Aug 22 22:24:30 2016
> @@ -30,7 +30,7 @@
> NTAPI
> gdb_receive_packet(_Inout_ PKD_CONTEXT KdContext)
> {
> - char* ByteBuffer = gdb_input;
> + UCHAR* ByteBuffer = (UCHAR*)gdb_input;
> UCHAR Byte;
> KDSTATUS Status;
> CHAR CheckSum = 0, ReceivedCheckSum;
> @@ -60,9 +60,18 @@
> *ByteBuffer = '\0';
> break;
> }
> -
> + CheckSum += (CHAR)Byte;
> +
> + /* See if we should escape */
> + if (Byte == 0x7d)
> + {
> + Status = KdpReceiveByte(&Byte);
> + if (Status != KdPacketReceived)
> + return Status;
> + CheckSum += (CHAR)Byte;
> + Byte ^= 0x20;
> + }
> *ByteBuffer++ = Byte;
> - CheckSum += (CHAR)Byte;
> }
>
> /* Get Check sum (two bytes) */
> @@ -80,6 +89,7 @@
> if (ReceivedCheckSum != CheckSum)
> {
> /* Do not acknowledge to GDB */
> + KDDBGPRINT("Check sums don't match!");
> KdpSendByte('-');
> return KdPacketNeedsResend;
> }
>
> Modified: trunk/reactos/drivers/base/kdgdb/gdb_send.c
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/gdb_send.c?rev=72435&r1=72434&r2=72435&view=diff
> ==============================================================================
> --- trunk/reactos/drivers/base/kdgdb/gdb_send.c [iso-8859-1] (original)
> +++ trunk/reactos/drivers/base/kdgdb/gdb_send.c [iso-8859-1] Mon Aug 22 22:24:30 2016
> @@ -168,7 +168,7 @@
> }
>
> void
> -gdb_send_exception(BOOLEAN WithThread)
> +gdb_send_exception()
> {
> char gdb_out[1024];
> char* ptr = gdb_out;
> @@ -184,20 +184,16 @@
> }
> else
> ptr += sprintf(ptr, "05");
> - if (WithThread)
> - {
> +
> #if MONOPROCESS
> - ptr += sprintf(ptr, "thread:%" PRIxPTR ";",
> - handle_to_gdb_tid(PsGetThreadId(Thread)));
> + 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)));
> + 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);
> }
>
>
> Modified: trunk/reactos/drivers/base/kdgdb/i386_sup.c
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/i386_sup.c?rev=72435&r1=72434&r2=72435&view=diff
> ==============================================================================
> --- trunk/reactos/drivers/base/kdgdb/i386_sup.c [iso-8859-1] (original)
> +++ trunk/reactos/drivers/base/kdgdb/i386_sup.c [iso-8859-1] Mon Aug 22 22:24:30 2016
> @@ -251,28 +251,4 @@
> }
> }
>
> -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;
> -}
> -
> +
>
> Modified: trunk/reactos/drivers/base/kdgdb/kdcom.c
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/kdcom.c?rev=72435&r1=72434&r2=72435&view=diff
> ==============================================================================
> --- trunk/reactos/drivers/base/kdgdb/kdcom.c [iso-8859-1] (original)
> +++ trunk/reactos/drivers/base/kdgdb/kdcom.c [iso-8859-1] Mon Aug 22 22:24:30 2016
> @@ -303,7 +303,6 @@
> return KdPacketReceived;
> }
>
> - KDDBGPRINT("CpGetByte returned %u.\n", CpStatus);
> return KdPacketTimedOut;
> }
>
>
> Modified: trunk/reactos/drivers/base/kdgdb/kdgdb.h
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/kdgdb.h?rev=72435&r1=72434&r2=72435&view=diff
> ==============================================================================
> --- trunk/reactos/drivers/base/kdgdb/kdgdb.h [iso-8859-1] (original)
> +++ trunk/reactos/drivers/base/kdgdb/kdgdb.h [iso-8859-1] Mon Aug 22 22:24:30 2016
> @@ -19,7 +19,7 @@
>
> #include <pstypes.h>
>
> -#define KDDEBUG /* uncomment to enable debugging this dll */
> +//#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
> @@ -83,7 +83,7 @@
> 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, _In_ BOOLEAN WithPrefix);
> -void gdb_send_exception(BOOLEAN WithThread);
> +void gdb_send_exception(void);
> void send_gdb_ntstatus(_In_ NTSTATUS Status);
> extern const char hex_chars[];
>
> @@ -113,15 +113,18 @@
> /* arch_sup.c */
> 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
> +/* Handling passing over the breakpoint instruction */
> # define KdpGetContextPc(Context) \
> ((Context)->Eip)
> # define KdpSetContextPc(Context, ProgramCounter) \
> ((Context)->Eip = (ProgramCounter))
> # define KD_BREAKPOINT_SIZE sizeof(UCHAR)
> +/* Single step mode */
> +# define KdpSetSingleStep(Context) \
> + ((Context)->EFlags |= EFLAGS_TF)
> #else
> # error "Please define relevant macros for your architecture"
> #endif
>
> Modified: trunk/reactos/drivers/base/kdgdb/kdpacket.c
> URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/base/kdgdb/kdpacket.c?rev=72435&r1=72434&r2=72435&view=diff
> ==============================================================================
> --- trunk/reactos/drivers/base/kdgdb/kdpacket.c [iso-8859-1] (original)
> +++ trunk/reactos/drivers/base/kdgdb/kdpacket.c [iso-8859-1] Mon Aug 22 22:24:30 2016
> @@ -160,7 +160,7 @@
> #else
> gdb_dbg_pid = handle_to_gdb_pid(PsGetThreadProcessId(Thread));
> #endif
> - gdb_send_exception(FALSE);
> + gdb_send_exception();
> /* Next receive call will ask for the context */
> KdpManipulateStateHandler = GetContextManipulateHandler;
> break;
> @@ -394,6 +394,13 @@
> IN PSTRING MessageData,
> IN OUT PKD_CONTEXT KdContext)
> {
> + /* Override if we have some debug print from KD. */
> + if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
> + {
> + send_kd_debug_io((DBGKD_DEBUG_IO*)MessageHeader->Buffer, MessageData);
> + return;
> + }
> +
> /* Maybe we are in a send <-> receive loop that GDB doesn't need to know about */
> if (KdpSendPacketHandler)
> {
>
>
--
Pierre Schweitzer <pierre at reactos.org>
System & Network Administrator
Senior Kernel Developer
ReactOS Deutschland e.V.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3960 bytes
Desc: Signature cryptographique S/MIME
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20160823/a190b402/attachment-0001.bin>
More information about the Ros-dev
mailing list