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

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

Issue 8826007: First bits of external debugger API (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_api_impl.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"
11 #include "vm/globals.h" 11 #include "vm/globals.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.h"
14 #include "vm/os.h" 14 #include "vm/os.h"
15 #include "vm/stack_frame.h" 15 #include "vm/stack_frame.h"
16 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
17 #include "vm/visitor.h" 17 #include "vm/visitor.h"
18 18
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DEFINE_FLAG(bool, debugger, false, "Debug breakpoint at main"); 22
23 DEFINE_FLAG(charp, bpt, NULL, "Debug breakpoint at <func>"); 23 DEFINE_FLAG(charp, bpt, NULL, "Debug breakpoint at <func>");
24 24
25 25
26
27 Breakpoint::Breakpoint(const Function& func, intptr_t pc_desc_index) 26 Breakpoint::Breakpoint(const Function& func, intptr_t pc_desc_index)
28 : function_(func.raw()), 27 : function_(func.raw()),
29 pc_desc_index_(pc_desc_index), 28 pc_desc_index_(pc_desc_index),
30 pc_(0), 29 pc_(0),
31 line_number_(-1), 30 line_number_(-1),
32 next_(NULL) { 31 next_(NULL) {
33 Code& code = Code::Handle(func.code()); 32 Code& code = Code::Handle(func.code());
34 ASSERT(!code.IsNull()); // Function must be compiled. 33 ASSERT(!code.IsNull()); // Function must be compiled.
35 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 34 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
36 ASSERT(pc_desc_index < desc.Length()); 35 ASSERT(pc_desc_index < desc.Length());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 177 }
179 178
180 179
181 Debugger::Debugger() 180 Debugger::Debugger()
182 : initialized_(false), 181 : initialized_(false),
183 bp_handler_(NULL), 182 bp_handler_(NULL),
184 breakpoints_(NULL) { 183 breakpoints_(NULL) {
185 } 184 }
186 185
187 186
188 static RawFunction* ResolveLibraryFunction(const String& fname) { 187 bool Debugger::IsActive() {
189 Isolate* isolate = Isolate::Current(); 188 // TODO(hausner): The code generator uses this function to prevent
190 const Library& root_lib = 189 // generation of optimized code when Dart code is being debugged.
191 Library::Handle(isolate->object_store()->root_library()); 190 // This is probably not conservative enough (we could set the first
192 ASSERT(!root_lib.IsNull()); 191 // breakpoint after optimized code has already been produced).
192 // Long-term, we need to be able to de-optimize code.
193 return breakpoints_ != NULL;
194 }
195
196
197 static RawFunction* ResolveLibraryFunction(
198 const Library& library,
199 const String& fname) {
200 ASSERT(!library.IsNull());
193 Function& function = Function::Handle(); 201 Function& function = Function::Handle();
194 const Object& object = Object::Handle(root_lib.LookupObject(fname)); 202 const Object& object = Object::Handle(library.LookupObject(fname));
195 if (!object.IsNull() && object.IsFunction()) { 203 if (!object.IsNull() && object.IsFunction()) {
196 function ^= object.raw(); 204 function ^= object.raw();
197 } 205 }
198 return function.raw(); 206 return function.raw();
199 } 207 }
200 208
201 209
202 static RawFunction* ResolveFunction(const String& class_name, 210 RawFunction* Debugger::ResolveFunction(const Library& library,
203 const String& function_name) { 211 const String& class_name,
204 Isolate* isolate = Isolate::Current(); 212 const String& function_name) {
205 const Library& root_lib = 213 ASSERT(!library.IsNull());
206 Library::Handle(isolate->object_store()->root_library()); 214 ASSERT(!class_name.IsNull());
207 const Class& cls = Class::Handle(root_lib.LookupClass(class_name)); 215 ASSERT(!function_name.IsNull());
208 216 if (class_name.Length() == 0) {
217 return ResolveLibraryFunction(library, function_name);
218 }
219 const Class& cls = Class::Handle(library.LookupClass(class_name));
209 Function& function = Function::Handle(); 220 Function& function = Function::Handle();
210 if (!cls.IsNull()) { 221 if (!cls.IsNull()) {
211 function = cls.LookupStaticFunction(function_name); 222 function = cls.LookupStaticFunction(function_name);
212 if (function.IsNull()) { 223 if (function.IsNull()) {
213 function = cls.LookupDynamicFunction(function_name); 224 function = cls.LookupDynamicFunction(function_name);
214 } 225 }
215 } 226 }
216 return function.raw(); 227 return function.raw();
217 } 228 }
218 229
219 230
220 void Debugger::SetBreakpointAtEntry(const String& class_name, 231 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function) {
221 const String& function_name) { 232 ASSERT(!target_function.IsNull());
222 Function& func = Function::Handle(); 233 if (!target_function.HasCode()) {
223 if (class_name.IsNull() || (class_name.Length() == 0)) { 234 Compiler::CompileFunction(target_function);
224 func = ResolveLibraryFunction(function_name);
225 } else {
226 func = ResolveFunction(class_name, function_name);
227 } 235 }
228 if (func.IsNull()) { 236 Code& code = Code::Handle(target_function.code());
229 OS::Print("could not find function '%s'\n", function_name.ToCString());
230 return;
231 }
232 if (!func.HasCode()) {
233 Compiler::CompileFunction(func);
234 }
235 Code& code = Code::Handle(func.code());
236 ASSERT(!code.IsNull()); 237 ASSERT(!code.IsNull());
237 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 238 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
238 for (int i = 0; i < desc.Length(); i++) { 239 for (int i = 0; i < desc.Length(); i++) {
239 PcDescriptors::Kind kind = desc.DescriptorKind(i); 240 PcDescriptors::Kind kind = desc.DescriptorKind(i);
240 Breakpoint* bpt = NULL; 241 Breakpoint* bpt = NULL;
241 if (kind == PcDescriptors::kIcCall) { 242 if (kind == PcDescriptors::kIcCall) {
242 CodePatcher::PatchInstanceCallAt( 243 CodePatcher::PatchInstanceCallAt(
243 desc.PC(i), StubCode::BreakpointDynamicEntryPoint()); 244 desc.PC(i), StubCode::BreakpointDynamicEntryPoint());
244 bpt = new Breakpoint(func, i); 245 bpt = new Breakpoint(target_function, i);
245 } else if (kind == PcDescriptors::kOther) { 246 } else if (kind == PcDescriptors::kOther) {
246 if (CodePatcher::IsDartCall(desc.PC(i))) { 247 if (CodePatcher::IsDartCall(desc.PC(i))) {
247 CodePatcher::PatchStaticCallAt( 248 CodePatcher::PatchStaticCallAt(
248 desc.PC(i), StubCode::BreakpointStaticEntryPoint()); 249 desc.PC(i), StubCode::BreakpointStaticEntryPoint());
249 bpt = new Breakpoint(func, i); 250 bpt = new Breakpoint(target_function, i);
250 } 251 }
251 } 252 }
252 if (bpt != NULL) { 253 if (bpt != NULL) {
253 OS::Print("Setting breakpoint at '%s' line %d (PC %p)\n", 254 OS::Print("Setting breakpoint at '%s' line %d (PC %p)\n",
254 String::Handle(bpt->SourceUrl()).ToCString(), 255 String::Handle(bpt->SourceUrl()).ToCString(),
255 bpt->LineNumber(), 256 bpt->LineNumber(),
256 bpt->pc()); 257 bpt->pc());
257 AddBreakpoint(bpt); 258 AddBreakpoint(bpt);
258 return; 259 return bpt;
259 } 260 }
260 } 261 }
261 OS::Print("no breakpoint location found in function '%s'\n", 262 return NULL;
262 function_name.ToCString());
263 } 263 }
264 264
265 265
266 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) { 266 void Debugger::VisitObjectPointers(ObjectPointerVisitor* visitor) {
267 ASSERT(visitor != NULL); 267 ASSERT(visitor != NULL);
268 Breakpoint* bpt = this->breakpoints_; 268 Breakpoint* bpt = this->breakpoints_;
269 while (bpt != NULL) { 269 while (bpt != NULL) {
270 bpt->VisitObjectPointers(visitor); 270 bpt->VisitObjectPointers(visitor);
271 bpt = bpt->next(); 271 bpt = bpt->next();
272 } 272 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 (*bp_handler_)(bpt, stack_trace); 313 (*bp_handler_)(bpt, stack_trace);
314 } 314 }
315 } 315 }
316 316
317 317
318 void Debugger::Initialize(Isolate* isolate) { 318 void Debugger::Initialize(Isolate* isolate) {
319 if (initialized_) { 319 if (initialized_) {
320 return; 320 return;
321 } 321 }
322 initialized_ = true; 322 initialized_ = true;
323 if (!FLAG_debugger) {
324 return;
325 }
326 if (FLAG_bpt == NULL) {
327 FLAG_bpt = "main";
328 }
329 String& cname = String::Handle();
330 String& fname = String::Handle();
331 const char* dot = strchr(FLAG_bpt, '.');
332 if (dot == NULL) {
333 fname = String::New(FLAG_bpt);
334 } else {
335 fname = String::New(dot + 1);
336 cname = String::New(reinterpret_cast<const uint8_t*>(FLAG_bpt),
337 dot - FLAG_bpt);
338 }
339 SetBreakpointHandler(DefaultBreakpointHandler); 323 SetBreakpointHandler(DefaultBreakpointHandler);
340 SetBreakpointAtEntry(cname, fname);
341 } 324 }
342 325
343 326
344 Breakpoint* Debugger::GetBreakpoint(uword breakpoint_address) { 327 Breakpoint* Debugger::GetBreakpoint(uword breakpoint_address) {
345 Breakpoint* bpt = this->breakpoints_; 328 Breakpoint* bpt = this->breakpoints_;
346 while (bpt != NULL) { 329 while (bpt != NULL) {
347 if (bpt->pc() == breakpoint_address) { 330 if (bpt->pc() == breakpoint_address) {
348 return bpt; 331 return bpt;
349 } 332 }
350 bpt = bpt->next(); 333 bpt = bpt->next();
351 } 334 }
352 return NULL; 335 return NULL;
353 } 336 }
354 337
355 338
356 void Debugger::AddBreakpoint(Breakpoint* bpt) { 339 void Debugger::AddBreakpoint(Breakpoint* bpt) {
357 ASSERT(bpt->next() == NULL); 340 ASSERT(bpt->next() == NULL);
358 bpt->set_next(this->breakpoints_); 341 bpt->set_next(this->breakpoints_);
359 this->breakpoints_ = bpt; 342 this->breakpoints_ = bpt;
360 } 343 }
361 344
362 345
363 } // namespace dart 346 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698