[Lldb-commits] [lldb] r223674 - Fix a bug where global variable can be reported as local.

Hafiz Abid Qadeer hafiz_abid at mentor.com
Mon Dec 8 10:07:40 PST 2014


Author: abidh
Date: Mon Dec  8 12:07:40 2014
New Revision: 223674

URL: http://llvm.org/viewvc/llvm-project?rev=223674&view=rev
Log:
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 at gmail.com>.

Added:
    lldb/trunk/test/tools/lldb-mi/TestMiStack.py
Modified:
    lldb/trunk/test/tools/lldb-mi/main.c
    lldb/trunk/tools/lldb-mi/MICmdCmdStack.cpp
    lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
    lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
    lldb/trunk/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp

Added: lldb/trunk/test/tools/lldb-mi/TestMiStack.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiStack.py?rev=223674&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiStack.py (added)
+++ lldb/trunk/test/tools/lldb-mi/TestMiStack.py Mon Dec  8 12:07:40 2014
@@ -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()

Modified: lldb/trunk/test/tools/lldb-mi/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/main.c?rev=223674&r1=223673&r2=223674&view=diff
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/main.c (original)
+++ lldb/trunk/test/tools/lldb-mi/main.c Mon Dec  8 12:07:40 2014
@@ -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') {

Modified: lldb/trunk/tools/lldb-mi/MICmdCmdStack.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmdCmdStack.cpp?rev=223674&r1=223673&r2=223674&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmdCmdStack.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmdCmdStack.cpp Mon Dec  8 12:07:40 2014
@@ -432,7 +432,7 @@ CMICmdCmdStackListArguments::Execute(voi
     {
         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;
 

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp?rev=223674&r1=223673&r2=223674&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp Mon Dec  8 12:07:40 2014
@@ -254,7 +254,7 @@ CMICmnLLDBDebugSessionInfo::GetThreadFra
 
         // 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::GetThreadFra
 
         // 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::MIResponseFo
 //          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::MIResponseFo
     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::MIResponseFo
 //          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::MIResponseFo
     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::MIResponseFo
 //          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::MIResponseFo
     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);

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h?rev=223674&r1=223673&r2=223674&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.h Mon Dec  8 12:07:40 2014
@@ -103,6 +103,19 @@ class CMICmnLLDBDebugSessionInfo : publi
         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;

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp?rev=223674&r1=223673&r2=223674&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp Mon Dec  8 12:07:40 2014
@@ -1077,7 +1077,7 @@ CMICmnLLDBDebuggerHandleEvents::MiStoppe
     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::HandlePr
 
     // 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;





More information about the lldb-commits mailing list