[Lldb-commits] [lldb] r130332 - in /lldb/trunk/test: lldbutil.py python_api/lldbutil/TestLLDBIterator.py

Johnny Chen johnny.chen at apple.com
Wed Apr 27 14:44:09 PDT 2011


Author: johnny
Date: Wed Apr 27 16:44:09 2011
New Revision: 130332

URL: http://llvm.org/viewvc/llvm-project?rev=130332&view=rev
Log:
Add a utility function smart_iter() which has knowledge of the getsize and the getelem
method names of all the lldb container objects and returns an iterator object when
passed an eligible lldb container object.

Example:

    from lldb_util import smart_iter
    for thread in smart_iter(process):
        ID = thread.GetThreadID()
        if thread.GetStopReason() == lldb.eStopReasonBreakpoint:
            stopped_due_to_breakpoint = True
        for frame in smart_iter(thread):
            self.assertTrue(frame.GetThread().GetThreadID() == ID)
        ...

Add a test case for lldb.smart_iter().

Modified:
    lldb/trunk/test/lldbutil.py
    lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py

Modified: lldb/trunk/test/lldbutil.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbutil.py?rev=130332&r1=130331&r2=130332&view=diff
==============================================================================
--- lldb/trunk/test/lldbutil.py (original)
+++ lldb/trunk/test/lldbutil.py Wed Apr 27 16:44:09 2011
@@ -56,11 +56,55 @@
         name = symbol.GetName()
         ...
     """
+    #import traceback
+    #traceback.print_stack()
     size = getattr(obj, getsize)
     elem = getattr(obj, getelem)
     for i in range(size()):
         yield elem(i)
 
+def smart_iter(obj):
+    """Returns an iterator for eligible lldb objects, or None otherwise.
+
+    An example of eligible lldb container object is SBModule, which contains
+    SBSymbols.  While SBTarget contains SBModules and SBBreakpoints, because it
+    is ambiguous which containee type to iterate on, the best we can do is to
+    return None.  API clients can use lldb_iter() to clarify their intentions.
+
+    SBSymbol does not have the notion of containee objects and is not eligible
+    for smart iterator.
+
+    Example usage:
+
+    from lldb_util import smart_iter
+    for thread in smart_iter(process):
+        ID = thread.GetThreadID()
+        if thread.GetStopReason() == lldb.eStopReasonBreakpoint:
+            stopped_due_to_breakpoint = True
+        for frame in smart_iter(thread):
+            self.assertTrue(frame.GetThread().GetThreadID() == ID)
+        ...
+    """
+    d = { lldb.SBBreakpoint:  ('GetNumLocations',   'GetLocationAtIndex'),
+          lldb.SBCompileUnit: ('GetNumLineEntries', 'GetLineEntryAtIndex'),
+          lldb.SBDebugger:    ('GetNumTargets',     'GetTargetAtIndex'),
+          lldb.SBModule:      ('GetNumSymbols',     'GetSymbolAtIndex'),
+          lldb.SBProcess:     ('GetNumThreads',     'GetThreadAtIndex'),
+          lldb.SBThread:      ('GetNumFrames',      'GetFrameAtIndex'),
+
+          lldb.SBInstructionList:   ('GetSize', 'GetInstructionAtIndex'),
+          lldb.SBStringList:        ('GetSize', 'GetStringAtIndex',),
+          lldb.SBSymbolContextList: ('GetSize', 'GetContextAtIndex'),
+          lldb.SBValueList:         ('GetSize',  'GetValueAtIndex'),
+
+          lldb.SBType:  ('GetNumberChildren', 'GetChildAtIndex'),
+          lldb.SBValue: ('GetNumChildren',    'GetChildAtIndex')
+          }
+    if obj.__class__ in d:
+        val = d.get(obj.__class__)
+        return lldb_iter(obj, val[0], val[1])
+    else:
+        return None
 
 # ===================================================
 # Disassembly for an SBFunction or an SBSymbol object

Modified: lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py?rev=130332&r1=130331&r2=130332&view=diff
==============================================================================
--- lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py (original)
+++ lldb/trunk/test/python_api/lldbutil/TestLLDBIterator.py Wed Apr 27 16:44:09 2011
@@ -1,6 +1,6 @@
 """
-Test lldbutil.lldb_iter() which returns an iterator object for lldb's aggregate
-data structures.
+Test lldb_iter/smart_iter() which returns an iterator object for lldb container
+objects.
 """
 
 import os, time
@@ -30,6 +30,11 @@
         self.buildDefault()
         self.lldb_iter_2()
 
+    def test_smart_iter_1(self):
+        """Test smart_iter works correctly for SBProcess->SBThread->SBFrame."""
+        self.buildDefault()
+        self.smart_iter_1()
+
     def lldb_iter_1(self):
         exe = os.path.join(os.getcwd(), "a.out")
 
@@ -91,6 +96,36 @@
             self.assertTrue(yours[i].GetID() == mine[i].GetID(),
                             "ID of yours[{0}] and mine[{0}] matches".format(i))
 
+    def smart_iter_1(self):
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target.IsValid(), VALID_TARGET)
+
+        breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line1)
+        self.assertTrue(breakpoint.IsValid(), VALID_BREAKPOINT)
+
+        # Now launch the process, and do not stop at entry point.
+        rc = lldb.SBError()
+        self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, rc)
+
+        if not rc.Success() or not self.process.IsValid():
+            self.fail("SBTarget.LaunchProcess() failed")
+
+        from lldbutil import smart_iter, print_stacktrace
+        stopped_due_to_breakpoint = False
+        for thread in smart_iter(self.process):
+            if self.TraceOn():
+                print_stacktrace(thread)
+            ID = thread.GetThreadID()
+            if thread.GetStopReason() == lldb.eStopReasonBreakpoint:
+                stopped_due_to_breakpoint = True
+            for frame in smart_iter(thread):
+                self.assertTrue(frame.GetThread().GetThreadID() == ID)
+                if self.TraceOn():
+                    print frame
+
+        self.assertTrue(stopped_due_to_breakpoint)
 
 if __name__ == '__main__':
     import atexit





More information about the lldb-commits mailing list