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