Files
clang-p2996/lldb/tools/lldb-mi/MICmdCmdThread.cpp
Ilia K 58627321f6 Refactor CMICmnLLDBDebuggerHandleEvents/CMICmnLLDBDebugSessionInfo/CMICmnLLDBDebugSessionInfoVarObj (MI)
Summary:
This patch includes the following changes:

# Refactor GetVariableInfo/GetValueStringFormatted/GetValue to use the same code (MI)
Also it expands the variable value format for strings (aka char*):
was:
```
^done,name="v4",numchild="1",value="0x0000000100000f56",type="const char *",thread-id="1",has_more="0"
```
now:
```
^done,name="v4",numchild="1",value="0x0000000100000f56 \"ab\"",type="const char *",thread-id="1",has_more="0"
```

# Expand the variable value format for arrays (according to GDB)
For example:
was:
```
^done,name="v3",numchild="2",value="{...}",type="char [2]",thread-id="1",has_more="0"
```
now:
```
^done,name="v3",numchild="2",value="[2]",type="char [2]",thread-id="1",has_more="0"
```

# Rename MiGdbSetShowTestCase.test_lldbmi_gdb_show_process_stopatentry_default to test_lldbmi_gdb_show_process_stopatentry (MI)

# Fix a comment in MiGdbSetShowTestCase.test_lldbmi_gdb_show_process_stopatentry (MI)

# Refactor CMICmnLLDBUtilSBValue
## Add CMICmnLLDBUtilSBValue::IsPointerType/IsArrayType
## Refactor CMICmnLLDBUtilSBValue::GetValue
## Fix CMICmnLLDBUtilSBValue::IsChildCharType to ignore a number of childs
## Rename CMICmnLLDBUtilSBValue::IsChildCharType to IsFirstChildCharType
## Fix CMICmnLLDBUtilSBValue::GetValueCString to accept char[]

# Minor changes in CMICmnLLDBUtilSBValue::GetValue

# Refactor CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo family functions (MI)

# Refactor CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo family functions (MI)
## Remove CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo2
## Improve CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo to accept args

# Refactor CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo family functions (MI)
## Add vArgInfo arg to CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo
## Move CMICmnLLDBDebugSessionInfo::GetFrameInfo/MIResponseFormFrameInfo to private namespace

# Refactor CMICmnLLDBDebugSessionInfo::GetThreadFrames family functions (MI)
## Remove CMICmnLLDBDebugSessionInfo::GetThreadFrames2
## Improve CMICmnLLDBDebugSessionInfo::GetThreadFrames to accept vnMaxDepth

# Fix vnMaxDepth arg name in CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo (MI)

# Refactor CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo family functions (MI)
## Merge CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo functions into one

# Don't modify fnName in CMICmnLLDBDebugSessionInfo::GetThreadFrames (MI)

# Refactor CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo family functions (MI)
## Remove CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo3
## Improve -CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo to accept vnMaxDepth

# Refactor CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo family functions (MI)
## Remove CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2
## Add CMICmnLLDBDebugSessionInfo::ThreadInfoFormat_e enum to specify thread format
## Improve CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo to accept veThreadInfoFormat
## Remove vnMaxDepth arg in CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo (not needed because veThreadInfoFormat was added)

# Move CMICmnLLDBDebugSessionInfo::GetThreadFrames to private namespace (MI)

# Refactor CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo (MI)
## Add CMICmnLLDBDebugSessionInfo::FrameInfoFormat_e enum to specify frame format
## Improve CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo to accept veFrameInfoFormat
## Remove vnMaxDepth arg in CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo (not needed because veFrameInfoFormat was added)

# Remove duplicated level field in CMICmnLLDBDebugSessionInfo::GetThreadFrames (MI)

# Refactor CMICmnLLDBUtilSBValue::GetValue (MI)
## Add CMICmnLLDBUtilSBValue::GetSimpleValue
## Use CMICmnLLDBUtilSBValue::GetSimpleValue in GetVlaue

