diff options
Diffstat (limited to 'tools/lldb-mi/MICmdCmdThread.cpp')
-rw-r--r-- | tools/lldb-mi/MICmdCmdThread.cpp | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/tools/lldb-mi/MICmdCmdThread.cpp b/tools/lldb-mi/MICmdCmdThread.cpp new file mode 100644 index 000000000000..8cfaae804931 --- /dev/null +++ b/tools/lldb-mi/MICmdCmdThread.cpp @@ -0,0 +1,207 @@ +//===-- MICmdCmdThread.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//++ +// File: MICmdCmdThread.cpp +// +// Overview: CMICmdCmdThreadInfo 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 <lldb/API/SBBreakpointLocation.h> +#include <lldb/API/SBThread.h> + +// In-house headers: +#include "MICmdCmdThread.h" +#include "MICmnMIResultRecord.h" +#include "MICmnMIValueConst.h" +#include "MICmnLLDBDebugger.h" +#include "MICmnLLDBDebugSessionInfo.h" +#include "MICmdArgValNumber.h" + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdThreadInfo constructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdThreadInfo::CMICmdCmdThreadInfo( void ) +: m_bSingleThread( false ) +, m_bThreadInvalid( true ) +, m_constStrArgNamedThreadId( "thread-id" ) +{ + // Command factory matches this name with that received from the stdin stream + m_strMiCmd = "thread-info"; + + // Required by the CMICmdFactory when registering *this command + m_pSelfCreatorFn = &CMICmdCmdThreadInfo::CreateSelf; +} + +//++ ------------------------------------------------------------------------------------ +// Details: CMICmdCmdThreadInfo destructor. +// Type: Overrideable. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMICmdCmdThreadInfo::~CMICmdCmdThreadInfo( void ) +{ + m_vecMIValueTuple.clear(); +} + +//++ ------------------------------------------------------------------------------------ +// 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 CMICmdCmdThreadInfo::ParseArgs( void ) +{ + bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedThreadId, false, true )) ); + 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 CMICmdCmdThreadInfo::Execute( void ) +{ + CMICMDBASE_GETOPTION( pArgThreadId, Number, m_constStrArgNamedThreadId ); + MIuint nThreadId = 0; + if( pArgThreadId->GetFound() && pArgThreadId->GetValid() ) + { + m_bSingleThread = true; + nThreadId = static_cast< MIuint >( pArgThreadId->GetValue() ); + } + + CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); + lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; + lldb::SBThread thread = rProcess.GetSelectedThread(); + + if( m_bSingleThread ) + { + thread = rProcess.GetThreadByIndexID( nThreadId ); + m_bThreadInvalid = thread.IsValid(); + if( !m_bThreadInvalid ) + return MIstatus::success; + + CMICmnMIValueTuple miTuple; + if( !rSessionInfo.MIResponseFormThreadInfo3( m_cmdData, thread, miTuple ) ) + return MIstatus::failure; + + m_miValueTupleThread = miTuple; + + return MIstatus::success; + } + + // Multiple threads + m_vecMIValueTuple.clear(); + const MIuint nThreads = rProcess.GetNumThreads(); + for( MIuint i = 0; i < nThreads; i++ ) + { + lldb::SBThread thread = rProcess.GetThreadAtIndex( i ); + if( thread.IsValid() ) + { + CMICmnMIValueTuple miTuple; + if( !rSessionInfo.MIResponseFormThreadInfo3( m_cmdData, thread, miTuple ) ) + return MIstatus::failure; + + m_vecMIValueTuple.push_back( miTuple ); + } + } + + 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 CMICmdCmdThreadInfo::Acknowledge( void ) +{ + if( m_bSingleThread ) + { + 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; + } + + // MI print "%s^done,threads=[{id=\"%d\",target-id=\"%s\",frame={},state=\"%s\"}] + const CMICmnMIValueList miValueList( m_miValueTupleThread ); + const CMICmnMIValueResult miValueResult( "threads", miValueList ); + const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); + m_miResultRecord = miRecordResult; + return MIstatus::success; + } + + // 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; +} + +//++ ------------------------------------------------------------------------------------ +// 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 * CMICmdCmdThreadInfo::CreateSelf( void ) +{ + return new CMICmdCmdThreadInfo(); +} |