[Lldb-commits] [lldb] r140595 - in /lldb/trunk: include/lldb/API/SBWatchpointLocation.h lldb.xcodeproj/project.pbxproj scripts/Python/build-swig-Python.sh scripts/Python/interface/SBTarget.i scripts/Python/interface/SBWatchpointLocation.i scripts/Python/modify-python-lldb.py scripts/Python/python-extensions.swig scripts/lldb.swig source/API/SBWatchpointLocation.cpp source/Breakpoint/WatchpointLocation.cpp test/python_api/watchpoint/TestWatchpointLocationIter.py

Johnny Chen johnny.chen at apple.com
Mon Sep 26 18:19:20 PDT 2011


Author: johnny
Date: Mon Sep 26 20:19:20 2011
New Revision: 140595

URL: http://llvm.org/viewvc/llvm-project?rev=140595&view=rev
Log:
Export the watchpoint related API (SBWatchpointLocation class and added SBTarget methods)
to the Python interface.

Implement yet another (threre're 3 now) iterator protocol for SBTarget: watchpoint_location_iter(),
to iterate on the available watchpoint locations.  And add a print representation for
SBWatchpointLocation.

Exercise some of these Python API with TestWatchpointLocationIter.py.

Added:
    lldb/trunk/scripts/Python/interface/SBWatchpointLocation.i
    lldb/trunk/test/python_api/watchpoint/TestWatchpointLocationIter.py
Modified:
    lldb/trunk/include/lldb/API/SBWatchpointLocation.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/scripts/Python/build-swig-Python.sh
    lldb/trunk/scripts/Python/interface/SBTarget.i
    lldb/trunk/scripts/Python/modify-python-lldb.py
    lldb/trunk/scripts/Python/python-extensions.swig
    lldb/trunk/scripts/lldb.swig
    lldb/trunk/source/API/SBWatchpointLocation.cpp
    lldb/trunk/source/Breakpoint/WatchpointLocation.cpp

Modified: lldb/trunk/include/lldb/API/SBWatchpointLocation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBWatchpointLocation.h?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBWatchpointLocation.h (original)
+++ lldb/trunk/include/lldb/API/SBWatchpointLocation.h Mon Sep 26 20:19:20 2011
@@ -29,9 +29,16 @@
     operator = (const lldb::SBWatchpointLocation &rhs);
 #endif
 
+    watch_id_t
+    GetID () const;
+
     bool
     IsValid() const;
 
+    /// With -1 representing an invalid hardware index.
+    int32_t
+    GetHardwareIndex () const;
+
     lldb::addr_t
     GetWatchAddress () const;
 
@@ -45,6 +52,9 @@
     IsEnabled ();
 
     uint32_t
+    GetHitCount () const;
+
+    uint32_t
     GetIgnoreCount ();
 
     void

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Sep 26 20:19:20 2011
@@ -1366,6 +1366,7 @@
 		B296983512C2FB2B002D92C3 /* CommandObjectVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectVersion.h; path = source/Commands/CommandObjectVersion.h; sourceTree = "<group>"; };
 		B2A58721143119810092BFBA /* SBWatchpointLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBWatchpointLocation.h; path = include/lldb/API/SBWatchpointLocation.h; sourceTree = "<group>"; };
 		B2A58723143119D50092BFBA /* SBWatchpointLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBWatchpointLocation.cpp; path = source/API/SBWatchpointLocation.cpp; sourceTree = "<group>"; };
+		B2A5872514313B480092BFBA /* SBWatchpointLocation.i */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; path = SBWatchpointLocation.i; sourceTree = "<group>"; };
 		B2D3033612EFA5C500F84EB3 /* InstructionUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InstructionUtils.h; path = Utility/InstructionUtils.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
@@ -1727,6 +1728,7 @@
 				2611FF11142D83060017FEA3 /* SBType.i */,
 				2611FF12142D83060017FEA3 /* SBValue.i */,
 				2611FF13142D83060017FEA3 /* SBValueList.i */,
+				B2A5872514313B480092BFBA /* SBWatchpointLocation.i */,
 			);
 			name = interface;
 			path = scripts/Python/interface;

