Index: lit/tools/lldb-mi/exec/exec-finish.test =================================================================== --- /dev/null +++ lit/tools/lldb-mi/exec/exec-finish.test @@ -0,0 +1,33 @@ +# XFAIL: windows +# -> llvm.org/pr24452 +# +# RUN: %cc -o %t %p/inputs/main.c -g +# RUN: %lldbmi %t < %s | FileCheck %s + +# Test lldb-mi -exec-finish command. + +# Check that we have a valid target created via '%lldbmi %t'. +# CHECK: ^done + +-break-insert main +# CHECK: ^done,bkpt={number="1" + +-break-insert dummyFunction +# CHECK: ^done,bkpt={number="2" + +-exec-run +# CHECK: ^running +# CHECK: *stopped,reason="breakpoint-hit" + +-exec-finish --thread 0 +# Check that exec-finish can process the case of invalid thread ID. +# CHECK: ^error,msg="Command 'exec-finish'. Thread ID invalid" + +-exec-finish --thread 1 +# CHECK: ^running +# CHECK: *stopped,reason="breakpoint-hit" + +-exec-finish +# Check exec-finish in a selected thread. +# CHECK: ^running +# CHECK: *stopped,reason="end-stepping-range" Index: lit/tools/lldb-mi/exec/exec-interrupt.test =================================================================== --- /dev/null +++ lit/tools/lldb-mi/exec/exec-interrupt.test @@ -0,0 +1,20 @@ +# XFAIL: windows +# -> llvm.org/pr24452 +# +# RUN: %cc -o %t %p/inputs/main.c -g +# RUN: %lldbmi %t < %s | FileCheck %s + +# Test lldb-mi -exec-interrupt command. + +# Check that we have a valid target created via '%lldbmi %t'. +# CHECK: ^done + +-break-insert main +# CHECK: ^done,bkpt={number="1" + +-exec-run +# CHECK: ^running +# CHECK: *stopped,reason="breakpoint-hit" + +-exec-interrupt +# CHECK: ^error,msg="Process is not running." Index: lit/tools/lldb-mi/exec/exec-next-instruction.test =================================================================== --- /dev/null +++ lit/tools/lldb-mi/exec/exec-next-instruction.test @@ -0,0 +1,30 @@ +# XFAIL: windows +# -> llvm.org/pr24452 +# +# RUN: %cc -o %t %p/inputs/main.c -g +# RUN: %lldbmi %t < %s | FileCheck %s + +# Test lldb-mi -exec-next-instruction command. + +# Check that we have a valid target created via '%lldbmi %t'. +# CHECK: ^done + +-break-insert main +# CHECK: ^done,bkpt={number="1" + +-exec-run +# CHECK: ^running +# CHECK: *stopped,reason="breakpoint-hit" + +-exec-next-instruction --thread 0 +# Check that exec-next-instruction can process the case of invalid thread ID. +# CHECK: ^error,msg="Command 'exec-next-instruction'. Thread ID invalid" + +-exec-next-instruction --thread 1 +# CHECK: ^running +# CHECK: *stopped,reason="end-stepping-range" + +-exec-next-instruction +# Check exec-next-instruction in a selected thread. +# CHECK: ^running +# CHECK: *stopped,reason="end-stepping-range" Index: lit/tools/lldb-mi/exec/exec-step-instruction.test =================================================================== --- /dev/null +++ lit/tools/lldb-mi/exec/exec-step-instruction.test @@ -0,0 +1,30 @@ +# XFAIL: windows +# -> llvm.org/pr24452 +# +# RUN: %cc -o %t %p/inputs/main.c -g +# RUN: %lldbmi %t < %s | FileCheck %s + +# Test lldb-mi -exec-step-instruction command. + +# Check that we have a valid target created via '%lldbmi %t'. +# CHECK: ^done + +-break-insert main +# CHECK: ^done,bkpt={number="1" + +-exec-run +# CHECK: ^running +# CHECK: *stopped,reason="breakpoint-hit" + +-exec-step-instruction --thread 0 +# Check that exec-step-instruction can process the case of invalid thread ID. +# CHECK: ^error,msg="Command 'exec-step-instruction'. Thread ID invalid" + +-exec-next-instruction --thread 1 +# CHECK: ^running +# CHECK: *stopped,reason="end-stepping-range" + +-exec-step-instruction +# Check exec-step-instruction in a selected thread. +# CHECK: ^running +# CHECK: *stopped,reason="end-stepping-range" Index: lit/tools/lldb-mi/exec/inputs/main.c =================================================================== --- lit/tools/lldb-mi/exec/inputs/main.c +++ lit/tools/lldb-mi/exec/inputs/main.c @@ -1,4 +1,9 @@ +void dummyFunction() { + int a = 0; +} + int main(void) { int x = 0; + dummyFunction(); return x; } Index: packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py =================================================================== --- packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py +++ packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py @@ -247,9 +247,9 @@ # Test that an invalid --thread is handled self.runCmd("-exec-next-instruction --thread 0") - self.expect("\^error,message=\"error: Thread index 0 is out of range") + self.expect("\^error,msg=\"Command 'exec-next-instruction'. Thread ID invalid\"") self.runCmd("-exec-next-instruction --thread 10") - self.expect("\^error,message=\"error: Thread index 10 is out of range") + self.expect("\^error,msg=\"Command 'exec-next-instruction'. Thread ID invalid") # Test that an invalid --frame is handled # FIXME: no error is returned @@ -406,9 +406,9 @@ # Test that an invalid --thread is handled self.runCmd("-exec-step-instruction --thread 0") - self.expect("\^error,message=\"error: Thread index 0 is out of range") + self.expect("\^error,msg=\"Command 'exec-step-instruction'. Thread ID invalid\"") self.runCmd("-exec-step-instruction --thread 10") - self.expect("\^error,message=\"error: Thread index 10 is out of range") + self.expect("\^error,msg=\"Command 'exec-step-instruction'. Thread ID invalid\"") # Test that an invalid --frame is handled # FIXME: no error is returned @@ -467,9 +467,9 @@ # Test that an invalid --thread is handled self.runCmd("-exec-finish --thread 0") - self.expect("\^error,message=\"error: Thread index 0 is out of range") + self.expect("\^error,msg=\"Command 'exec-finish'. Thread ID invalid\"") self.runCmd("-exec-finish --thread 10") - self.expect("\^error,message=\"error: Thread index 10 is out of range") + self.expect("\^error,msg=\"Command 'exec-finish'. Thread ID invalid\"") # Test that an invalid --frame is handled # FIXME: no error is returned Index: tools/lldb-mi/MICmdCmdExec.h =================================================================== --- tools/lldb-mi/MICmdCmdExec.h +++ tools/lldb-mi/MICmdCmdExec.h @@ -33,8 +33,6 @@ #pragma once // Third party headers: -#include "lldb/API/SBCommandReturnObject.h" - // In-house headers: #include "MICmdBase.h" @@ -90,7 +88,6 @@ bool Acknowledge() override; // From CMICmnBase /* dtor */ ~CMICmdCmdExecContinue() override; - // Attributes: }; //++ @@ -179,7 +176,6 @@ // Attributes: private: - lldb::SBCommandReturnObject m_lldbResult; const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but // Eclipse gives this option }; @@ -210,7 +206,6 @@ // Attributes: private: - lldb::SBCommandReturnObject m_lldbResult; const CMIUtilString m_constStrArgNumber; // Not specified in MI spec but // Eclipse gives this option }; @@ -238,10 +233,6 @@ bool ParseArgs() override; // From CMICmnBase /* dtor */ ~CMICmdCmdExecFinish() override; - - // Attributes: -private: - lldb::SBCommandReturnObject m_lldbResult; }; // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM @@ -270,10 +261,6 @@ bool Acknowledge() override; // From CMICmnBase /* dtor */ ~CMICmdCmdExecInterrupt() override; - - // Attributes: -private: - lldb::SBCommandReturnObject m_lldbResult; }; //++ Index: tools/lldb-mi/MICmdCmdExec.cpp =================================================================== --- tools/lldb-mi/MICmdCmdExec.cpp +++ tools/lldb-mi/MICmdCmdExec.cpp @@ -601,14 +601,23 @@ CMICmnLLDBDebugSessionInfo &rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance()); - lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger(); - CMIUtilString strCmd("thread step-inst-over"); - if (nThreadId != UINT64_MAX) - strCmd += CMIUtilString::Format(" %llu", nThreadId); - rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult, - false); - return MIstatus::success; + lldb::SBError error; + if (nThreadId != UINT64_MAX) { + lldb::SBThread sbThread = + rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId); + if (!sbThread.IsValid()) { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), + m_cmdData.strMiCmd.c_str(), + m_constStrArgThread.c_str())); + return MIstatus::failure; + } + sbThread.StepInstruction(true, error); + } else + rSessionInfo.GetProcess().GetSelectedThread().StepInstruction( + true, error); + + return HandleSBError(error); } //++ @@ -623,21 +632,8 @@ // Throws: None. //-- bool CMICmdCmdExecNextInstruction::Acknowledge() { - if (m_lldbResult.GetErrorSize() > 0) { - const char *pLldbErr = m_lldbResult.GetError(); - MIunused(pLldbErr); - const CMICmnMIValueConst miValueConst(m_lldbResult.GetError()); - const CMICmnMIValueResult miValueResult("message", miValueConst); - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, - miValueResult); - m_miResultRecord = miRecordResult; - } else { - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running); - m_miResultRecord = miRecordResult; - } - + m_miResultRecord = CMICmnMIResultRecord( + m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running); return MIstatus::success; } @@ -729,14 +725,23 @@ CMICmnLLDBDebugSessionInfo &rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance()); - lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger(); - CMIUtilString strCmd("thread step-inst"); - if (nThreadId != UINT64_MAX) - strCmd += CMIUtilString::Format(" %llu", nThreadId); - rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult, - false); - return MIstatus::success; + lldb::SBError error; + if (nThreadId != UINT64_MAX) { + lldb::SBThread sbThread = + rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId); + if (!sbThread.IsValid()) { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), + m_cmdData.strMiCmd.c_str(), + m_constStrArgThread.c_str())); + return MIstatus::failure; + } + sbThread.StepInstruction(false, error); + } else + rSessionInfo.GetProcess().GetSelectedThread().StepInstruction( + false, error); + + return HandleSBError(error); } //++ @@ -751,21 +756,8 @@ // Throws: None. //-- bool CMICmdCmdExecStepInstruction::Acknowledge() { - if (m_lldbResult.GetErrorSize() > 0) { - const char *pLldbErr = m_lldbResult.GetError(); - MIunused(pLldbErr); - const CMICmnMIValueConst miValueConst(m_lldbResult.GetError()); - const CMICmnMIValueResult miValueResult("message", miValueConst); - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, - miValueResult); - m_miResultRecord = miRecordResult; - } else { - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running); - m_miResultRecord = miRecordResult; - } - + m_miResultRecord = CMICmnMIResultRecord( + m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running); return MIstatus::success; } @@ -853,14 +845,22 @@ CMICmnLLDBDebugSessionInfo &rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance()); - lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger(); - CMIUtilString strCmd("thread step-out"); - if (nThreadId != UINT64_MAX) - strCmd += CMIUtilString::Format(" %llu", nThreadId); - rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult, - false); - return MIstatus::success; + lldb::SBError error; + if (nThreadId != UINT64_MAX) { + lldb::SBThread sbThread = + rSessionInfo.GetProcess().GetThreadByIndexID(nThreadId); + if (!sbThread.IsValid()) { + SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), + m_cmdData.strMiCmd.c_str(), + m_constStrArgThread.c_str())); + return MIstatus::failure; + } + sbThread.StepOut(error); + } else + rSessionInfo.GetProcess().GetSelectedThread().StepOut(error); + + return HandleSBError(error); } //++ @@ -875,21 +875,8 @@ // Throws: None. //-- bool CMICmdCmdExecFinish::Acknowledge() { - if (m_lldbResult.GetErrorSize() > 0) { - const char *pLldbErr = m_lldbResult.GetError(); - MIunused(pLldbErr); - const CMICmnMIValueConst miValueConst(m_lldbResult.GetError()); - const CMICmnMIValueResult miValueResult("message", miValueConst); - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, - miValueResult); - m_miResultRecord = miRecordResult; - } else { - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running); - m_miResultRecord = miRecordResult; - } - + m_miResultRecord = CMICmnMIResultRecord( + m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running); return MIstatus::success; } @@ -950,25 +937,22 @@ // Throws: None. //-- bool CMICmdCmdExecInterrupt::Execute() { - CMICmnLLDBDebugSessionInfo &rSessionInfo( - CMICmnLLDBDebugSessionInfo::Instance()); - lldb::SBDebugger &rDebugger = rSessionInfo.GetDebugger(); - CMIUtilString strCmd("process interrupt"); - const lldb::ReturnStatus status = - rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), - m_lldbResult, false); - MIunused(status); - - // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM - if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging()) { - const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription()); - SetErrorDescription( - CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE), - strCmd.c_str(), rErrMsg.c_str())); - return MIstatus::failure; - } + const auto successHandler = [this] { + // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM + if (!CMIDriver::Instance().SetDriverStateRunningNotDebugging()) { + const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription()); + this->SetErrorDescription(CMIUtilString::Format( + MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE), + this->m_cmdData.strMiCmd.c_str(), + rErrMsg.c_str())); + return MIstatus::failure; + } + return MIstatus::success; + }; - return MIstatus::success; + return HandleSBErrorWithSuccess( + CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Stop(), + successHandler); } //++ @@ -983,19 +967,8 @@ // Throws: None. //-- bool CMICmdCmdExecInterrupt::Acknowledge() { - if (m_lldbResult.GetErrorSize() > 0) { - const CMICmnMIValueConst miValueConst(m_lldbResult.GetError()); - const CMICmnMIValueResult miValueResult("message", miValueConst); - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, - miValueResult); - m_miResultRecord = miRecordResult; - } else { - const CMICmnMIResultRecord miRecordResult( - m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); - m_miResultRecord = miRecordResult; - } - + m_miResultRecord = CMICmnMIResultRecord( + m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); return MIstatus::success; }