blob: ae2cdd921219d4f426ae74fd631fe48a8651632b [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"
21#include "lldb/Target/ThreadPlanTestCondition.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 Chen8ed0ef92011-09-06 02:52:28 +000027 StoppointLocation (GetNextID(), addr, size, hardware),
Johnny Chen5d043462011-09-26 22:40:50 +000028 m_target(NULL),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029 m_enabled(0),
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),
36 m_callback(NULL),
Johnny Chened456eb2011-10-14 19:15:48 +000037 m_callback_baton(NULL),
38 m_decl_str(),
39 m_error()
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
47break_id_t
Johnny Chen01a67862011-10-14 00:42:25 +000048Watchpoint::GetNextID()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049{
50 static break_id_t g_next_ID = 0;
51 return ++g_next_ID;
52}
53
54bool
Johnny Chen01a67862011-10-14 00:42:25 +000055Watchpoint::SetCallback (WatchpointHitCallback callback, void *callback_baton)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056{
57 m_callback = callback;
58 m_callback_baton = callback_baton;
59 return true;
60}
61
Johnny Chende6bd242011-09-16 21:41:42 +000062void
Johnny Chen01a67862011-10-14 00:42:25 +000063Watchpoint::SetDeclInfo (std::string &str)
Johnny Chende6bd242011-09-16 21:41:42 +000064{
65 m_decl_str = str;
66 return;
67}
68
Johnny Chenfab7a912012-01-23 23:03:59 +000069// Override default impl of StoppointLocation::IsHardware() since m_is_hardware
70// member field is more accurate.
Johnny Chenf04ee932011-09-22 18:04:58 +000071bool
Johnny Chen01a67862011-10-14 00:42:25 +000072Watchpoint::IsHardware () const
Johnny Chenf04ee932011-09-22 18:04:58 +000073{
74 return m_is_hardware;
75}
76
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077// RETURNS - true if we should stop at this breakpoint, false if we
78// should continue.
79
80bool
Johnny Chen01a67862011-10-14 00:42:25 +000081Watchpoint::ShouldStop (StoppointCallbackContext *context)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082{
Johnny Chenfab7a912012-01-23 23:03:59 +000083 IncrementHitCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084
Johnny Chenf04ee932011-09-22 18:04:58 +000085 if (!IsEnabled())
86 return false;
Johnny Chenfd158f42011-09-21 22:47:15 +000087
Johnny Chenfab7a912012-01-23 23:03:59 +000088 if (GetHitCount() <= GetIgnoreCount())
Johnny Chenf04ee932011-09-22 18:04:58 +000089 return false;
90
Johnny Chen16dcf712011-10-17 18:58:00 +000091 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092}
93
94void
Johnny Chen01a67862011-10-14 00:42:25 +000095Watchpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
Johnny Chen887062a2011-09-12 23:38:44 +000096{
Johnny Chende6bd242011-09-16 21:41:42 +000097 DumpWithLevel(s, level);
Johnny Chen887062a2011-09-12 23:38:44 +000098 return;
99}
100
101void
Johnny Chen01a67862011-10-14 00:42:25 +0000102Watchpoint::Dump(Stream *s) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103{
Johnny Chende6bd242011-09-16 21:41:42 +0000104 DumpWithLevel(s, lldb::eDescriptionLevelBrief);
105}
106
107void
Johnny Chen01a67862011-10-14 00:42:25 +0000108Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const
Johnny Chende6bd242011-09-16 21:41:42 +0000109{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000110 if (s == NULL)
111 return;
112
Johnny Chende6bd242011-09-16 21:41:42 +0000113 assert(description_level >= lldb::eDescriptionLevelBrief &&
114 description_level <= lldb::eDescriptionLevelVerbose);
115
Greg Claytonc91d8042011-12-03 00:46:21 +0000116 s->Printf("Watchpoint %u: addr = 0x%8.8llx size = %u state = %s type = %s%s",
Johnny Chende6bd242011-09-16 21:41:42 +0000117 GetID(),
Johnny Chena5cde262012-01-24 00:11:02 +0000118 GetLoadAddress(),
Johnny Chende6bd242011-09-16 21:41:42 +0000119 m_byte_size,
120 m_enabled ? "enabled" : "disabled",
121 m_watch_read ? "r" : "",
122 m_watch_write ? "w" : "");
123
Johnny Chen16dcf712011-10-17 18:58:00 +0000124 if (description_level >= lldb::eDescriptionLevelFull) {
Johnny Chendedb67a2012-01-30 21:46:17 +0000125 if (!m_decl_str.empty())
Johnny Chen16dcf712011-10-17 18:58:00 +0000126 s->Printf("\n declare @ '%s'", m_decl_str.c_str());
127 if (GetConditionText())
128 s->Printf("\n condition = '%s'", GetConditionText());
129 }
Johnny Chende6bd242011-09-16 21:41:42 +0000130
131 if (description_level >= lldb::eDescriptionLevelVerbose)
Johnny Chen98a49d9b2011-10-06 20:27:05 +0000132 if (m_callback)
133 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %8p baton = %8p",
134 GetHardwareIndex(),
135 GetHitCount(),
136 GetIgnoreCount(),
137 m_callback,
138 m_callback_baton);
139 else
140 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u",
141 GetHardwareIndex(),
142 GetHitCount(),
143 GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144}
145
146bool
Johnny Chen01a67862011-10-14 00:42:25 +0000147Watchpoint::IsEnabled() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148{
149 return m_enabled;
150}
151
152void
Johnny Chen01a67862011-10-14 00:42:25 +0000153Watchpoint::SetEnabled(bool enabled)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000154{
155 if (!enabled)
156 SetHardwareIndex(LLDB_INVALID_INDEX32);
157 m_enabled = enabled;
158}
159
160void
Johnny Chen01a67862011-10-14 00:42:25 +0000161Watchpoint::SetWatchpointType (uint32_t type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162{
163 m_watch_read = (type & LLDB_WATCH_TYPE_READ) != 0;
164 m_watch_write = (type & LLDB_WATCH_TYPE_WRITE) != 0;
165}
166
167bool
Johnny Chen01a67862011-10-14 00:42:25 +0000168Watchpoint::WatchpointRead () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169{
170 return m_watch_read != 0;
171}
172bool
Johnny Chen01a67862011-10-14 00:42:25 +0000173Watchpoint::WatchpointWrite () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174{
175 return m_watch_write != 0;
176}
Greg Claytonc982c762010-07-09 20:39:50 +0000177uint32_t
Johnny Chen01a67862011-10-14 00:42:25 +0000178Watchpoint::GetIgnoreCount () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179{
180 return m_ignore_count;
181}
182
183void
Johnny Chen01a67862011-10-14 00:42:25 +0000184Watchpoint::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185{
186 m_ignore_count = n;
187}
Johnny Chen16dcf712011-10-17 18:58:00 +0000188
189bool
190Watchpoint::InvokeCallback (StoppointCallbackContext *context)
191{
192 if (m_callback && context->is_synchronous)
193 {
194 uint32_t access = 0;
195 if (m_watch_was_read)
196 access |= LLDB_WATCH_TYPE_READ;
197 if (m_watch_was_written)
198 access |= LLDB_WATCH_TYPE_WRITE;
199 return m_callback(m_callback_baton, context, GetID(), access);
200 }
201 else
202 return true;
203}
204
205void
206Watchpoint::SetCondition (const char *condition)
207{
208 if (condition == NULL || condition[0] == '\0')
209 {
210 if (m_condition_ap.get())
211 m_condition_ap.reset();
212 }
213 else
214 {
215 // Pass NULL for expr_prefix (no translation-unit level definitions).
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000216 m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Johnny Chen16dcf712011-10-17 18:58:00 +0000217 }
218}
219
220const char *
221Watchpoint::GetConditionText () const
222{
223 if (m_condition_ap.get())
224 return m_condition_ap->GetUserText();
225 else
226 return NULL;
227}
228