blob: 4645b6072e05065a328bef25bd1892463b5b6676 [file] [log] [blame]
Johnny Chenecd4feb2011-10-14 00:42:25 +00001//===-- Watchpoint.cpp ------------------------------------------*- C++ -*-===//
Chris Lattner24943d22010-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 Chenecd4feb2011-10-14 00:42:25 +000010#include "lldb/Breakpoint/Watchpoint.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Johnny Chen712a6282011-10-17 18:58:00 +000016#include "lldb/Breakpoint/StoppointCallbackContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/Stream.h"
Johnny Chen712a6282011-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 Lattner24943d22010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
Johnny Chenecd4feb2011-10-14 00:42:25 +000026Watchpoint::Watchpoint (lldb::addr_t addr, size_t size, bool hardware) :
Johnny Chenedda23f2011-09-06 02:52:28 +000027 StoppointLocation (GetNextID(), addr, size, hardware),
Johnny Chen096c2932011-09-26 22:40:50 +000028 m_target(NULL),
Chris Lattner24943d22010-06-08 16:52:24 +000029 m_enabled(0),
Johnny Chen01acfa72011-09-22 18:04:58 +000030 m_is_hardware(hardware),
Chris Lattner24943d22010-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 Chen41a55ef2011-10-14 19:15:48 +000037 m_callback_baton(NULL),
38 m_decl_str(),
39 m_error()
Chris Lattner24943d22010-06-08 16:52:24 +000040{
41}
42
Johnny Chenecd4feb2011-10-14 00:42:25 +000043Watchpoint::~Watchpoint()
Chris Lattner24943d22010-06-08 16:52:24 +000044{
45}
46
47break_id_t
Johnny Chenecd4feb2011-10-14 00:42:25 +000048Watchpoint::GetNextID()
Chris Lattner24943d22010-06-08 16:52:24 +000049{
50 static break_id_t g_next_ID = 0;
51 return ++g_next_ID;
52}
53
54bool
Johnny Chenecd4feb2011-10-14 00:42:25 +000055Watchpoint::SetCallback (WatchpointHitCallback callback, void *callback_baton)
Chris Lattner24943d22010-06-08 16:52:24 +000056{
57 m_callback = callback;
58 m_callback_baton = callback_baton;
59 return true;
60}
61
Johnny Chen10b12b32011-09-16 21:41:42 +000062void
Johnny Chenecd4feb2011-10-14 00:42:25 +000063Watchpoint::SetDeclInfo (std::string &str)
Johnny Chen10b12b32011-09-16 21:41:42 +000064{
65 m_decl_str = str;
66 return;
67}
68
Chris Lattner24943d22010-06-08 16:52:24 +000069
Johnny Chen01acfa72011-09-22 18:04:58 +000070bool
Johnny Chenecd4feb2011-10-14 00:42:25 +000071Watchpoint::IsHardware () const
Johnny Chen01acfa72011-09-22 18:04:58 +000072{
73 return m_is_hardware;
74}
75
Chris Lattner24943d22010-06-08 16:52:24 +000076// RETURNS - true if we should stop at this breakpoint, false if we
77// should continue.
78
79bool
Johnny Chenecd4feb2011-10-14 00:42:25 +000080Watchpoint::ShouldStop (StoppointCallbackContext *context)
Chris Lattner24943d22010-06-08 16:52:24 +000081{
Johnny Chen01acfa72011-09-22 18:04:58 +000082 ++m_hit_count;
Chris Lattner24943d22010-06-08 16:52:24 +000083
Johnny Chen01acfa72011-09-22 18:04:58 +000084 if (!IsEnabled())
85 return false;
Johnny Chen043f8c22011-09-21 22:47:15 +000086
Johnny Chen01acfa72011-09-22 18:04:58 +000087 if (m_hit_count <= GetIgnoreCount())
88 return false;
89
Johnny Chen712a6282011-10-17 18:58:00 +000090 return true;
Chris Lattner24943d22010-06-08 16:52:24 +000091}
92
93void
Johnny Chenecd4feb2011-10-14 00:42:25 +000094Watchpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
Johnny Chen34bbf852011-09-12 23:38:44 +000095{
Johnny Chen10b12b32011-09-16 21:41:42 +000096 DumpWithLevel(s, level);
Johnny Chen34bbf852011-09-12 23:38:44 +000097 return;
98}
99
100void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000101Watchpoint::Dump(Stream *s) const
Chris Lattner24943d22010-06-08 16:52:24 +0000102{
Johnny Chen10b12b32011-09-16 21:41:42 +0000103 DumpWithLevel(s, lldb::eDescriptionLevelBrief);
104}
105
106void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000107Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const
Johnny Chen10b12b32011-09-16 21:41:42 +0000108{
Chris Lattner24943d22010-06-08 16:52:24 +0000109 if (s == NULL)
110 return;
111
Johnny Chen10b12b32011-09-16 21:41:42 +0000112 assert(description_level >= lldb::eDescriptionLevelBrief &&
113 description_level <= lldb::eDescriptionLevelVerbose);
114
Greg Claytonbae39c52011-12-03 00:46:21 +0000115 s->Printf("Watchpoint %u: addr = 0x%8.8llx size = %u state = %s type = %s%s",
Johnny Chen10b12b32011-09-16 21:41:42 +0000116 GetID(),
117 (uint64_t)m_addr,
118 m_byte_size,
119 m_enabled ? "enabled" : "disabled",
120 m_watch_read ? "r" : "",
121 m_watch_write ? "w" : "");
122
Johnny Chen712a6282011-10-17 18:58:00 +0000123 if (description_level >= lldb::eDescriptionLevelFull) {
124 if (m_decl_str.c_str())
125 s->Printf("\n declare @ '%s'", m_decl_str.c_str());
126 if (GetConditionText())
127 s->Printf("\n condition = '%s'", GetConditionText());
128 }
Johnny Chen10b12b32011-09-16 21:41:42 +0000129
130 if (description_level >= lldb::eDescriptionLevelVerbose)
Johnny Chenb2385172011-10-06 20:27:05 +0000131 if (m_callback)
132 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %8p baton = %8p",
133 GetHardwareIndex(),
134 GetHitCount(),
135 GetIgnoreCount(),
136 m_callback,
137 m_callback_baton);
138 else
139 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u",
140 GetHardwareIndex(),
141 GetHitCount(),
142 GetIgnoreCount());
Chris Lattner24943d22010-06-08 16:52:24 +0000143}
144
145bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000146Watchpoint::IsEnabled() const
Chris Lattner24943d22010-06-08 16:52:24 +0000147{
148 return m_enabled;
149}
150
151void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000152Watchpoint::SetEnabled(bool enabled)
Chris Lattner24943d22010-06-08 16:52:24 +0000153{
154 if (!enabled)
155 SetHardwareIndex(LLDB_INVALID_INDEX32);
156 m_enabled = enabled;
157}
158
159void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000160Watchpoint::SetWatchpointType (uint32_t type)
Chris Lattner24943d22010-06-08 16:52:24 +0000161{
162 m_watch_read = (type & LLDB_WATCH_TYPE_READ) != 0;
163 m_watch_write = (type & LLDB_WATCH_TYPE_WRITE) != 0;
164}
165
166bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000167Watchpoint::WatchpointRead () const
Chris Lattner24943d22010-06-08 16:52:24 +0000168{
169 return m_watch_read != 0;
170}
171bool
Johnny Chenecd4feb2011-10-14 00:42:25 +0000172Watchpoint::WatchpointWrite () const
Chris Lattner24943d22010-06-08 16:52:24 +0000173{
174 return m_watch_write != 0;
175}
Greg Clayton54e7afa2010-07-09 20:39:50 +0000176uint32_t
Johnny Chenecd4feb2011-10-14 00:42:25 +0000177Watchpoint::GetIgnoreCount () const
Chris Lattner24943d22010-06-08 16:52:24 +0000178{
179 return m_ignore_count;
180}
181
182void
Johnny Chenecd4feb2011-10-14 00:42:25 +0000183Watchpoint::SetIgnoreCount (uint32_t n)
Chris Lattner24943d22010-06-08 16:52:24 +0000184{
185 m_ignore_count = n;
186}
Johnny Chen712a6282011-10-17 18:58:00 +0000187
188bool
189Watchpoint::InvokeCallback (StoppointCallbackContext *context)
190{
191 if (m_callback && context->is_synchronous)
192 {
193 uint32_t access = 0;
194 if (m_watch_was_read)
195 access |= LLDB_WATCH_TYPE_READ;
196 if (m_watch_was_written)
197 access |= LLDB_WATCH_TYPE_WRITE;
198 return m_callback(m_callback_baton, context, GetID(), access);
199 }
200 else
201 return true;
202}
203
204void
205Watchpoint::SetCondition (const char *condition)
206{
207 if (condition == NULL || condition[0] == '\0')
208 {
209 if (m_condition_ap.get())
210 m_condition_ap.reset();
211 }
212 else
213 {
214 // Pass NULL for expr_prefix (no translation-unit level definitions).
Sean Callanan5b658cc2011-11-07 23:35:40 +0000215 m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown));
Johnny Chen712a6282011-10-17 18:58:00 +0000216 }
217}
218
219const char *
220Watchpoint::GetConditionText () const
221{
222 if (m_condition_ap.get())
223 return m_condition_ap->GetUserText();
224 else
225 return NULL;
226}
227