Modified: lldb/trunk/scripts/Python/build-swig-Python.sh
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/build-swig-Python.sh?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/build-swig-Python.sh (original)
+++ lldb/trunk/scripts/Python/build-swig-Python.sh Mon Sep 26 20:19:20 2011
@@ -71,7 +71,8 @@
 " ${SRC_ROOT}/include/lldb/API/SBThread.h"\
 " ${SRC_ROOT}/include/lldb/API/SBType.h"\
 " ${SRC_ROOT}/include/lldb/API/SBValue.h"\
-" ${SRC_ROOT}/include/lldb/API/SBValueList.h"
+" ${SRC_ROOT}/include/lldb/API/SBValueList.h"\
+" ${SRC_ROOT}/include/lldb/API/SBWatchpointLocation.h"\
 
 INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBBlock.i"\
@@ -106,7 +107,8 @@
 " ${SRC_ROOT}/scripts/Python/interface/SBThread.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBType.i"\
 " ${SRC_ROOT}/scripts/Python/interface/SBValue.i"\
-" ${SRC_ROOT}/scripts/Python/interface/SBValueList.i"
+" ${SRC_ROOT}/scripts/Python/interface/SBValueList.i"\
+" ${SRC_ROOT}/scripts/Python/interface/SBWatchpointLocation.i"
 
 if [ $Debug == 1 ]
 then

Modified: lldb/trunk/scripts/Python/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBTarget.i?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/Python/interface/SBTarget.i Mon Sep 26 20:19:20 2011
@@ -12,7 +12,8 @@
 %feature("docstring",
 "Represents the target program running under the debugger.
 
-SBTarget supports module and breakpoint iterations. For example,
+SBTarget supports module, breakpoint, and watchpoint_location iterations. For
+example,
 
     for m in target.module_iter():
         print m
@@ -34,7 +35,18 @@
 produces:
 
 SBBreakpoint: id = 1, file ='main.cpp', line = 66, locations = 1
-SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1"
+SBBreakpoint: id = 2, file ='main.cpp', line = 85, locations = 1
+
+and,
+
+    for wp_loc in target.watchpoint_location_iter():
+        print wp_loc
+
+produces:
+
+WatchpointLocation 1: addr = 0x1034ca048 size = 4 state = enabled type = rw
+    declare @ '/Volumes/data/lldb/svn/trunk/test/python_api/watchpoint/main.c:12'
+    hw_index = 0  hit_count = 2     ignore_count = 0     callback =      0x0 baton =      0x0"
 ) SBTarget;
 class SBTarget
 {
@@ -423,6 +435,27 @@
     bool
     DeleteAllBreakpoints ();
 
+    uint32_t
+    GetNumWatchpointLocations () const;
+
+    lldb::SBWatchpointLocation
+    GetWatchpointLocationAtIndex (uint32_t idx) const;
+
+    bool
+    WatchpointLocationDelete (watch_id_t watch_id);
+
+    lldb::SBWatchpointLocation
+    FindWatchpointLocationByID (watch_id_t watch_id);
+
+    bool
+    EnableAllWatchpointLocations ();
+
+    bool
+    DisableAllWatchpointLocations ();
+
+    bool
+    DeleteAllWatchpointLocations ();
+
     lldb::SBBroadcaster
     GetBroadcaster () const;
 

Added: lldb/trunk/scripts/Python/interface/SBWatchpointLocation.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBWatchpointLocation.i?rev=140595&view=auto
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBWatchpointLocation.i (added)
+++ lldb/trunk/scripts/Python/interface/SBWatchpointLocation.i Mon Sep 26 20:19:20 2011
@@ -0,0 +1,71 @@
+//===-- SWIG Interface for SBWatchpointLocation -----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+%feature("docstring",
+"Represents an instance of watchpoint location for a specific target program.
+
+A watchpoint location is determined by the address and the byte size that
+resulted in this particular instantiation.  Each watchpoint location has its
+settable options.
+
+See also SBTarget.watchpoint_location_iter() for for example usage of iterating
+through the watchpoint locations of the target."
+) SBWatchpointLocation;
+class SBWatchpointLocation
+{
+public:
+
+    SBWatchpointLocation ();
+
+    SBWatchpointLocation (const lldb::SBWatchpointLocation &rhs);
+
+    ~SBWatchpointLocation ();
+
+    watch_id_t
+    GetID () const;
+
+    bool
+    IsValid() const;
+
+    %feature("docstring", "
+    //------------------------------------------------------------------
+    /// With -1 representing an invalid hardware index.
+    //------------------------------------------------------------------
+    ") GetHardwareIndex;
+    int32_t
+    GetHardwareIndex () const;
+
+    lldb::addr_t
+    GetWatchAddress () const;
+
+    size_t
+    GetWatchSize() const;
+
+    void
+    SetEnabled(bool enabled);
+
+    bool
+    IsEnabled ();
+
+    uint32_t
+    GetHitCount () const;
+
+    uint32_t
+    GetIgnoreCount ();
+
+    void
+    SetIgnoreCount (uint32_t n);
+
+    bool
+    GetDescription (lldb::SBStream &description, DescriptionLevel level);
+};
+
+} // namespace lldb

