From 6f5d109fca23056dd74d673d2e3439ece22c80b4 Mon Sep 17 00:00:00 2001 From: Laura Chaparro-Gutierrez Date: Mon, 12 Sep 2022 15:39:57 +0000 Subject: [PATCH] [lldb] Add SBBreakpointLocation::SetCallback * Include SetCallback in SBBreakpointLocation, similar as in SBBreakpoint. * Add test_breakpoint_location_callback test as part of TestMultithreaded. Reviewed By: werat, JDevlieghere Differential Revision: https://reviews.llvm.org/D133689 Co-authored-by: Andy Yankovsky --- lldb/include/lldb/API/SBBreakpointLocation.h | 4 +- lldb/source/API/SBBreakpointLocation.cpp | 17 +++++++ .../API/api/multithreaded/TestMultithreaded.py | 10 +++++ .../test_breakpoint_location_callback.cpp.template | 52 ++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 lldb/test/API/api/multithreaded/test_breakpoint_location_callback.cpp.template diff --git a/lldb/include/lldb/API/SBBreakpointLocation.h b/lldb/include/lldb/API/SBBreakpointLocation.h index a906727..ca29696 100644 --- a/lldb/include/lldb/API/SBBreakpointLocation.h +++ b/lldb/include/lldb/API/SBBreakpointLocation.h @@ -48,11 +48,13 @@ public: void SetCondition(const char *condition); const char *GetCondition(); - + void SetAutoContinue(bool auto_continue); bool GetAutoContinue(); + void SetCallback(SBBreakpointHitCallback callback, void *baton); + void SetScriptCallbackFunction(const char *callback_function_name); SBError SetScriptCallbackFunction(const char *callback_function_name, diff --git a/lldb/source/API/SBBreakpointLocation.cpp b/lldb/source/API/SBBreakpointLocation.cpp index 6c03aba..a253530 100644 --- a/lldb/source/API/SBBreakpointLocation.cpp +++ b/lldb/source/API/SBBreakpointLocation.cpp @@ -28,6 +28,8 @@ #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" +#include "SBBreakpointOptionCommon.h" + using namespace lldb; using namespace lldb_private; @@ -198,6 +200,21 @@ bool SBBreakpointLocation::GetAutoContinue() { return false; } +void SBBreakpointLocation::SetCallback(SBBreakpointHitCallback callback, + void *baton) { + LLDB_INSTRUMENT_VA(this, callback, baton); + + BreakpointLocationSP loc_sp = GetSP(); + + if (loc_sp) { + std::lock_guard guard( + loc_sp->GetTarget().GetAPIMutex()); + BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton)); + loc_sp->SetCallback(SBBreakpointCallbackBaton::PrivateBreakpointHitCallback, + baton_sp, false); + } +} + void SBBreakpointLocation::SetScriptCallbackFunction( const char *callback_function_name) { LLDB_INSTRUMENT_VA(this, callback_function_name); diff --git a/lldb/test/API/api/multithreaded/TestMultithreaded.py b/lldb/test/API/api/multithreaded/TestMultithreaded.py index 231eb9f..3375990 100644 --- a/lldb/test/API/api/multithreaded/TestMultithreaded.py +++ b/lldb/test/API/api/multithreaded/TestMultithreaded.py @@ -18,6 +18,7 @@ class SBBreakpointCallbackCase(TestBase): self.generateSource('driver.cpp') self.generateSource('listener_test.cpp') self.generateSource('test_breakpoint_callback.cpp') + self.generateSource('test_breakpoint_location_callback.cpp') self.generateSource('test_listener_event_description.cpp') self.generateSource('test_listener_event_process_state.cpp') self.generateSource('test_listener_resume.cpp') @@ -45,6 +46,15 @@ class SBBreakpointCallbackCase(TestBase): @skipIfNoSBHeaders # clang-cl does not support throw or catch (llvm.org/pr24538) @skipIfWindows + def test_breakpoint_location_callback(self): + """Test the that SBBreakpointLocation callback is invoked when a breakpoint is hit. """ + self.build_and_test('driver.cpp test_breakpoint_location_callback.cpp', + 'test_breakpoint_location_callback') + + @skipIfRemote + @skipIfNoSBHeaders + # clang-cl does not support throw or catch (llvm.org/pr24538) + @skipIfWindows @expectedFlakeyFreeBSD def test_sb_api_listener_event_description(self): """ Test the description of an SBListener breakpoint event is valid.""" diff --git a/lldb/test/API/api/multithreaded/test_breakpoint_location_callback.cpp.template b/lldb/test/API/api/multithreaded/test_breakpoint_location_callback.cpp.template new file mode 100644 index 0000000..0b0dc56 --- /dev/null +++ b/lldb/test/API/api/multithreaded/test_breakpoint_location_callback.cpp.template @@ -0,0 +1,52 @@ + +// LLDB C++ API Test: verify that the function registered with +// SBBreakpoint.SetCallback() is invoked when a breakpoint is hit. + +#include +#include +#include +#include + +%include_SB_APIs% + +#include "common.h" + +using namespace std; +using namespace lldb; + +mutex g_mutex; +condition_variable g_condition; +int g_breakpoint_hit_count = 0; + +bool BPCallback (void *baton, + SBProcess &process, + SBThread &thread, + SBBreakpointLocation &location) { + lock_guard lock(g_mutex); + g_breakpoint_hit_count += 1; + g_condition.notify_all(); + return true; +} + +void test(SBDebugger &dbg, vector args) { + dbg.SetAsync(false); + SBTarget target = dbg.CreateTarget(args.at(0).c_str()); + if (!target.IsValid()) throw Exception("invalid target"); + + SBBreakpoint breakpoint = target.BreakpointCreateByName("next"); + if (!breakpoint.IsValid()) throw Exception("invalid breakpoint"); + + if(breakpoint.GetNumLocations() != 1) throw Exception("unexpected amount of breakpoint locations"); + SBBreakpointLocation breakpoint_location = breakpoint.GetLocationAtIndex(0); + breakpoint_location.SetCallback(BPCallback, 0); + + std::unique_ptr working_dir(get_working_dir()); + SBProcess process = target.LaunchSimple (0, 0, working_dir.get()); + + { + unique_lock lock(g_mutex); + g_condition.wait_for(lock, chrono::seconds(5)); + if (g_breakpoint_hit_count != 1) + throw Exception("Breakpoint hit count expected to be 1"); + } +} -- 2.7.4