blob: f90d7ad37e62e01bc94e920a0bd7795c36064c0b [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/API/SBBreakpoint.h"
11#include "lldb/API/SBBreakpointLocation.h"
12#include "lldb/API/SBDebugger.h"
13#include "lldb/API/SBProcess.h"
14#include "lldb/API/SBThread.h"
15
16#include "lldb/Breakpoint/Breakpoint.h"
17#include "lldb/Breakpoint/BreakpointLocation.h"
18#include "lldb/Breakpoint/StoppointCallbackContext.h"
19#include "lldb/Core/Address.h"
20#include "lldb/Core/Stream.h"
21#include "lldb/Core/StreamFile.h"
22#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Target/Target.h"
Jim Ingham8e5e38f2010-06-18 01:47:08 +000024#include "lldb/Target/Thread.h"
25#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000026
27
28#include "lldb/lldb-enumerations.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33struct CallbackData
34{
35 SBBreakpoint::BreakpointHitCallback callback;
36 void *callback_baton;
37};
38
39class SBBreakpointCallbackBaton : public Baton
40{
41public:
42
43 SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
44 Baton (new CallbackData)
45 {
46 CallbackData *data = (CallbackData *)m_data;
47 data->callback = callback;
48 data->callback_baton = baton;
49 }
50
51 virtual ~SBBreakpointCallbackBaton()
52 {
53 CallbackData *data = (CallbackData *)m_data;
54
55 if (data)
56 {
57 delete data;
58 m_data = NULL;
59 }
60 }
61};
62
63
64SBBreakpoint::SBBreakpoint () :
Greg Clayton63094e02010-06-23 01:19:29 +000065 m_opaque_sp ()
Chris Lattner24943d22010-06-08 16:52:24 +000066{
67}
68
69SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
Greg Clayton63094e02010-06-23 01:19:29 +000070 m_opaque_sp (rhs.m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000071{
72}
73
74
75SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000076 m_opaque_sp (bp_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000077{
78}
79
80SBBreakpoint::~SBBreakpoint()
81{
82}
83
84const SBBreakpoint &
85SBBreakpoint::operator = (const SBBreakpoint& rhs)
86{
87 if (this != &rhs)
88 {
Greg Clayton63094e02010-06-23 01:19:29 +000089 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000090 }
91 return *this;
92}
93
94break_id_t
95SBBreakpoint::GetID () const
96{
Greg Clayton63094e02010-06-23 01:19:29 +000097 if (m_opaque_sp)
98 return m_opaque_sp->GetID();
Chris Lattner24943d22010-06-08 16:52:24 +000099 return LLDB_INVALID_BREAK_ID;
100}
101
102
103bool
104SBBreakpoint::IsValid() const
105{
Greg Clayton63094e02010-06-23 01:19:29 +0000106 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000107}
108
109void
110SBBreakpoint::Dump (FILE *f)
111{
Greg Clayton63094e02010-06-23 01:19:29 +0000112 if (m_opaque_sp && f)
Chris Lattner24943d22010-06-08 16:52:24 +0000113 {
Chris Lattner24943d22010-06-08 16:52:24 +0000114 lldb_private::StreamFile str (f);
Greg Clayton63094e02010-06-23 01:19:29 +0000115 m_opaque_sp->Dump (&str);
Chris Lattner24943d22010-06-08 16:52:24 +0000116 }
117}
118
119void
120SBBreakpoint::ClearAllBreakpointSites ()
121{
Greg Clayton63094e02010-06-23 01:19:29 +0000122 if (m_opaque_sp)
123 m_opaque_sp->ClearAllBreakpointSites ();
Chris Lattner24943d22010-06-08 16:52:24 +0000124}
125
126SBBreakpointLocation
127SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
128{
129 SBBreakpointLocation sb_bp_location;
130
Greg Clayton63094e02010-06-23 01:19:29 +0000131 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000132 {
133 if (vm_addr != LLDB_INVALID_ADDRESS)
134 {
135 Address address;
Greg Clayton63094e02010-06-23 01:19:29 +0000136 Process *sb_process = m_opaque_sp->GetTarget().GetProcessSP().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000137 if (sb_process == NULL || sb_process->ResolveLoadAddress (vm_addr, address) == false)
138 {
139 address.SetSection (NULL);
140 address.SetOffset (vm_addr);
141 }
Greg Clayton63094e02010-06-23 01:19:29 +0000142 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
Chris Lattner24943d22010-06-08 16:52:24 +0000143 }
144 }
145 return sb_bp_location;
146}
147
148break_id_t
149SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
150{
151 break_id_t lldb_id = (break_id_t) 0;
152
Greg Clayton63094e02010-06-23 01:19:29 +0000153 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000154 {
155 if (vm_addr != LLDB_INVALID_ADDRESS)
156 {
157 Address address;
Greg Clayton63094e02010-06-23 01:19:29 +0000158 Process *sb_process = m_opaque_sp->GetTarget().GetProcessSP().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000159 if (sb_process == NULL || sb_process->ResolveLoadAddress (vm_addr, address) == false)
160 {
161 address.SetSection (NULL);
162 address.SetOffset (vm_addr);
163 }
Greg Clayton63094e02010-06-23 01:19:29 +0000164 lldb_id = m_opaque_sp->FindLocationIDByAddress (address);
Chris Lattner24943d22010-06-08 16:52:24 +0000165 }
166 }
167
168 return lldb_id;
169}
170
171SBBreakpointLocation
172SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
173{
174 SBBreakpointLocation sb_bp_location;
175
Greg Clayton63094e02010-06-23 01:19:29 +0000176 if (m_opaque_sp)
177 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000178
179 return sb_bp_location;
180}
181
182SBBreakpointLocation
183SBBreakpoint::GetLocationAtIndex (uint32_t index)
184{
185 SBBreakpointLocation sb_bp_location;
186
Greg Clayton63094e02010-06-23 01:19:29 +0000187 if (m_opaque_sp)
188 sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
Chris Lattner24943d22010-06-08 16:52:24 +0000189
190 return sb_bp_location;
191}
192
193void
194SBBreakpoint::ListLocations (FILE* f, const char *description_level)
195{
Greg Clayton63094e02010-06-23 01:19:29 +0000196 if (m_opaque_sp && f)
Chris Lattner24943d22010-06-08 16:52:24 +0000197 {
198 DescriptionLevel level;
199 if (strcmp (description_level, "brief") == 0)
200 level = eDescriptionLevelBrief;
201 else if (strcmp (description_level, "full") == 0)
202 level = eDescriptionLevelFull;
203 else if (strcmp (description_level, "verbose") == 0)
204 level = eDescriptionLevelVerbose;
205 else
206 level = eDescriptionLevelBrief;
207
208 StreamFile str (f);
209
210 str.IndentMore();
Greg Clayton63094e02010-06-23 01:19:29 +0000211 int num_locs = m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000212 for (int i = 0; i < num_locs; ++i)
213 {
Greg Clayton63094e02010-06-23 01:19:29 +0000214 BreakpointLocation *loc = m_opaque_sp->GetLocationAtIndex (i).get();
Chris Lattner24943d22010-06-08 16:52:24 +0000215 loc->GetDescription (&str, level);
216 str.EOL();
217 }
218 }
219}
220
221void
222SBBreakpoint::SetEnabled (bool enable)
223{
Greg Clayton63094e02010-06-23 01:19:29 +0000224 if (m_opaque_sp)
225 m_opaque_sp->SetEnabled (enable);
Chris Lattner24943d22010-06-08 16:52:24 +0000226}
227
228bool
229SBBreakpoint::IsEnabled ()
230{
Greg Clayton63094e02010-06-23 01:19:29 +0000231 if (m_opaque_sp)
232 return m_opaque_sp->IsEnabled();
Chris Lattner24943d22010-06-08 16:52:24 +0000233 else
234 return false;
235}
236
237void
238SBBreakpoint::SetIgnoreCount (int32_t count)
239{
Greg Clayton63094e02010-06-23 01:19:29 +0000240 if (m_opaque_sp)
241 m_opaque_sp->SetIgnoreCount (count);
Chris Lattner24943d22010-06-08 16:52:24 +0000242}
243
244int32_t
245SBBreakpoint::GetIgnoreCount () const
246{
Greg Clayton63094e02010-06-23 01:19:29 +0000247 if (m_opaque_sp)
248 return m_opaque_sp->GetIgnoreCount();
Chris Lattner24943d22010-06-08 16:52:24 +0000249 else
250 return 0;
251}
252
253void
254SBBreakpoint::SetThreadID (tid_t sb_thread_id)
255{
Greg Clayton63094e02010-06-23 01:19:29 +0000256 if (m_opaque_sp)
257 m_opaque_sp->SetThreadID (sb_thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000258}
259
260tid_t
261SBBreakpoint::GetThreadID ()
262{
263 tid_t lldb_thread_id = LLDB_INVALID_THREAD_ID;
Greg Clayton63094e02010-06-23 01:19:29 +0000264 if (m_opaque_sp)
265 lldb_thread_id = m_opaque_sp->GetThreadID();
Chris Lattner24943d22010-06-08 16:52:24 +0000266
267 return lldb_thread_id;
268}
269
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000270void
271SBBreakpoint::SetThreadIndex (uint32_t index)
272{
Greg Clayton63094e02010-06-23 01:19:29 +0000273 if (m_opaque_sp)
274 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000275}
276
277uint32_t
278SBBreakpoint::GetThreadIndex() const
279{
Greg Clayton63094e02010-06-23 01:19:29 +0000280 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000281 {
Greg Clayton63094e02010-06-23 01:19:29 +0000282 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000283 if (thread_spec == NULL)
284 return 0;
285 else
286 return thread_spec->GetIndex();
287 }
288 return 0;
289}
290
291
292void
293SBBreakpoint::SetThreadName (const char *thread_name)
294{
Greg Clayton63094e02010-06-23 01:19:29 +0000295 if (m_opaque_sp)
296 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000297}
298
299const char *
300SBBreakpoint::GetThreadName () const
301{
Greg Clayton63094e02010-06-23 01:19:29 +0000302 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000303 {
Greg Clayton63094e02010-06-23 01:19:29 +0000304 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000305 if (thread_spec == NULL)
306 return NULL;
307 else
308 return thread_spec->GetName();
309 }
310 return NULL;
311}
312
313void
314SBBreakpoint::SetQueueName (const char *queue_name)
315{
Greg Clayton63094e02010-06-23 01:19:29 +0000316 if (m_opaque_sp)
317 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000318}
319
320const char *
321SBBreakpoint::GetQueueName () const
322{
Greg Clayton63094e02010-06-23 01:19:29 +0000323 if (m_opaque_sp)
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000324 {
Greg Clayton63094e02010-06-23 01:19:29 +0000325 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpec();
Jim Ingham8e5e38f2010-06-18 01:47:08 +0000326 if (thread_spec == NULL)
327 return NULL;
328 else
329 return thread_spec->GetQueueName();
330 }
331 return NULL;
332}
333
Chris Lattner24943d22010-06-08 16:52:24 +0000334size_t
335SBBreakpoint::GetNumResolvedLocations() const
336{
Greg Clayton63094e02010-06-23 01:19:29 +0000337 if (m_opaque_sp)
338 return m_opaque_sp->GetNumResolvedLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000339 else
340 return 0;
341}
342
343size_t
344SBBreakpoint::GetNumLocations() const
345{
Greg Clayton63094e02010-06-23 01:19:29 +0000346 if (m_opaque_sp)
347 return m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000348 else
349 return 0;
350}
351
352void
353SBBreakpoint::GetDescription (FILE *f, const char *description_level, bool describe_locations)
354{
355 if (f == NULL)
356 return;
357
Greg Clayton63094e02010-06-23 01:19:29 +0000358 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000359 {
360 DescriptionLevel level;
361 if (strcmp (description_level, "brief") == 0)
362 level = eDescriptionLevelBrief;
363 else if (strcmp (description_level, "full") == 0)
364 level = eDescriptionLevelFull;
365 else if (strcmp (description_level, "verbose") == 0)
366 level = eDescriptionLevelVerbose;
367 else
368 level = eDescriptionLevelBrief;
369
370 StreamFile str (f);
371
Greg Clayton63094e02010-06-23 01:19:29 +0000372 m_opaque_sp->GetDescription (&str, level);
Chris Lattner24943d22010-06-08 16:52:24 +0000373 str.EOL();
374 if (describe_locations)
375 {
376 //str.IndentMore();
Greg Clayton63094e02010-06-23 01:19:29 +0000377 // int num_locs = m_opaque_sp->GetNumLocations();
Chris Lattner24943d22010-06-08 16:52:24 +0000378 // for (int i = 0; i < num_locs; ++i)
379 // {
Greg Clayton63094e02010-06-23 01:19:29 +0000380 // BreakpointLocation *loc = m_opaque_sp->FindLocationByIndex (i);
Chris Lattner24943d22010-06-08 16:52:24 +0000381 // loc->GetDescription (&str, level);
382 // str.EOL();
383 // }
384 ListLocations (f, description_level);
385 }
386 }
387}
388
389bool
390SBBreakpoint::PrivateBreakpointHitCallback
391(
392 void *baton,
393 StoppointCallbackContext *ctx,
394 lldb::user_id_t break_id,
395 lldb::user_id_t break_loc_id
396)
397{
Greg Clayton63094e02010-06-23 01:19:29 +0000398 BreakpointSP bp_sp(ctx->exe_ctx.target->GetBreakpointList().FindBreakpointByID(break_id));
Chris Lattner24943d22010-06-08 16:52:24 +0000399 if (baton && bp_sp)
400 {
401 CallbackData *data = (CallbackData *)baton;
402 lldb_private::Breakpoint *bp = bp_sp.get();
403 if (bp && data->callback)
404 {
Greg Clayton63094e02010-06-23 01:19:29 +0000405 if (ctx->exe_ctx.process)
Chris Lattner24943d22010-06-08 16:52:24 +0000406 {
Greg Clayton63094e02010-06-23 01:19:29 +0000407 SBProcess sb_process (ctx->exe_ctx.process->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000408 SBThread sb_thread;
409 SBBreakpointLocation sb_location;
410 assert (bp_sp);
411 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
Greg Clayton63094e02010-06-23 01:19:29 +0000412 if (ctx->exe_ctx.thread)
413 sb_thread.SetThread(ctx->exe_ctx.thread->GetSP());
Chris Lattner24943d22010-06-08 16:52:24 +0000414
415 return data->callback (data->callback_baton,
416 sb_process,
417 sb_thread,
418 sb_location);
419 }
420 }
421 }
422 return true; // Return true if we should stop at this breakpoint
423}
424
425void
426SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
427{
Greg Clayton63094e02010-06-23 01:19:29 +0000428 if (m_opaque_sp.get())
Chris Lattner24943d22010-06-08 16:52:24 +0000429 {
430 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
Greg Clayton63094e02010-06-23 01:19:29 +0000431 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000432 }
433}
434
435
436lldb_private::Breakpoint *
437SBBreakpoint::operator->() const
438{
Greg Clayton63094e02010-06-23 01:19:29 +0000439 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000440}
441
442lldb_private::Breakpoint *
443SBBreakpoint::get() const
444{
Greg Clayton63094e02010-06-23 01:19:29 +0000445 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000446}
447
448lldb::BreakpointSP &
449SBBreakpoint::operator *()
450{
Greg Clayton63094e02010-06-23 01:19:29 +0000451 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000452}
453
454const lldb::BreakpointSP &
455SBBreakpoint::operator *() const
456{
Greg Clayton63094e02010-06-23 01:19:29 +0000457 return m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000458}
459