A lot of comments in LLDB are surrounded by an ASCII line to delimit the begging and end of the comment. Its use is not really consistent across the code base, sometimes the lines are longer, sometimes they are shorter and sometimes they are omitted. Furthermore, it looks kind of weird with the 80 column limit, where the comment actually extends past the line, but not by much. Furthermore, when /// is used for Doxygen comments, it looks particularly odd. And when // is used, it incorrectly gives the impression that it's actually a Doxygen comment. I assume these lines were added to improve distinguishing between comments and code. However, given that todays editors and IDEs do a great job at highlighting comments, I think it's worth to drop this for the sake of consistency. The alternative is fixing all the inconsistencies, which would create a lot more churn. Differential revision: https://reviews.llvm.org/D60508 llvm-svn: 358135
1116 lines
35 KiB
C++
1116 lines
35 KiB
C++
//===-- MICmdCmdExec.cpp ----------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Overview: CMICmdCmdExecRun implementation.
|
|
// CMICmdCmdExecContinue implementation.
|
|
// CMICmdCmdExecNext implementation.
|
|
// CMICmdCmdExecStep implementation.
|
|
// CMICmdCmdExecNextInstruction implementation.
|
|
// CMICmdCmdExecStepInstruction implementation.
|
|
// CMICmdCmdExecFinish implementation.
|
|
// CMICmdCmdExecInterrupt implementation.
|
|
// CMICmdCmdExecArguments implementation.
|
|
// CMICmdCmdExecAbort implementation.
|
|
|
|
// Third Party Headers:
|
|
#include "lldb/API/SBCommandInterpreter.h"
|
|
#include "lldb/API/SBProcess.h"
|
|
#include "lldb/API/SBStream.h"
|
|
#include "lldb/API/SBThread.h"
|
|
#include "lldb/lldb-enumerations.h"
|
|
|
|
// In-house headers:
|
|
#include "MICmdArgValListOfN.h"
|
|
#include "MICmdArgValNumber.h"
|
|
#include "MICmdArgValOptionLong.h"
|
|
#include "MICmdArgValOptionShort.h"
|
|
#include "MICmdArgValString.h"
|
|
#include "MICmdArgValThreadGrp.h"
|
|
#include "MICmdCmdExec.h"
|
|
#include "MICmnLLDBDebugSessionInfo.h"
|
|
#include "MICmnLLDBDebugger.h"
|
|
#include "MICmnMIOutOfBandRecord.h"
|
|
#include "MICmnMIResultRecord.h"
|
|
#include "MICmnMIValueConst.h"
|
|
#include "MICmnStreamStdout.h"
|
|
#include "MIDriver.h"
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecRun constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecRun::CMICmdCmdExecRun() : m_constStrArgStart("start") {
|
|
// 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() {}
|
|
|
|
//++
|
|
// Details: The invoker requires this function. It 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 CMICmdCmdExecRun::ParseArgs() {
|
|
m_setCmdArgs.Add(new CMICmdArgValOptionLong(
|
|
m_constStrArgStart, false, true,
|
|
CMICmdArgValListBase::eArgValType_OptionLong, 0));
|
|
return 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 CMICmdCmdExecRun::Execute() {
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(
|
|
CMICmnLLDBDebugSessionInfo::Instance());
|
|
|
|
{
|
|
// Check we have a valid target.
|
|
// Note: target created via 'file-exec-and-symbols' command.
|
|
lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
|
|
if (!sbTarget.IsValid() ||
|
|
sbTarget == rSessionInfo.GetDebugger().GetDummyTarget()) {
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
|
|
m_cmdData.strMiCmd.c_str()));
|
|
return MIstatus::failure;
|
|
}
|
|
}
|
|
|
|
lldb::SBError error;
|
|
lldb::SBStream errMsg;
|
|
lldb::SBLaunchInfo launchInfo = rSessionInfo.GetTarget().GetLaunchInfo();
|
|
launchInfo.SetListener(rSessionInfo.GetListener());
|
|
|
|
// Run to first instruction or main() requested?
|
|
CMICMDBASE_GETOPTION(pArgStart, OptionLong, m_constStrArgStart);
|
|
if (pArgStart->GetFound()) {
|
|
launchInfo.SetLaunchFlags(launchInfo.GetLaunchFlags() |
|
|
lldb::eLaunchFlagStopAtEntry);
|
|
}
|
|
|
|
lldb::SBProcess process = rSessionInfo.GetTarget().Launch(launchInfo, error);
|
|
if (!process.IsValid()) {
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
|
|
m_cmdData.strMiCmd.c_str(),
|
|
errMsg.GetData()));
|
|
return MIstatus::failure;
|
|
}
|
|
|
|
const auto successHandler = [this] {
|
|
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;
|
|
};
|
|
|
|
return HandleSBErrorWithSuccess(error, successHandler);
|
|
}
|
|
|
|
//++
|
|
// Details: The invoker requires this function. The command prepares a MI Record
|
|
// Result
|
|
// for the work carried out in the Execute().
|
|
// Called only if Execute() set status as successful on completion.
|
|
// Type: Overridden.
|
|
// Args: None.
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
// MIstatus::failure - Functional failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdCmdExecRun::Acknowledge() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(
|
|
CMICmnLLDBDebugSessionInfo::Instance());
|
|
lldb::pid_t pid = rSessionInfo.GetProcess().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() { return new CMICmdCmdExecRun(); }
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecContinue constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecContinue::CMICmdCmdExecContinue() {
|
|
// 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() {}
|
|
|
|
//++
|
|
// 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() {
|
|
const auto successHandler = [this] {
|
|
// 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;
|
|
}
|
|
return MIstatus::success;
|
|
};
|
|
|
|
return HandleSBErrorWithSuccess(
|
|
CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Continue(),
|
|
successHandler);
|
|
}
|
|
|
|
//++
|
|
// 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() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
|
|
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() {
|
|
return new CMICmdCmdExecContinue();
|
|
}
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecNext constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecNext::CMICmdCmdExecNext() : 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() {}
|
|
|
|
//++
|
|
// 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() {
|
|
m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
|
|
return 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() {
|
|
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
|
|
|
|
// Retrieve the --thread option's thread ID (only 1)
|
|
MIuint64 nThreadId = UINT64_MAX;
|
|
if (pArgThread->GetFound() &&
|
|
!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(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::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.StepOver(lldb::eOnlyDuringStepping, error);
|
|
} else
|
|
rSessionInfo.GetProcess().GetSelectedThread().StepOver(
|
|
lldb::eOnlyDuringStepping, error);
|
|
|
|
return HandleSBError(error);
|
|
}
|
|
|
|
//++
|
|
// 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() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
|
|
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() { return new CMICmdCmdExecNext(); }
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecStep constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecStep::CMICmdCmdExecStep() : 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() {}
|
|
|
|
//++
|
|
// 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() {
|
|
m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
|
|
return 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() {
|
|
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
|
|
|
|
// Retrieve the --thread option's thread ID (only 1)
|
|
MIuint64 nThreadId = UINT64_MAX;
|
|
if (pArgThread->GetFound() &&
|
|
!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(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::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.StepInto(nullptr, LLDB_INVALID_LINE_NUMBER, error);
|
|
} else
|
|
rSessionInfo.GetProcess().GetSelectedThread().StepInto(
|
|
nullptr, LLDB_INVALID_LINE_NUMBER, error);
|
|
|
|
return HandleSBError(error);
|
|
}
|
|
|
|
//++
|
|
// 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() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
|
|
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() { return new CMICmdCmdExecStep(); }
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecNextInstruction constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecNextInstruction::CMICmdCmdExecNextInstruction()
|
|
: 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() {}
|
|
|
|
//++
|
|
// 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() {
|
|
m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
|
|
return 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() {
|
|
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
|
|
|
|
// Retrieve the --thread option's thread ID (only 1)
|
|
MIuint64 nThreadId = UINT64_MAX;
|
|
if (pArgThread->GetFound() &&
|
|
!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(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::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);
|
|
}
|
|
|
|
//++
|
|
// 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() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
|
|
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() {
|
|
return new CMICmdCmdExecNextInstruction();
|
|
}
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecStepInstruction constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecStepInstruction::CMICmdCmdExecStepInstruction()
|
|
: 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() {}
|
|
|
|
//++
|
|
// 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() {
|
|
m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, false, false));
|
|
return 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() {
|
|
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
|
|
|
|
// Retrieve the --thread option's thread ID (only 1)
|
|
MIuint64 nThreadId = UINT64_MAX;
|
|
if (pArgThread->GetFound() &&
|
|
!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(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::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);
|
|
}
|
|
|
|
//++
|
|
// 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() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
|
|
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() {
|
|
return new CMICmdCmdExecStepInstruction();
|
|
}
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecFinish constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecFinish::CMICmdCmdExecFinish() {
|
|
// 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() {}
|
|
|
|
//++
|
|
// 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() { return 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() {
|
|
CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
|
|
|
|
// Retrieve the --thread option's thread ID (only 1)
|
|
MIuint64 nThreadId = UINT64_MAX;
|
|
if (pArgThread->GetFound() &&
|
|
!pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(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::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);
|
|
}
|
|
|
|
//++
|
|
// 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() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Running);
|
|
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() {
|
|
return new CMICmdCmdExecFinish();
|
|
}
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecInterrupt constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecInterrupt::CMICmdCmdExecInterrupt() {
|
|
// 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() {}
|
|
|
|
//++
|
|
// 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() {
|
|
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 HandleSBErrorWithSuccess(
|
|
CMICmnLLDBDebugSessionInfo::Instance().GetProcess().Stop(),
|
|
successHandler);
|
|
}
|
|
|
|
//++
|
|
// 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() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
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() {
|
|
return new CMICmdCmdExecInterrupt();
|
|
}
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecArguments constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecArguments::CMICmdCmdExecArguments()
|
|
: m_constStrArgArguments("arguments") {
|
|
// Command factory matches this name with that received from the stdin stream
|
|
m_strMiCmd = "exec-arguments";
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
m_pSelfCreatorFn = &CMICmdCmdExecArguments::CreateSelf;
|
|
}
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecArguments destructor.
|
|
// Type: Overrideable.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecArguments::~CMICmdCmdExecArguments() {}
|
|
|
|
//++
|
|
// 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 - Function succeeded.
|
|
// MIstatus::failure - Function failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdCmdExecArguments::ParseArgs() {
|
|
m_setCmdArgs.Add(new CMICmdArgValListOfN(
|
|
m_constStrArgArguments, false, true,
|
|
CMICmdArgValListBase::eArgValType_StringAnything));
|
|
return 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 - Function succeeded.
|
|
// MIstatus::failure - Function failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdCmdExecArguments::Execute() {
|
|
CMICMDBASE_GETOPTION(pArgArguments, ListOfN, m_constStrArgArguments);
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(
|
|
CMICmnLLDBDebugSessionInfo::Instance());
|
|
lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
|
|
if (!sbTarget.IsValid()) {
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_TARGET_CURRENT),
|
|
m_cmdData.strMiCmd.c_str()));
|
|
return MIstatus::failure;
|
|
}
|
|
|
|
lldb::SBLaunchInfo sbLaunchInfo = sbTarget.GetLaunchInfo();
|
|
sbLaunchInfo.SetArguments(NULL, false);
|
|
|
|
CMIUtilString strArg;
|
|
size_t nArgIndex = 0;
|
|
while (pArgArguments->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
|
|
strArg, nArgIndex)) {
|
|
const char *argv[2] = {strArg.c_str(), NULL};
|
|
sbLaunchInfo.SetArguments(argv, true);
|
|
++nArgIndex;
|
|
}
|
|
|
|
sbTarget.SetLaunchInfo(sbLaunchInfo);
|
|
|
|
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 - Function succeeded.
|
|
// MIstatus::failure - Function failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdCmdExecArguments::Acknowledge() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
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 *CMICmdCmdExecArguments::CreateSelf() {
|
|
return new CMICmdCmdExecArguments();
|
|
}
|
|
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecAbort constructor.
|
|
// Type: Method.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecAbort::CMICmdCmdExecAbort() {
|
|
// Command factory matches this name with that received from the stdin stream
|
|
m_strMiCmd = "exec-abort";
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
m_pSelfCreatorFn = &CMICmdCmdExecAbort::CreateSelf;
|
|
}
|
|
|
|
//++
|
|
// Details: CMICmdCmdExecAbort destructor.
|
|
// Type: Overrideable.
|
|
// Args: None.
|
|
// Return: None.
|
|
// Throws: None.
|
|
//--
|
|
CMICmdCmdExecAbort::~CMICmdCmdExecAbort() {}
|
|
|
|
//++
|
|
// 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 - Function succeeded.
|
|
// MIstatus::failure - Function failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdCmdExecAbort::Execute() {
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(
|
|
CMICmnLLDBDebugSessionInfo::Instance());
|
|
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
|
|
if (!sbProcess.IsValid()) {
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
|
|
m_cmdData.strMiCmd.c_str()));
|
|
return MIstatus::failure;
|
|
}
|
|
|
|
lldb::SBError sbError = sbProcess.Destroy();
|
|
if (sbError.Fail()) {
|
|
SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDBPROCESS_DESTROY),
|
|
m_cmdData.strMiCmd.c_str(),
|
|
sbError.GetCString()));
|
|
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 - Function succeeded.
|
|
// MIstatus::failure - Function failed.
|
|
// Throws: None.
|
|
//--
|
|
bool CMICmdCmdExecAbort::Acknowledge() {
|
|
m_miResultRecord = CMICmnMIResultRecord(
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
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 *CMICmdCmdExecAbort::CreateSelf() {
|
|
return new CMICmdCmdExecAbort();
|
|
}
|