]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / API / SBBreakpoint.cpp
1 //===-- 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/SBEvent.h"
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBStream.h"
16 #include "lldb/API/SBThread.h"
17
18 #include "lldb/Breakpoint/Breakpoint.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Breakpoint/StoppointCallbackContext.h"
21 #include "lldb/Core/Address.h"
22 #include "lldb/Core/Log.h"
23 #include "lldb/Core/Stream.h"
24 #include "lldb/Core/StreamFile.h"
25 #include "lldb/Target/Process.h"
26 #include "lldb/Target/SectionLoadList.h"
27 #include "lldb/Target/Target.h"
28 #include "lldb/Target/Thread.h"
29 #include "lldb/Target/ThreadSpec.h"
30
31
32 #include "lldb/lldb-enumerations.h"
33
34 using namespace lldb;
35 using namespace lldb_private;
36
37 struct CallbackData
38 {
39     SBBreakpoint::BreakpointHitCallback callback;
40     void *callback_baton;
41 };
42
43 class SBBreakpointCallbackBaton : public Baton
44 {
45 public:
46
47     SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
48         Baton (new CallbackData)
49     {
50         CallbackData *data = (CallbackData *)m_data;
51         data->callback = callback;
52         data->callback_baton = baton;
53     }
54     
55     virtual ~SBBreakpointCallbackBaton()
56     {
57         CallbackData *data = (CallbackData *)m_data;
58
59         if (data)
60         {
61             delete data;
62             m_data = NULL;
63         }
64     }
65 };
66
67
68 SBBreakpoint::SBBreakpoint () :
69     m_opaque_sp ()
70 {
71 }
72
73 SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
74     m_opaque_sp (rhs.m_opaque_sp)
75 {
76 }
77
78
79 SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
80     m_opaque_sp (bp_sp)
81 {
82 }
83
84 SBBreakpoint::~SBBreakpoint()
85 {
86 }
87
88 const SBBreakpoint &
89 SBBreakpoint::operator = (const SBBreakpoint& rhs)
90 {
91     if (this != &rhs)
92         m_opaque_sp = rhs.m_opaque_sp;
93     return *this;
94 }
95
96 bool
97 SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs)
98 {
99     if (m_opaque_sp && rhs.m_opaque_sp)
100         return m_opaque_sp.get() == rhs.m_opaque_sp.get();
101     return false;
102 }
103
104 bool
105 SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs)
106 {
107     if (m_opaque_sp && rhs.m_opaque_sp)
108         return m_opaque_sp.get() != rhs.m_opaque_sp.get();
109     return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
110 }
111
112 break_id_t
113 SBBreakpoint::GetID () const
114 {
115     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
116
117     break_id_t break_id = LLDB_INVALID_BREAK_ID;
118     if (m_opaque_sp)
119         break_id = m_opaque_sp->GetID();
120
121     if (log)
122     {
123         if (break_id == LLDB_INVALID_BREAK_ID)
124             log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID", m_opaque_sp.get());
125         else
126             log->Printf ("SBBreakpoint(%p)::GetID () => %u", m_opaque_sp.get(), break_id);
127     }
128
129     return break_id;
130 }
131
132
133 bool
134 SBBreakpoint::IsValid() const
135 {
136     return (bool) m_opaque_sp;
137 }
138
139 void
140 SBBreakpoint::ClearAllBreakpointSites ()
141 {
142     if (m_opaque_sp)
143     {
144         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
145         m_opaque_sp->ClearAllBreakpointSites ();
146     }
147 }
148
149 SBBreakpointLocation
150 SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
151 {
152     SBBreakpointLocation sb_bp_location;
153
154     if (m_opaque_sp)
155     {
156         if (vm_addr != LLDB_INVALID_ADDRESS)
157         {
158             Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
159             Address address;
160             Target &target = m_opaque_sp->GetTarget();
161             if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
162             {
163                 address.SetRawAddress (vm_addr);
164             }
165             sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
166         }
167     }
168     return sb_bp_location;
169 }
170
171 break_id_t
172 SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
173 {
174     break_id_t break_id = LLDB_INVALID_BREAK_ID;
175
176     if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS)
177     {
178         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
179         Address address;
180         Target &target = m_opaque_sp->GetTarget();
181         if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
182         {
183             address.SetRawAddress (vm_addr);
184         }
185         break_id = m_opaque_sp->FindLocationIDByAddress (address);
186     }
187
188     return break_id;
189 }
190
191 SBBreakpointLocation
192 SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
193 {
194     SBBreakpointLocation sb_bp_location;
195
196     if (m_opaque_sp)
197     {
198         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
199         sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
200     }
201
202     return sb_bp_location;
203 }
204
205 SBBreakpointLocation
206 SBBreakpoint::GetLocationAtIndex (uint32_t index)
207 {
208     SBBreakpointLocation sb_bp_location;
209
210     if (m_opaque_sp)
211     {
212         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
213         sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
214     }
215
216     return sb_bp_location;
217 }
218
219 void
220 SBBreakpoint::SetEnabled (bool enable)
221 {
222     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
223
224     if (log)
225         log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)", m_opaque_sp.get(), enable);
226
227     if (m_opaque_sp)
228     {
229         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
230         m_opaque_sp->SetEnabled (enable);
231     }
232 }
233
234 bool
235 SBBreakpoint::IsEnabled ()
236 {
237     if (m_opaque_sp)
238     {
239         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
240         return m_opaque_sp->IsEnabled();
241     }
242     else
243         return false;
244 }
245
246 void
247 SBBreakpoint::SetOneShot (bool one_shot)
248 {
249     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
250
251     if (log)
252         log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)", m_opaque_sp.get(), one_shot);
253
254     if (m_opaque_sp)
255     {
256         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
257         m_opaque_sp->SetOneShot (one_shot);
258     }
259 }
260
261 bool
262 SBBreakpoint::IsOneShot () const
263 {
264     if (m_opaque_sp)
265     {
266         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
267         return m_opaque_sp->IsOneShot();
268     }
269     else
270         return false;
271 }
272
273 bool
274 SBBreakpoint::IsInternal ()
275 {
276     if (m_opaque_sp)
277     {
278         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
279         return m_opaque_sp->IsInternal();
280     }
281     else
282         return false;
283 }
284
285 void
286 SBBreakpoint::SetIgnoreCount (uint32_t count)
287 {
288     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
289
290     if (log)
291         log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)", m_opaque_sp.get(), count);
292         
293     if (m_opaque_sp)
294     {
295         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
296         m_opaque_sp->SetIgnoreCount (count);
297     }
298 }
299
300 void
301 SBBreakpoint::SetCondition (const char *condition)
302 {
303     if (m_opaque_sp)
304     {
305         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
306         m_opaque_sp->SetCondition (condition);
307     }
308 }
309
310 const char *
311 SBBreakpoint::GetCondition ()
312 {
313     if (m_opaque_sp)
314     {
315         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
316         return m_opaque_sp->GetConditionText ();
317     }
318     return NULL;
319 }
320
321 uint32_t
322 SBBreakpoint::GetHitCount () const
323 {
324     uint32_t count = 0;
325     if (m_opaque_sp)
326     {
327         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
328         count = m_opaque_sp->GetHitCount();
329     }
330
331     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
332     if (log)
333         log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u", m_opaque_sp.get(), count);
334
335     return count;
336 }
337
338 uint32_t
339 SBBreakpoint::GetIgnoreCount () const
340 {
341     uint32_t count = 0;
342     if (m_opaque_sp)
343     {
344         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
345         count = m_opaque_sp->GetIgnoreCount();
346     }
347
348     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
349     if (log)
350         log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u", m_opaque_sp.get(), count);
351
352     return count;
353 }
354
355 void
356 SBBreakpoint::SetThreadID (tid_t tid)
357 {
358     if (m_opaque_sp)
359     {
360         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
361         m_opaque_sp->SetThreadID (tid);
362     }
363     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
364     if (log)
365         log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")", m_opaque_sp.get(), tid);
366
367 }
368
369 tid_t
370 SBBreakpoint::GetThreadID ()
371 {
372     tid_t tid = LLDB_INVALID_THREAD_ID;
373     if (m_opaque_sp)
374     {
375         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
376         tid = m_opaque_sp->GetThreadID();
377     }
378
379     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
380     if (log)
381         log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64, m_opaque_sp.get(), tid);
382     return tid;
383 }
384
385 void
386 SBBreakpoint::SetThreadIndex (uint32_t index)
387 {
388     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
389     if (log)
390         log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)", m_opaque_sp.get(), index);
391     if (m_opaque_sp)
392     {
393         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
394         m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
395     }
396 }
397
398 uint32_t
399 SBBreakpoint::GetThreadIndex() const
400 {
401     uint32_t thread_idx = UINT32_MAX;
402     if (m_opaque_sp)
403     {
404         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
405         const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
406         if (thread_spec != NULL)
407             thread_idx = thread_spec->GetIndex();
408     }
409     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
410     if (log)
411         log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u", m_opaque_sp.get(), thread_idx);
412
413     return thread_idx;
414 }
415     
416
417 void
418 SBBreakpoint::SetThreadName (const char *thread_name)
419 {
420     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
421     if (log)
422         log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)", m_opaque_sp.get(), thread_name);
423
424     if (m_opaque_sp)
425     {
426         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
427         m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
428     }
429 }
430
431 const char *
432 SBBreakpoint::GetThreadName () const
433 {
434     const char *name = NULL;
435     if (m_opaque_sp)
436     {
437         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
438         const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
439         if (thread_spec != NULL)
440             name = thread_spec->GetName();
441     }
442     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
443     if (log)
444         log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s", m_opaque_sp.get(), name);
445
446     return name;
447 }
448
449 void
450 SBBreakpoint::SetQueueName (const char *queue_name)
451 {
452     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
453     if (log)
454         log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)", m_opaque_sp.get(), queue_name);
455     if (m_opaque_sp)
456     {
457         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
458         m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
459     }
460 }
461
462 const char *
463 SBBreakpoint::GetQueueName () const
464 {
465     const char *name = NULL;
466     if (m_opaque_sp)
467     {
468         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
469         const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
470         if (thread_spec)
471             name = thread_spec->GetQueueName();
472     }
473     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
474     if (log)
475         log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s", m_opaque_sp.get(), name);
476
477     return name;
478 }
479
480 size_t
481 SBBreakpoint::GetNumResolvedLocations() const
482 {
483     size_t num_resolved = 0;
484     if (m_opaque_sp)
485     {
486         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
487         num_resolved = m_opaque_sp->GetNumResolvedLocations();
488     }
489     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
490     if (log)
491         log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_resolved);
492     return num_resolved;
493 }
494
495 size_t
496 SBBreakpoint::GetNumLocations() const
497 {
498     size_t num_locs = 0;
499     if (m_opaque_sp)
500     {
501         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
502         num_locs = m_opaque_sp->GetNumLocations();
503     }
504     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
505     if (log)
506         log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_locs);
507     return num_locs;
508 }
509
510 bool
511 SBBreakpoint::GetDescription (SBStream &s)
512 {
513     if (m_opaque_sp)
514     {
515         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
516         s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
517         m_opaque_sp->GetResolverDescription (s.get());
518         m_opaque_sp->GetFilterDescription (s.get());
519         const size_t num_locations = m_opaque_sp->GetNumLocations ();
520         s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
521         return true;
522     }
523     s.Printf ("No value");
524     return false;
525 }
526
527 bool
528 SBBreakpoint::PrivateBreakpointHitCallback 
529 (
530     void *baton, 
531     StoppointCallbackContext *ctx, 
532     lldb::user_id_t break_id, 
533     lldb::user_id_t break_loc_id
534 )
535 {
536     ExecutionContext exe_ctx (ctx->exe_ctx_ref);
537     BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
538     if (baton && bp_sp)
539     {
540         CallbackData *data = (CallbackData *)baton;
541         lldb_private::Breakpoint *bp = bp_sp.get();
542         if (bp && data->callback)
543         {
544             Process *process = exe_ctx.GetProcessPtr();
545             if (process)
546             {
547                 SBProcess sb_process (process->shared_from_this());
548                 SBThread sb_thread;
549                 SBBreakpointLocation sb_location;
550                 assert (bp_sp);
551                 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
552                 Thread *thread = exe_ctx.GetThreadPtr();
553                 if (thread)
554                     sb_thread.SetThread(thread->shared_from_this());
555
556                 return data->callback (data->callback_baton, 
557                                           sb_process, 
558                                           sb_thread, 
559                                           sb_location);
560             }
561         }
562     }
563     return true;    // Return true if we should stop at this breakpoint
564 }
565
566 void
567 SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
568 {
569     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
570     
571     if (log)
572         log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)", m_opaque_sp.get(), callback, baton);
573
574     if (m_opaque_sp)
575     {
576         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
577         BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
578         m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
579     }
580 }
581
582
583 lldb_private::Breakpoint *
584 SBBreakpoint::operator->() const
585 {
586     return m_opaque_sp.get();
587 }
588
589 lldb_private::Breakpoint *
590 SBBreakpoint::get() const
591 {
592     return m_opaque_sp.get();
593 }
594
595 lldb::BreakpointSP &
596 SBBreakpoint::operator *()
597 {
598     return m_opaque_sp;
599 }
600
601 const lldb::BreakpointSP &
602 SBBreakpoint::operator *() const
603 {
604     return m_opaque_sp;
605 }
606
607 bool
608 SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event)
609 {
610     return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL;
611
612 }
613
614 BreakpointEventType
615 SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
616 {
617     if (event.IsValid())
618         return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
619     return eBreakpointEventTypeInvalidType;
620 }
621
622 SBBreakpoint
623 SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
624 {
625     SBBreakpoint sb_breakpoint;
626     if (event.IsValid())
627         sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
628     return sb_breakpoint;
629 }
630
631 SBBreakpointLocation
632 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
633 {
634     SBBreakpointLocation sb_breakpoint_loc;
635     if (event.IsValid())
636         sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
637     return sb_breakpoint_loc;
638 }
639
640 uint32_t
641 SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event)
642 {
643     uint32_t num_locations = 0;
644     if (event.IsValid())
645         num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP()));
646     return num_locations;
647 }
648
649