blob: 32c60a51238fa2541bf9447a6a3028ce591019cc [file] [log] [blame]
Johnny Chen01a67862011-10-14 00:42:25 +00001//===-- Watchpoint.cpp ------------------------------------------*- C++ -*-===//
Chris Lattner30fdc8d2010-06-08 16:52:24 +00002//
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
Johnny Chen01a67862011-10-14 00:42:25 +000010#include "lldb/Breakpoint/Watchpoint.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Johnny Chen16dcf712011-10-17 18:58:00 +000016#include "lldb/Breakpoint/StoppointCallbackContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Core/Stream.h"
Johnny Chen16dcf712011-10-17 18:58:00 +000018#include "lldb/Target/Process.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Target/ThreadSpec.h"
Jim Inghamc7dccb72012-05-02 00:30:53 +000021#include "lldb/Expression/ClangUserExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
Johnny Chen01a67862011-10-14 00:42:25 +000026Watchpoint::Watchpoint (lldb::addr_t addr, size_t size, bool hardware) :
Johnny Chena4d6bc92012-02-25 06:44:30 +000027 StoppointLocation (0, addr, size, hardware),
Johnny Chen5d043462011-09-26 22:40:50 +000028 m_target(NULL),
Johnny Chena4d6bc92012-02-25 06:44:30 +000029 m_enabled(false),
Johnny Chenf04ee932011-09-22 18:04:58 +000030 m_is_hardware(hardware),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031 m_watch_read(0),
32 m_watch_write(0),
33 m_watch_was_read(0),
34 m_watch_was_written(0),
35 m_ignore_count(0),
Johnny Chened456eb2011-10-14 19:15:48 +000036 m_decl_str(),
Johnny Chena4d6bc92012-02-25 06:44:30 +000037 m_watch_spec_str(),
Johnny Chene9a56272012-08-09 23:09:42 +000038 m_error(),
39 m_options ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040{
41}
42
Johnny Chen01a67862011-10-14 00:42:25 +000043Watchpoint::~Watchpoint()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044{
45}
46
Johnny Chene9a56272012-08-09 23:09:42 +000047// This function is used when "baton" doesn't need to be freed
48void
49Watchpoint::SetCallback (WatchpointHitCallback callback, void *baton, bool is_synchronous)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050{
Johnny Chene9a56272012-08-09 23:09:42 +000051 // The default "Baton" class will keep a copy of "baton" and won't free
52 // or delete it when it goes goes out of scope.
53 m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
54
55 //SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
56}
57
58// This function is used when a baton needs to be freed and therefore is
59// contained in a "Baton" subclass.
60void
61Watchpoint::SetCallback (WatchpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
62{
63 m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
64}
65
66void
67Watchpoint::ClearCallback ()
68{
69 m_options.ClearCallback ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070}
71
Johnny Chende6bd242011-09-16 21:41:42 +000072void
Johnny Chen01a67862011-10-14 00:42:25 +000073Watchpoint::SetDeclInfo (std::string &str)
Johnny Chende6bd242011-09-16 21:41:42 +000074{
75 m_decl_str = str;
76 return;
77}
78
Johnny Chena4d6bc92012-02-25 06:44:30 +000079void
80Watchpoint::SetWatchSpec (std::string &str)
81{
82 m_watch_spec_str = str;
83 return;
84}
85
Johnny Chenfab7a912012-01-23 23:03:59 +000086// Override default impl of StoppointLocation::IsHardware() since m_is_hardware
87// member field is more accurate.
Johnny Chenf04ee932011-09-22 18:04:58 +000088bool
Johnny Chen01a67862011-10-14 00:42:25 +000089Watchpoint::IsHardware () const
Johnny Chenf04ee932011-09-22 18:04:58 +000090{
91 return m_is_hardware;
92}
93
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094// RETURNS - true if we should stop at this breakpoint, false if we
95// should continue.
96
97bool
Johnny Chen01a67862011-10-14 00:42:25 +000098Watchpoint::ShouldStop (StoppointCallbackContext *context)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099{
Johnny Chenfab7a912012-01-23 23:03:59 +0000100 IncrementHitCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101
Johnny Chenf04ee932011-09-22 18:04:58 +0000102 if (!IsEnabled())
103 return false;
Johnny Chenfd158f42011-09-21 22:47:15 +0000104
Johnny Chenfab7a912012-01-23 23:03:59 +0000105 if (GetHitCount() <= GetIgnoreCount())
Johnny Chenf04ee932011-09-22 18:04:58 +0000106 return false;
107
Johnny Chen16dcf712011-10-17 18:58:00 +0000108 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109}
110
111void
Johnny Chen01a67862011-10-14 00:42:25 +0000112Watchpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
Johnny Chen887062a2011-09-12 23:38:44 +0000113{
Johnny Chende6bd242011-09-16 21:41:42 +0000114 DumpWithLevel(s, level);
Johnny Chen887062a2011-09-12 23:38:44 +0000115 return;
116}
117
118void
Johnny Chen01a67862011-10-14 00:42:25 +0000119Watchpoint::Dump(Stream *s) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000120{
Johnny Chende6bd242011-09-16 21:41:42 +0000121 DumpWithLevel(s, lldb::eDescriptionLevelBrief);
122}
123
124void
Johnny Chen01a67862011-10-14 00:42:25 +0000125Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const
Johnny Chende6bd242011-09-16 21:41:42 +0000126{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127 if (s == NULL)
128 return;
129
Johnny Chende6bd242011-09-16 21:41:42 +0000130 assert(description_level >= lldb::eDescriptionLevelBrief &&
131 description_level <= lldb::eDescriptionLevelVerbose);
132
Greg Claytonc91d8042011-12-03 00:46:21 +0000133 s->Printf("Watchpoint %u: addr = 0x%8.8llx size = %u state = %s type = %s%s",
Johnny Chende6bd242011-09-16 21:41:42 +0000134 GetID(),
Johnny Chena5cde262012-01-24 00:11:02 +0000135 GetLoadAddress(),
Johnny Chende6bd242011-09-16 21:41:42 +0000136 m_byte_size,
Johnny Chena4d6bc92012-02-25 06:44:30 +0000137 IsEnabled() ? "enabled" : "disabled",
Johnny Chende6bd242011-09-16 21:41:42 +0000138 m_watch_read ? "r" : "",
139 m_watch_write ? "w" : "");
140
Johnny Chen16dcf712011-10-17 18:58:00 +0000141 if (description_level >= lldb::eDescriptionLevelFull) {
Johnny Chendedb67a2012-01-30 21:46:17 +0000142 if (!m_decl_str.empty())
Johnny Chen16dcf712011-10-17 18:58:00 +0000143 s->Printf("\n declare @ '%s'", m_decl_str.c_str());
Johnny Chena4d6bc92012-02-25 06:44:30 +0000144 if (!m_watch_spec_str.empty())
145 s->Printf("\n static watchpoint spec = '%s'", m_watch_spec_str.c_str());
Johnny Chen16dcf712011-10-17 18:58:00 +0000146 if (GetConditionText())
147 s->Printf("\n condition = '%s'", GetConditionText());
Johnny Chene9a56272012-08-09 23:09:42 +0000148 m_options.GetCallbackDescription(s, description_level);
Johnny Chen16dcf712011-10-17 18:58:00 +0000149 }
Johnny Chende6bd242011-09-16 21:41:42 +0000150
151 if (description_level >= lldb::eDescriptionLevelVerbose)
Jason Molenda7e1f45f2012-02-23 22:32:13 +0000152 {
Johnny Chene9a56272012-08-09 23:09:42 +0000153 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u",
154 GetHardwareIndex(),
155 GetHitCount(),
156 GetIgnoreCount());
Jason Molenda7e1f45f2012-02-23 22:32:13 +0000157 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158}
159
160bool
Johnny Chen01a67862011-10-14 00:42:25 +0000161Watchpoint::IsEnabled() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162{
163 return m_enabled;
164}
165
166void
Johnny Chen01a67862011-10-14 00:42:25 +0000167Watchpoint::SetEnabled(bool enabled)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168{
169 if (!enabled)
170 SetHardwareIndex(LLDB_INVALID_INDEX32);
171 m_enabled = enabled;
172}
173
174void
Johnny Chen01a67862011-10-14 00:42:25 +0000175Watchpoint::SetWatchpointType (uint32_t type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000176{
177 m_watch_read = (type & LLDB_WATCH_TYPE_READ) != 0;
178 m_watch_write = (type & LLDB_WATCH_TYPE_WRITE) != 0;
179}
180
181bool
Johnny Chen01a67862011-10-14 00:42:25 +0000182Watchpoint::WatchpointRead () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183{
184 return m_watch_read != 0;
185}
186bool
Johnny Chen01a67862011-10-14 00:42:25 +0000187Watchpoint::WatchpointWrite () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188{
189 return m_watch_write != 0;
190}
Greg Claytonc982c762010-07-09 20:39:50 +0000191uint32_t
Johnny Chen01a67862011-10-14 00:42:25 +0000192Watchpoint::GetIgnoreCount () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193{
194 return m_ignore_count;
195}
196
197void
Johnny Chen01a67862011-10-14 00:42:25 +0000198Watchpoint::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199{
200 m_ignore_count = n;
201}
Johnny Chen16dcf712011-10-17 18:58:00 +0000202
203bool
204Watchpoint::InvokeCallback (StoppointCallbackContext *context)
205{
Johnny Chene9a56272012-08-09 23:09:42 +0000206 return m_options.InvokeCallback (context, GetID());
Johnny Chen16dcf712011-10-17 18:58:00 +0000207}
208
209void
210Watchpoint::SetCondition (const char *condition)
211{
212 if (condition == NULL || condition[0] == '\0')
213 {
214 if (m_condition_ap.get())
215 m_condition_ap.reset();
216 }
217 else
218 {
219 // Pass NULL for expr_prefix (no translation-unit level definitions).
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000220 m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Johnny Chen16dcf712011-10-17 18:58:00 +0000221 }
222}
223
224const char *
225Watchpoint::GetConditionText () const
226{
227 if (m_condition_ap.get())
228 return m_condition_ap->GetUserText();
229 else
230 return NULL;
231}
232