diff options
author | Johnny Chen <johnny.chen@apple.com> | 2012-06-04 23:19:54 +0000 |
---|---|---|
committer | Johnny Chen <johnny.chen@apple.com> | 2012-06-04 23:19:54 +0000 |
commit | b90827e66c6576a229b9018ba8400a2e3e300d02 (patch) | |
tree | 982b29230add06d804c9c61b0299fd05fd992d3e | |
parent | 188d830405a47a6c1b5c87f85cd46bce587c2ec7 (diff) | |
download | bcm5719-llvm-b90827e66c6576a229b9018ba8400a2e3e300d02.tar.gz bcm5719-llvm-b90827e66c6576a229b9018ba8400a2e3e300d02.zip |
rdar://problem/11584012
Refactorings of watchpoint creation APIs so that SBTarget::WatchAddress(), SBValue::Watch(), and SBValue::WatchPointee()
now take an additional 'SBError &error' parameter (at the end) to contain the reason if there is some failure in the
operation. Update 'watchpoint set variable/expression' commands to take advantage of that.
Update existing test cases to reflect the API change and add test cases to verify that the SBError mechanism works for
SBTarget::WatchAddress() by passing an invalid watch_size.
llvm-svn: 157964
21 files changed, 137 insertions, 77 deletions
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 4ee539835b3..c6f90ca1f6c 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -692,7 +692,7 @@ public: FindWatchpointByID (lldb::watch_id_t watch_id); lldb::SBWatchpoint - WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write); + WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError& error); bool EnableAllWatchpoints (); diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 7e7b9dbdb6e..bd6d56db43d 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -325,6 +325,9 @@ public: /// @param[in] write /// Stop when this value is modified /// + /// @param[out] + /// An error object. Contains the reason if there is some failure. + /// /// @return /// An SBWatchpoint object. This object might not be valid upon /// return due to a value not being contained in memory, too @@ -332,7 +335,7 @@ public: /// use. //------------------------------------------------------------------ lldb::SBWatchpoint - Watch (bool resolve_location, bool read, bool write); + Watch (bool resolve_location, bool read, bool write, SBError &error); //------------------------------------------------------------------ /// Watch this value that this value points to in memory @@ -351,6 +354,9 @@ public: /// @param[in] write /// Stop when this value is modified /// + /// @param[out] + /// An error object. Contains the reason if there is some failure. + /// /// @return /// An SBWatchpoint object. This object might not be valid upon /// return due to a value not being contained in memory, too @@ -358,7 +364,7 @@ public: /// use. //------------------------------------------------------------------ lldb::SBWatchpoint - WatchPointee (bool resolve_location, bool read, bool write); + WatchPointee (bool resolve_location, bool read, bool write, SBError &error); // this must be defined in the .h file because synthetic children as implemented in the core // currently rely on being able to extract the SharedPointer out of an SBValue. if the implementation diff --git a/lldb/include/lldb/API/SBWatchpoint.h b/lldb/include/lldb/API/SBWatchpoint.h index d4f8d21a220..9d8d455ca37 100644 --- a/lldb/include/lldb/API/SBWatchpoint.h +++ b/lldb/include/lldb/API/SBWatchpoint.h @@ -32,9 +32,6 @@ public: bool IsValid() const; - SBError - GetError(); - watch_id_t GetID (); diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 3daf659562c..40e5979157d 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -523,7 +523,8 @@ public: lldb::WatchpointSP CreateWatchpoint (lldb::addr_t addr, size_t size, - uint32_t type); + uint32_t type, + Error &error); lldb::WatchpointSP GetLastCreatedWatchpoint () diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i index e8b6a00bdb8..052f4d6e86f 100644 --- a/lldb/scripts/Python/interface/SBTarget.i +++ b/lldb/scripts/Python/interface/SBTarget.i @@ -668,7 +668,8 @@ public: WatchAddress (lldb::addr_t addr, size_t size, bool read, - bool write); + bool write, + SBError &error); lldb::SBBroadcaster diff --git a/lldb/scripts/Python/interface/SBValue.i b/lldb/scripts/Python/interface/SBValue.i index 9b9fd529de8..4b9d5d727b4 100644 --- a/lldb/scripts/Python/interface/SBValue.i +++ b/lldb/scripts/Python/interface/SBValue.i @@ -313,14 +313,14 @@ public: /// It returns an SBWatchpoint, which may be invalid. ") Watch; lldb::SBWatchpoint - Watch (bool resolve_location, bool read, bool write); + Watch (bool resolve_location, bool read, bool write, SBError &error); %feature("docstring", " /// Find and watch the location pointed to by a variable. /// It returns an SBWatchpoint, which may be invalid. ") WatchPointee; lldb::SBWatchpoint - WatchPointee (bool resolve_location, bool read, bool write); + WatchPointee (bool resolve_location, bool read, bool write, SBError &error); bool GetDescription (lldb::SBStream &description); diff --git a/lldb/scripts/Python/interface/SBWatchpoint.i b/lldb/scripts/Python/interface/SBWatchpoint.i index 23c27d8905e..3649b2d21e0 100644 --- a/lldb/scripts/Python/interface/SBWatchpoint.i +++ b/lldb/scripts/Python/interface/SBWatchpoint.i @@ -31,9 +31,6 @@ public: bool IsValid(); - SBError - GetError(); - watch_id_t GetID (); diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index d26788642ae..1b2b94847a2 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -1674,7 +1674,7 @@ SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id) } lldb::SBWatchpoint -SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write) +SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -1690,7 +1690,9 @@ SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write) if (write) watch_type |= LLDB_WATCH_TYPE_WRITE; // Target::CreateWatchpoint() is thread safe. - watchpoint_sp = target_sp->CreateWatchpoint(addr, size, watch_type); + Error cw_error; + watchpoint_sp = target_sp->CreateWatchpoint(addr, size, watch_type, cw_error); + error.SetError(cw_error); sb_watchpoint.SetSP (watchpoint_sp); } diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index bb656e57956..bd6a5fcdcb0 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -1655,7 +1655,7 @@ SBValue::GetData () } lldb::SBWatchpoint -SBValue::Watch (bool resolve_location, bool read, bool write) +SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error) { SBWatchpoint sb_watchpoint; @@ -1696,7 +1696,9 @@ SBValue::Watch (bool resolve_location, bool read, bool write) if (write) watch_type |= LLDB_WATCH_TYPE_WRITE; - WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, watch_type); + Error rc; + WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, watch_type, rc); + error.SetError(rc); if (watchpoint_sp) { @@ -1718,11 +1720,11 @@ SBValue::Watch (bool resolve_location, bool read, bool write) } lldb::SBWatchpoint -SBValue::WatchPointee (bool resolve_location, bool read, bool write) +SBValue::WatchPointee (bool resolve_location, bool read, bool write, SBError &error) { SBWatchpoint sb_watchpoint; if (IsInScope() && GetType().IsPointerType()) - sb_watchpoint = Dereference().Watch (resolve_location, read, write); + sb_watchpoint = Dereference().Watch (resolve_location, read, write, error); return sb_watchpoint; } diff --git a/lldb/source/API/SBWatchpoint.cpp b/lldb/source/API/SBWatchpoint.cpp index fd505aead54..76ce57cccf7 100644 --- a/lldb/source/API/SBWatchpoint.cpp +++ b/lldb/source/API/SBWatchpoint.cpp @@ -87,22 +87,7 @@ SBWatchpoint::GetID () bool SBWatchpoint::IsValid() const { - lldb::WatchpointSP watchpoint_sp(GetSP()); - if (watchpoint_sp && watchpoint_sp->GetError().Success()) - return true; - return false; -} - -SBError -SBWatchpoint::GetError () -{ - SBError sb_error; - lldb::WatchpointSP watchpoint_sp(GetSP()); - if (watchpoint_sp) - { - sb_error.SetError(watchpoint_sp->GetError()); - } - return sb_error; + return m_opaque_sp; } int32_t diff --git a/lldb/source/Commands/CommandObjectWatchpoint.cpp b/lldb/source/Commands/CommandObjectWatchpoint.cpp index 591b8ec4201..04d87898149 100644 --- a/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -59,20 +59,6 @@ CheckTargetForWatchpointOperations(Target *target, CommandReturnObject &result) return true; } -static void -CheckIfWatchpointsExhausted(Target *target, CommandReturnObject &result) -{ - uint32_t num_supported_hardware_watchpoints; - Error error = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints); - if (error.Success()) - { - uint32_t num_current_watchpoints = target->GetWatchpointList().GetSize(); - if (num_current_watchpoints >= num_supported_hardware_watchpoints) - result.AppendErrorWithFormat("Number of supported hardware watchpoints (%u) has been reached.\n", - num_supported_hardware_watchpoints); - } -} - #include "llvm/ADT/StringRef.h" // Equivalent class: {"-", "to", "To", "TO"} of range specifier array. @@ -1013,11 +999,6 @@ CommandObjectWatchpointSetVariable::Execute // Find out the size of this variable. size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize() : m_option_watchpoint.watch_size; - if (!m_option_watchpoint.IsWatchSizeSupported(size)) - { - result.GetErrorStream().Printf("Watch size of %lu is not supported\n", size); - return false; - } } } else { const char *error_cstr = error.AsCString(NULL); @@ -1031,7 +1012,8 @@ CommandObjectWatchpointSetVariable::Execute // Now it's time to create the watchpoint. uint32_t watch_type = m_option_watchpoint.watch_type; - Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type).get(); + error.Clear(); + Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get(); if (wp) { if (var_sp && var_sp->GetDeclaration().GetFile()) { StreamString ss; @@ -1047,7 +1029,8 @@ CommandObjectWatchpointSetVariable::Execute } else { result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n", addr, size); - CheckIfWatchpointsExhausted(target, result); + if (error.AsCString(NULL)) + result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); } @@ -1221,15 +1204,11 @@ CommandObjectWatchpointSetExpression::ExecuteRawCommandString } size = with_dash_x ? m_option_watchpoint.watch_size : target->GetArchitecture().GetAddressByteSize(); - if (!m_option_watchpoint.IsWatchSizeSupported(size)) - { - result.GetErrorStream().Printf("Watch size of %lu is not supported\n", size); - return false; - } // Now it's time to create the watchpoint. uint32_t watch_type = m_option_watchpoint.watch_type; - Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type).get(); + Error error; + Watchpoint *wp = target->CreateWatchpoint(addr, size, watch_type, error).get(); if (wp) { if (var_sp && var_sp->GetDeclaration().GetFile()) { StreamString ss; @@ -1245,7 +1224,8 @@ CommandObjectWatchpointSetExpression::ExecuteRawCommandString } else { result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n", addr, size); - CheckIfWatchpointsExhausted(target, result); + if (error.AsCString(NULL)) + result.AppendError(error.AsCString()); result.SetStatus(eReturnStatusFailed); } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 0fce9ae06d8..c5c0a187990 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -30,6 +30,7 @@ #include "lldb/Host/Host.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionGroupWatchpoint.h" #include "lldb/lldb-private-log.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" @@ -465,10 +466,25 @@ Target::ProcessIsValid() return (m_process_sp && m_process_sp->IsAlive()); } +static bool +CheckIfWatchpointsExhausted(Target *target, Error &error) +{ + uint32_t num_supported_hardware_watchpoints; + Error rc = target->GetProcessSP()->GetWatchpointSupportInfo(num_supported_hardware_watchpoints); + if (rc.Success()) + { + uint32_t num_current_watchpoints = target->GetWatchpointList().GetSize(); + if (num_current_watchpoints >= num_supported_hardware_watchpoints) + error.SetErrorStringWithFormat("number of supported hardware watchpoints (%u) has been reached", + num_supported_hardware_watchpoints); + } + return false; +} + // See also Watchpoint::SetWatchpointType(uint32_t type) and // the OptionGroupWatchpoint::WatchType enum type. WatchpointSP -Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type) +Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type, Error &error) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); if (log) @@ -477,9 +493,18 @@ Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type) WatchpointSP wp_sp; if (!ProcessIsValid()) + { + error.SetErrorString("process is not alive"); return wp_sp; + } if (addr == LLDB_INVALID_ADDRESS || size == 0) + { + if (size == 0) + error.SetErrorString("cannot set a watchpoint with watch_size of 0"); + else + error.SetErrorStringWithFormat("invalid watch address: %llu", addr); return wp_sp; + } // Currently we only support one watchpoint per address, with total number // of watchpoints limited by the hardware which the inferior is running on. @@ -517,17 +542,23 @@ Target::CreateWatchpoint(lldb::addr_t addr, size_t size, uint32_t type) m_watchpoint_list.Add(wp_sp); } - Error rc = m_process_sp->EnableWatchpoint(wp_sp.get()); + error = m_process_sp->EnableWatchpoint(wp_sp.get()); if (log) log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n", __FUNCTION__, - rc.Success() ? "succeeded" : "failed", + error.Success() ? "succeeded" : "failed", wp_sp->GetID()); - if (rc.Fail()) { + if (error.Fail()) { // Enabling the watchpoint on the device side failed. // Remove the said watchpoint from the list maintained by the target instance. m_watchpoint_list.Remove(wp_sp->GetID()); + // See if we could provide more helpful error message. + if (!CheckIfWatchpointsExhausted(this, error)) + { + if (!OptionGroupWatchpoint::IsWatchSizeSupported(size)) + error.SetErrorStringWithFormat("watch size of %lu is not supported", size); + } wp_sp.reset(); } else diff --git a/lldb/test/python_api/default-constructor/sb_target.py b/lldb/test/python_api/default-constructor/sb_target.py index 3e6c6f63056..823b49f6243 100644 --- a/lldb/test/python_api/default-constructor/sb_target.py +++ b/lldb/test/python_api/default-constructor/sb_target.py @@ -52,7 +52,8 @@ def fuzz_obj(obj): obj.GetAddressByteSize() obj.GetByteOrder() obj.GetTriple() - obj.WatchAddress(123, 8, True, True) + error = lldb.SBError() + obj.WatchAddress(123, 8, True, True, error) obj.GetBroadcaster() obj.GetDescription(lldb.SBStream(), lldb.eDescriptionLevelBrief) obj.Clear() diff --git a/lldb/test/python_api/default-constructor/sb_value.py b/lldb/test/python_api/default-constructor/sb_value.py index a82a3e38f78..d103551635f 100644 --- a/lldb/test/python_api/default-constructor/sb_value.py +++ b/lldb/test/python_api/default-constructor/sb_value.py @@ -34,8 +34,9 @@ def fuzz_obj(obj): obj.GetDescription(stream) obj.GetExpressionPath(stream) obj.GetExpressionPath(stream, True) - obj.Watch(True, True, False) - obj.WatchPointee(True, False, True) + error = lldb.SBError() + obj.Watch(True, True, False, error) + obj.WatchPointee(True, False, True, error) for child_val in obj: print child_val error = lldb.SBError() diff --git a/lldb/test/python_api/default-constructor/sb_watchpoint.py b/lldb/test/python_api/default-constructor/sb_watchpoint.py index a028cb48c4c..f462e62ff16 100644 --- a/lldb/test/python_api/default-constructor/sb_watchpoint.py +++ b/lldb/test/python_api/default-constructor/sb_watchpoint.py @@ -8,7 +8,6 @@ import lldb def fuzz_obj(obj): obj.GetID() obj.IsValid() - obj.GetError() obj.GetHardwareIndex() obj.GetWatchAddress() obj.GetWatchSize() diff --git a/lldb/test/python_api/watchpoint/TestSetWatchpoint.py b/lldb/test/python_api/watchpoint/TestSetWatchpoint.py index e283ab0762c..124dec11cbd 100644 --- a/lldb/test/python_api/watchpoint/TestSetWatchpoint.py +++ b/lldb/test/python_api/watchpoint/TestSetWatchpoint.py @@ -61,7 +61,8 @@ class SetWatchpointAPITestCase(TestBase): # Watch 'global' for read and write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) - watchpoint = value.Watch(True, True, True) + error = lldb.SBError(); + watchpoint = value.Watch(True, True, True, error) self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) diff --git a/lldb/test/python_api/watchpoint/TestWatchpointIgnoreCount.py b/lldb/test/python_api/watchpoint/TestWatchpointIgnoreCount.py index 2076ea6b6c5..ffe770852e5 100644 --- a/lldb/test/python_api/watchpoint/TestWatchpointIgnoreCount.py +++ b/lldb/test/python_api/watchpoint/TestWatchpointIgnoreCount.py @@ -61,7 +61,8 @@ class WatchpointIgnoreCountTestCase(TestBase): # Watch 'global' for read and write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) - watchpoint = value.Watch(True, True, True) + error = lldb.SBError(); + watchpoint = value.Watch(True, True, True, error) self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) diff --git a/lldb/test/python_api/watchpoint/TestWatchpointIter.py b/lldb/test/python_api/watchpoint/TestWatchpointIter.py index db6d70f5bbc..c6d37502ec3 100644 --- a/lldb/test/python_api/watchpoint/TestWatchpointIter.py +++ b/lldb/test/python_api/watchpoint/TestWatchpointIter.py @@ -61,7 +61,8 @@ class WatchpointIteratorTestCase(TestBase): # Watch 'global' for read and write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) - watchpoint = value.Watch(True, True, True) + error = lldb.SBError(); + watchpoint = value.Watch(True, True, True, error) self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) diff --git a/lldb/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py b/lldb/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py index 8f46670db28..d3707bad21e 100644 --- a/lldb/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py +++ b/lldb/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py @@ -66,7 +66,8 @@ class WatchpointConditionAPITestCase(TestBase): # Watch 'global' for write. value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal) - watchpoint = value.Watch(True, False, True) + error = lldb.SBError(); + watchpoint = value.Watch(True, False, True, error) self.assertTrue(value and watchpoint, "Successfully found the variable and set a watchpoint") self.DebugSBValue(value) diff --git a/lldb/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py b/lldb/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py index 21ac809420b..2310fdc7489 100644 --- a/lldb/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py +++ b/lldb/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py @@ -67,7 +67,8 @@ class SetWatchlocationAPITestCase(TestBase): value.GetValueAsUnsigned(0), value.GetType().GetPointeeType()) # Watch for write to *g_char_ptr. - watchpoint = value.WatchPointee(True, False, True) + error = lldb.SBError(); + watchpoint = value.WatchPointee(True, False, True, error) self.assertTrue(value and watchpoint, "Successfully found the pointer and set a watchpoint") self.DebugSBValue(value) diff --git a/lldb/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py b/lldb/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py index 34c2daefe2d..407e7919d0d 100644 --- a/lldb/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py +++ b/lldb/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py @@ -37,6 +37,21 @@ class TargetWatchAddressAPITestCase(TestBase): self.buildDwarf() self.do_set_watchaddress() + @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") + @python_api_test + @dsym_test + def test_watch_address_with_invalid_watch_size_with_dsym(self): + """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" + self.buildDsym() + self.do_set_watchaddress_with_invalid_watch_size() + + @python_api_test + @dwarf_test + def test_watch_address_with_invalid_watch_size_with_dwarf(self): + """Exercise SBTarget.WatchAddress() API but pass an invalid watch_size.""" + self.buildDwarf() + self.do_set_watchaddress_with_invalid_watch_size() + def do_set_watchaddress(self): """Use SBTarget.WatchAddress() to set a watchpoint and verify that the program stops later due to the watchpoint.""" exe = os.path.join(os.getcwd(), "a.out") @@ -67,7 +82,8 @@ class TargetWatchAddressAPITestCase(TestBase): value.GetValueAsUnsigned(0), value.GetType().GetPointeeType()) # Watch for write to *g_char_ptr. - watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True) + error = lldb.SBError(); + watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 1, False, True, error) self.assertTrue(value and watchpoint, "Successfully found the pointer and set a watchpoint") self.DebugSBValue(value) @@ -95,6 +111,42 @@ class TargetWatchAddressAPITestCase(TestBase): # This finishes our test. + def do_set_watchaddress_with_invalid_watch_size(self): + """Use SBTarget.WatchAddress() to set a watchpoint with invalid watch_size and verify we get a meaningful error message.""" + exe = os.path.join(os.getcwd(), "a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Now create a breakpoint on main.c. + 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.FindValue('g_char_ptr', + lldb.eValueTypeVariableGlobal) + pointee = value.CreateValueFromAddress("pointee", + value.GetValueAsUnsigned(0), + value.GetType().GetPointeeType()) + # Watch for write to *g_char_ptr. + error = lldb.SBError(); + watchpoint = target.WatchAddress(value.GetValueAsUnsigned(), 365, False, True, error) + self.assertFalse(watchpoint) + self.expect(error.GetCString(), exe=False, + substrs = ['watch size of %d is not supported' % 365]) + if __name__ == '__main__': import atexit |