//===-- MICmdCmdExec.cpp ----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //++ // File: MICmdCmdExec.cpp // // Overview: CMICmdCmdExecRun implementation. // CMICmdCmdExecContinue implementation. // CMICmdCmdExecNext implementation. // CMICmdCmdExecStep implementation. // CMICmdCmdExecNextInstruction implementation. // CMICmdCmdExecStepInstruction implementation. // CMICmdCmdExecFinish implementation. // CMICmdCmdExecInterrupt implementation. // // Environment: Compilers: Visual C++ 12. // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 // Libraries: See MIReadmetxt. // // Copyright: None. //-- // Third Party Headers: #include #include #include #include "lldb/lldb-enumerations.h" // In-house headers: #include "MICmdCmdExec.h" #include "MICmnMIResultRecord.h" #include "MICmnMIValueConst.h" #include "MICmnLLDBDebugger.h" #include "MICmnLLDBDebugSessionInfo.h" #include "MIDriver.h" #include "MICmdArgValNumber.h" #include "MICmdArgValString.h" #include "MICmdArgValThreadGrp.h" #include "MICmdArgValOptionLong.h" #include "MICmdArgValOptionShort.h" #include "MICmdArgValListOfN.h" #include "MICmnStreamStdout.h" #include "MICmnMIOutOfBandRecord.h" //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecRun constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecRun::CMICmdCmdExecRun(void) { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-run"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecRun::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecRun destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecRun::~CMICmdCmdExecRun(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecRun::Execute(void) { CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBError error; lldb::SBStream errMsg; uint32_t launch_flags = lldb::LaunchFlags::eLaunchFlagDebug; lldb::SBProcess process = rSessionInfo.m_lldbTarget.Launch(rSessionInfo.m_rLlldbListener, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, launch_flags, false, error); if ((!process.IsValid()) || (error.Fail())) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str(), errMsg.GetData())); return MIstatus::failure; } // Save the process in the session info rSessionInfo.m_lldbProcess = process; if (!CMIDriver::Instance().SetDriverStateRunningDebugging()) { const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription()); SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE), m_cmdData.strMiCmd.c_str(), rErrMsg.c_str())); return MIstatus::failure; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecRun::Acknowledge(void) { 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_Running); m_miResultRecord = miRecordResult; CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::pid_t pid = rSessionInfo.m_lldbProcess.GetProcessID(); // Give the client '=thread-group-started,id="i1" pid="xyz"' m_bHasResultRecordExtra = true; const CMICmnMIValueConst miValueConst2("i1"); const CMICmnMIValueResult miValueResult2("id", miValueConst2); const CMIUtilString strPid(CMIUtilString::Format("%lld", pid)); const CMICmnMIValueConst miValueConst(strPid); const CMICmnMIValueResult miValueResult("pid", miValueConst); CMICmnMIOutOfBandRecord miOutOfBand(CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupStarted, miValueResult2); miOutOfBand.Add(miValueResult); m_miResultRecordExtra = miOutOfBand.GetString(); } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecRun::CreateSelf(void) { return new CMICmdCmdExecRun(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecContinue constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecContinue::CMICmdCmdExecContinue(void) { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-continue"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecContinue::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecContinue destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecContinue::~CMICmdCmdExecContinue(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecContinue::Execute(void) { const MIchar *pCmd = "continue"; CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); const lldb::ReturnStatus rtn = rSessionInfo.m_rLldbDebugger.GetCommandInterpreter().HandleCommand(pCmd, m_lldbResult); MIunused(rtn); if (m_lldbResult.GetErrorSize() == 0) { // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM if (!CMIDriver::Instance().SetDriverStateRunningDebugging()) { const CMIUtilString &rErrMsg(CMIDriver::Instance().GetErrorDescription()); SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SET_NEW_DRIVER_STATE), m_cmdData.strMiCmd.c_str(), rErrMsg.c_str())); return MIstatus::failure; } } else { // ToDo: Re-evaluate if this is required when application near finished as this is parsing LLDB error message // which seems a hack and is code brittle const MIchar *pLldbErr = m_lldbResult.GetError(); const CMIUtilString strLldbMsg(CMIUtilString(pLldbErr).StripCREndOfLine()); if (strLldbMsg == "error: Process must be launched.") { CMIDriver::Instance().SetExitApplicationFlag(true); } } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecContinue::Acknowledge(void) { 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_Running); m_miResultRecord = miRecordResult; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecContinue::CreateSelf(void) { return new CMICmdCmdExecContinue(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecNext constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecNext::CMICmdCmdExecNext(void) : m_constStrArgThread("thread") , m_constStrArgNumber("number") { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-next"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecNext::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecNext destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecNext::~CMICmdCmdExecNext(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The parses the command line options // arguments to extract values for each of those arguments. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecNext::ParseArgs(void) { bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1))); bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false))); return (bOk && ParseValidateCmdOptions()); } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecNext::Execute(void) { CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if (!pArgThread->GetExpectedOption(nThreadId)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); return MIstatus::failure; } CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger; CMIUtilString strCmd("thread step-over"); if (nThreadId != UINT64_MAX) strCmd += CMIUtilString::Format(" %llu", nThreadId); rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult, false); return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecNext::Acknowledge(void) { if (m_lldbResult.GetErrorSize() > 0) { const MIchar *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; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecNext::CreateSelf(void) { return new CMICmdCmdExecNext(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecStep constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecStep::CMICmdCmdExecStep(void) : m_constStrArgThread("thread") , m_constStrArgNumber("number") { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-step"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecStep::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecStep destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecStep::~CMICmdCmdExecStep(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The parses the command line options // arguments to extract values for each of those arguments. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecStep::ParseArgs(void) { bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1))); bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false))); return (bOk && ParseValidateCmdOptions()); } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecStep::Execute(void) { CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if (!pArgThread->GetExpectedOption(nThreadId)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); return MIstatus::failure; } CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger; CMIUtilString strCmd("thread step-in"); if (nThreadId != UINT64_MAX) strCmd += CMIUtilString::Format(" %llu", nThreadId); rDebugger.GetCommandInterpreter().HandleCommand(strCmd.c_str(), m_lldbResult, false); return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecStep::Acknowledge(void) { if (m_lldbResult.GetErrorSize() > 0) { const MIchar *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; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecStep::CreateSelf(void) { return new CMICmdCmdExecStep(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecNextInstruction constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecNextInstruction::CMICmdCmdExecNextInstruction(void) : m_constStrArgThread("thread") , m_constStrArgNumber("number") { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-next-instruction"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecNextInstruction::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecNextInstruction destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecNextInstruction::~CMICmdCmdExecNextInstruction(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The parses the command line options // arguments to extract values for each of those arguments. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecNextInstruction::ParseArgs(void) { bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1))); bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false))); return (bOk && ParseValidateCmdOptions()); } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecNextInstruction::Execute(void) { CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if (!pArgThread->GetExpectedOption(nThreadId)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); return MIstatus::failure; } CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger; 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; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecNextInstruction::Acknowledge(void) { if (m_lldbResult.GetErrorSize() > 0) { const MIchar *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; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecNextInstruction::CreateSelf(void) { return new CMICmdCmdExecNextInstruction(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecStepInstruction constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecStepInstruction::CMICmdCmdExecStepInstruction(void) : m_constStrArgThread("thread") , m_constStrArgNumber("number") { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-step-instruction"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecStepInstruction::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecStepInstruction destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecStepInstruction::~CMICmdCmdExecStepInstruction(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The parses the command line options // arguments to extract values for each of those arguments. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecStepInstruction::ParseArgs(void) { bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1))); bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, false, false))); return (bOk && ParseValidateCmdOptions()); } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecStepInstruction::Execute(void) { CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if (!pArgThread->GetExpectedOption(nThreadId)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); return MIstatus::failure; } CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger; 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; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecStepInstruction::Acknowledge(void) { if (m_lldbResult.GetErrorSize() > 0) { const MIchar *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; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecStepInstruction::CreateSelf(void) { return new CMICmdCmdExecStepInstruction(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecFinish constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecFinish::CMICmdCmdExecFinish(void) : m_constStrArgThread("thread") , m_constStrArgFrame("frame") { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-finish"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecFinish::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecFinish destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecFinish::~CMICmdCmdExecFinish(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The parses the command line options // arguments to extract values for each of those arguments. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecFinish::ParseArgs(void) { bool bOk = m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1))); bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, false, CMICmdArgValListBase::eArgValType_Number, 1))); return (bOk && ParseValidateCmdOptions()); } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecFinish::Execute(void) { CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread); // Retrieve the --thread option's thread ID (only 1) MIuint64 nThreadId = UINT64_MAX; if (!pArgThread->GetExpectedOption(nThreadId)) { SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str())); return MIstatus::failure; } CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger; 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; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecFinish::Acknowledge(void) { if (m_lldbResult.GetErrorSize() > 0) { const MIchar *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; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecFinish::CreateSelf(void) { return new CMICmdCmdExecFinish(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecInterrupt constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecInterrupt::CMICmdCmdExecInterrupt(void) { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "exec-interrupt"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdExecInterrupt::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdExecInterrupt destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdExecInterrupt::~CMICmdCmdExecInterrupt(void) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecInterrupt::Execute(void) { CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); lldb::SBDebugger &rDebugger = rSessionInfo.m_rLldbDebugger; 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; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdExecInterrupt::Acknowledge(void) { 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; } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdExecInterrupt::CreateSelf(void) { return new CMICmdCmdExecInterrupt(); }