Modified: lldb/trunk/scripts/Python/modify-python-lldb.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/modify-python-lldb.py?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/modify-python-lldb.py (original)
+++ lldb/trunk/scripts/Python/modify-python-lldb.py Mon Sep 26 20:19:20 2011
@@ -150,6 +150,7 @@
 iter_def = "    def __iter__(self): return lldb_iter(self, '%s', '%s')"
 module_iter = "    def module_iter(self): return lldb_iter(self, '%s', '%s')"
 breakpoint_iter = "    def breakpoint_iter(self): return lldb_iter(self, '%s', '%s')"
+watchpoint_location_iter = "    def watchpoint_location_iter(self): return lldb_iter(self, '%s', '%s')"
 section_iter = "    def section_iter(self): return lldb_iter(self, '%s', '%s')"
 
 # Called to implement the built-in function len().
@@ -187,7 +188,8 @@
 
       # SBTarget needs special processing, see below.
       'SBTarget': {'module':     ('GetNumModules', 'GetModuleAtIndex'),
-                   'breakpoint': ('GetNumBreakpoints', 'GetBreakpointAtIndex')
+                   'breakpoint': ('GetNumBreakpoints', 'GetBreakpointAtIndex'),
+                   'watchpoint_location': ('GetNumWatchpointLocations', 'GetWatchpointLocationAtIndex')
                    },
 
       # SBModule has an additional section_iter(), see below.
@@ -325,10 +327,11 @@
             # We found the beginning of the __init__ method definition.
             # This is a good spot to insert the iter and/or eq-ne support.
             #
-            # But note that SBTarget has two types of iterations.
+            # But note that SBTarget has three types of iterations.
             if cls == "SBTarget":
                 new_content.add_line(module_iter % (d[cls]['module']))
                 new_content.add_line(breakpoint_iter % (d[cls]['breakpoint']))
+                new_content.add_line(watchpoint_location_iter % (d[cls]['watchpoint_location']))
             else:
                 if (state & DEFINING_ITERATOR):
                     new_content.add_line(iter_def % d[cls])

Modified: lldb/trunk/scripts/Python/python-extensions.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-extensions.swig?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/python-extensions.swig (original)
+++ lldb/trunk/scripts/Python/python-extensions.swig Mon Sep 26 20:19:20 2011
@@ -160,4 +160,11 @@
                 return PyString_FromString (description.GetData());
         }
 }
+%extend lldb::SBWatchpointLocation {
+        PyObject *lldb::SBWatchpointLocation::__repr__ (){
+                lldb::SBStream description;
+                $self->GetDescription (description, lldb::eDescriptionLevelVerbose);
+                return PyString_FromString (description.GetData());
+        }
+}
 

