1 //===-- SBBreakpointLocation.cpp ------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/API/SBBreakpointLocation.h"
10 #include "lldb/API/SBAddress.h"
11 #include "lldb/API/SBDebugger.h"
12 #include "lldb/API/SBDefines.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBStringList.h"
15 #include "lldb/API/SBStructuredData.h"
16 #include "lldb/Utility/Instrumentation.h"
18 #include "lldb/Breakpoint/Breakpoint.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Core/Debugger.h"
21 #include "lldb/Core/StructuredDataImpl.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/ScriptInterpreter.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/ThreadSpec.h"
26 #include "lldb/Utility/Stream.h"
27 #include "lldb/lldb-defines.h"
28 #include "lldb/lldb-types.h"
30 #include "SBBreakpointOptionCommon.h"
33 using namespace lldb_private
;
35 SBBreakpointLocation::SBBreakpointLocation() { LLDB_INSTRUMENT_VA(this); }
37 SBBreakpointLocation::SBBreakpointLocation(
38 const lldb::BreakpointLocationSP
&break_loc_sp
)
39 : m_opaque_wp(break_loc_sp
) {
40 LLDB_INSTRUMENT_VA(this, break_loc_sp
);
43 SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation
&rhs
)
44 : m_opaque_wp(rhs
.m_opaque_wp
) {
45 LLDB_INSTRUMENT_VA(this, rhs
);
48 const SBBreakpointLocation
&SBBreakpointLocation::
49 operator=(const SBBreakpointLocation
&rhs
) {
50 LLDB_INSTRUMENT_VA(this, rhs
);
52 m_opaque_wp
= rhs
.m_opaque_wp
;
56 SBBreakpointLocation::~SBBreakpointLocation() = default;
58 BreakpointLocationSP
SBBreakpointLocation::GetSP() const {
59 return m_opaque_wp
.lock();
62 bool SBBreakpointLocation::IsValid() const {
63 LLDB_INSTRUMENT_VA(this);
64 return this->operator bool();
66 SBBreakpointLocation::operator bool() const {
67 LLDB_INSTRUMENT_VA(this);
72 SBAddress
SBBreakpointLocation::GetAddress() {
73 LLDB_INSTRUMENT_VA(this);
75 BreakpointLocationSP loc_sp
= GetSP();
77 return SBAddress(loc_sp
->GetAddress());
83 addr_t
SBBreakpointLocation::GetLoadAddress() {
84 LLDB_INSTRUMENT_VA(this);
86 addr_t ret_addr
= LLDB_INVALID_ADDRESS
;
87 BreakpointLocationSP loc_sp
= GetSP();
90 std::lock_guard
<std::recursive_mutex
> guard(
91 loc_sp
->GetTarget().GetAPIMutex());
92 ret_addr
= loc_sp
->GetLoadAddress();
98 void SBBreakpointLocation::SetEnabled(bool enabled
) {
99 LLDB_INSTRUMENT_VA(this, enabled
);
101 BreakpointLocationSP loc_sp
= GetSP();
103 std::lock_guard
<std::recursive_mutex
> guard(
104 loc_sp
->GetTarget().GetAPIMutex());
105 loc_sp
->SetEnabled(enabled
);
109 bool SBBreakpointLocation::IsEnabled() {
110 LLDB_INSTRUMENT_VA(this);
112 BreakpointLocationSP loc_sp
= GetSP();
114 std::lock_guard
<std::recursive_mutex
> guard(
115 loc_sp
->GetTarget().GetAPIMutex());
116 return loc_sp
->IsEnabled();
121 uint32_t SBBreakpointLocation::GetHitCount() {
122 LLDB_INSTRUMENT_VA(this);
124 BreakpointLocationSP loc_sp
= GetSP();
126 std::lock_guard
<std::recursive_mutex
> guard(
127 loc_sp
->GetTarget().GetAPIMutex());
128 return loc_sp
->GetHitCount();
133 uint32_t SBBreakpointLocation::GetIgnoreCount() {
134 LLDB_INSTRUMENT_VA(this);
136 BreakpointLocationSP loc_sp
= GetSP();
138 std::lock_guard
<std::recursive_mutex
> guard(
139 loc_sp
->GetTarget().GetAPIMutex());
140 return loc_sp
->GetIgnoreCount();
145 void SBBreakpointLocation::SetIgnoreCount(uint32_t n
) {
146 LLDB_INSTRUMENT_VA(this, n
);
148 BreakpointLocationSP loc_sp
= GetSP();
150 std::lock_guard
<std::recursive_mutex
> guard(
151 loc_sp
->GetTarget().GetAPIMutex());
152 loc_sp
->SetIgnoreCount(n
);
156 void SBBreakpointLocation::SetCondition(const char *condition
) {
157 LLDB_INSTRUMENT_VA(this, condition
);
159 BreakpointLocationSP loc_sp
= GetSP();
161 std::lock_guard
<std::recursive_mutex
> guard(
162 loc_sp
->GetTarget().GetAPIMutex());
163 loc_sp
->SetCondition(condition
);
167 const char *SBBreakpointLocation::GetCondition() {
168 LLDB_INSTRUMENT_VA(this);
170 BreakpointLocationSP loc_sp
= GetSP();
174 std::lock_guard
<std::recursive_mutex
> guard(
175 loc_sp
->GetTarget().GetAPIMutex());
176 return ConstString(loc_sp
->GetConditionText()).GetCString();
179 void SBBreakpointLocation::SetAutoContinue(bool auto_continue
) {
180 LLDB_INSTRUMENT_VA(this, auto_continue
);
182 BreakpointLocationSP loc_sp
= GetSP();
184 std::lock_guard
<std::recursive_mutex
> guard(
185 loc_sp
->GetTarget().GetAPIMutex());
186 loc_sp
->SetAutoContinue(auto_continue
);
190 bool SBBreakpointLocation::GetAutoContinue() {
191 LLDB_INSTRUMENT_VA(this);
193 BreakpointLocationSP loc_sp
= GetSP();
195 std::lock_guard
<std::recursive_mutex
> guard(
196 loc_sp
->GetTarget().GetAPIMutex());
197 return loc_sp
->IsAutoContinue();
202 void SBBreakpointLocation::SetCallback(SBBreakpointHitCallback callback
,
204 LLDB_INSTRUMENT_VA(this, callback
, baton
);
206 BreakpointLocationSP loc_sp
= GetSP();
209 std::lock_guard
<std::recursive_mutex
> guard(
210 loc_sp
->GetTarget().GetAPIMutex());
211 BatonSP
baton_sp(new SBBreakpointCallbackBaton(callback
, baton
));
212 loc_sp
->SetCallback(SBBreakpointCallbackBaton::PrivateBreakpointHitCallback
,
217 void SBBreakpointLocation::SetScriptCallbackFunction(
218 const char *callback_function_name
) {
219 LLDB_INSTRUMENT_VA(this, callback_function_name
);
222 SBError
SBBreakpointLocation::SetScriptCallbackFunction(
223 const char *callback_function_name
,
224 SBStructuredData
&extra_args
) {
225 LLDB_INSTRUMENT_VA(this, callback_function_name
, extra_args
);
227 BreakpointLocationSP loc_sp
= GetSP();
231 std::lock_guard
<std::recursive_mutex
> guard(
232 loc_sp
->GetTarget().GetAPIMutex());
233 BreakpointOptions
&bp_options
= loc_sp
->GetLocationOptions();
234 error
= loc_sp
->GetBreakpoint()
237 .GetScriptInterpreter()
238 ->SetBreakpointCommandCallbackFunction(bp_options
,
239 callback_function_name
,
242 sb_error
.SetError(std::move(error
));
244 sb_error
= Status::FromErrorString("invalid breakpoint");
250 SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text
) {
251 LLDB_INSTRUMENT_VA(this, callback_body_text
);
253 BreakpointLocationSP loc_sp
= GetSP();
257 std::lock_guard
<std::recursive_mutex
> guard(
258 loc_sp
->GetTarget().GetAPIMutex());
259 BreakpointOptions
&bp_options
= loc_sp
->GetLocationOptions();
261 loc_sp
->GetBreakpoint()
264 .GetScriptInterpreter()
265 ->SetBreakpointCommandCallback(bp_options
, callback_body_text
,
266 /*is_callback=*/false);
267 sb_error
.SetError(std::move(error
));
269 sb_error
= Status::FromErrorString("invalid breakpoint");
274 void SBBreakpointLocation::SetCommandLineCommands(SBStringList
&commands
) {
275 LLDB_INSTRUMENT_VA(this, commands
);
277 BreakpointLocationSP loc_sp
= GetSP();
280 if (commands
.GetSize() == 0)
283 std::lock_guard
<std::recursive_mutex
> guard(
284 loc_sp
->GetTarget().GetAPIMutex());
285 std::unique_ptr
<BreakpointOptions::CommandData
> cmd_data_up(
286 new BreakpointOptions::CommandData(*commands
, eScriptLanguageNone
));
288 loc_sp
->GetLocationOptions().SetCommandDataCallback(cmd_data_up
);
291 bool SBBreakpointLocation::GetCommandLineCommands(SBStringList
&commands
) {
292 LLDB_INSTRUMENT_VA(this, commands
);
294 BreakpointLocationSP loc_sp
= GetSP();
297 StringList command_list
;
299 loc_sp
->GetLocationOptions().GetCommandLineCallbacks(command_list
);
301 commands
.AppendList(command_list
);
305 void SBBreakpointLocation::SetThreadID(lldb::tid_t thread_id
) {
306 LLDB_INSTRUMENT_VA(this, thread_id
);
308 BreakpointLocationSP loc_sp
= GetSP();
310 std::lock_guard
<std::recursive_mutex
> guard(
311 loc_sp
->GetTarget().GetAPIMutex());
312 loc_sp
->SetThreadID(thread_id
);
316 lldb::tid_t
SBBreakpointLocation::GetThreadID() {
317 LLDB_INSTRUMENT_VA(this);
319 lldb::tid_t tid
= LLDB_INVALID_THREAD_ID
;
320 BreakpointLocationSP loc_sp
= GetSP();
322 std::lock_guard
<std::recursive_mutex
> guard(
323 loc_sp
->GetTarget().GetAPIMutex());
324 return loc_sp
->GetThreadID();
329 void SBBreakpointLocation::SetThreadIndex(uint32_t index
) {
330 LLDB_INSTRUMENT_VA(this, index
);
332 BreakpointLocationSP loc_sp
= GetSP();
334 std::lock_guard
<std::recursive_mutex
> guard(
335 loc_sp
->GetTarget().GetAPIMutex());
336 loc_sp
->SetThreadIndex(index
);
340 uint32_t SBBreakpointLocation::GetThreadIndex() const {
341 LLDB_INSTRUMENT_VA(this);
343 uint32_t thread_idx
= UINT32_MAX
;
344 BreakpointLocationSP loc_sp
= GetSP();
346 std::lock_guard
<std::recursive_mutex
> guard(
347 loc_sp
->GetTarget().GetAPIMutex());
348 return loc_sp
->GetThreadIndex();
353 void SBBreakpointLocation::SetThreadName(const char *thread_name
) {
354 LLDB_INSTRUMENT_VA(this, thread_name
);
356 BreakpointLocationSP loc_sp
= GetSP();
358 std::lock_guard
<std::recursive_mutex
> guard(
359 loc_sp
->GetTarget().GetAPIMutex());
360 loc_sp
->SetThreadName(thread_name
);
364 const char *SBBreakpointLocation::GetThreadName() const {
365 LLDB_INSTRUMENT_VA(this);
367 BreakpointLocationSP loc_sp
= GetSP();
371 std::lock_guard
<std::recursive_mutex
> guard(
372 loc_sp
->GetTarget().GetAPIMutex());
373 return ConstString(loc_sp
->GetThreadName()).GetCString();
376 void SBBreakpointLocation::SetQueueName(const char *queue_name
) {
377 LLDB_INSTRUMENT_VA(this, queue_name
);
379 BreakpointLocationSP loc_sp
= GetSP();
381 std::lock_guard
<std::recursive_mutex
> guard(
382 loc_sp
->GetTarget().GetAPIMutex());
383 loc_sp
->SetQueueName(queue_name
);
387 const char *SBBreakpointLocation::GetQueueName() const {
388 LLDB_INSTRUMENT_VA(this);
390 BreakpointLocationSP loc_sp
= GetSP();
394 std::lock_guard
<std::recursive_mutex
> guard(
395 loc_sp
->GetTarget().GetAPIMutex());
396 return ConstString(loc_sp
->GetQueueName()).GetCString();
399 bool SBBreakpointLocation::IsResolved() {
400 LLDB_INSTRUMENT_VA(this);
402 BreakpointLocationSP loc_sp
= GetSP();
404 std::lock_guard
<std::recursive_mutex
> guard(
405 loc_sp
->GetTarget().GetAPIMutex());
406 return loc_sp
->IsResolved();
411 void SBBreakpointLocation::SetLocation(
412 const lldb::BreakpointLocationSP
&break_loc_sp
) {
413 // Uninstall the callbacks?
414 m_opaque_wp
= break_loc_sp
;
417 bool SBBreakpointLocation::GetDescription(SBStream
&description
,
418 DescriptionLevel level
) {
419 LLDB_INSTRUMENT_VA(this, description
, level
);
421 Stream
&strm
= description
.ref();
422 BreakpointLocationSP loc_sp
= GetSP();
425 std::lock_guard
<std::recursive_mutex
> guard(
426 loc_sp
->GetTarget().GetAPIMutex());
427 loc_sp
->GetDescription(&strm
, level
);
430 strm
.PutCString("No value");
435 break_id_t
SBBreakpointLocation::GetID() {
436 LLDB_INSTRUMENT_VA(this);
438 BreakpointLocationSP loc_sp
= GetSP();
440 std::lock_guard
<std::recursive_mutex
> guard(
441 loc_sp
->GetTarget().GetAPIMutex());
442 return loc_sp
->GetID();
444 return LLDB_INVALID_BREAK_ID
;
447 SBBreakpoint
SBBreakpointLocation::GetBreakpoint() {
448 LLDB_INSTRUMENT_VA(this);
450 BreakpointLocationSP loc_sp
= GetSP();
454 std::lock_guard
<std::recursive_mutex
> guard(
455 loc_sp
->GetTarget().GetAPIMutex());
456 sb_bp
= loc_sp
->GetBreakpoint().shared_from_this();