[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