blob: 1abe7c88ae431c948a22cc8f2002f4a536c4df9f [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),
36 m_callback(NULL),
Johnny Chened456eb2011-10-14 19:15:48 +000037 m_callback_baton(NULL),
38 m_decl_str(),
Johnny Chena4d6bc92012-02-25 06:44:30 +000039 m_watch_spec_str(),
Johnny Chened456eb2011-10-14 19:15:48 +000040 m_error()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041{
42}
43
Johnny Chen01a67862011-10-14 00:42:25 +000044Watchpoint::~Watchpoint()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045{
46}
47
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048bool
Johnny Chen01a67862011-10-14 00:42:25 +000049Watchpoint::SetCallback (WatchpointHitCallback callback, void *callback_baton)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050{
51 m_callback = callback;
52 m_callback_baton = callback_baton;
53 return true;
54}
55
Johnny Chende6bd242011-09-16 21:41:42 +000056void
Johnny Chen01a67862011-10-14 00:42:25 +000057Watchpoint::SetDeclInfo (std::string &str)
Johnny Chende6bd242011-09-16 21:41:42 +000058{
59 m_decl_str = str;
60 return;
61}
62
Johnny Chena4d6bc92012-02-25 06:44:30 +000063void
64Watchpoint::SetWatchSpec (std::string &str)
65{
66 m_watch_spec_str = str;
67 return;
68}
69
Johnny Chenfab7a912012-01-23 23:03:59 +000070// Override default impl of StoppointLocation::IsHardware() since m_is_hardware
71// member field is more accurate.
Johnny Chenf04ee932011-09-22 18:04:58 +000072bool
Johnny Chen01a67862011-10-14 00:42:25 +000073Watchpoint::IsHardware () const
Johnny Chenf04ee932011-09-22 18:04:58 +000074{
75 return m_is_hardware;
76}
77
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078// RETURNS - true if we should stop at this breakpoint, false if we
79// should continue.
80
81bool
Johnny Chen01a67862011-10-14 00:42:25 +000082Watchpoint::ShouldStop (StoppointCallbackContext *context)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083{
Johnny Chenfab7a912012-01-23 23:03:59 +000084 IncrementHitCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085
Johnny Chenf04ee932011-09-22 18:04:58 +000086 if (!IsEnabled())
87 return false;
Johnny Chenfd158f42011-09-21 22:47:15 +000088
Johnny Chenfab7a912012-01-23 23:03:59 +000089 if (GetHitCount() <= GetIgnoreCount())
Johnny Chenf04ee932011-09-22 18:04:58 +000090 return false;
91
Johnny Chen16dcf712011-10-17 18:58:00 +000092 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093}
94
95void
Johnny Chen01a67862011-10-14 00:42:25 +000096Watchpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
Johnny Chen887062a2011-09-12 23:38:44 +000097{
Johnny Chende6bd242011-09-16 21:41:42 +000098 DumpWithLevel(s, level);
Johnny Chen887062a2011-09-12 23:38:44 +000099 return;
100}
101
102void
Johnny Chen01a67862011-10-14 00:42:25 +0000103Watchpoint::Dump(Stream *s) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104{
Johnny Chende6bd242011-09-16 21:41:42 +0000105 DumpWithLevel(s, lldb::eDescriptionLevelBrief);
106}
107
108void
Johnny Chen01a67862011-10-14 00:42:25 +0000109Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const
Johnny Chende6bd242011-09-16 21:41:42 +0000110{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000111 if (s == NULL)
112 return;
113
Johnny Chende6bd242011-09-16 21:41:42 +0000114 assert(description_level >= lldb::eDescriptionLevelBrief &&
115 description_level <= lldb::eDescriptionLevelVerbose);
116
Greg Claytonc91d8042011-12-03 00:46:21 +0000117 s->Printf("Watchpoint %u: addr = 0x%8.8llx size = %u state = %s type = %s%s",
Johnny Chende6bd242011-09-16 21:41:42 +0000118 GetID(),
Johnny Chena5cde262012-01-24 00:11:02 +0000119 GetLoadAddress(),
Johnny Chende6bd242011-09-16 21:41:42 +0000120 m_byte_size,
Johnny Chena4d6bc92012-02-25 06:44:30 +0000121 IsEnabled() ? "enabled" : "disabled",
Johnny Chende6bd242011-09-16 21:41:42 +0000122 m_watch_read ? "r" : "",
123 m_watch_write ? "w" : "");
124
Johnny Chen16dcf712011-10-17 18:58:00 +0000125 if (description_level >= lldb::eDescriptionLevelFull) {
Johnny Chendedb67a2012-01-30 21:46:17 +0000126 if (!m_decl_str.empty())
Johnny Chen16dcf712011-10-17 18:58:00 +0000127 s->Printf("\n declare @ '%s'", m_decl_str.c_str());
Johnny Chena4d6bc92012-02-25 06:44:30 +0000128 if (!m_watch_spec_str.empty())
129 s->Printf("\n static watchpoint spec = '%s'", m_watch_spec_str.c_str());
Johnny Chen16dcf712011-10-17 18:58:00 +0000130 if (GetConditionText())
131 s->Printf("\n condition = '%s'", GetConditionText());
132 }
Johnny Chende6bd242011-09-16 21:41:42 +0000133
134 if (description_level >= lldb::eDescriptionLevelVerbose)
Jason Molenda7e1f45f2012-02-23 22:32:13 +0000135 {
Johnny Chen98a49d9b2011-10-06 20:27:05 +0000136 if (m_callback)
Jason Molenda7e1f45f2012-02-23 22:32:13 +0000137 {
Johnny Chen98a49d9b2011-10-06 20:27:05 +0000138 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %8p baton = %8p",
139 GetHardwareIndex(),
140 GetHitCount(),
141 GetIgnoreCount(),
142 m_callback,
143 m_callback_baton);
Jason Molenda7e1f45f2012-02-23 22:32:13 +0000144 }
Johnny Chen98a49d9b2011-10-06 20:27:05 +0000145 else
Jason Molenda7e1f45f2012-02-23 22:32:13 +0000146 {
Johnny Chen98a49d9b2011-10-06 20:27:05 +0000147 s->Printf("\n hw_index = %i hit_count = %-4u ignore_count = %-4u",
148 GetHardwareIndex(),
149 GetHitCount(),
150 GetIgnoreCount());
Jason Molenda7e1f45f2012-02-23 22:32:13 +0000151 }
152 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153}
154
155bool
Johnny Chen01a67862011-10-14 00:42:25 +0000156Watchpoint::IsEnabled() const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157{
158 return m_enabled;
159}
160
161void
Johnny Chen01a67862011-10-14 00:42:25 +0000162Watchpoint::SetEnabled(bool enabled)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163{
164 if (!enabled)
165 SetHardwareIndex(LLDB_INVALID_INDEX32);
166 m_enabled = enabled;
167}
168
169void
Johnny Chen01a67862011-10-14 00:42:25 +0000170Watchpoint::SetWatchpointType (uint32_t type)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171{
172 m_watch_read = (type & LLDB_WATCH_TYPE_READ) != 0;
173 m_watch_write = (type & LLDB_WATCH_TYPE_WRITE) != 0;
174}
175
176bool
Johnny Chen01a67862011-10-14 00:42:25 +0000177Watchpoint::WatchpointRead () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178{
179 return m_watch_read != 0;
180}
181bool
Johnny Chen01a67862011-10-14 00:42:25 +0000182Watchpoint::WatchpointWrite () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183{
184 return m_watch_write != 0;
185}
Greg Claytonc982c762010-07-09 20:39:50 +0000186uint32_t
Johnny Chen01a67862011-10-14 00:42:25 +0000187Watchpoint::GetIgnoreCount () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188{
189 return m_ignore_count;
190}
191
192void
Johnny Chen01a67862011-10-14 00:42:25 +0000193Watchpoint::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194{
195 m_ignore_count = n;
196}
Johnny Chen16dcf712011-10-17 18:58:00 +0000197
198bool
199Watchpoint::InvokeCallback (StoppointCallbackContext *context)
200{
201 if (m_callback && context->is_synchronous)
202 {
203 uint32_t access = 0;
204 if (m_watch_was_read)
205 access |= LLDB_WATCH_TYPE_READ;
206 if (m_watch_was_written)
207 access |= LLDB_WATCH_TYPE_WRITE;
208 return m_callback(m_callback_baton, context, GetID(), access);
209 }
210 else
211 return true;
212}
213
214void
215Watchpoint::SetCondition (const char *condition)
216{
217 if (condition == NULL || condition[0] == '\0')
218 {
219 if (m_condition_ap.get())
220 m_condition_ap.reset();
221 }
222 else
223 {
224 // Pass NULL for expr_prefix (no translation-unit level definitions).
Sean Callanan20bb3aa2011-12-21 22:22:58 +0000225 m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
Johnny Chen16dcf712011-10-17 18:58:00 +0000226 }
227}
228
229const char *
230Watchpoint::GetConditionText () const
231{
232 if (m_condition_ap.get())
233 return m_condition_ap->GetUserText();
234 else
235 return NULL;
236}
237