2014-05-16 18:51:01 +08:00
|
|
|
//===-- MICmdCmdMiscellanous.cpp --------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2014-11-18 02:06:21 +08:00
|
|
|
// Overview: CMICmdCmdGdbExit implementation.
|
|
|
|
// CMICmdCmdListThreadGroups implementation.
|
|
|
|
// CMICmdCmdInterpreterExec implementation.
|
|
|
|
// CMICmdCmdInferiorTtySet implementation.
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
// Third Party Headers:
|
2015-01-20 08:04:26 +08:00
|
|
|
#include "lldb/API/SBCommandInterpreter.h"
|
|
|
|
#include "lldb/API/SBThread.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
// In-house headers:
|
|
|
|
#include "MICmdArgValFile.h"
|
2016-09-07 04:57:50 +08:00
|
|
|
#include "MICmdArgValListOfN.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
#include "MICmdArgValNumber.h"
|
|
|
|
#include "MICmdArgValOptionLong.h"
|
|
|
|
#include "MICmdArgValOptionShort.h"
|
2016-09-07 04:57:50 +08:00
|
|
|
#include "MICmdArgValString.h"
|
|
|
|
#include "MICmdArgValThreadGrp.h"
|
|
|
|
#include "MICmdCmdMiscellanous.h"
|
|
|
|
#include "MICmnLLDBDebugSessionInfo.h"
|
|
|
|
#include "MICmnLLDBDebugger.h"
|
|
|
|
#include "MICmnMIOutOfBandRecord.h"
|
|
|
|
#include "MICmnMIResultRecord.h"
|
|
|
|
#include "MICmnMIValueConst.h"
|
2014-06-25 00:35:50 +08:00
|
|
|
#include "MICmnStreamStderr.h"
|
2016-09-07 04:57:50 +08:00
|
|
|
#include "MICmnStreamStdout.h"
|
|
|
|
#include "MIDriverBase.h"
|
2014-05-16 18:51:01 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdGdbExit constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdCmdGdbExit::CMICmdCmdGdbExit() {
|
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "gdb-exit";
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdGdbExit::CreateSelf;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdGdbExit destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdCmdGdbExit::~CMICmdCmdGdbExit() {}
|
|
|
|
|
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// 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.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdGdbExit::Execute() {
|
|
|
|
CMICmnLLDBDebugger::Instance().GetDriver().SetExitApplicationFlag(true);
|
|
|
|
const lldb::SBError sbErr = m_rLLDBDebugSessionInfo.GetProcess().Destroy();
|
|
|
|
// Do not check for sbErr.Fail() here, m_lldbProcess is likely !IsValid()
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record
|
|
|
|
// Result
|
2014-11-18 02:06:21 +08:00
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdGdbExit::Acknowledge() {
|
|
|
|
const CMICmnMIResultRecord miRecordResult(
|
|
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Exit);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
|
|
|
|
// Prod the client i.e. Eclipse with out-of-band results to help it 'continue'
|
|
|
|
// because it is using LLDB debugger
|
|
|
|
// Give the client '=thread-group-exited,id="i1"'
|
|
|
|
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;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The
|
|
|
|
// factory
|
2014-11-18 02:06:21 +08:00
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdBase *CMICmdCmdGdbExit::CreateSelf() { return new CMICmdCmdGdbExit(); }
|
2014-05-16 18:51:01 +08:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdListThreadGroups constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2015-08-04 18:24:20 +08:00
|
|
|
CMICmdCmdListThreadGroups::CMICmdCmdListThreadGroups()
|
2016-09-07 04:57:50 +08:00
|
|
|
: m_bIsI1(false), m_bHaveArgOption(false), m_bHaveArgRecurse(false),
|
|
|
|
m_constStrArgNamedAvailable("available"),
|
|
|
|
m_constStrArgNamedRecurse("recurse"), m_constStrArgNamedGroup("group"),
|
|
|
|
m_constStrArgNamedThreadGroup("i1") {
|
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "list-thread-groups";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdListThreadGroups::CreateSelf;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdListThreadGroups destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdCmdListThreadGroups::~CMICmdCmdListThreadGroups() {
|
|
|
|
m_vecMIValueTuple.clear();
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: The invoker requires this function. The parses the command line
|
|
|
|
// options
|
2014-11-18 02:06:21 +08:00
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
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();
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// 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.
|
|
|
|
// Synopsis: -list-thread-groups [ --available ] [ --recurse 1 ] [
|
|
|
|
// group ... ]
|
|
|
|
// This command does not follow the MI documentation exactly. Has an
|
|
|
|
// extra
|
2014-11-18 02:06:21 +08:00
|
|
|
// argument "i1" to handle.
|
|
|
|
// Ref:
|
|
|
|
// http://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Miscellaneous-Commands.html#GDB_002fMI-Miscellaneous-Commands
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdListThreadGroups::Execute() {
|
|
|
|
if (m_setCmdArgs.IsArgContextEmpty())
|
|
|
|
// No options so "top level thread groups"
|
|
|
|
return MIstatus::success;
|
|
|
|
|
|
|
|
CMICMDBASE_GETOPTION(pArgAvailable, OptionLong, m_constStrArgNamedAvailable);
|
|
|
|
CMICMDBASE_GETOPTION(pArgRecurse, OptionLong, m_constStrArgNamedRecurse);
|
|
|
|
CMICMDBASE_GETOPTION(pArgThreadGroup, ThreadGrp,
|
|
|
|
m_constStrArgNamedThreadGroup);
|
|
|
|
|
|
|
|
// Got some options so "threads"
|
|
|
|
if (pArgAvailable->GetFound()) {
|
|
|
|
if (pArgRecurse->GetFound()) {
|
|
|
|
m_bHaveArgRecurse = true;
|
|
|
|
return MIstatus::success;
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
m_bHaveArgOption = true;
|
2014-11-18 02:06:21 +08:00
|
|
|
return MIstatus::success;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
// "i1" as first argument (pos 0 of possible arg)
|
|
|
|
if (!pArgThreadGroup->GetFound())
|
|
|
|
return MIstatus::success;
|
|
|
|
m_bIsI1 = true;
|
|
|
|
|
|
|
|
CMICmnLLDBDebugSessionInfo &rSessionInfo(
|
|
|
|
CMICmnLLDBDebugSessionInfo::Instance());
|
|
|
|
lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
|
|
|
|
|
|
|
|
// Note do not check for sbProcess is IsValid(), continue
|
|
|
|
|
|
|
|
m_vecMIValueTuple.clear();
|
|
|
|
const MIuint nThreads = sbProcess.GetNumThreads();
|
|
|
|
for (MIuint i = 0; i < nThreads; i++) {
|
|
|
|
// GetThreadAtIndex() uses a base 0 index
|
|
|
|
// GetThreadByIndexID() uses a base 1 index
|
|
|
|
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;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record
|
|
|
|
// Result
|
2014-11-18 02:06:21 +08:00
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
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;
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
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);
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
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);
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
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", pDir, pFileName));
|
|
|
|
const CMICmnMIValueConst miValueConst4(strFile);
|
|
|
|
const CMICmnMIValueResult miValueResult4("executable", miValueConst4);
|
|
|
|
miTuple.Add(miValueResult4);
|
2014-11-18 02:06:21 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
const CMICmnMIValueList miValueList(miTuple);
|
|
|
|
const CMICmnMIValueResult miValueResult5("groups", miValueList);
|
|
|
|
const CMICmnMIResultRecord miRecordResult(
|
|
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
|
|
|
|
miValueResult5);
|
2014-11-18 02:06:21 +08:00
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
return MIstatus::success;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Build up a list of thread information from tuples
|
|
|
|
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);
|
|
|
|
|
|
|
|
// Next
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
const CMICmnMIValueResult miValueResult("threads", miValueList);
|
|
|
|
const CMICmnMIResultRecord miRecordResult(
|
|
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
|
|
|
|
miValueResult);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-05-16 18:51:01 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The
|
|
|
|
// factory
|
2014-11-18 02:06:21 +08:00
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-05-16 18:51:01 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdBase *CMICmdCmdListThreadGroups::CreateSelf() {
|
|
|
|
return new CMICmdCmdListThreadGroups();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdInterpreterExec constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2015-08-04 18:24:20 +08:00
|
|
|
CMICmdCmdInterpreterExec::CMICmdCmdInterpreterExec()
|
2016-09-07 04:57:50 +08:00
|
|
|
: m_constStrArgNamedInterpreter("interpreter"),
|
|
|
|
m_constStrArgNamedCommand("command") {
|
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "interpreter-exec";
|
|
|
|
|
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdInterpreterExec::CreateSelf;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdInterpreterExec destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdCmdInterpreterExec::~CMICmdCmdInterpreterExec() {}
|
2014-06-25 00:35:50 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: The invoker requires this function. The parses the command line
|
|
|
|
// options
|
2014-11-18 02:06:21 +08:00
|
|
|
// arguments to extract values for each of those arguments.
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdInterpreterExec::ParseArgs() {
|
|
|
|
m_setCmdArgs.Add(
|
|
|
|
new CMICmdArgValString(m_constStrArgNamedInterpreter, true, true));
|
|
|
|
m_setCmdArgs.Add(
|
|
|
|
new CMICmdArgValString(m_constStrArgNamedCommand, true, true, true));
|
|
|
|
return ParseValidateCmdOptions();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// 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.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdInterpreterExec::Execute() {
|
|
|
|
CMICMDBASE_GETOPTION(pArgInterpreter, String, m_constStrArgNamedInterpreter);
|
|
|
|
CMICMDBASE_GETOPTION(pArgCommand, String, m_constStrArgNamedCommand);
|
|
|
|
|
|
|
|
// Handle the interpreter parameter by do nothing on purpose (set to 'handled'
|
|
|
|
// in
|
|
|
|
// the arg definition above)
|
|
|
|
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;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record
|
|
|
|
// Result
|
2014-11-18 02:06:21 +08:00
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdInterpreterExec::Acknowledge() {
|
|
|
|
if (m_lldbResult.GetOutputSize() > 0) {
|
2017-01-05 21:23:47 +08:00
|
|
|
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;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
if (m_lldbResult.GetErrorSize() > 0) {
|
2017-01-05 21:23:47 +08:00
|
|
|
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;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const CMICmnMIResultRecord miRecordResult(
|
|
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
|
|
|
|
m_miResultRecord = miRecordResult;
|
|
|
|
|
|
|
|
return MIstatus::success;
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The
|
|
|
|
// factory
|
2014-11-18 02:06:21 +08:00
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-06-25 00:35:50 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdBase *CMICmdCmdInterpreterExec::CreateSelf() {
|
|
|
|
return new CMICmdCmdInterpreterExec();
|
2014-06-25 00:35:50 +08:00
|
|
|
}
|
2014-08-09 00:47:42 +08:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------------------
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdInferiorTtySet constructor.
|
|
|
|
// Type: Method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdCmdInferiorTtySet::CMICmdCmdInferiorTtySet() {
|
|
|
|
// Command factory matches this name with that received from the stdin stream
|
|
|
|
m_strMiCmd = "inferior-tty-set";
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
// Required by the CMICmdFactory when registering *this command
|
|
|
|
m_pSelfCreatorFn = &CMICmdCmdInferiorTtySet::CreateSelf;
|
2014-08-09 00:47:42 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
2014-11-18 02:06:21 +08:00
|
|
|
// Details: CMICmdCmdInferiorTtySet destructor.
|
|
|
|
// Type: Overrideable.
|
|
|
|
// Args: None.
|
|
|
|
// Return: None.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdCmdInferiorTtySet::~CMICmdCmdInferiorTtySet() {}
|
|
|
|
|
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// 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.
|
2014-11-18 02:06:21 +08:00
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdInferiorTtySet::Execute() {
|
|
|
|
// Do nothing
|
2014-11-18 02:06:21 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return MIstatus::success;
|
2014-08-09 00:47:42 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: The invoker requires this function. The command prepares a MI Record
|
|
|
|
// Result
|
2014-11-18 02:06:21 +08:00
|
|
|
// for the work carried out in the Execute().
|
|
|
|
// Type: Overridden.
|
|
|
|
// Args: None.
|
|
|
|
// Return: MIstatus::success - Functional succeeded.
|
|
|
|
// MIstatus::failure - Functional failed.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
bool CMICmdCmdInferiorTtySet::Acknowledge() {
|
|
|
|
const CMICmnMIResultRecord miRecordResult(
|
|
|
|
m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error);
|
|
|
|
m_miResultRecord = miRecordResult;
|
2014-08-09 00:47:42 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
return MIstatus::success;
|
2014-08-09 00:47:42 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//++
|
|
|
|
//------------------------------------------------------------------------------------
|
|
|
|
// Details: Required by the CMICmdFactory when registering *this command. The
|
|
|
|
// factory
|
2014-11-18 02:06:21 +08:00
|
|
|
// calls this function to create an instance of *this command.
|
|
|
|
// Type: Static method.
|
|
|
|
// Args: None.
|
|
|
|
// Return: CMICmdBase * - Pointer to a new command.
|
|
|
|
// Throws: None.
|
2014-08-09 00:47:42 +08:00
|
|
|
//--
|
2016-09-07 04:57:50 +08:00
|
|
|
CMICmdBase *CMICmdCmdInferiorTtySet::CreateSelf() {
|
|
|
|
return new CMICmdCmdInferiorTtySet();
|
2014-08-15 00:45:50 +08:00
|
|
|
}
|