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:
Hafiz Abid Qadeer 2014-12-08 18:07:40 +00:00
parent beadd56a7d
commit 290ece8278
6 changed files with 157 additions and 30 deletions

View File

@ -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()

View File

@ -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') {

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;