Modified: lldb/trunk/scripts/lldb.swig
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/lldb.swig?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/scripts/lldb.swig (original)
+++ lldb/trunk/scripts/lldb.swig Mon Sep 26 20:19:20 2011
@@ -79,6 +79,7 @@
 #include "lldb/API/SBType.h"
 #include "lldb/API/SBValue.h"
 #include "lldb/API/SBValueList.h"
+#include "lldb/API/SBWatchpointLocation.h"
 %}
 
 /* Various liblldb typedefs that SWIG needs to know about.  */
@@ -131,6 +132,7 @@
 %include "./Python/interface/SBType.i"
 %include "./Python/interface/SBValue.i"
 %include "./Python/interface/SBValueList.i"
+%include "./Python/interface/SBWatchpointLocation.i"
 
 %include "./Python/python-extensions.swig"
 

Modified: lldb/trunk/source/API/SBWatchpointLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBWatchpointLocation.cpp?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/source/API/SBWatchpointLocation.cpp (original)
+++ lldb/trunk/source/API/SBWatchpointLocation.cpp Mon Sep 26 20:19:20 2011
@@ -63,12 +63,46 @@
 {
 }
 
+watch_id_t
+SBWatchpointLocation::GetID () const
+{
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+    watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
+    if (m_opaque_sp)
+        watch_id = m_opaque_sp->GetID();
+
+    if (log)
+    {
+        if (watch_id == LLDB_INVALID_WATCH_ID)
+            log->Printf ("SBWatchpointLocation(%p)::GetID () => LLDB_INVALID_WATCH_ID", m_opaque_sp.get());
+        else
+            log->Printf ("SBWatchpointLocation(%p)::GetID () => %u", m_opaque_sp.get(), watch_id);
+    }
+
+    return watch_id;
+}
+
 bool
 SBWatchpointLocation::IsValid() const
 {
     return m_opaque_sp.get() != NULL;
 }
 
+int32_t
+SBWatchpointLocation::GetHardwareIndex () const
+{
+    int32_t hw_index = -1;
+
+    if (m_opaque_sp)
+    {
+        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+        hw_index = m_opaque_sp->GetHardwareIndex();
+    }
+
+    return hw_index;
+}
+
 addr_t
 SBWatchpointLocation::GetWatchAddress () const
 {
@@ -103,7 +137,7 @@
     if (m_opaque_sp)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
-        m_opaque_sp->SetEnabled (enabled);
+        m_opaque_sp->GetTarget().DisableWatchpointLocationByID(m_opaque_sp->GetID());
     }
 }
 
@@ -120,6 +154,23 @@
 }
 
 uint32_t
