blob: b3aa1152761dfb0b040c5ccc1d658f72e2d700dd [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- BreakpointOptions.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/Breakpoint/BreakpointOptions.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Stream.h"
17#include "lldb/Core/StringList.h"
Jim Inghamd1686902010-10-14 23:45:03 +000018#include "lldb/Core/Value.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Breakpoint/StoppointCallbackContext.h"
Jim Inghamd1686902010-10-14 23:45:03 +000020#include "lldb/Target/Process.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000021#include "lldb/Target/ThreadSpec.h"
Jim Inghamd1686902010-10-14 23:45:03 +000022#include "lldb/Target/ThreadPlanTestCondition.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023
24using namespace lldb;
25using namespace lldb_private;
26
27bool
28BreakpointOptions::NullCallback (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
29{
30 return true;
31}
32
33//----------------------------------------------------------------------
34// BreakpointOptions constructor
35//----------------------------------------------------------------------
36BreakpointOptions::BreakpointOptions() :
37 m_callback (BreakpointOptions::NullCallback),
Chris Lattner24943d22010-06-08 16:52:24 +000038 m_callback_baton_sp (),
Greg Clayton54e7afa2010-07-09 20:39:50 +000039 m_callback_is_synchronous (false),
Chris Lattner24943d22010-06-08 16:52:24 +000040 m_enabled (true),
41 m_ignore_count (0),
Jim Inghamd1686902010-10-14 23:45:03 +000042 m_thread_spec_ap (NULL),
43 m_condition_ap()
Chris Lattner24943d22010-06-08 16:52:24 +000044{
45}
46
47//----------------------------------------------------------------------
48// BreakpointOptions copy constructor
49//----------------------------------------------------------------------
50BreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) :
51 m_callback (rhs.m_callback),
52 m_callback_baton_sp (rhs.m_callback_baton_sp),
53 m_callback_is_synchronous (rhs.m_callback_is_synchronous),
54 m_enabled (rhs.m_enabled),
55 m_ignore_count (rhs.m_ignore_count),
Jim Inghamd1686902010-10-14 23:45:03 +000056 m_thread_spec_ap (NULL),
57 m_condition_ap (NULL)
Chris Lattner24943d22010-06-08 16:52:24 +000058{
Jim Ingham3c7b5b92010-06-16 02:00:15 +000059 if (rhs.m_thread_spec_ap.get() != NULL)
60 m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Jim Inghamd1686902010-10-14 23:45:03 +000061 if (rhs.m_condition_ap.get())
62 m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText()));
Chris Lattner24943d22010-06-08 16:52:24 +000063}
64
65//----------------------------------------------------------------------
66// BreakpointOptions assignment operator
67//----------------------------------------------------------------------
68const BreakpointOptions&
69BreakpointOptions::operator=(const BreakpointOptions& rhs)
70{
71 m_callback = rhs.m_callback;
72 m_callback_baton_sp = rhs.m_callback_baton_sp;
73 m_callback_is_synchronous = rhs.m_callback_is_synchronous;
74 m_enabled = rhs.m_enabled;
75 m_ignore_count = rhs.m_ignore_count;
Jim Ingham3c7b5b92010-06-16 02:00:15 +000076 if (rhs.m_thread_spec_ap.get() != NULL)
77 m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
Jim Inghamd1686902010-10-14 23:45:03 +000078 if (rhs.m_condition_ap.get())
79 m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText()));
Chris Lattner24943d22010-06-08 16:52:24 +000080 return *this;
81}
82
Jim Ingham649492b2010-06-18 01:00:58 +000083BreakpointOptions *
84BreakpointOptions::CopyOptionsNoCallback (BreakpointOptions &orig)
85{
86 BreakpointHitCallback orig_callback = orig.m_callback;
87 lldb::BatonSP orig_callback_baton_sp = orig.m_callback_baton_sp;
88 bool orig_is_sync = orig.m_callback_is_synchronous;
89
90 orig.ClearCallback();
91 BreakpointOptions *ret_val = new BreakpointOptions(orig);
92
93 orig.SetCallback (orig_callback, orig_callback_baton_sp, orig_is_sync);
94
95 return ret_val;
96}
97
Chris Lattner24943d22010-06-08 16:52:24 +000098//----------------------------------------------------------------------
99// Destructor
100//----------------------------------------------------------------------
101BreakpointOptions::~BreakpointOptions()
102{
103}
104
105//------------------------------------------------------------------
106// Callbacks
107//------------------------------------------------------------------
108void
109BreakpointOptions::SetCallback (BreakpointHitCallback callback, const BatonSP &callback_baton_sp, bool callback_is_synchronous)
110{
111 m_callback_is_synchronous = callback_is_synchronous;
112 m_callback = callback;
113 m_callback_baton_sp = callback_baton_sp;
114}
115
116void
117BreakpointOptions::ClearCallback ()
118{
Jim Inghamd1686902010-10-14 23:45:03 +0000119 m_callback = BreakpointOptions::NullCallback;
120 m_callback_is_synchronous = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000121 m_callback_baton_sp.reset();
122}
123
124Baton *
125BreakpointOptions::GetBaton ()
126{
127 return m_callback_baton_sp.get();
128}
129
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000130const Baton *
131BreakpointOptions::GetBaton () const
132{
133 return m_callback_baton_sp.get();
134}
135
Chris Lattner24943d22010-06-08 16:52:24 +0000136bool
137BreakpointOptions::InvokeCallback (StoppointCallbackContext *context,
138 lldb::user_id_t break_id,
139 lldb::user_id_t break_loc_id)
140{
141 if (m_callback && context->is_synchronous == IsCallbackSynchronous())
142 {
143 return m_callback (m_callback_baton_sp ? m_callback_baton_sp->m_data : NULL,
144 context,
145 break_id,
146 break_loc_id);
147 }
148 else
149 return true;
150}
151
Jim Ingham649492b2010-06-18 01:00:58 +0000152bool
153BreakpointOptions::HasCallback ()
154{
155 return m_callback != BreakpointOptions::NullCallback;
156}
157
Jim Inghamd1686902010-10-14 23:45:03 +0000158void
159BreakpointOptions::SetCondition (const char *condition)
160{
161 if (condition == NULL || condition[0] == '\0')
162 {
163 if (m_condition_ap.get())
164 m_condition_ap.reset();
165 }
166 else
167 {
168 m_condition_ap.reset(new ClangUserExpression (condition));
169 }
170}
171
172ThreadPlan *
173BreakpointOptions::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx,
174 lldb::BreakpointLocationSP break_loc_sp,
175 Stream &error_stream)
176{
177 // No condition means we should stop, so return NULL.
178 if (!m_condition_ap.get())
179 return NULL;
180
181 // FIXME: I shouldn't have to do this, the process should handle it for me:
182 if (!exe_ctx.process->GetDynamicCheckers())
183 {
184 DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
185
186 StreamString install_errors;
187
188 if (!dynamic_checkers->Install(install_errors, exe_ctx))
189 {
190 error_stream.Printf("Couldn't install dynamic checkers into the execution context: %s\n", install_errors.GetData());
191 return NULL;
192 }
193
194 exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
195 }
196
197 if (!m_condition_ap->Parse (error_stream, exe_ctx))
198 {
199 // Errors mean we should stop.
200 return NULL;
201 }
202 // FIXME: When we can execute static expressions without running the target, we should check that here,
203 // and return something to indicate we should stop or just continue.
204
205 ThreadPlan *new_plan = new ThreadPlanTestCondition (*exe_ctx.thread,
206 exe_ctx,
207 m_condition_ap.get(),
208 break_loc_sp,
209 true);
210
211 return new_plan;
212}
213
214const char *
215BreakpointOptions::GetConditionText ()
216{
217 if (m_condition_ap.get())
218 return m_condition_ap->GetUserText();
219 else
220 return "<No Condition>";
221}
222
Chris Lattner24943d22010-06-08 16:52:24 +0000223//------------------------------------------------------------------
224// Enabled/Ignore Count
225//------------------------------------------------------------------
226bool
227BreakpointOptions::IsEnabled () const
228{
229 return m_enabled;
230}
231
232void
233BreakpointOptions::SetEnabled (bool enabled)
234{
235 m_enabled = enabled;
236}
237
Greg Clayton54e7afa2010-07-09 20:39:50 +0000238uint32_t
Chris Lattner24943d22010-06-08 16:52:24 +0000239BreakpointOptions::GetIgnoreCount () const
240{
241 return m_ignore_count;
242}
243
244void
Greg Clayton54e7afa2010-07-09 20:39:50 +0000245BreakpointOptions::SetIgnoreCount (uint32_t n)
Chris Lattner24943d22010-06-08 16:52:24 +0000246{
247 m_ignore_count = n;
248}
249
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000250const ThreadSpec *
Jim Ingham9c6898b2010-06-22 21:12:54 +0000251BreakpointOptions::GetThreadSpecNoCreate () const
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000252{
253 return m_thread_spec_ap.get();
254}
255
256ThreadSpec *
257BreakpointOptions::GetThreadSpec ()
258{
259 if (m_thread_spec_ap.get() == NULL)
260 m_thread_spec_ap.reset (new ThreadSpec());
261
262 return m_thread_spec_ap.get();
263}
264
Chris Lattner24943d22010-06-08 16:52:24 +0000265void
266BreakpointOptions::SetThreadID (lldb::tid_t thread_id)
267{
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000268 GetThreadSpec()->SetTID(thread_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000269}
270
Chris Lattner24943d22010-06-08 16:52:24 +0000271void
Jim Ingham649492b2010-06-18 01:00:58 +0000272BreakpointOptions::GetDescription (Stream *s, lldb::DescriptionLevel level) const
273{
274
275 // Figure out if there are any options not at their default value, and only print
276 // anything if there are:
277
Jim Ingham9c6898b2010-06-22 21:12:54 +0000278 if (m_ignore_count != 0 || !m_enabled || (GetThreadSpecNoCreate() != NULL && GetThreadSpecNoCreate()->HasSpecification ()))
Jim Ingham649492b2010-06-18 01:00:58 +0000279 {
280 if (level == lldb::eDescriptionLevelVerbose)
281 {
282 s->EOL ();
283 s->IndentMore();
284 s->Indent();
285 s->PutCString("Breakpoint Options:\n");
286 s->IndentMore();
287 s->Indent();
288 }
289 else
290 s->PutCString(" Options: ");
291
292 if (m_ignore_count > 0)
293 s->Printf("ignore: %d ", m_ignore_count);
294 s->Printf("%sabled ", m_enabled ? "en" : "dis");
295
296 if (m_thread_spec_ap.get())
297 m_thread_spec_ap->GetDescription (s, level);
298 else if (level == eDescriptionLevelBrief)
299 s->PutCString ("thread spec: no ");
300 if (level == lldb::eDescriptionLevelFull)
301 {
302 s->IndentLess();
303 s->IndentMore();
304 }
305 }
306
307 if (m_callback_baton_sp.get())
308 {
309 if (level != eDescriptionLevelBrief)
310 s->EOL();
311 m_callback_baton_sp->GetDescription (s, level);
Jim Inghamd1686902010-10-14 23:45:03 +0000312 }
313 if (m_condition_ap.get())
314 {
315 if (level != eDescriptionLevelBrief)
316 {
317 s->EOL();
318 s->Printf("Condition: %s\n", m_condition_ap->GetUserText());
319 }
Greg Clayton12bec712010-06-28 21:30:43 +0000320 }
Jim Ingham649492b2010-06-18 01:00:58 +0000321}
322
323void
Chris Lattner24943d22010-06-08 16:52:24 +0000324BreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const
325{
Chris Lattner24943d22010-06-08 16:52:24 +0000326 CommandData *data = (CommandData *)m_data;
Jim Ingham649492b2010-06-18 01:00:58 +0000327
328 if (level == eDescriptionLevelBrief)
329 {
Greg Clayton12bec712010-06-28 21:30:43 +0000330 s->Printf (", commands = %s", (data && data->user_source.GetSize() > 0) ? "yes" : "no");
Jim Ingham649492b2010-06-18 01:00:58 +0000331 return;
332 }
333
334 s->IndentMore ();
335 s->Indent("Breakpoint commands:\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000336
337 s->IndentMore ();
338 if (data && data->user_source.GetSize() > 0)
339 {
340 const size_t num_strings = data->user_source.GetSize();
341 for (size_t i = 0; i < num_strings; ++i)
342 {
343 s->Indent(data->user_source.GetStringAtIndex(i));
344 s->EOL();
345 }
346 }
347 else
348 {
349 s->PutCString ("No commands.\n");
350 }
351 s->IndentLess ();
Jim Ingham649492b2010-06-18 01:00:58 +0000352 s->IndentLess ();
Chris Lattner24943d22010-06-08 16:52:24 +0000353}
354