From: Hafiz Abid Qadeer Date: Mon, 8 Dec 2014 18:07:40 +0000 (+0000) Subject: Fix a bug where global variable can be reported as local. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=290ece827804d40e2e5e98832624d31434ef8e18;p=platform%2Fupstream%2Fllvm.git 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 . llvm-svn: 223674 --- diff --git a/lldb/test/tools/lldb-mi/TestMiStack.py b/lldb/test/tools/lldb-mi/TestMiStack.py new file mode 100644 index 0000000..10c723d --- /dev/null +++ b/lldb/test/tools/lldb-mi/TestMiStack.py @@ -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() diff --git a/lldb/test/tools/lldb-mi/main.c b/lldb/test/tools/lldb-mi/main.c index 3e16f08..c1ed36c 100644 --- a/lldb/test/tools/lldb-mi/main.c +++ b/lldb/test/tools/lldb-mi/main.c @@ -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') { diff --git a/lldb/tools/lldb-mi/MICmdCmdStack.cpp b/lldb/tools/lldb-mi/MICmdCmdStack.cpp index 0c6d413..4ed6803 100644 --- a/lldb/tools/lldb-mi/MICmdCmdStack.cpp +++ b/lldb/tools/lldb-mi/MICmdCmdStack.cpp @@ -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; diff --git a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp index 97e031c..3e9ed22 100644 --- a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp +++ b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp @@ -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(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(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(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); diff --git a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h index 53cb8a0..e2463f1 100644 --- a/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h +++ b/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h @@ -103,6 +103,19 @@ class CMICmnLLDBDebugSessionInfo : public CMICmnBase, public MI::ISingleton VecActiveThreadId_t; diff --git a/lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp index eba082f..b375611 100644 --- a/lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp +++ b/lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp @@ -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;