+SBWatchpointLocation::GetHitCount () const
+{
+    uint32_t count = 0;
+    if (m_opaque_sp)
+    {
+        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
+        count = m_opaque_sp->GetHitCount();
+    }
+
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+    if (log)
+        log->Printf ("SBWatchpointLocation(%p)::GetHitCount () => %u", m_opaque_sp.get(), count);
+
+    return count;
+}
+
+uint32_t
 SBWatchpointLocation::GetIgnoreCount ()
 {
     if (m_opaque_sp)

Modified: lldb/trunk/source/Breakpoint/WatchpointLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/WatchpointLocation.cpp?rev=140595&r1=140594&r2=140595&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/WatchpointLocation.cpp (original)
+++ lldb/trunk/source/Breakpoint/WatchpointLocation.cpp Mon Sep 26 20:19:20 2011
@@ -95,7 +95,6 @@
 void
 WatchpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
 {
-    s->Printf(" ");
     DumpWithLevel(s, level);
     return;
 }

Added: lldb/trunk/test/python_api/watchpoint/TestWatchpointLocationIter.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/watchpoint/TestWatchpointLocationIter.py?rev=140595&view=auto
==============================================================================
--- lldb/trunk/test/python_api/watchpoint/TestWatchpointLocationIter.py (added)
+++ lldb/trunk/test/python_api/watchpoint/TestWatchpointLocationIter.py Mon Sep 26 20:19:20 2011
@@ -0,0 +1,118 @@
+"""
+Use lldb Python SBTarget API to iterate on the watchpoint(s) for the target.
+"""
+
+import os, time
+import re
+import unittest2
+import lldb, lldbutil
+from lldbtest import *
+
+class WatchpointLocationIteratorTestCase(TestBase):
+
+    mydir = os.path.join("python_api", "watchpoint")
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        # Our simple source filename.
+        self.source = 'main.c'
+        # Find the line number to break inside main().
+        self.line = line_number(self.source, '// Set break point at this line.')
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @python_api_test
+    def test_watch_loc_iter_with_dsym(self):
+        """Exercise SBTarget.watchpoint_location_iter() API to iterate on the available watchpoint locations."""
+        self.buildDsym()
+        self.do_watchpoint_location_iter()
+
+    @python_api_test
+    def test_watch_loc_iter_with_dwarf(self):
+        """Exercise SBTarget.watchpoint_location_iter() API to iterate on the available watchpoint locations."""
+        self.buildDwarf()
+        self.do_watchpoint_location_iter()
+
+    def do_watchpoint_location_iter(self):
+        """Use SBTarget.watchpoint_location_iter() to do Pythonic iteration on the available watchpoint locations."""
+        exe = os.path.join(os.getcwd(), "a.out")
+
+        # Create a target by the debugger.
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        # Create a breakpoint on main.c in order to set our watchpoint later.
+        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
+        self.assertTrue(breakpoint and
+                        breakpoint.GetNumLocations() == 1,
+                        VALID_BREAKPOINT)
+
+        # Now launch the process, and do not stop at the entry point.
+        process = target.LaunchSimple(None, None, os.getcwd())
+
+        # We should be stopped due to the breakpoint.  Get frame #0.
+        process = target.GetProcess()
+        self.assertTrue(process.GetState() == lldb.eStateStopped,
+                        PROCESS_STOPPED)
+        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+        frame0 = thread.GetFrameAtIndex(0)
+
+        value = frame0.WatchValue('global',
+                                  lldb.eValueTypeVariableGlobal,
+                                  lldb.LLDB_WATCH_TYPE_READ|lldb.LLDB_WATCH_TYPE_WRITE)
+        self.assertTrue(value, "Successfully found the variable and set a watchpoint")
+        self.DebugSBValue(value)
+
+        # There should be only 1 watchpoint location under the target.
+        self.assertTrue(target.GetNumWatchpointLocations() == 1)
+        wp_loc = target.GetWatchpointLocationAtIndex(0) 
+        self.assertTrue(wp_loc.IsEnabled())
+        watch_id = wp_loc.GetID()
+        self.assertTrue(watch_id != 0)
+
+        # Continue.  Expect the program to stop due to the variable being written to.
+        process.Continue()
+
+        # Hide stdout if not running with '-t' option.
+        if not self.TraceOn():
+            self.HideStdout()
+
+        # Print the stack traces.
+        lldbutil.print_stacktraces(process)
+
+        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)
+        self.assertTrue(thread, "The thread stopped due to watchpoint")
+        self.DebugSBValue(value)
+
+        # We currently only support hardware watchpoint.  Verify that we have a
+        # meaningful hardware index at this point.  Exercise the printed repr of
+        # SBWatchpointLocation.
+        print wp_loc
+        self.assertTrue(wp_loc.GetHardwareIndex() != -1)
+
+        # Now disable the 'rw' watchpoint.  The program won't stop when it reads
+        # 'global' next.
+        wp_loc.SetEnabled(False)
+        self.assertTrue(wp_loc.GetHardwareIndex() == -1)
+        self.assertFalse(wp_loc.IsEnabled())
+
+        # Continue.  The program does not stop again when the variable is being
+        # read from because the watchpoint location has been disabled.
+        process.Continue()
+
+        # At this point, the inferior process should have exited.
+        self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
+
+        # Verify some vital statistics and exercise the iterator API.
+        for wp_loc in target.watchpoint_location_iter():
+            self.assertTrue(wp_loc)
+            self.assertTrue(wp_loc.GetWatchSize() == 4)
+            self.assertTrue(wp_loc.GetHitCount() == 1)
+            print wp_loc
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()





More information about the lldb-commits mailing list