#include "lldb/API/SBCommandInterpreter.h"
#include "lldb/API/SBThread.h"
#include "MICmdArgValFile.h"
#include "MICmdArgValListOfN.h"
#include "MICmdArgValNumber.h"
#include "MICmdArgValOptionLong.h"
#include "MICmdArgValOptionShort.h"
#include "MICmdArgValString.h"
#include "MICmdArgValThreadGrp.h"
#include "MICmdCmdMiscellanous.h"
#include "MICmnLLDBDebugSessionInfo.h"
#include "MICmnLLDBDebugger.h"
#include "MICmnMIOutOfBandRecord.h"
#include "MICmnMIResultRecord.h"
#include "MICmnMIValueConst.h"
#include "MICmnStreamStderr.h"
#include "MICmnStreamStdout.h"
#include "MIDriverBase.h"
CMICmdCmdGdbExit::CMICmdCmdGdbExit() {
m_strMiCmd = "gdb-exit";
m_pSelfCreatorFn = &CMICmdCmdGdbExit::CreateSelf;
}
CMICmdCmdGdbExit::~CMICmdCmdGdbExit() {}
bool CMICmdCmdGdbExit::Execute() {
CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(true);
const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.GetProcess().Destroy();
return MIstatus::success;
}
bool CMICmdCmdGdbExit::Acknowledge() {
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Exit);
m_miResultRecord = miRecordResult;
m_bHasResultRecordExtra = true;
const CMICmnMIValueConst miValueConst2("i1");
const CMICmnMIValueResult miValueResult2("id", miValueConst2);
const CMICmnMIOutOfBandRecord miOutOfBand(
CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult2);
m_miResultRecordExtra = miOutOfBand.GetString();
return MIstatus::success;
}
CMICmdBase *CMICmdCmdGdbExit::CreateSelf() { return new CMICmdCmdGdbExit(); }
CMICmdCmdListThreadGroups::CMICmdCmdListThreadGroups()
: m_bIsI1(false), m_bHaveArgOption(false), m_bHaveArgRecurse(false),
m_constStrArgNamedAvailable("available"),
m_constStrArgNamedRecurse("recurse"), m_constStrArgNamedGroup("group"),
m_constStrArgNamedThreadGroup("i1") {
m_strMiCmd = "list-thread-groups";
m_pSelfCreatorFn = &CMICmdCmdListThreadGroups::CreateSelf;
}
CMICmdCmdListThreadGroups::~CMICmdCmdListThreadGroups() {
m_vecMIValueTuple.clear();
}
bool CMICmdCmdListThreadGroups::ParseArgs() {
m_setCmdArgs.Add(
new CMICmdArgValOptionLong(m_constStrArgNamedAvailable, false, true));
m_setCmdArgs.Add(
new CMICmdArgValOptionLong(m_constStrArgNamedRecurse, false, true,
CMICmdArgValListBase::eArgValType_Number, 1));
m_setCmdArgs.Add(
new CMICmdArgValListOfN(m_constStrArgNamedGroup, false, true,
CMICmdArgValListBase::eArgValType_Number));
m_setCmdArgs.Add(
new CMICmdArgValThreadGrp(m_constStrArgNamedThreadGroup, false, true));
return ParseValidateCmdOptions();
}
bool CMICmdCmdListThreadGroups::Execute() {
if (m_setCmdArgs.IsArgContextEmpty())
return MIstatus::success;
CMICMDBASE_GETOPTION(pArgAvailable, OptionLong, m_constStrArgNamedAvailable);
CMICMDBASE_GETOPTION(pArgRecurse, OptionLong, m_constStrArgNamedRecurse);
CMICMDBASE_GETOPTION(pArgThreadGroup, ThreadGrp,
m_constStrArgNamedThreadGroup);
if (pArgAvailable->GetFound()) {
if (pArgRecurse->GetFound()) {
m_bHaveArgRecurse = true;
return MIstatus::success;
}
m_bHaveArgOption = true;
return MIstatus::success;
}
if (!pArgThreadGroup->GetFound())
return MIstatus::success;
m_bIsI1 = true;
CMICmnLLDBDebugSessionInfo &rSessionInfo(
CMICmnLLDBDebugSessionInfo::Instance());
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
m_vecMIValueTuple.clear();
const MIuint nThreads = sbProcess.GetNumThreads();
for (MIuint i = 0; i < nThreads; i++) {
lldb::SBThread thread = sbProcess.GetThreadAtIndex(i);
if (thread.IsValid()) {
CMICmnMIValueTuple miTuple;
if (!rSessionInfo.MIResponseFormThreadInfo(
m_cmdData, thread,
CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_NoFrames, miTuple))
return MIstatus::failure;
m_vecMIValueTuple.push_back(miTuple);
}
}
return MIstatus::success;
}
bool CMICmdCmdListThreadGroups::Acknowledge() {
if (m_bHaveArgOption) {
if (m_bHaveArgRecurse) {
const CMICmnMIValueConst miValueConst(
MIRSRC(IDS_WORD_NOT_IMPLEMENTED_BRKTS));
const CMICmnMIValueResult miValueResult("msg", miValueConst);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
const CMICmnMIValueConst miValueConst1("i1");
const CMICmnMIValueResult miValueResult1("id", miValueConst1);
CMICmnMIValueTuple miTuple(miValueResult1);
const CMICmnMIValueConst miValueConst2("process");
const CMICmnMIValueResult miValueResult2("type", miValueConst2);
miTuple.Add(miValueResult2);
CMICmnLLDBDebugSessionInfo &rSessionInfo(
CMICmnLLDBDebugSessionInfo::Instance());
if (rSessionInfo.GetProcess().IsValid()) {
const lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
const CMICmnMIValueConst miValueConst3(strPid);
const CMICmnMIValueResult miValueResult3("pid", miValueConst3);
miTuple.Add(miValueResult3);
}
const CMICmnMIValueConst miValueConst4(
MIRSRC(IDS_WORD_NOT_IMPLEMENTED_BRKTS));
const CMICmnMIValueResult miValueResult4("num_children", miValueConst4);
miTuple.Add(miValueResult4);
const CMICmnMIValueConst miValueConst5(
MIRSRC(IDS_WORD_NOT_IMPLEMENTED_BRKTS));
const CMICmnMIValueResult miValueResult5("cores", miValueConst5);
miTuple.Add(miValueResult5);
const CMICmnMIValueList miValueList(miTuple);
const CMICmnMIValueResult miValueResult6("groups", miValueList);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
miValueResult6);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
if (!m_bIsI1) {
const CMICmnMIValueConst miValueConst1("i1");
const CMICmnMIValueResult miValueResult1("id", miValueConst1);
CMICmnMIValueTuple miTuple(miValueResult1);
const CMICmnMIValueConst miValueConst2("process");
const CMICmnMIValueResult miValueResult2("type", miValueConst2);
miTuple.Add(miValueResult2);
CMICmnLLDBDebugSessionInfo &rSessionInfo(
CMICmnLLDBDebugSessionInfo::Instance());
if (rSessionInfo.GetProcess().IsValid()) {
const lldb::pid_t pid = rSessionInfo.GetProcess().GetProcessID();
const CMIUtilString strPid(CMIUtilString::Format("%lld", pid));
const CMICmnMIValueConst miValueConst3(strPid);
const CMICmnMIValueResult miValueResult3("pid", miValueConst3);
miTuple.Add(miValueResult3);
}
if (rSessionInfo.GetTarget().IsValid()) {
lldb::SBTarget sbTrgt = rSessionInfo.GetTarget();
const char *pDir = sbTrgt.GetExecutable().GetDirectory();
const char *pFileName = sbTrgt.GetExecutable().GetFilename();
const CMIUtilString strFile(
CMIUtilString::Format("%s/%s", CMIUtilString::WithNullAsEmpty(pDir),
CMIUtilString::WithNullAsEmpty(pFileName)));
const CMICmnMIValueConst miValueConst4(strFile);
const CMICmnMIValueResult miValueResult4("executable", miValueConst4);
miTuple.Add(miValueResult4);
}
const CMICmnMIValueList miValueList(miTuple);
const CMICmnMIValueResult miValueResult5("groups", miValueList);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
miValueResult5);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
VecMIValueTuple_t::const_iterator it = m_vecMIValueTuple.begin();
if (it == m_vecMIValueTuple.end()) {
const CMICmnMIValueConst miValueConst("[]");
const CMICmnMIValueResult miValueResult("threads", miValueConst);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
CMICmnMIValueList miValueList(*it);
++it;
while (it != m_vecMIValueTuple.end()) {
const CMICmnMIValueTuple &rTuple(*it);
miValueList.Add(rTuple);
++it;
}
const CMICmnMIValueResult miValueResult("threads", miValueList);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
miValueResult);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
CMICmdBase *CMICmdCmdListThreadGroups::CreateSelf() {
return new CMICmdCmdListThreadGroups();
}
CMICmdCmdInterpreterExec::CMICmdCmdInterpreterExec()
: m_constStrArgNamedInterpreter("interpreter"),
m_constStrArgNamedCommand("command") {
m_strMiCmd = "interpreter-exec";
m_pSelfCreatorFn = &CMICmdCmdInterpreterExec::CreateSelf;
}
CMICmdCmdInterpreterExec::~CMICmdCmdInterpreterExec() {}
bool CMICmdCmdInterpreterExec::ParseArgs() {
m_setCmdArgs.Add(
new CMICmdArgValString(m_constStrArgNamedInterpreter, true, true));
m_setCmdArgs.Add(
new CMICmdArgValString(m_constStrArgNamedCommand, true, true, true));
return ParseValidateCmdOptions();
}
bool CMICmdCmdInterpreterExec::Execute() {
CMICMDBASE_GETOPTION(pArgInterpreter, String, m_constStrArgNamedInterpreter);
CMICMDBASE_GETOPTION(pArgCommand, String, m_constStrArgNamedCommand);
const CMIUtilString &rStrInterpreter(pArgInterpreter->GetValue());
MIunused(rStrInterpreter);
const CMIUtilString &rStrCommand(pArgCommand->GetValue());
CMICmnLLDBDebugSessionInfo &rSessionInfo(
CMICmnLLDBDebugSessionInfo::Instance());
const lldb::ReturnStatus rtn =
rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(
rStrCommand.c_str(), m_lldbResult, true);
MIunused(rtn);
return MIstatus::success;
}
bool CMICmdCmdInterpreterExec::Acknowledge() {
#ifdef MS_DEBUGGER
if (m_lldbResult.GetErrorSize() > 0 && m_lldbResult.GetOutputSize() > 0) {
#else
if (m_lldbResult.GetOutputSize() > 0) {
#endif
const CMIUtilString line(m_lldbResult.GetOutput());
const bool bEscapeQuotes(true);
CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
CMICmnMIOutOfBandRecord miOutOfBandRecord(
CMICmnMIOutOfBandRecord::eOutOfBand_ConsoleStreamOutput, miValueConst);
const bool bOk =
CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
if (!bOk)
return MIstatus::failure;
}
if (m_lldbResult.GetErrorSize() > 0) {
const CMIUtilString line(m_lldbResult.GetError());
const bool bEscapeQuotes(true);
CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
CMICmnMIOutOfBandRecord miOutOfBandRecord(
CMICmnMIOutOfBandRecord::eOutOfBand_LogStreamOutput, miValueConst);
const bool bOk =
CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
if (!bOk)
return MIstatus::failure;
}
#ifdef MS_DEBUGGER
if (m_lldbResult.GetOutputSize() > 0) {
const CMIUtilString line(m_lldbResult.GetOutput());
const bool bEscapeQuotes(true);
CMICmnMIValueConst miValueConst(line.Escape(bEscapeQuotes));
const CMICmnMIValueResult miValueResult("result", miValueConst);
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
miValueResult);
m_miResultRecord = miRecordResult;
} else {
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
m_miResultRecord = miRecordResult;
}
#else
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
m_miResultRecord = miRecordResult;
#endif
return MIstatus::success;
}
CMICmdBase *CMICmdCmdInterpreterExec::CreateSelf() {
return new CMICmdCmdInterpreterExec();
}
CMICmdCmdInferiorTtySet::CMICmdCmdInferiorTtySet() {
m_strMiCmd = "inferior-tty-set";
m_pSelfCreatorFn = &CMICmdCmdInferiorTtySet::CreateSelf;
}
CMICmdCmdInferiorTtySet::~CMICmdCmdInferiorTtySet() {}
bool CMICmdCmdInferiorTtySet::Execute() {
return MIstatus::success;
}
bool CMICmdCmdInferiorTtySet::Acknowledge() {
const CMICmnMIResultRecord miRecordResult(
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error);
m_miResultRecord = miRecordResult;
return MIstatus::success;
}
CMICmdBase *CMICmdCmdInferiorTtySet::CreateSelf() {
return new CMICmdCmdInferiorTtySet();
}