forked from OSchip/llvm-project
Fix a bug where global variable can be reported as local.
There was an error in ORing mask which is used for getting a list of variables. Previously, these constants were unnamed, and possible it become the reason of this bug. Also added test case for -stack-list-local and -stack-list_arguments. Patch from Ilia K <ki.stfu@gmail.com>. llvm-svn: 223674
This commit is contained in:
parent
beadd56a7d
commit
290ece8278
|
@ -0,0 +1,122 @@
|
|||
"""
|
||||
Test that the lldb-mi driver works with -stack-xxx commands
|
||||
"""
|
||||
|
||||
import os
|
||||
import unittest2
|
||||
import lldb
|
||||
from lldbtest import *
|
||||
|
||||
class MiStackTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
myexe = "a.out"
|
||||
|
||||
@classmethod
|
||||
def classCleanup(cls):
|
||||
"""Cleanup the test byproducts."""
|
||||
try:
|
||||
os.remove("child_send.txt")
|
||||
os.remove("child_read.txt")
|
||||
os.remove(cls.myexe)
|
||||
except:
|
||||
pass
|
||||
|
||||
@lldbmi_test
|
||||
def test_lldbmi_stackargs(self):
|
||||
"""Test that 'lldb-mi --interpreter' can shows arguments."""
|
||||
import pexpect
|
||||
self.buildDefault()
|
||||
|
||||
# So that the child gets torn down after the test.
|
||||
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
|
||||
child = self.child
|
||||
child.setecho(True)
|
||||
# Turn on logging for input/output to/from the child.
|
||||
with open('child_send.txt', 'w') as f_send:
|
||||
with open('child_read.txt', 'w') as f_read:
|
||||
child.logfile_send = f_send
|
||||
child.logfile_read = f_read
|
||||
|
||||
# Load executable
|
||||
child.sendline("-file-exec-and-symbols %s" % (self.myexe))
|
||||
child.expect("\^done")
|
||||
|
||||
# Run to main
|
||||
child.sendline("-break-insert -f main")
|
||||
child.expect("\^done,bkpt={number=\"1\"")
|
||||
child.sendline("-exec-run")
|
||||
child.expect("\^running")
|
||||
child.expect("\*stopped,reason=\"breakpoint-hit\"")
|
||||
|
||||
# Test arguments
|
||||
child.sendline("-stack-list-arguments 0")
|
||||
child.expect("\^done,stack-args=\[frame={level=\"0\",args=\[{name=\"argc\",value=\"1\"},{name=\"argv\",value=\".*\"}\]}")
|
||||
|
||||
# Now that the necessary logging is done, restore logfile to None to
|
||||
# stop further logging.
|
||||
child.logfile_send = None
|
||||
child.logfile_read = None
|
||||
|
||||
with open('child_send.txt', 'r') as fs:
|
||||
if self.TraceOn():
|
||||
print "\n\nContents of child_send.txt:"
|
||||
print fs.read()
|
||||
with open('child_read.txt', 'r') as fr:
|
||||
from_child = fr.read()
|
||||
if self.TraceOn():
|
||||
print "\n\nContents of child_read.txt:"
|
||||
print from_child
|
||||
|
||||
@lldbmi_test
|
||||
def test_lldbmi_locals(self):
|
||||
"""Test that 'lldb-mi --interpreter' can shows local variables."""
|
||||
import pexpect
|
||||
self.buildDefault()
|
||||
|
||||
# So that the child gets torn down after the test.
|
||||
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
|
||||
child = self.child
|
||||
child.setecho(True)
|
||||
# Turn on logging for input/output to/from the child.
|
||||
with open('child_send.txt', 'w') as f_send:
|
||||
with open('child_read.txt', 'w') as f_read:
|
||||
child.logfile_send = f_send
|
||||
child.logfile_read = f_read
|
||||
|
||||
# Load executable
|
||||
child.sendline("-file-exec-and-symbols %s" % (self.myexe))
|
||||
child.expect("\^done")
|
||||
|
||||
# Run to main
|
||||
self.line = line_number('main.c', '//BP_localstest')
|
||||
child.sendline("-break-insert --file main.c:%d" % (self.line))
|
||||
child.expect("\^done,bkpt={number=\"1\"")
|
||||
child.sendline("-exec-run")
|
||||
child.expect("\^running")
|
||||
child.expect("\*stopped,reason=\"breakpoint-hit\"")
|
||||
|
||||
# Test locals
|
||||
child.sendline("-stack-list-locals 0")
|
||||
child.expect("\^done,locals=\[{name=\"a\",value=\"10\"},{name=\"b\",value=\"20\"}\]")
|
||||
|
||||
# Now that the necessary logging is done, restore logfile to None to
|
||||
# stop further logging.
|
||||
child.logfile_send = None
|
||||
child.logfile_read = None
|
||||
|
||||
with open('child_send.txt', 'r') as fs:
|
||||
if self.TraceOn():
|
||||
print "\n\nContents of child_send.txt:"
|
||||
print fs.read()
|
||||
with open('child_read.txt', 'r') as fr:
|
||||
from_child = fr.read()
|
||||
if self.TraceOn():
|
||||
print "\n\nContents of child_read.txt:"
|
||||
print from_child
|
||||
|
||||
if __name__ == '__main__':
|
||||
import atexit
|
||||
lldb.SBDebugger.Initialize()
|
||||
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
||||
unittest2.main()
|
|
@ -20,6 +20,7 @@ int main (int argc, char const *argv[])
|
|||
printf("argc=%d\n", argc);
|
||||
a = a_MyFunction();
|
||||
b = b_MyFunction();
|
||||
//BP_localstest
|
||||
if (doloop)
|
||||
infloop();
|
||||
if (argc > 1 && *argv[1] == 'l') {
|
||||
|
|
|
@ -432,7 +432,7 @@ CMICmdCmdStackListArguments::Execute(void)
|
|||
{
|
||||
lldb::SBFrame frame = thread.GetFrameAtIndex(i);
|
||||
CMICmnMIValueList miValueList(true);
|
||||
const MIuint maskVarTypes = 0x1000;
|
||||
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
|
||||
if (!rSessionInfo.MIResponseFormVariableInfo3(frame, maskVarTypes, miValueList))
|
||||
return MIstatus::failure;
|
||||
const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", i));
|
||||
|
@ -600,7 +600,7 @@ CMICmdCmdStackListLocals::Execute(void)
|
|||
MIunused(nFrames);
|
||||
lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame) : thread.GetSelectedFrame();
|
||||
CMICmnMIValueList miValueList(true);
|
||||
const MIuint maskVarTypes = 0x0110;
|
||||
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Locals;
|
||||
if (!rSessionInfo.MIResponseFormVariableInfo(frame, maskVarTypes, miValueList))
|
||||
return MIstatus::failure;
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MI
|
|||
|
||||
// Function args
|
||||
CMICmnMIValueList miValueList(true);
|
||||
const MIuint maskVarTypes = 0x1000;
|
||||
const MIuint maskVarTypes = eVariableType_Arguments;
|
||||
if (!MIResponseFormVariableInfo(frame, maskVarTypes, miValueList))
|
||||
return MIstatus::failure;
|
||||
|
||||
|
@ -327,7 +327,7 @@ CMICmnLLDBDebugSessionInfo::GetThreadFrames2(const SMICmdData &vCmdData, const M
|
|||
|
||||
// Function args
|
||||
CMICmnMIValueList miValueList(true);
|
||||
const MIuint maskVarTypes = 0x1000;
|
||||
const MIuint maskVarTypes = eVariableType_Arguments;
|
||||
if (!MIResponseFormVariableInfo2(frame, maskVarTypes, miValueList))
|
||||
return MIstatus::failure;
|
||||
|
||||
|
@ -647,10 +647,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2(const SMICmdData &vCmdData
|
|||
// tuple type object past in.
|
||||
// Type: Method.
|
||||
// Args: vrFrame - (R) LLDB thread object.
|
||||
// vMaskVarTypes - (R) 0x1000 = arguments,
|
||||
// 0x0100 = locals,
|
||||
// 0x0010 = statics,
|
||||
// 0x0001 = in scope only.
|
||||
// vMaskVarTypes - (R) Construed according to VariableType_e.
|
||||
// vwrMIValueList - (W) MI value list object.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
|
@ -663,10 +660,10 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrF
|
|||
bool bOk = MIstatus::success;
|
||||
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
|
||||
|
||||
const bool bArg = (vMaskVarTypes & 0x1000);
|
||||
const bool bLocals = (vMaskVarTypes & 0x0100);
|
||||
const bool bStatics = (vMaskVarTypes & 0x0010);
|
||||
const bool bInScopeOnly = (vMaskVarTypes & 0x0001);
|
||||
const bool bArg = (vMaskVarTypes & eVariableType_Arguments);
|
||||
const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
|
||||
const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
|
||||
const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
|
||||
lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly);
|
||||
const MIuint nArgs = listArg.GetSize();
|
||||
for (MIuint i = 0; bOk && (i < nArgs); i++)
|
||||
|
@ -690,10 +687,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2(const lldb::SBFrame &vrF
|
|||
// tuple type object past in.
|
||||
// Type: Method.
|
||||
// Args: vrFrame - (R) LLDB thread object.
|
||||
// vMaskVarTypes - (R) 0x1000 = arguments,
|
||||
// 0x0100 = locals,
|
||||
// 0x0010 = statics,
|
||||
// 0x0001 = in scope only.
|
||||
// vMaskVarTypes - (R) Construed according to VariableType_e.
|
||||
// vwrMIValueList - (W) MI value list object.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
|
@ -706,10 +700,10 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr
|
|||
bool bOk = MIstatus::success;
|
||||
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
|
||||
|
||||
const bool bArg = (vMaskVarTypes & 0x1000);
|
||||
const bool bLocals = (vMaskVarTypes & 0x0100);
|
||||
const bool bStatics = (vMaskVarTypes & 0x0010);
|
||||
const bool bInScopeOnly = (vMaskVarTypes & 0x0001);
|
||||
const bool bArg = (vMaskVarTypes & eVariableType_Arguments);
|
||||
const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
|
||||
const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
|
||||
const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
|
||||
const MIuint nMaxRecusiveDepth = 10;
|
||||
MIuint nCurrentRecursiveDepth = 0;
|
||||
lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly);
|
||||
|
@ -730,10 +724,7 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFr
|
|||
// tuple type object past in.
|
||||
// Type: Method.
|
||||
// Args: vrFrame - (R) LLDB thread object.
|
||||
// vMaskVarTypes - (R) 0x1000 = arguments,
|
||||
// 0x0100 = locals,
|
||||
// 0x0010 = statics,
|
||||
// 0x0001 = in scope only.
|
||||
// vMaskVarTypes - (R) Construed according to VariableType_e.
|
||||
// vwrMIValueList - (W) MI value list object.
|
||||
// Return: MIstatus::success - Functional succeeded.
|
||||
// MIstatus::failure - Functional failed.
|
||||
|
@ -746,10 +737,10 @@ CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo3(const lldb::SBFrame &vrF
|
|||
bool bOk = MIstatus::success;
|
||||
lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
|
||||
|
||||
const bool bArg = (vMaskVarTypes & 0x1000);
|
||||
const bool bLocals = (vMaskVarTypes & 0x0100);
|
||||
const bool bStatics = (vMaskVarTypes & 0x0010);
|
||||
const bool bInScopeOnly = (vMaskVarTypes & 0x0001);
|
||||
const bool bArg = (vMaskVarTypes & eVariableType_Arguments);
|
||||
const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
|
||||
const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
|
||||
const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
|
||||
const MIuint nMaxRecusiveDepth = 10;
|
||||
MIuint nCurrentRecursiveDepth = 0;
|
||||
lldb::SBValueList listArg = rFrame.GetVariables(bArg, bLocals, bStatics, bInScopeOnly);
|
||||
|
|
|
@ -103,6 +103,19 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton<CMIC
|
|||
MIuint m_nBrkPtThreadId; // Restrict the breakpoint to the specified thread-id
|
||||
};
|
||||
|
||||
// Enumerations:
|
||||
public:
|
||||
//++ ===================================================================
|
||||
// Details: The type of variable used by MIResponseFormVariableInfo family functions.
|
||||
//--
|
||||
enum VariableType_e
|
||||
{
|
||||
eVariableType_InScope = (1u << 0), // In scope only.
|
||||
eVariableType_Statics = (1u << 1), // Statics.
|
||||
eVariableType_Locals = (1u << 2), // Locals.
|
||||
eVariableType_Arguments = (1u << 3) // Arguments.
|
||||
};
|
||||
|
||||
// Typedefs:
|
||||
public:
|
||||
typedef std::vector<uint32_t> VecActiveThreadId_t;
|
||||
|
|
|
@ -1077,7 +1077,7 @@ CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint(const MIuint64 vBrkPtId, c
|
|||
if (bOk)
|
||||
{
|
||||
CMICmnMIValueList miValueList(true);
|
||||
const MIuint maskVarTypes = 0x1000;
|
||||
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
|
||||
bOk = rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, miValueList);
|
||||
|
||||
CMICmnMIValueTuple miValueTuple;
|
||||
|
@ -1153,7 +1153,7 @@ CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace(void)
|
|||
|
||||
// Function args
|
||||
CMICmnMIValueList miValueList(true);
|
||||
const MIuint maskVarTypes = 0x1000;
|
||||
const MIuint maskVarTypes = CMICmnLLDBDebugSessionInfo::eVariableType_Arguments;
|
||||
if (!rSession.MIResponseFormVariableInfo2(frame, maskVarTypes, miValueList))
|
||||
return MIstatus::failure;
|
||||
CMICmnMIValueTuple miValueTuple;
|
||||
|
|
Loading…
Reference in New Issue