summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBWatchpointLocation.h10
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj2
-rwxr-xr-xlldb/scripts/Python/build-swig-Python.sh6
-rw-r--r--lldb/scripts/Python/interface/SBTarget.i37
-rw-r--r--lldb/scripts/Python/interface/SBWatchpointLocation.i71
-rw-r--r--lldb/scripts/Python/modify-python-lldb.py7
-rw-r--r--lldb/scripts/Python/python-extensions.swig7
-rw-r--r--lldb/scripts/lldb.swig2
-rw-r--r--lldb/source/API/SBWatchpointLocation.cpp53
-rw-r--r--lldb/source/Breakpoint/WatchpointLocation.cpp1
-rw-r--r--lldb/test/python_api/watchpoint/TestWatchpointLocationIter.py118
11 files changed, 306 insertions, 8 deletions
diff --git a/lldb/include/lldb/API/SBWatchpointLocation.h b/lldb/include/lldb/API/SBWatchpointLocation.h
index 37df01658a4..632ccd5369f 100644
--- a/lldb/include/lldb/API/SBWatchpointLocation.h
+++ b/lldb/include/lldb/API/SBWatchpointLocation.h
@@ -29,9 +29,16 @@ public:
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 @@ public:
IsEnabled ();
uint32_t
+ GetHitCount () const;
+
+ uint32_t
GetIgnoreCount ();
void
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index bc8aacee321..28849ca527f 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -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;
diff --git a/lldb/scripts/Python/build-swig-Python.sh b/lldb/scripts/Python/build-swig-Python.sh
index 1391e81e712..69da019a0b5 100755
--- a/lldb/scripts/Python/build-swig-Python.sh
+++ b/lldb/scripts/Python/build-swig-Python.sh
@@ -71,7 +71,8 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/lldb.h"\
" ${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 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\
" ${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
diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i
index acd894cb57a..3bf14b1010a 100644
--- a/lldb/scripts/Python/interface/SBTarget.i
+++ b/lldb/scripts/Python/interface/SBTarget.i
@@ -12,7 +12,8 @@ namespace lldb {
%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 @@ and,
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 @@ public:
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;
diff --git a/lldb/scripts/Python/interface/SBWatchpointLocation.i b/lldb/scripts/Python/interface/SBWatchpointLocation.i
new file mode 100644
index 00000000000..a5e21ddb894
--- /dev/null
+++ b/lldb/scripts/Python/interface/SBWatchpointLocation.i
@@ -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
diff --git a/lldb/scripts/Python/modify-python-lldb.py b/lldb/scripts/Python/modify-python-lldb.py
index 33929c62d0e..462467734cd 100644
--- a/lldb/scripts/Python/modify-python-lldb.py
+++ b/lldb/scripts/Python/modify-python-lldb.py
@@ -150,6 +150,7 @@ linked_list_iter_def = '''
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 @@ d = { 'SBBreakpoint': ('GetNumLocations', 'GetLocationAtIndex'),
# 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 @@ for line in content.splitlines():
# 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])
diff --git a/lldb/scripts/Python/python-extensions.swig b/lldb/scripts/Python/python-extensions.swig
index 246fd97982e..5c302ba6f86 100644
--- a/lldb/scripts/Python/python-extensions.swig
+++ b/lldb/scripts/Python/python-extensions.swig
@@ -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());
+ }
+}
diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig
index 3b0fab43538..1996aabb2eb 100644
--- a/lldb/scripts/lldb.swig
+++ b/lldb/scripts/lldb.swig
@@ -79,6 +79,7 @@ o SBLineEntry: Specifies an association with a contiguous range of instructions
#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 @@ o SBLineEntry: Specifies an association with a contiguous range of instructions
%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"
diff --git a/lldb/source/API/SBWatchpointLocation.cpp b/lldb/source/API/SBWatchpointLocation.cpp
index b0e3eb827b8..33b035ff11f 100644
--- a/lldb/source/API/SBWatchpointLocation.cpp
+++ b/lldb/source/API/SBWatchpointLocation.cpp
@@ -63,12 +63,46 @@ SBWatchpointLocation::~SBWatchpointLocation ()
{
}
+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 @@ SBWatchpointLocation::SetEnabled (bool enabled)
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 @@ SBWatchpointLocation::IsEnabled ()
}
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)
diff --git a/lldb/source/Breakpoint/WatchpointLocation.cpp b/lldb/source/Breakpoint/WatchpointLocation.cpp
index 6b2785a22b3..01f6189821d 100644
--- a/lldb/source/Breakpoint/WatchpointLocation.cpp
+++ b/lldb/source/Breakpoint/WatchpointLocation.cpp
@@ -95,7 +95,6 @@ WatchpointLocation::ShouldStop (StoppointCallbackContext *context)
void
WatchpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
- s->Printf(" ");
DumpWithLevel(s, level);
return;
}
diff --git a/lldb/test/python_api/watchpoint/TestWatchpointLocationIter.py b/lldb/test/python_api/watchpoint/TestWatchpointLocationIter.py
new file mode 100644
index 00000000000..d54c2105333
--- /dev/null
+++ b/lldb/test/python_api/watchpoint/TestWatchpointLocationIter.py
@@ -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()
OpenPOWER on IntegriCloud