SBBreakpointLocation.cpp revision 360784
1//===-- SBBreakpointLocation.cpp --------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/API/SBBreakpointLocation.h"
10#include "SBReproducerPrivate.h"
11#include "lldb/API/SBAddress.h"
12#include "lldb/API/SBDebugger.h"
13#include "lldb/API/SBDefines.h"
14#include "lldb/API/SBStream.h"
15#include "lldb/API/SBStructuredData.h"
16#include "lldb/API/SBStringList.h"
17
18#include "lldb/Breakpoint/Breakpoint.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Core/Debugger.h"
21#include "lldb/Core/StreamFile.h"
22#include "lldb/Core/StructuredDataImpl.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/ScriptInterpreter.h"
25#include "lldb/Target/Target.h"
26#include "lldb/Target/ThreadSpec.h"
27#include "lldb/Utility/Stream.h"
28#include "lldb/lldb-defines.h"
29#include "lldb/lldb-types.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34SBBreakpointLocation::SBBreakpointLocation() {
35  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpointLocation);
36}
37
38SBBreakpointLocation::SBBreakpointLocation(
39    const lldb::BreakpointLocationSP &break_loc_sp)
40    : m_opaque_wp(break_loc_sp) {
41  LLDB_RECORD_CONSTRUCTOR(SBBreakpointLocation,
42                          (const lldb::BreakpointLocationSP &), break_loc_sp);
43}
44
45SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation &rhs)
46    : m_opaque_wp(rhs.m_opaque_wp) {
47  LLDB_RECORD_CONSTRUCTOR(SBBreakpointLocation,
48                          (const lldb::SBBreakpointLocation &), rhs);
49}
50
51const SBBreakpointLocation &SBBreakpointLocation::
52operator=(const SBBreakpointLocation &rhs) {
53  LLDB_RECORD_METHOD(
54      const lldb::SBBreakpointLocation &,
55      SBBreakpointLocation, operator=,(const lldb::SBBreakpointLocation &),
56      rhs);
57
58  m_opaque_wp = rhs.m_opaque_wp;
59  return LLDB_RECORD_RESULT(*this);
60}
61
62SBBreakpointLocation::~SBBreakpointLocation() {}
63
64BreakpointLocationSP SBBreakpointLocation::GetSP() const {
65  return m_opaque_wp.lock();
66}
67
68bool SBBreakpointLocation::IsValid() const {
69  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointLocation, IsValid);
70  return this->operator bool();
71}
72SBBreakpointLocation::operator bool() const {
73  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpointLocation, operator bool);
74
75  return bool(GetSP());
76}
77
78SBAddress SBBreakpointLocation::GetAddress() {
79  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBAddress, SBBreakpointLocation, GetAddress);
80
81  BreakpointLocationSP loc_sp = GetSP();
82  if (loc_sp) {
83    return LLDB_RECORD_RESULT(SBAddress(&loc_sp->GetAddress()));
84  }
85
86  return LLDB_RECORD_RESULT(SBAddress());
87}
88
89addr_t SBBreakpointLocation::GetLoadAddress() {
90  LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBBreakpointLocation,
91                             GetLoadAddress);
92
93  addr_t ret_addr = LLDB_INVALID_ADDRESS;
94  BreakpointLocationSP loc_sp = GetSP();
95
96  if (loc_sp) {
97    std::lock_guard<std::recursive_mutex> guard(
98        loc_sp->GetTarget().GetAPIMutex());
99    ret_addr = loc_sp->GetLoadAddress();
100  }
101
102  return ret_addr;
103}
104
105void SBBreakpointLocation::SetEnabled(bool enabled) {
106  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetEnabled, (bool), enabled);
107
108  BreakpointLocationSP loc_sp = GetSP();
109  if (loc_sp) {
110    std::lock_guard<std::recursive_mutex> guard(
111        loc_sp->GetTarget().GetAPIMutex());
112    loc_sp->SetEnabled(enabled);
113  }
114}
115
116bool SBBreakpointLocation::IsEnabled() {
117  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, IsEnabled);
118
119  BreakpointLocationSP loc_sp = GetSP();
120  if (loc_sp) {
121    std::lock_guard<std::recursive_mutex> guard(
122        loc_sp->GetTarget().GetAPIMutex());
123    return loc_sp->IsEnabled();
124  } else
125    return false;
126}
127
128uint32_t SBBreakpointLocation::GetHitCount() {
129  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBreakpointLocation, GetHitCount);
130
131  BreakpointLocationSP loc_sp = GetSP();
132  if (loc_sp) {
133    std::lock_guard<std::recursive_mutex> guard(
134        loc_sp->GetTarget().GetAPIMutex());
135    return loc_sp->GetHitCount();
136  } else
137    return 0;
138}
139
140uint32_t SBBreakpointLocation::GetIgnoreCount() {
141  LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBBreakpointLocation, GetIgnoreCount);
142
143  BreakpointLocationSP loc_sp = GetSP();
144  if (loc_sp) {
145    std::lock_guard<std::recursive_mutex> guard(
146        loc_sp->GetTarget().GetAPIMutex());
147    return loc_sp->GetIgnoreCount();
148  } else
149    return 0;
150}
151
152void SBBreakpointLocation::SetIgnoreCount(uint32_t n) {
153  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetIgnoreCount, (uint32_t), n);
154
155  BreakpointLocationSP loc_sp = GetSP();
156  if (loc_sp) {
157    std::lock_guard<std::recursive_mutex> guard(
158        loc_sp->GetTarget().GetAPIMutex());
159    loc_sp->SetIgnoreCount(n);
160  }
161}
162
163void SBBreakpointLocation::SetCondition(const char *condition) {
164  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetCondition, (const char *),
165                     condition);
166
167  BreakpointLocationSP loc_sp = GetSP();
168  if (loc_sp) {
169    std::lock_guard<std::recursive_mutex> guard(
170        loc_sp->GetTarget().GetAPIMutex());
171    loc_sp->SetCondition(condition);
172  }
173}
174
175const char *SBBreakpointLocation::GetCondition() {
176  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpointLocation, GetCondition);
177
178  BreakpointLocationSP loc_sp = GetSP();
179  if (loc_sp) {
180    std::lock_guard<std::recursive_mutex> guard(
181        loc_sp->GetTarget().GetAPIMutex());
182    return loc_sp->GetConditionText();
183  }
184  return nullptr;
185}
186
187void SBBreakpointLocation::SetAutoContinue(bool auto_continue) {
188  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetAutoContinue, (bool),
189                     auto_continue);
190
191  BreakpointLocationSP loc_sp = GetSP();
192  if (loc_sp) {
193    std::lock_guard<std::recursive_mutex> guard(
194        loc_sp->GetTarget().GetAPIMutex());
195    loc_sp->SetAutoContinue(auto_continue);
196  }
197}
198
199bool SBBreakpointLocation::GetAutoContinue() {
200  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, GetAutoContinue);
201
202  BreakpointLocationSP loc_sp = GetSP();
203  if (loc_sp) {
204    std::lock_guard<std::recursive_mutex> guard(
205        loc_sp->GetTarget().GetAPIMutex());
206    return loc_sp->IsAutoContinue();
207  }
208  return false;
209}
210
211void SBBreakpointLocation::SetScriptCallbackFunction(
212  const char *callback_function_name) {
213LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetScriptCallbackFunction,
214                   (const char *), callback_function_name);
215}
216
217SBError SBBreakpointLocation::SetScriptCallbackFunction(
218    const char *callback_function_name,
219    SBStructuredData &extra_args) {
220  LLDB_RECORD_METHOD(SBError, SBBreakpointLocation, SetScriptCallbackFunction,
221                     (const char *, SBStructuredData &),
222                     callback_function_name, extra_args);
223  SBError sb_error;
224  BreakpointLocationSP loc_sp = GetSP();
225
226  if (loc_sp) {
227    Status error;
228    std::lock_guard<std::recursive_mutex> guard(
229        loc_sp->GetTarget().GetAPIMutex());
230    BreakpointOptions *bp_options = loc_sp->GetLocationOptions();
231    error = loc_sp->GetBreakpoint()
232        .GetTarget()
233        .GetDebugger()
234        .GetScriptInterpreter()
235        ->SetBreakpointCommandCallbackFunction(bp_options,
236                                               callback_function_name,
237                                               extra_args.m_impl_up
238                                                   ->GetObjectSP());
239      sb_error.SetError(error);
240    } else
241      sb_error.SetErrorString("invalid breakpoint");
242
243    return LLDB_RECORD_RESULT(sb_error);
244}
245
246SBError
247SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) {
248  LLDB_RECORD_METHOD(lldb::SBError, SBBreakpointLocation, SetScriptCallbackBody,
249                     (const char *), callback_body_text);
250
251  BreakpointLocationSP loc_sp = GetSP();
252
253  SBError sb_error;
254  if (loc_sp) {
255    std::lock_guard<std::recursive_mutex> guard(
256        loc_sp->GetTarget().GetAPIMutex());
257    BreakpointOptions *bp_options = loc_sp->GetLocationOptions();
258    Status error =
259        loc_sp->GetBreakpoint()
260            .GetTarget()
261            .GetDebugger()
262            .GetScriptInterpreter()
263            ->SetBreakpointCommandCallback(bp_options, callback_body_text);
264    sb_error.SetError(error);
265  } else
266    sb_error.SetErrorString("invalid breakpoint");
267
268  return LLDB_RECORD_RESULT(sb_error);
269}
270
271void SBBreakpointLocation::SetCommandLineCommands(SBStringList &commands) {
272  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetCommandLineCommands,
273                     (lldb::SBStringList &), commands);
274
275  BreakpointLocationSP loc_sp = GetSP();
276  if (!loc_sp)
277    return;
278  if (commands.GetSize() == 0)
279    return;
280
281  std::lock_guard<std::recursive_mutex> guard(
282      loc_sp->GetTarget().GetAPIMutex());
283  std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
284      new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
285
286  loc_sp->GetLocationOptions()->SetCommandDataCallback(cmd_data_up);
287}
288
289bool SBBreakpointLocation::GetCommandLineCommands(SBStringList &commands) {
290  LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetCommandLineCommands,
291                     (lldb::SBStringList &), commands);
292
293  BreakpointLocationSP loc_sp = GetSP();
294  if (!loc_sp)
295    return false;
296  StringList command_list;
297  bool has_commands =
298      loc_sp->GetLocationOptions()->GetCommandLineCallbacks(command_list);
299  if (has_commands)
300    commands.AppendList(command_list);
301  return has_commands;
302}
303
304void SBBreakpointLocation::SetThreadID(tid_t thread_id) {
305  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadID, (lldb::tid_t),
306                     thread_id);
307
308  BreakpointLocationSP loc_sp = GetSP();
309  if (loc_sp) {
310    std::lock_guard<std::recursive_mutex> guard(
311        loc_sp->GetTarget().GetAPIMutex());
312    loc_sp->SetThreadID(thread_id);
313  }
314}
315
316tid_t SBBreakpointLocation::GetThreadID() {
317  LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpointLocation, GetThreadID);
318
319  tid_t tid = LLDB_INVALID_THREAD_ID;
320  BreakpointLocationSP loc_sp = GetSP();
321  if (loc_sp) {
322    std::lock_guard<std::recursive_mutex> guard(
323        loc_sp->GetTarget().GetAPIMutex());
324    return loc_sp->GetThreadID();
325  }
326  return tid;
327}
328
329void SBBreakpointLocation::SetThreadIndex(uint32_t index) {
330  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadIndex, (uint32_t),
331                     index);
332
333  BreakpointLocationSP loc_sp = GetSP();
334  if (loc_sp) {
335    std::lock_guard<std::recursive_mutex> guard(
336        loc_sp->GetTarget().GetAPIMutex());
337    loc_sp->SetThreadIndex(index);
338  }
339}
340
341uint32_t SBBreakpointLocation::GetThreadIndex() const {
342  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpointLocation,
343                                   GetThreadIndex);
344
345  uint32_t thread_idx = UINT32_MAX;
346  BreakpointLocationSP loc_sp = GetSP();
347  if (loc_sp) {
348    std::lock_guard<std::recursive_mutex> guard(
349        loc_sp->GetTarget().GetAPIMutex());
350    return loc_sp->GetThreadIndex();
351  }
352  return thread_idx;
353}
354
355void SBBreakpointLocation::SetThreadName(const char *thread_name) {
356  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetThreadName, (const char *),
357                     thread_name);
358
359  BreakpointLocationSP loc_sp = GetSP();
360  if (loc_sp) {
361    std::lock_guard<std::recursive_mutex> guard(
362        loc_sp->GetTarget().GetAPIMutex());
363    loc_sp->SetThreadName(thread_name);
364  }
365}
366
367const char *SBBreakpointLocation::GetThreadName() const {
368  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation,
369                                   GetThreadName);
370
371  BreakpointLocationSP loc_sp = GetSP();
372  if (loc_sp) {
373    std::lock_guard<std::recursive_mutex> guard(
374        loc_sp->GetTarget().GetAPIMutex());
375    return loc_sp->GetThreadName();
376  }
377  return nullptr;
378}
379
380void SBBreakpointLocation::SetQueueName(const char *queue_name) {
381  LLDB_RECORD_METHOD(void, SBBreakpointLocation, SetQueueName, (const char *),
382                     queue_name);
383
384  BreakpointLocationSP loc_sp = GetSP();
385  if (loc_sp) {
386    std::lock_guard<std::recursive_mutex> guard(
387        loc_sp->GetTarget().GetAPIMutex());
388    loc_sp->SetQueueName(queue_name);
389  }
390}
391
392const char *SBBreakpointLocation::GetQueueName() const {
393  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpointLocation,
394                                   GetQueueName);
395
396  BreakpointLocationSP loc_sp = GetSP();
397  if (loc_sp) {
398    std::lock_guard<std::recursive_mutex> guard(
399        loc_sp->GetTarget().GetAPIMutex());
400    loc_sp->GetQueueName();
401  }
402  return nullptr;
403}
404
405bool SBBreakpointLocation::IsResolved() {
406  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpointLocation, IsResolved);
407
408  BreakpointLocationSP loc_sp = GetSP();
409  if (loc_sp) {
410    std::lock_guard<std::recursive_mutex> guard(
411        loc_sp->GetTarget().GetAPIMutex());
412    return loc_sp->IsResolved();
413  }
414  return false;
415}
416
417void SBBreakpointLocation::SetLocation(
418    const lldb::BreakpointLocationSP &break_loc_sp) {
419  // Uninstall the callbacks?
420  m_opaque_wp = break_loc_sp;
421}
422
423bool SBBreakpointLocation::GetDescription(SBStream &description,
424                                          DescriptionLevel level) {
425  LLDB_RECORD_METHOD(bool, SBBreakpointLocation, GetDescription,
426                     (lldb::SBStream &, lldb::DescriptionLevel), description,
427                     level);
428
429  Stream &strm = description.ref();
430  BreakpointLocationSP loc_sp = GetSP();
431
432  if (loc_sp) {
433    std::lock_guard<std::recursive_mutex> guard(
434        loc_sp->GetTarget().GetAPIMutex());
435    loc_sp->GetDescription(&strm, level);
436    strm.EOL();
437  } else
438    strm.PutCString("No value");
439
440  return true;
441}
442
443break_id_t SBBreakpointLocation::GetID() {
444  LLDB_RECORD_METHOD_NO_ARGS(lldb::break_id_t, SBBreakpointLocation, GetID);
445
446  BreakpointLocationSP loc_sp = GetSP();
447  if (loc_sp) {
448    std::lock_guard<std::recursive_mutex> guard(
449        loc_sp->GetTarget().GetAPIMutex());
450    return loc_sp->GetID();
451  } else
452    return LLDB_INVALID_BREAK_ID;
453}
454
455SBBreakpoint SBBreakpointLocation::GetBreakpoint() {
456  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBreakpoint, SBBreakpointLocation,
457                             GetBreakpoint);
458
459  BreakpointLocationSP loc_sp = GetSP();
460
461  SBBreakpoint sb_bp;
462  if (loc_sp) {
463    std::lock_guard<std::recursive_mutex> guard(
464        loc_sp->GetTarget().GetAPIMutex());
465    sb_bp = loc_sp->GetBreakpoint().shared_from_this();
466  }
467
468  return LLDB_RECORD_RESULT(sb_bp);
469}
470
471namespace lldb_private {
472namespace repro {
473
474template <>
475void RegisterMethods<SBBreakpointLocation>(Registry &R) {
476  LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation, ());
477  LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation,
478                            (const lldb::BreakpointLocationSP &));
479  LLDB_REGISTER_CONSTRUCTOR(SBBreakpointLocation,
480                            (const lldb::SBBreakpointLocation &));
481  LLDB_REGISTER_METHOD(
482      const lldb::SBBreakpointLocation &,
483      SBBreakpointLocation, operator=,(const lldb::SBBreakpointLocation &));
484  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpointLocation, IsValid, ());
485  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpointLocation, operator bool, ());
486  LLDB_REGISTER_METHOD(lldb::SBAddress, SBBreakpointLocation, GetAddress, ());
487  LLDB_REGISTER_METHOD(lldb::addr_t, SBBreakpointLocation, GetLoadAddress,
488                       ());
489  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetEnabled, (bool));
490  LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, IsEnabled, ());
491  LLDB_REGISTER_METHOD(uint32_t, SBBreakpointLocation, GetHitCount, ());
492  LLDB_REGISTER_METHOD(uint32_t, SBBreakpointLocation, GetIgnoreCount, ());
493  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetIgnoreCount,
494                       (uint32_t));
495  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetCondition,
496                       (const char *));
497  LLDB_REGISTER_METHOD(const char *, SBBreakpointLocation, GetCondition, ());
498  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetAutoContinue, (bool));
499  LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetAutoContinue, ());
500  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetScriptCallbackFunction,
501                       (const char *));
502  LLDB_REGISTER_METHOD(SBError, SBBreakpointLocation, SetScriptCallbackFunction,
503                       (const char *, SBStructuredData &));
504  LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpointLocation,
505                       SetScriptCallbackBody, (const char *));
506  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetCommandLineCommands,
507                       (lldb::SBStringList &));
508  LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetCommandLineCommands,
509                       (lldb::SBStringList &));
510  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadID,
511                       (lldb::tid_t));
512  LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpointLocation, GetThreadID, ());
513  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadIndex,
514                       (uint32_t));
515  LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpointLocation, GetThreadIndex,
516                             ());
517  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetThreadName,
518                       (const char *));
519  LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpointLocation,
520                             GetThreadName, ());
521  LLDB_REGISTER_METHOD(void, SBBreakpointLocation, SetQueueName,
522                       (const char *));
523  LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpointLocation, GetQueueName,
524                             ());
525  LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, IsResolved, ());
526  LLDB_REGISTER_METHOD(bool, SBBreakpointLocation, GetDescription,
527                       (lldb::SBStream &, lldb::DescriptionLevel));
528  LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpointLocation, GetID, ());
529  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointLocation,
530                       GetBreakpoint, ());
531}
532
533}
534}
535