# Fix CMICmnLLDBDebugSessionInfo::GetThreadFrames (MI)
## Add CMICmnLLDBDebugSessionInfo::FrameInfoFormat_e::eFrameInfoFormat_AllArgumentsInSimpleForm which is used to get stack-args in simple form (i.e. show {...} for composite types). It can be done by calling MIResponseFormVariableInfo with vnMaxDepth=0.
## Improve CMICmnLLDBDebugSessionInfo::GetThreadFrames to accept veFrameInfoFormat
## Remove vnMaxDepth from CMICmnLLDBDebugSessionInfo::GetThreadFrames (we should use veFrameInfoFormat instead)

# Refactor CMICmnLLDBUtilSBValue::GetValue to expand composite types (MI)
## Add CMICmnLLDBUtilSBValue::GetCompositeValue to expand composite types
## Add CMICmnLLDBUtilSBValue::m_pComposite to avoid multiple {...} in the code
## Improve CMICmnLLDBUtilSBValue::GetValue to accept vbExpandAggregates option (default=false)
## Clean up CMICmnLLDBDebugSessionInfo::GetVariableInfo to use CMICmnLLDBUtilSBValue::GetValue
## Remove the wrapping into {} in CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo
## Fix MiStackTestCase.test_lldbmi_stack_list_locals test to expect result without superfluous space ' ' around the '{' or '}' brackets:
was:
```
{name=\"var_c\",value=\"{var_a = 10,var_b = 97 'a',inner_ = { var_d = 30 }}
```
now:
```
{name=\"var_c\",value=\"{var_a = 10,var_b = 97 'a',inner_ = {var_d = 30}}
```
## Fix vwrValue arg name in CMICmnLLDBUtilSBValue::GetSimpleValue (was vrValue)

# Refactor CMICmnLLDBDebugSessionInfo::GetVariableInfo (MI)
## Remove vnMaxDepth/vbIsChildValue/vnDepth args in CMICmnLLDBDebugSessionInfo::GetVariableInfo
## Improve CMICmnLLDBDebugSessionInfo::GetVariableInfo to accept vwrStrValue
## Remove vwrMiValueList arg in CMICmnLLDBDebugSessionInfo::GetVariableInfo (we should use vwrStrValue instead)
## Fix CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo to Escape values
was:
```
{name="p",value="0x0000000000000000 """}
```
now:
```
{name="p",value="0x0000000000000000 \"\""}
```

# Refactor CMICmnLLDBUtilSBValue
## Improve CMICmnLLDBUtilSBValue::GetValue to handle PrintExpandAggregates
## Improve CMICmnLLDBUtilSBValue::GetSimpleValue to handle vbHandleArrayType (use it to specify that array should be represented as simple type, i.e. value="[2]")

# Add spacing between fields in CMICmnLLDBUtilSBValue::GetCompositeValue (MI)
For example:
was:
```
^done,name="var3",numchild="3",value="{i = 3,inner = {l = 3},complex_ptr = 0x00007fff5fbff848}",type="complex_type",thread-id="1",has_more="0"
```
now:
```
^done,name="var3",numchild="3",value="{i = 3, inner = {l = 3}, complex_ptr = 0x00007fff5fbff848}",type="complex_type",thread-id="1",has_more="0"
```

# Fix spacing in MiStackTestCase.test_lldbmi_stack_list_locals test (MI)

Test Plan: ./dotest.py -v --executable $BUILDDIR/bin/lldb tools/lldb-mi/

Reviewers: abidh

Subscribers: lldb-commits, abidh

Differential Revision: http://reviews.llvm.org/D8913

llvm-svn: 234476
2015-04-09 11:17:54 +00:00

202 lines
6.9 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.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, 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.MIResponseFormThreadInfo(m_cmdData, thread, CMICmnLLDBDebugSessionInfo::eThreadInfoFormat_AllFrames, 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();
}