Index: lldb/trunk/lit/tools/lldb-mi/exec/exec-finish.test =================================================================== --- lldb/trunk/lit/tools/lldb-mi/exec/exec-finish.test +++ lldb/trunk/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: lldb/trunk/lit/tools/lldb-mi/exec/exec-interrupt.test =================================================================== --- lldb/trunk/lit/tools/lldb-mi/exec/exec-interrupt.test +++ lldb/trunk/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: lldb/trunk/lit/tools/lldb-mi/exec/exec-next-instruction.test =================================================================== --- lldb/trunk/lit/tools/lldb-mi/exec/exec-next-instruction.test +++ lldb/trunk/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: lldb/trunk/lit/tools/lldb-mi/exec/exec-step-instruction.test =================================================================== --- lldb/trunk/lit/tools/lldb-mi/exec/exec-step-instruction.test +++ lldb/trunk/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: lldb/trunk/lit/tools/lldb-mi/exec/inputs/main.c =================================================================== --- lldb/trunk/lit/tools/lldb-mi/exec/inputs/main.c +++ lldb/trunk/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: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py @@ -139,351 +139,3 @@ # Check argc to see if arg passed self.runCmd("-data-evaluate-expression argc") self.expect("\^done,value=\"1\"") - - @skipIfRemote # We do not currently support remote debugging via the MI. - @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows - @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - def test_lldbmi_exec_next(self): - """Test that 'lldb-mi --interpreter' works for stepping.""" - - self.spawnLldbMi(args=None) - - # Load executable - self.runCmd("-file-exec-and-symbols %s" % self.myexe) - self.expect("\^done") - - # Run to main - self.runCmd("-break-insert -f main") - self.expect("\^done,bkpt={number=\"1\"") - self.runCmd("-exec-run") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Warning: the following is sensitive to the lines in the source - - # Test -exec-next - self.runCmd("-exec-next --thread 1 --frame 0") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\"") - - # Test that --thread is optional - self.runCmd("-exec-next --frame 0") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"") - - # Test that --frame is optional - self.runCmd("-exec-next --thread 1") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"31\"") - - # Test that both --thread and --frame are optional - self.runCmd("-exec-next") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"32\"") - - # Test that an invalid --thread is handled - self.runCmd("-exec-next --thread 0") - self.expect("\^error,msg=\"Command 'exec-next'. Thread ID invalid") - self.runCmd("-exec-next --thread 10") - self.expect("\^error,msg=\"Command 'exec-next'. Thread ID invalid") - - # Test that an invalid --frame is handled - # FIXME: no error is returned - self.runCmd("-exec-next --frame 10") - #self.expect("\^error: Frame index 10 is out of range") - - @skipIfRemote # We do not currently support remote debugging via the MI. - @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows - @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - def test_lldbmi_exec_next_instruction(self): - """Test that 'lldb-mi --interpreter' works for instruction stepping.""" - - self.spawnLldbMi(args=None) - - # Load executable - self.runCmd("-file-exec-and-symbols %s" % self.myexe) - self.expect("\^done") - - # Run to main - self.runCmd("-break-insert -f main") - self.expect("\^done,bkpt={number=\"1\"") - self.runCmd("-exec-run") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Warning: the following is sensitive to the lines in the - # source and optimizations - - # Test -exec-next-instruction - self.runCmd("-exec-next-instruction --thread 1 --frame 0") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"28\"") - - # Test that --thread is optional - self.runCmd("-exec-next-instruction --frame 0") - self.expect("\^running") - # Depending on compiler, it can stop at different line - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(28|29)\"") - - # Test that --frame is optional - self.runCmd("-exec-next-instruction --thread 1") - self.expect("\^running") - # Depending on compiler, it can stop at different line - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(28|29|30)\"") - - # Test that both --thread and --frame are optional - self.runCmd("-exec-next-instruction") - self.expect("\^running") - # Depending on compiler, it can stop at different line - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"(28|29|30|31)\"") - - # 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.runCmd("-exec-next-instruction --thread 10") - self.expect("\^error,message=\"error: Thread index 10 is out of range") - - # Test that an invalid --frame is handled - # FIXME: no error is returned - self.runCmd("-exec-next-instruction --frame 10") - #self.expect("\^error: Frame index 10 is out of range") - - @skipIfRemote # We do not currently support remote debugging via the MI. - @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows - @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - def test_lldbmi_exec_step(self): - """Test that 'lldb-mi --interpreter' works for stepping into.""" - - self.spawnLldbMi(args=None) - - # Load executable - self.runCmd("-file-exec-and-symbols %s" % self.myexe) - self.expect("\^done") - - # Run to main - self.runCmd("-break-insert -f main") - self.expect("\^done,bkpt={number=\"1\"") - self.runCmd("-exec-run") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Warning: the following is sensitive to the lines in the source - - # Test that -exec-step steps into (or not) printf depending on debug info - # Note that message is different in Darwin and Linux: - # Darwin: "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x[0-9a-f]+\",func=\"main\",args=[{name=\"argc\",value=\"1\"},{name=\"argv\",value="0x[0-9a-f]+\"}],file=\"main.cpp\",fullname=\".+main.cpp\",line=\"\d\"},thread-id=\"1\",stopped-threads=\"all\" - # Linux: - # "*stopped,reason=\"end-stepping-range\",frame={addr="0x[0-9a-f]+\",func=\"__printf\",args=[{name=\"format\",value=\"0x[0-9a-f]+\"}],file=\"printf.c\",fullname=\".+printf.c\",line="\d+"},thread-id=\"1\",stopped-threads=\"all\" - self.runCmd("-exec-step --thread 1 --frame 0") - self.expect("\^running") - it = self.expect(["\*stopped,reason=\"end-stepping-range\".+?func=\"main\"", - "\*stopped,reason=\"end-stepping-range\".+?func=\"(?!main).+?\""]) - # Exit from printf if needed - if it == 1: - self.runCmd("-exec-finish") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\"main\"") - - # Test that -exec-step steps into g_MyFunction and back out - # (and that --thread is optional) - self.runCmd("-exec-step --frame 0") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"") - # Use -exec-finish here to make sure that control reaches the caller. - # -exec-step can keep us in the g_MyFunction for gcc - self.runCmd("-exec-finish --frame 0") - self.expect("\^running") - it = self.expect(["\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"", - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\""]) - - if it == 1: - # Call to s_MyFunction may not follow immediately after g_MyFunction. - # There might be some instructions in between to restore caller-saved registers. - # We need to get past these instructions with a next to reach call to s_MyFunction. - self.runCmd("-exec-next --thread 1") - self.expect("\^running") - self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"") - - # Test that -exec-step steps into s_MyFunction - # (and that --frame is optional) - self.runCmd("-exec-step --thread 1") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\".*?s_MyFunction.*?\"") - - # Test that -exec-step steps into g_MyFunction from inside - # s_MyFunction (and that both --thread and --frame are optional) - self.runCmd("-exec-step") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"") - - # Test that an invalid --thread is handled - self.runCmd("-exec-step --thread 0") - self.expect("\^error,msg=\"Command 'exec-step'. Thread ID invalid") - self.runCmd("-exec-step --thread 10") - self.expect("\^error,msg=\"Command 'exec-step'. Thread ID invalid") - - # Test that an invalid --frame is handled - # FIXME: no error is returned - self.runCmd("-exec-step --frame 10") - #self.expect("\^error: Frame index 10 is out of range") - - @skipIfRemote # We do not currently support remote debugging via the MI. - @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows - @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - def test_lldbmi_exec_step_instruction(self): - """Test that 'lldb-mi --interpreter' works for instruction stepping into.""" - - self.spawnLldbMi(args=None) - - # Load executable - self.runCmd("-file-exec-and-symbols %s" % self.myexe) - self.expect("\^done") - - # Warning: the following is sensitive to the lines in the - # source and optimizations - - # Run to main - self.runCmd("-break-insert -f main") - self.expect("\^done,bkpt={number=\"1\"") - self.runCmd("-exec-run") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Test that -exec-next steps over printf - self.runCmd("-exec-next --thread 1 --frame 0") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\"") - - # Test that -exec-step-instruction steps over non branching - # instruction - self.runCmd("-exec-step-instruction --thread 1 --frame 0") - self.expect("\^running") - self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\"") - - # Test that -exec-step-instruction steps into g_MyFunction - # instruction (and that --thread is optional) - - # In case of MIPS, there might be more than one instruction - # before actual call instruction (like load, move and call instructions). - # The -exec-step-instruction would step one assembly instruction. - # Thus we may not enter into g_MyFunction function. The -exec-step would definitely - # step into the function. - - if self.isMIPS(): - self.runCmd("-exec-step --frame 0") - else: - self.runCmd("-exec-step-instruction --frame 0") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"") - - # Test that -exec-step-instruction steps over non branching - # (and that --frame is optional) - self.runCmd("-exec-step-instruction --thread 1") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"") - - # Test that -exec-step-instruction steps into g_MyFunction - # (and that both --thread and --frame are optional) - self.runCmd("-exec-step-instruction") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\"g_MyFunction.*?\"") - - # 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.runCmd("-exec-step-instruction --thread 10") - self.expect("\^error,message=\"error: Thread index 10 is out of range") - - # Test that an invalid --frame is handled - # FIXME: no error is returned - self.runCmd("-exec-step-instruction --frame 10") - #self.expect("\^error: Frame index 10 is out of range") - - @skipIfRemote # We do not currently support remote debugging via the MI. - @skipIfWindows # llvm.org/pr24452: Get lldb-mi tests working on Windows - @skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races - def test_lldbmi_exec_finish(self): - """Test that 'lldb-mi --interpreter' works for -exec-finish.""" - - self.spawnLldbMi(args=None) - - # Load executable - self.runCmd("-file-exec-and-symbols %s" % self.myexe) - self.expect("\^done") - - # Set BP at g_MyFunction and run to BP - self.runCmd("-break-insert -f g_MyFunction") - self.expect("\^done,bkpt={number=\"1\"") - self.runCmd("-exec-run") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Test that -exec-finish returns from g_MyFunction - self.runCmd("-exec-finish --thread 1 --frame 0") - self.expect("\^running") - self.expect("\*stopped,reason=\"end-stepping-range\".+?func=\"main\"") - - # Run to BP inside s_MyFunction call - self.runCmd("-break-insert s_MyFunction") - self.expect("\^done,bkpt={number=\"2\"") - self.runCmd("-exec-continue") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Test that -exec-finish hits BP at g_MyFunction call inside - # s_MyFunction (and that --thread is optional) - self.runCmd("-exec-finish --frame 0") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Test that -exec-finish returns from g_MyFunction call inside - # s_MyFunction (and that --frame is optional) - self.runCmd("-exec-finish --thread 1") - self.expect("\^running") - self.expect( - "\*stopped,reason=\"end-stepping-range\".+?func=\".*?s_MyFunction.*?\"") - - # Test that -exec-finish returns from s_MyFunction - # (and that both --thread and --frame are optional) - self.runCmd("-exec-finish") - self.expect("\^running") - self.expect("\*stopped,reason=\"end-stepping-range\".+?func=\"main\"") - - # 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.runCmd("-exec-finish --thread 10") - self.expect("\^error,message=\"error: Thread index 10 is out of range") - - # Test that an invalid --frame is handled - # FIXME: no error is returned - #self.runCmd("-exec-finish --frame 10") - #self.expect("\^error: Frame index 10 is out of range") - - # Set BP at printf and run to BP - self.runCmd("-break-insert -f printf") - self.expect("\^done,bkpt={number=\"3\"") - self.runCmd("-exec-continue") - self.expect("\^running") - self.expect("\*stopped,reason=\"breakpoint-hit\"") - - # Test that -exec-finish returns from printf - self.runCmd("-exec-finish --thread 1 --frame 0") - self.expect("\^running") - self.expect("\*stopped,reason=\"end-stepping-range\".+?func=\"main\"") Index: lldb/trunk/tools/lldb-mi/MICmdCmdExec.h =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdExec.h +++ lldb/trunk/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: lldb/trunk/tools/lldb-mi/MICmdCmdExec.cpp =================================================================== --- lldb/trunk/tools/lldb-mi/MICmdCmdExec.cpp +++ lldb/trunk/tools/lldb-mi/MICmdCmdExec.cpp @@ -599,14 +599,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); } //++ @@ -621,21 +630,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; } @@ -727,14 +723,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); } //++ @@ -749,21 +754,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; } @@ -851,14 +843,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); } //++ @@ -873,21 +873,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; } @@ -948,25 +935,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()); + SetErrorDescription(CMIUtilString::Format( + MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE), + m_cmdData.strMiCmd.c_str(), + rErrMsg.c_str())); + return MIstatus::failure; + } + return MIstatus::success; + }; - return MIstatus::success; + return HandleSBErrorWithSuccess( + CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Stop(), + successHandler); } //++ @@ -981,19 +965,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; } @@ -1113,10 +1086,8 @@ // Throws: None. //-- bool CMICmdCmdExecArguments::Acknowledge() { - const CMICmnMIResultRecord miRecordResult( + m_miResultRecord = CMICmnMIResultRecord( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); - m_miResultRecord = miRecordResult; - return MIstatus::success; } @@ -1209,9 +1180,8 @@ // Throws: None. //-- bool CMICmdCmdExecAbort::Acknowledge() { - const CMICmnMIResultRecord miRecordResult( + m_miResultRecord = CMICmnMIResultRecord( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); - m_miResultRecord = miRecordResult; return MIstatus::success; }