Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: runtime/vm/debugger.cc

Issue 9019029: Retrieve value of local variables in stack frames. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/debugger.h" 5 #include "vm/debugger.h"
6 6
7 #include "vm/code_index_table.h" 7 #include "vm/code_index_table.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 } 61 }
62 return this->line_number_; 62 return this->line_number_;
63 } 63 }
64 64
65 65
66 void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { 66 void Breakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) {
67 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); 67 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_));
68 } 68 }
69 69
70 70
71 ActivationFrame::ActivationFrame(uword pc) 71 ActivationFrame::ActivationFrame(uword pc, uword fp)
72 : pc_(pc), 72 : pc_(pc), fp_(fp),
73 function_(NULL), 73 function_(Function::ZoneHandle()),
74 token_index_(-1), 74 token_index_(-1),
75 line_number_(-1), 75 line_number_(-1),
76 locals_(NULL) { 76 var_descriptors_(NULL),
77 desc_indices_(8) {
77 } 78 }
78 79
79 80
80 Function* ActivationFrame::DartFunction() { 81 const Function& ActivationFrame::DartFunction() {
81 if (function_ == NULL) { 82 if (function_.IsNull()) {
82 ASSERT(Isolate::Current() != NULL); 83 ASSERT(Isolate::Current() != NULL);
83 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); 84 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table();
84 ASSERT(code_index_table != NULL); 85 ASSERT(code_index_table != NULL);
85 function_ = &Function::ZoneHandle(code_index_table->LookupFunction(pc_)); 86 function_ = code_index_table->LookupFunction(pc_);
86 } 87 }
87 return function_; 88 return function_;
88 } 89 }
89 90
90 91
91 const char* Debugger::QualifiedFunctionName(const Function& func) { 92 const char* Debugger::QualifiedFunctionName(const Function& func) {
92 String& func_name = String::Handle(func.name()); 93 const String& func_name = String::Handle(func.name());
93 Class& func_class = Class::Handle(func.owner()); 94 Class& func_class = Class::Handle(func.owner());
94 String& class_name = String::Handle(func_class.Name()); 95 String& class_name = String::Handle(func_class.Name());
95 96
96 const char* kFormat = "%s%s%s"; 97 const char* kFormat = "%s%s%s";
97 intptr_t len = OS::SNPrint(NULL, 0, kFormat, 98 intptr_t len = OS::SNPrint(NULL, 0, kFormat,
98 func_class.IsTopLevel() ? "" : class_name.ToCString(), 99 func_class.IsTopLevel() ? "" : class_name.ToCString(),
99 func_class.IsTopLevel() ? "" : ".", 100 func_class.IsTopLevel() ? "" : ".",
100 func_name.ToCString()); 101 func_name.ToCString());
101 len++; // String terminator. 102 len++; // String terminator.
102 char* chars = reinterpret_cast<char*>( 103 char* chars = reinterpret_cast<char*>(
103 Isolate::Current()->current_zone()->Allocate(len)); 104 Isolate::Current()->current_zone()->Allocate(len));
104 OS::SNPrint(chars, len, kFormat, 105 OS::SNPrint(chars, len, kFormat,
105 func_class.IsTopLevel() ? "" : class_name.ToCString(), 106 func_class.IsTopLevel() ? "" : class_name.ToCString(),
106 func_class.IsTopLevel() ? "" : ".", 107 func_class.IsTopLevel() ? "" : ".",
107 func_name.ToCString()); 108 func_name.ToCString());
108 return chars; 109 return chars;
109 } 110 }
110 111
111 112
112 RawString* ActivationFrame::QualifiedFunctionName() { 113 RawString* ActivationFrame::QualifiedFunctionName() {
113 Function& func = *DartFunction(); 114 const Function& func = DartFunction();
114 return String::New(Debugger::QualifiedFunctionName(func)); 115 return String::New(Debugger::QualifiedFunctionName(func));
115 } 116 }
116 117
117 118
118 RawString* ActivationFrame::SourceUrl() { 119 RawString* ActivationFrame::SourceUrl() {
119 const Script& script = Script::Handle(SourceScript()); 120 const Script& script = Script::Handle(SourceScript());
120 return script.url(); 121 return script.url();
121 } 122 }
122 123
123 124
124 RawScript* ActivationFrame::SourceScript() { 125 RawScript* ActivationFrame::SourceScript() {
125 const Function& func = *DartFunction(); 126 const Function& func = DartFunction();
126 const Class& cls = Class::Handle(func.owner()); 127 const Class& cls = Class::Handle(func.owner());
127 return cls.script(); 128 return cls.script();
128 } 129 }
129 130
130 131
131 intptr_t ActivationFrame::TokenIndex() { 132 intptr_t ActivationFrame::TokenIndex() {
132 if (token_index_ < 0) { 133 if (token_index_ < 0) {
133 const Function& func = *DartFunction(); 134 const Function& func = DartFunction();
134 Code& code = Code::Handle(func.code()); 135 Code& code = Code::Handle(func.code());
135 ASSERT(!code.IsNull()); 136 ASSERT(!code.IsNull());
136 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 137 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
137 for (int i = 0; i < desc.Length(); i++) { 138 for (int i = 0; i < desc.Length(); i++) {
138 if (desc.PC(i) == pc_) { 139 if (desc.PC(i) == pc_) {
139 token_index_ = desc.TokenIndex(i); 140 token_index_ = desc.TokenIndex(i);
140 break; 141 break;
141 } 142 }
142 } 143 }
143 ASSERT(token_index_ >= 0); 144 ASSERT(token_index_ >= 0);
144 } 145 }
145 return token_index_; 146 return token_index_;
146 } 147 }
147 148
148 149
149 intptr_t ActivationFrame::LineNumber() { 150 intptr_t ActivationFrame::LineNumber() {
150 // Compute line number lazily since it causes scanning of the script. 151 // Compute line number lazily since it causes scanning of the script.
151 if (line_number_ < 0) { 152 if (line_number_ < 0) {
152 const Script& script = Script::Handle(SourceScript()); 153 const Script& script = Script::Handle(SourceScript());
153 intptr_t ignore_column; 154 intptr_t ignore_column;
154 script.GetTokenLocation(TokenIndex(), &line_number_, &ignore_column); 155 script.GetTokenLocation(TokenIndex(), &line_number_, &ignore_column);
155 } 156 }
156 return line_number_; 157 return line_number_;
157 } 158 }
158 159
159 160
160 ActiveVariables* ActivationFrame::LocalVariables() { 161 void ActivationFrame::GetLocalVariables() {
161 if (locals_ == NULL) { 162 if (var_descriptors_ == NULL) {
162 const Function& func = *DartFunction(); 163 const Code& code = Code::Handle(DartFunction().code());
163 locals_ = new ActiveVariables(func, TokenIndex()); 164 var_descriptors_ =
165 &LocalVarDescriptors::ZoneHandle(code.var_descriptors());
166 intptr_t activation_token_pos = TokenIndex();
167 intptr_t desc_len = var_descriptors_->Length();
168 for (int i = 0; i < desc_len; i++) {
169 intptr_t begin_pos, end_pos;
170 var_descriptors_->GetRange(i, &begin_pos, &end_pos);
171 if ((begin_pos <= activation_token_pos) &&
172 (activation_token_pos <= end_pos)) {
173 desc_indices_.Add(i);
174 }
175 }
164 } 176 }
165 return locals_; 177 }
178
179
180 intptr_t ActivationFrame::NumLocalVariables() {
181 GetLocalVariables();
182 return desc_indices_.length();
183 }
184
185
186 void ActivationFrame::VariableAt(intptr_t i,
187 String* name,
188 intptr_t* token_pos,
189 intptr_t* end_pos,
190 Instance* value) {
191 GetLocalVariables();
192 ASSERT(i < desc_indices_.length());
193 ASSERT(name != NULL);
194 intptr_t desc_index = desc_indices_[i];
195 *name ^= var_descriptors_->GetName(desc_index);
196 var_descriptors_->GetRange(i, token_pos, end_pos);
197 ASSERT(value != NULL);
198 *value = GetLocalVarValue(var_descriptors_->GetSlotIndex(i));
166 } 199 }
167 200
168 201
169 RawInstance* ActivationFrame::Value(const String& variable_name) { 202 RawInstance* ActivationFrame::Value(const String& variable_name) {
170 UNIMPLEMENTED(); 203 UNIMPLEMENTED();
171 return NULL; 204 return NULL;
172 } 205 }
173 206
174 207
175 const char* ActivationFrame::ToCString() { 208 const char* ActivationFrame::ToCString() {
176 const char* kFormat = "Function: '%s' url: '%s' line: %d"; 209 const char* kFormat = "Function: '%s' url: '%s' line: %d";
177 210
178 Function& func = *DartFunction(); 211 const Function& func = DartFunction();
179 String& url = String::Handle(SourceUrl()); 212 const String& url = String::Handle(SourceUrl());
180 intptr_t line = LineNumber(); 213 intptr_t line = LineNumber();
181 const char* func_name = Debugger::QualifiedFunctionName(func); 214 const char* func_name = Debugger::QualifiedFunctionName(func);
182 215
183 intptr_t len = 216 intptr_t len =
184 OS::SNPrint(NULL, 0, kFormat, func_name, url.ToCString(), line); 217 OS::SNPrint(NULL, 0, kFormat, func_name, url.ToCString(), line);
185 len++; // String terminator. 218 len++; // String terminator.
186 char* chars = reinterpret_cast<char*>( 219 char* chars = reinterpret_cast<char*>(
187 Isolate::Current()->current_zone()->Allocate(len)); 220 Isolate::Current()->current_zone()->Allocate(len));
188 OS::SNPrint(chars, len, kFormat, func_name, url.ToCString(), line); 221 OS::SNPrint(chars, len, kFormat, func_name, url.ToCString(), line);
189 return chars; 222 return chars;
190 } 223 }
191 224
192 225
193 void StackTrace::AddActivation(ActivationFrame* frame) { 226 void StackTrace::AddActivation(ActivationFrame* frame) {
194 this->trace_.Add(frame); 227 this->trace_.Add(frame);
195 } 228 }
196 229
197 230
198 ActiveVariables::ActiveVariables(const Function& function, intptr_t token_pos)
199 : descriptors_(NULL),
200 desc_indices_(8) {
201 const Code& code = Code::Handle(function.code());
202 LocalVarDescriptors& var_descs =
203 LocalVarDescriptors::ZoneHandle(code.var_descriptors());
204 descriptors_ = &var_descs;
205 intptr_t desc_len = var_descs.Length();
206 for (int i = 0; i < desc_len; i++) {
207 intptr_t begin_pos, end_pos;
208 var_descs.GetRange(i, &begin_pos, &end_pos);
209 if ((begin_pos <= token_pos) && (token_pos <= end_pos)) {
210 desc_indices_.Add(i);
211 }
212 }
213 }
214
215
216 void ActiveVariables::VariableAt(intptr_t i,
217 String* name,
218 intptr_t* token_pos,
219 intptr_t* end_pos,
220 Instance* value) const {
221 ASSERT(i < Length());
222 ASSERT(name != NULL);
223 intptr_t desc_index = desc_indices_[i];
224 *name ^= descriptors_->GetName(desc_index);
225 descriptors_->GetRange(i, token_pos, end_pos);
226 ASSERT(value != NULL);
227 *value = Instance::null(); // TODO(hausner): get actual variable value.
228 }
229
230
231 Debugger::Debugger() 231 Debugger::Debugger()
232 : initialized_(false), 232 : initialized_(false),
233 bp_handler_(NULL), 233 bp_handler_(NULL),
234 breakpoints_(NULL) { 234 breakpoints_(NULL) {
235 } 235 }
236 236
237 237
238 bool Debugger::IsActive() { 238 bool Debugger::IsActive() {
239 // TODO(hausner): The code generator uses this function to prevent 239 // TODO(hausner): The code generator uses this function to prevent
240 // generation of optimized code when Dart code is being debugged. 240 // generation of optimized code when Dart code is being debugged.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 } 326 }
327 327
328 328
329 static void DefaultBreakpointHandler(Breakpoint* bpt, StackTrace* stack) { 329 static void DefaultBreakpointHandler(Breakpoint* bpt, StackTrace* stack) {
330 String& var_name = String::Handle(); 330 String& var_name = String::Handle();
331 Instance& value = Instance::Handle(); 331 Instance& value = Instance::Handle();
332 for (intptr_t i = 0; i < stack->Length(); i++) { 332 for (intptr_t i = 0; i < stack->Length(); i++) {
333 ActivationFrame* frame = stack->ActivationFrameAt(i); 333 ActivationFrame* frame = stack->ActivationFrameAt(i);
334 OS::Print(" %d. %s\n", 334 OS::Print(" %d. %s\n",
335 i + 1, frame->ToCString()); 335 i + 1, frame->ToCString());
336 ActiveVariables* locals = frame->LocalVariables(); 336 intptr_t num_locals = frame->NumLocalVariables();
337 intptr_t num_locals = locals->Length();
338 for (intptr_t i = 0; i < num_locals; i++) { 337 for (intptr_t i = 0; i < num_locals; i++) {
339 intptr_t token_pos, end_pos; 338 intptr_t token_pos, end_pos;
340 locals->VariableAt(i, &var_name, &token_pos, &end_pos, &value); 339 frame->VariableAt(i, &var_name, &token_pos, &end_pos, &value);
341 OS::Print(" var %s (pos %d) = %s\n", 340 OS::Print(" var %s (pos %d) = %s\n",
342 var_name.ToCString(), token_pos, value.ToCString()); 341 var_name.ToCString(), token_pos, value.ToCString());
343 } 342 }
344 } 343 }
345 } 344 }
346 345
347 346
348 void Debugger::SetBreakpointHandler(BreakpointHandler* handler) { 347 void Debugger::SetBreakpointHandler(BreakpointHandler* handler) {
349 bp_handler_ = handler; 348 bp_handler_ = handler;
350 if (bp_handler_ == NULL) { 349 if (bp_handler_ == NULL) {
(...skipping 12 matching lines...) Expand all
363 if (verbose) { 362 if (verbose) {
364 OS::Print(">>> Breakpoint at %s:%d (Address %p)\n", 363 OS::Print(">>> Breakpoint at %s:%d (Address %p)\n",
365 bpt ? String::Handle(bpt->SourceUrl()).ToCString() : "?", 364 bpt ? String::Handle(bpt->SourceUrl()).ToCString() : "?",
366 bpt ? bpt->LineNumber() : 0, 365 bpt ? bpt->LineNumber() : 0,
367 frame->pc()); 366 frame->pc());
368 } 367 }
369 StackTrace* stack_trace = new StackTrace(8); 368 StackTrace* stack_trace = new StackTrace(8);
370 while (frame != NULL) { 369 while (frame != NULL) {
371 ASSERT(frame->IsValid()); 370 ASSERT(frame->IsValid());
372 ASSERT(frame->IsDartFrame()); 371 ASSERT(frame->IsDartFrame());
373 ActivationFrame* activation = new ActivationFrame(frame->pc()); 372 ActivationFrame* activation =
373 new ActivationFrame(frame->pc(), frame->fp());
374 stack_trace->AddActivation(activation); 374 stack_trace->AddActivation(activation);
375 frame = iterator.NextFrame(); 375 frame = iterator.NextFrame();
376 } 376 }
377 377
378 if (bp_handler_ != NULL) { 378 if (bp_handler_ != NULL) {
379 (*bp_handler_)(bpt, stack_trace); 379 (*bp_handler_)(bpt, stack_trace);
380 } 380 }
381 } 381 }
382 382
383 383
(...skipping 19 matching lines...) Expand all
403 403
404 404
405 void Debugger::AddBreakpoint(Breakpoint* bpt) { 405 void Debugger::AddBreakpoint(Breakpoint* bpt) {
406 ASSERT(bpt->next() == NULL); 406 ASSERT(bpt->next() == NULL);
407 bpt->set_next(this->breakpoints_); 407 bpt->set_next(this->breakpoints_);
408 this->breakpoints_ = bpt; 408 this->breakpoints_ = bpt;
409 } 409 }
410 410
411 411
412 } // namespace dart 412 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698