forked from OSchip/llvm-project
[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 <weratt@gmail.com>
This commit is contained in:
parent
38ffa2bb96
commit
6f5d109fca
|
@ -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,
|
||||
|
|
|
@ -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<std::recursive_mutex> 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);
|
||||
|
|
|
@ -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')
|
||||
|
@ -41,6 +42,15 @@ class SBBreakpointCallbackCase(TestBase):
|
|||
self.build_and_test('driver.cpp test_breakpoint_callback.cpp',
|
||||
'test_breakpoint_callback')
|
||||
|
||||
@skipIfRemote
|
||||
@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)
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
// LLDB C++ API Test: verify that the function registered with
|
||||
// SBBreakpoint.SetCallback() is invoked when a breakpoint is hit.
|
||||
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
%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<mutex> lock(g_mutex);
|
||||
g_breakpoint_hit_count += 1;
|
||||
g_condition.notify_all();
|
||||
return true;
|
||||
}
|
||||
|
||||
void test(SBDebugger &dbg, vector<string> 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<char> working_dir(get_working_dir());
|
||||
SBProcess process = target.LaunchSimple (0, 0, working_dir.get());
|
||||
|
||||
{
|
||||
unique_lock<mutex> 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");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue