From f131eda087bf59d062637dfccfbf1689d9534d5e Mon Sep 17 00:00:00 2001 From: John Dallaway Date: Thu, 22 Jan 2026 14:49:29 +0000 Subject: [PATCH] Implement -thread-select command --- src/MICmdCmdThread.cpp | 104 +++++++++++++++++++++++++++++++++++++++++ src/MICmdCmdThread.h | 30 ++++++++++++ src/MICmdCommands.cpp | 1 + 3 files changed, 135 insertions(+) diff --git a/src/MICmdCmdThread.cpp b/src/MICmdCmdThread.cpp index e0c74f9..410ef53 100644 --- a/src/MICmdCmdThread.cpp +++ b/src/MICmdCmdThread.cpp @@ -209,3 +209,107 @@ bool CMICmdCmdThreadInfo::Acknowledge() { CMICmdBase *CMICmdCmdThreadInfo::CreateSelf() { return new CMICmdCmdThreadInfo(); } + +//++ +// Details: CMICmdCmdThreadSelect constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdThreadSelect::CMICmdCmdThreadSelect() + : m_bThreadInvalid(true), m_constStrArgNamedThreadId("thread-id") { + // Command factory matches this name with that received from the stdin stream + m_strMiCmd = "thread-select"; + + // Required by the CMICmdFactory when registering *this command + m_pSelfCreatorFn = &CMICmdCmdThreadSelect::CreateSelf; +} + +//++ +// Details: CMICmdCmdThreadSelect destructor. +// Type: Overrideable. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdThreadSelect::~CMICmdCmdThreadSelect() {} + +//++ +// 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 CMICmdCmdThreadSelect::ParseArgs() { + m_setCmdArgs.Add( + new CMICmdArgValNumber(m_constStrArgNamedThreadId, true, true)); + 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 CMICmdCmdThreadSelect::Execute() { + CMICMDBASE_GETOPTION(pArgThreadId, Number, m_constStrArgNamedThreadId); + const MIuint nThreadId = static_cast(pArgThreadId->GetValue()); + + CMICmnLLDBDebugSessionInfo &rSessionInfo( + CMICmnLLDBDebugSessionInfo::Instance()); + lldb::SBProcess sbProcess = rSessionInfo.GetProcess(); + m_bThreadInvalid = !sbProcess.SetSelectedThreadByIndexID(nThreadId); + 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 CMICmdCmdThreadSelect::Acknowledge() { + if (m_bThreadInvalid) { + const CMICmnMIValueConst miValueConst("invalid thread id"); + const CMICmnMIValueResult miValueResult("msg", miValueConst); + const CMICmnMIResultRecord miRecordResult( + m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, + miValueResult); + m_miResultRecord = miRecordResult; + return MIstatus::success; + } + + 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 *CMICmdCmdThreadSelect::CreateSelf() { + return new CMICmdCmdThreadSelect(); +} diff --git a/src/MICmdCmdThread.h b/src/MICmdCmdThread.h index 413e293..c2e700e 100644 --- a/src/MICmdCmdThread.h +++ b/src/MICmdCmdThread.h @@ -67,3 +67,33 @@ class CMICmdCmdThreadInfo : public CMICmdBase { bool m_bHasCurrentThread; CMICmnMIValue m_miValueCurrThreadId; }; + +//++ +//============================================================================ +// Details: MI command class. MI commands derived from the command base class. +// *this class implements MI command "thread-select". +//-- +class CMICmdCmdThreadSelect : public CMICmdBase { + // Statics: +public: + // Required by the CMICmdFactory when registering *this command + static CMICmdBase *CreateSelf(); + + // Methods: +public: + /* ctor */ CMICmdCmdThreadSelect(); + + // Overridden: +public: + // From CMICmdInvoker::ICmd + bool Execute() override; + bool Acknowledge() override; + bool ParseArgs() override; + // From CMICmnBase + /* dtor */ ~CMICmdCmdThreadSelect() override; + + // Attributes: +private: + bool m_bThreadInvalid; // True = invalid, false = ok + const CMIUtilString m_constStrArgNamedThreadId; +}; diff --git a/src/MICmdCommands.cpp b/src/MICmdCommands.cpp index 839920e..185f48c 100644 --- a/src/MICmdCommands.cpp +++ b/src/MICmdCommands.cpp @@ -122,6 +122,7 @@ bool MICmnCommands::RegisterAll() { bOk &= Register(); bOk &= Register(); bOk &= Register(); + bOk &= Register(); bOk &= Register(); bOk &= Register(); bOk &= Register();