ADDRESS_TYPE CLiveExdiGdbSrvServer::ParseAsynchronousCommandResult()

in Exdi/exdigdbsrv/ExdiGdbSrv/LiveExdiGdbSrvServer.cpp [1788:1899]


ADDRESS_TYPE CLiveExdiGdbSrvServer::ParseAsynchronousCommandResult(_Out_ DWORD * pProcessorNumberOfLastEvent, _Out_ HALT_REASON_TYPE * pHaltReason)
{
    assert(pProcessorNumberOfLastEvent != nullptr);
    AsynchronousGdbSrvController * pController = GetGdbSrvController();
    assert(pController != nullptr);

    ADDRESS_TYPE currentPcAddress = 0;
    if (pController->GetAsynchronousCmdStopReplyPacket())
    {
        int attempts = 0;
        bool isWaitingOnStopReply = false;
        ULONG totalPackets = 0;
        do
        {
            StopReplyPacketStruct stopReply = {0};
            const std::string reply = pController->GetCommandResult();
            bool isParsed = pController->HandleAsynchronousCommandResponse(reply, &stopReply);
            if (isParsed)
            {
                attempts = 0;
                //  Is it a OXX console packet? 
                if (stopReply.status.isOXXPacket)
                {
                    //  Try to display the GDB server ouput message if there is an attached text console.
                    pController->DisplayConsoleMessage(reply);
                    //  Post another receive request on the packet buffer
                    pController->ContinueWaitingOnStopReplyPacket();
                    isWaitingOnStopReply = true;
                }
                //  Is it a T packet?
                else if (stopReply.status.isTAAPacket)
                {
                    if (stopReply.status.isPcRegFound)
                    {
                        assert(stopReply.currentAddress != 0);
                        currentPcAddress = m_lastPcAddress = stopReply.currentAddress;
                    }
                    else
                    {
                        //  The packet didn't contain the PC, but we'd better find out what it is, so we can inform the debugger
                        DWORD pcAddressRequest;
                        currentPcAddress = m_lastPcAddress = GetCurrentExecutionAddress(&pcAddressRequest);
                    }

                    if (stopReply.status.isThreadFound)
                    {
                        assert(stopReply.processorNumber != static_cast<ULONG>(-1));
                        if (stopReply.processorNumber <= pController->GetProcessorCount())
                        {
                            *pProcessorNumberOfLastEvent = stopReply.processorNumber;
                        }
                    }
                    else
                    {
                        *pProcessorNumberOfLastEvent = pController->GetLastKnownActiveCpu();
                    }
                    isWaitingOnStopReply = false;
                }
                //  Is it a S AA packet?
                else if (stopReply.status.isSAAPacket)
                {
                    //  There is a no any processor number or pc adddress in the response
                    if (stopReply.status.isPowerDown)
                    {
                        MessageBox(0, _T("The Target is running or it is in a power down state."),nullptr, MB_ICONERROR);                    
                    }
                    stopReply.currentAddress = m_lastPcAddress;
                    *pProcessorNumberOfLastEvent = pController->GetLastKnownActiveCpu();
                    isWaitingOnStopReply = false;
                } 
                // Is it an "OK" response w/o any other field (e.g. OpenOCD can send "OK" after 's'/'g')?
                else if (stopReply.status.isCoreRunning)
                {
                    //  Post another receive request on the packet buffer, since there is still no
                    //  trace of the current thread-core/Pc address packet.
                    pController->ContinueWaitingOnStopReplyPacket();
                    isWaitingOnStopReply = true;                
                }

                if (!isWaitingOnStopReply)
                {
                    //  Convert the stop reason code
                    switch (stopReply.stopReason) 
                    {
                    case TARGET_BREAK_SIGINT:
                       *pHaltReason = hrUser;
                       break;
                    case TARGET_BREAK_SIGTRAP:
                       *pHaltReason = hrBp;
                       break;
                    default:
                       *pHaltReason = hrUnknown;
                    }
                    pController->ResetAsynchronousCmdStopReplyPacket();
                }
            }
            else
            {
                Sleep(c_asyncResponsePauseMs);
            }
        }
        while (isWaitingOnStopReply &&
            (attempts++ < c_attemptsWaitingOnPendingResponse) &&
            (totalPackets < c_maximumReplyPacketsInResponse));
    }
    else
    {
        //  This can happen only if there was a previously handled Halt event.
        currentPcAddress = m_lastPcAddress;
    }
    return currentPcAddress;
}