forked from OSchip/llvm-project
202 lines
6.8 KiB
C++
202 lines
6.8 KiB
C++
//===-- MICmdCmdThread.cpp --------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Overview: CMICmdCmdThreadInfo implementation.
|
|
|
|
// 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 sbProcess = rSessionInfo.GetProcess();
|
|
lldb::SBThread thread = sbProcess.GetSelectedThread();
|
|
|
|
if (m_bSingleThread)
|
|
{
|
|
thread = sbProcess.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 = sbProcess.GetNumThreads();
|
|
for (MIuint i = 0; i < nThreads; i++)
|
|
{
|
|
lldb::SBThread thread = sbProcess.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();
|
|
}
|