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, jgar...@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.

Attachment: smime.p7s
Description: Signature cryptographique S/MIME

_______________________________________________
Ros-dev mailing list
Ros-dev@reactos.org
http://www.reactos.org/mailman/listinfo/ros-dev

Reply via email to