| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 | 303 |
| 304 if (FLAG_steal_breakpoints && event->IsPauseEvent()) { | 304 if (FLAG_steal_breakpoints && event->IsPauseEvent()) { |
| 305 // We allow the embedder's default breakpoint handler to be overridden. | 305 // We allow the embedder's default breakpoint handler to be overridden. |
| 306 isolate_->PauseEventHandler(); | 306 isolate_->PauseEventHandler(); |
| 307 } else if (event_handler_ != NULL) { | 307 } else if (event_handler_ != NULL) { |
| 308 (*event_handler_)(event); | 308 (*event_handler_)(event); |
| 309 } | 309 } |
| 310 | 310 |
| 311 if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) { | 311 if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) { |
| 312 // If we were paused, notify the service that we have resumed. | 312 // If we were paused, notify the service that we have resumed. |
| 313 const Error& error = Error::Handle(zone(), | 313 const Error& error = |
| 314 isolate_->object_store()->sticky_error()); | 314 Error::Handle(isolate_->object_store()->sticky_error()); |
| 315 ASSERT(error.IsNull() || error.IsUnwindError()); | 315 ASSERT(error.IsNull() || error.IsUnwindError()); |
| 316 | 316 |
| 317 // Only send a resume event when the isolate is not unwinding. | 317 // Only send a resume event when the isolate is not unwinding. |
| 318 if (!error.IsUnwindError()) { | 318 if (!error.IsUnwindError()) { |
| 319 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume); | 319 ServiceEvent service_event(event->isolate(), ServiceEvent::kResume); |
| 320 service_event.set_top_frame(event->top_frame()); | 320 service_event.set_top_frame(event->top_frame()); |
| 321 Service::HandleEvent(&service_event); | 321 Service::HandleEvent(&service_event); |
| 322 } | 322 } |
| 323 } | 323 } |
| 324 } | 324 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 "\tisolate: %s\n", isolate_->name()); | 358 "\tisolate: %s\n", isolate_->name()); |
| 359 } | 359 } |
| 360 const String& msg = | 360 const String& msg = |
| 361 String::Handle(String::New("isolate terminated by embedder")); | 361 String::Handle(String::New("isolate terminated by embedder")); |
| 362 return UnwindError::New(msg); | 362 return UnwindError::New(msg); |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 | 365 |
| 366 // If any error occurred while in the debug message loop, return it here. | 366 // If any error occurred while in the debug message loop, return it here. |
| 367 const Error& error = | 367 const Error& error = |
| 368 Error::Handle(zone(), isolate_->object_store()->sticky_error()); | 368 Error::Handle(isolate_->object_store()->sticky_error()); |
| 369 ASSERT(error.IsNull() || error.IsUnwindError()); | 369 ASSERT(error.IsNull() || error.IsUnwindError()); |
| 370 isolate_->object_store()->clear_sticky_error(); | 370 isolate_->object_store()->clear_sticky_error(); |
| 371 return error.raw(); | 371 return error.raw(); |
| 372 } | 372 } |
| 373 | 373 |
| 374 | 374 |
| 375 // The vm service handles breakpoint notifications in a different way | 375 // The vm service handles breakpoint notifications in a different way |
| 376 // than the regular debugger breakpoint notifications. | 376 // than the regular debugger breakpoint notifications. |
| 377 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, | 377 static void SendServiceBreakpointEvent(ServiceEvent::EventKind kind, |
| 378 Breakpoint* bpt) { | 378 Breakpoint* bpt) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 intptr_t token_pos) { | 461 intptr_t token_pos) { |
| 462 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { | 462 if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) { |
| 463 // Check script equality second because it allocates | 463 // Check script equality second because it allocates |
| 464 // handles as a side effect. | 464 // handles as a side effect. |
| 465 return func.script() == script.raw(); | 465 return func.script() == script.raw(); |
| 466 } | 466 } |
| 467 return false; | 467 return false; |
| 468 } | 468 } |
| 469 | 469 |
| 470 | 470 |
| 471 bool Debugger::HasBreakpoint(const Function& func) { | 471 bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { |
| 472 if (!func.HasCode()) { | 472 if (!func.HasCode()) { |
| 473 // If the function is not compiled yet, just check whether there | 473 // If the function is not compiled yet, just check whether there |
| 474 // is a user-defined breakpoint that falls into the token | 474 // is a user-defined breakpoint that falls into the token |
| 475 // range of the function. This may be a false positive: the breakpoint | 475 // range of the function. This may be a false positive: the breakpoint |
| 476 // might be inside a local closure. | 476 // might be inside a local closure. |
| 477 Script& script = Script::Handle(zone()); | 477 Script& script = Script::Handle(zone); |
| 478 BreakpointLocation* sbpt = breakpoint_locations_; | 478 BreakpointLocation* sbpt = breakpoint_locations_; |
| 479 while (sbpt != NULL) { | 479 while (sbpt != NULL) { |
| 480 script = sbpt->script(); | 480 script = sbpt->script(); |
| 481 if (FunctionContains(func, script, sbpt->token_pos())) { | 481 if (FunctionContains(func, script, sbpt->token_pos())) { |
| 482 return true; | 482 return true; |
| 483 } | 483 } |
| 484 sbpt = sbpt->next_; | 484 sbpt = sbpt->next_; |
| 485 } | 485 } |
| 486 return false; | 486 return false; |
| 487 } | 487 } |
| (...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 return stack_trace; | 1513 return stack_trace; |
| 1514 } | 1514 } |
| 1515 | 1515 |
| 1516 | 1516 |
| 1517 ActivationFrame* Debugger::TopDartFrame() const { | 1517 ActivationFrame* Debugger::TopDartFrame() const { |
| 1518 StackFrameIterator iterator(false); | 1518 StackFrameIterator iterator(false); |
| 1519 StackFrame* frame = iterator.NextFrame(); | 1519 StackFrame* frame = iterator.NextFrame(); |
| 1520 while ((frame != NULL) && !frame->IsDartFrame()) { | 1520 while ((frame != NULL) && !frame->IsDartFrame()) { |
| 1521 frame = iterator.NextFrame(); | 1521 frame = iterator.NextFrame(); |
| 1522 } | 1522 } |
| 1523 Code& code = Code::Handle(zone(), frame->LookupDartCode()); | 1523 Code& code = Code::Handle(frame->LookupDartCode()); |
| 1524 ActivationFrame* activation = | 1524 ActivationFrame* activation = |
| 1525 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, | 1525 new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), code, |
| 1526 Object::null_array(), 0); | 1526 Object::null_array(), 0); |
| 1527 return activation; | 1527 return activation; |
| 1528 } | 1528 } |
| 1529 | 1529 |
| 1530 | 1530 |
| 1531 DebuggerStackTrace* Debugger::StackTrace() { | 1531 DebuggerStackTrace* Debugger::StackTrace() { |
| 1532 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); | 1532 return (stack_trace_ != NULL) ? stack_trace_ : CollectStackTrace(); |
| 1533 } | 1533 } |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1860 if (loc->AnyEnabled()) { | 1860 if (loc->AnyEnabled()) { |
| 1861 code_bpt->Enable(); | 1861 code_bpt->Enable(); |
| 1862 } | 1862 } |
| 1863 } | 1863 } |
| 1864 | 1864 |
| 1865 | 1865 |
| 1866 void Debugger::FindCompiledFunctions(const Script& script, | 1866 void Debugger::FindCompiledFunctions(const Script& script, |
| 1867 intptr_t start_pos, | 1867 intptr_t start_pos, |
| 1868 intptr_t end_pos, | 1868 intptr_t end_pos, |
| 1869 GrowableObjectArray* function_list) { | 1869 GrowableObjectArray* function_list) { |
| 1870 Zone* zn = zone(); | 1870 Zone* zone = Thread::Current()->zone(); |
| 1871 Class& cls = Class::Handle(zn); | 1871 Class& cls = Class::Handle(zone); |
| 1872 Array& functions = Array::Handle(zn); | 1872 Array& functions = Array::Handle(zone); |
| 1873 GrowableObjectArray& closures = GrowableObjectArray::Handle(zn); | 1873 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
| 1874 Function& function = Function::Handle(zn); | 1874 Function& function = Function::Handle(zone); |
| 1875 | 1875 |
| 1876 const ClassTable& class_table = *isolate_->class_table(); | 1876 const ClassTable& class_table = *isolate_->class_table(); |
| 1877 const intptr_t num_classes = class_table.NumCids(); | 1877 const intptr_t num_classes = class_table.NumCids(); |
| 1878 for (intptr_t i = 1; i < num_classes; i++) { | 1878 for (intptr_t i = 1; i < num_classes; i++) { |
| 1879 if (class_table.HasValidClassAt(i)) { | 1879 if (class_table.HasValidClassAt(i)) { |
| 1880 cls = class_table.At(i); | 1880 cls = class_table.At(i); |
| 1881 // If the class is not finalized, e.g. if it hasn't been parsed | 1881 // If the class is not finalized, e.g. if it hasn't been parsed |
| 1882 // yet entirely, we can ignore it. If it contains a function with | 1882 // yet entirely, we can ignore it. If it contains a function with |
| 1883 // an unresolved breakpoint, we will detect it if and when the | 1883 // an unresolved breakpoint, we will detect it if and when the |
| 1884 // function gets compiled. | 1884 // function gets compiled. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 if ((func->token_pos() > best_fit->token_pos()) && | 1944 if ((func->token_pos() > best_fit->token_pos()) && |
| 1945 ((func->end_token_pos() <= best_fit->end_token_pos()))) { | 1945 ((func->end_token_pos() <= best_fit->end_token_pos()))) { |
| 1946 *best_fit = func->raw(); | 1946 *best_fit = func->raw(); |
| 1947 } | 1947 } |
| 1948 } | 1948 } |
| 1949 } | 1949 } |
| 1950 | 1950 |
| 1951 | 1951 |
| 1952 RawFunction* Debugger::FindBestFit(const Script& script, | 1952 RawFunction* Debugger::FindBestFit(const Script& script, |
| 1953 intptr_t token_pos) { | 1953 intptr_t token_pos) { |
| 1954 Zone* zn = zone(); | 1954 Zone* zone = Thread::Current()->zone(); |
| 1955 Class& cls = Class::Handle(zn); | 1955 Class& cls = Class::Handle(zone); |
| 1956 Array& functions = Array::Handle(zn); | 1956 Array& functions = Array::Handle(zone); |
| 1957 GrowableObjectArray& closures = GrowableObjectArray::Handle(zn); | 1957 GrowableObjectArray& closures = GrowableObjectArray::Handle(zone); |
| 1958 Function& function = Function::Handle(zn); | 1958 Function& function = Function::Handle(zone); |
| 1959 Function& best_fit = Function::Handle(zn); | 1959 Function& best_fit = Function::Handle(zone); |
| 1960 Error& error = Error::Handle(zn); | 1960 Error& error = Error::Handle(zone); |
| 1961 | 1961 |
| 1962 const ClassTable& class_table = *isolate_->class_table(); | 1962 const ClassTable& class_table = *isolate_->class_table(); |
| 1963 const intptr_t num_classes = class_table.NumCids(); | 1963 const intptr_t num_classes = class_table.NumCids(); |
| 1964 for (intptr_t i = 1; i < num_classes; i++) { | 1964 for (intptr_t i = 1; i < num_classes; i++) { |
| 1965 if (class_table.HasValidClassAt(i)) { | 1965 if (class_table.HasValidClassAt(i)) { |
| 1966 cls = class_table.At(i); | 1966 cls = class_table.At(i); |
| 1967 // Note: if this class has been parsed and finalized already, | 1967 // Note: if this class has been parsed and finalized already, |
| 1968 // we need to check the functions of this class even if | 1968 // we need to check the functions of this class even if |
| 1969 // it is defined in a differenct 'script'. There could | 1969 // it is defined in a differenct 'script'. There could |
| 1970 // be mixin functions from the given script in this class. | 1970 // be mixin functions from the given script in this class. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 } | 2009 } |
| 2010 return best_fit.raw(); | 2010 return best_fit.raw(); |
| 2011 } | 2011 } |
| 2012 | 2012 |
| 2013 | 2013 |
| 2014 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, | 2014 BreakpointLocation* Debugger::SetBreakpoint(const Script& script, |
| 2015 intptr_t token_pos, | 2015 intptr_t token_pos, |
| 2016 intptr_t last_token_pos, | 2016 intptr_t last_token_pos, |
| 2017 intptr_t requested_line, | 2017 intptr_t requested_line, |
| 2018 intptr_t requested_column) { | 2018 intptr_t requested_column) { |
| 2019 Function& func = Function::Handle(zone()); | 2019 Function& func = Function::Handle(); |
| 2020 func = FindBestFit(script, token_pos); | 2020 func = FindBestFit(script, token_pos); |
| 2021 if (func.IsNull()) { | 2021 if (func.IsNull()) { |
| 2022 return NULL; | 2022 return NULL; |
| 2023 } | 2023 } |
| 2024 // There may be more than one function object for a given function | 2024 // There may be more than one function object for a given function |
| 2025 // in source code. There may be implicit closure functions, and | 2025 // in source code. There may be implicit closure functions, and |
| 2026 // there may be copies of mixin functions. Collect all compiled | 2026 // there may be copies of mixin functions. Collect all compiled |
| 2027 // functions whose source code range matches exactly the best fit | 2027 // functions whose source code range matches exactly the best fit |
| 2028 // function we found. | 2028 // function we found. |
| 2029 GrowableObjectArray& functions = | 2029 GrowableObjectArray& functions = |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2201 return loc->AddRepeated(this); | 2201 return loc->AddRepeated(this); |
| 2202 } | 2202 } |
| 2203 return NULL; | 2203 return NULL; |
| 2204 } | 2204 } |
| 2205 | 2205 |
| 2206 | 2206 |
| 2207 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( | 2207 BreakpointLocation* Debugger::BreakpointLocationAtLineCol( |
| 2208 const String& script_url, | 2208 const String& script_url, |
| 2209 intptr_t line_number, | 2209 intptr_t line_number, |
| 2210 intptr_t column_number) { | 2210 intptr_t column_number) { |
| 2211 Library& lib = Library::Handle(zone()); | 2211 Zone* zone = Thread::Current()->zone(); |
| 2212 Script& script = Script::Handle(zone()); | 2212 Library& lib = Library::Handle(zone); |
| 2213 Script& script = Script::Handle(zone); |
| 2213 const GrowableObjectArray& libs = | 2214 const GrowableObjectArray& libs = |
| 2214 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 2215 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
| 2215 const GrowableObjectArray& scripts = | 2216 const GrowableObjectArray& scripts = |
| 2216 GrowableObjectArray::Handle(zone(), GrowableObjectArray::New()); | 2217 GrowableObjectArray::Handle(zone, GrowableObjectArray::New()); |
| 2217 for (intptr_t i = 0; i < libs.Length(); i++) { | 2218 for (intptr_t i = 0; i < libs.Length(); i++) { |
| 2218 lib ^= libs.At(i); | 2219 lib ^= libs.At(i); |
| 2219 script = lib.LookupScript(script_url); | 2220 script = lib.LookupScript(script_url); |
| 2220 if (!script.IsNull()) { | 2221 if (!script.IsNull()) { |
| 2221 scripts.Add(script); | 2222 scripts.Add(script); |
| 2222 } | 2223 } |
| 2223 } | 2224 } |
| 2224 if (scripts.Length() == 0) { | 2225 if (scripts.Length() == 0) { |
| 2225 // No script found with given url. Create a latent breakpoint which | 2226 // No script found with given url. Create a latent breakpoint which |
| 2226 // will be set if the url is loaded later. | 2227 // will be set if the url is loaded later. |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2396 } | 2397 } |
| 2397 return Array::MakeArray(field_list); | 2398 return Array::MakeArray(field_list); |
| 2398 } | 2399 } |
| 2399 | 2400 |
| 2400 | 2401 |
| 2401 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list, | 2402 void Debugger::CollectLibraryFields(const GrowableObjectArray& field_list, |
| 2402 const Library& lib, | 2403 const Library& lib, |
| 2403 const String& prefix, | 2404 const String& prefix, |
| 2404 bool include_private_fields) { | 2405 bool include_private_fields) { |
| 2405 DictionaryIterator it(lib); | 2406 DictionaryIterator it(lib); |
| 2406 Object& entry = Object::Handle(zone()); | 2407 Zone* zone = Thread::Current()->zone(); |
| 2407 Field& field = Field::Handle(zone()); | 2408 Object& entry = Object::Handle(zone); |
| 2408 String& field_name = String::Handle(zone()); | 2409 Field& field = Field::Handle(zone); |
| 2409 PassiveObject& field_value = PassiveObject::Handle(zone()); | 2410 String& field_name = String::Handle(zone); |
| 2411 PassiveObject& field_value = PassiveObject::Handle(zone); |
| 2410 while (it.HasNext()) { | 2412 while (it.HasNext()) { |
| 2411 entry = it.GetNext(); | 2413 entry = it.GetNext(); |
| 2412 if (entry.IsField()) { | 2414 if (entry.IsField()) { |
| 2413 field ^= entry.raw(); | 2415 field ^= entry.raw(); |
| 2414 ASSERT(field.is_static()); | 2416 ASSERT(field.is_static()); |
| 2415 field_name = field.name(); | 2417 field_name = field.name(); |
| 2416 if ((field_name.CharAt(0) == '_') && !include_private_fields) { | 2418 if ((field_name.CharAt(0) == '_') && !include_private_fields) { |
| 2417 // Skip library-private field. | 2419 // Skip library-private field. |
| 2418 continue; | 2420 continue; |
| 2419 } | 2421 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2430 field_name = String::Concat(prefix, field_name); | 2432 field_name = String::Concat(prefix, field_name); |
| 2431 } | 2433 } |
| 2432 field_list.Add(field_name); | 2434 field_list.Add(field_name); |
| 2433 field_list.Add(field_value); | 2435 field_list.Add(field_value); |
| 2434 } | 2436 } |
| 2435 } | 2437 } |
| 2436 } | 2438 } |
| 2437 | 2439 |
| 2438 | 2440 |
| 2439 RawArray* Debugger::GetLibraryFields(const Library& lib) { | 2441 RawArray* Debugger::GetLibraryFields(const Library& lib) { |
| 2442 Zone* zone = Thread::Current()->zone(); |
| 2440 const GrowableObjectArray& field_list = | 2443 const GrowableObjectArray& field_list = |
| 2441 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 2444 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); |
| 2442 CollectLibraryFields(field_list, lib, String::Handle(zone()), true); | 2445 CollectLibraryFields(field_list, lib, String::Handle(zone), true); |
| 2443 return Array::MakeArray(field_list); | 2446 return Array::MakeArray(field_list); |
| 2444 } | 2447 } |
| 2445 | 2448 |
| 2446 | 2449 |
| 2447 RawArray* Debugger::GetGlobalFields(const Library& lib) { | 2450 RawArray* Debugger::GetGlobalFields(const Library& lib) { |
| 2451 Zone* zone = Thread::Current()->zone(); |
| 2448 const GrowableObjectArray& field_list = | 2452 const GrowableObjectArray& field_list = |
| 2449 GrowableObjectArray::Handle(GrowableObjectArray::New(8)); | 2453 GrowableObjectArray::Handle(zone, GrowableObjectArray::New(8)); |
| 2450 String& prefix_name = String::Handle(zone()); | 2454 String& prefix_name = String::Handle(zone); |
| 2451 CollectLibraryFields(field_list, lib, prefix_name, true); | 2455 CollectLibraryFields(field_list, lib, prefix_name, true); |
| 2452 Library& imported = Library::Handle(zone()); | 2456 Library& imported = Library::Handle(zone); |
| 2453 intptr_t num_imports = lib.num_imports(); | 2457 intptr_t num_imports = lib.num_imports(); |
| 2454 for (intptr_t i = 0; i < num_imports; i++) { | 2458 for (intptr_t i = 0; i < num_imports; i++) { |
| 2455 imported = lib.ImportLibraryAt(i); | 2459 imported = lib.ImportLibraryAt(i); |
| 2456 ASSERT(!imported.IsNull()); | 2460 ASSERT(!imported.IsNull()); |
| 2457 CollectLibraryFields(field_list, imported, prefix_name, false); | 2461 CollectLibraryFields(field_list, imported, prefix_name, false); |
| 2458 } | 2462 } |
| 2459 LibraryPrefix& prefix = LibraryPrefix::Handle(zone()); | 2463 LibraryPrefix& prefix = LibraryPrefix::Handle(zone); |
| 2460 LibraryPrefixIterator it(lib); | 2464 LibraryPrefixIterator it(lib); |
| 2461 while (it.HasNext()) { | 2465 while (it.HasNext()) { |
| 2462 prefix = it.GetNext(); | 2466 prefix = it.GetNext(); |
| 2463 prefix_name = prefix.name(); | 2467 prefix_name = prefix.name(); |
| 2464 ASSERT(!prefix_name.IsNull()); | 2468 ASSERT(!prefix_name.IsNull()); |
| 2465 prefix_name = String::Concat(prefix_name, Symbols::Dot()); | 2469 prefix_name = String::Concat(prefix_name, Symbols::Dot()); |
| 2466 for (int32_t i = 0; i < prefix.num_imports(); i++) { | 2470 for (int32_t i = 0; i < prefix.num_imports(); i++) { |
| 2467 imported = prefix.GetLibrary(i); | 2471 imported = prefix.GetLibrary(i); |
| 2468 CollectLibraryFields(field_list, imported, prefix_name, false); | 2472 CollectLibraryFields(field_list, imported, prefix_name, false); |
| 2469 } | 2473 } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2658 } | 2662 } |
| 2659 | 2663 |
| 2660 ASSERT(stack_trace_ == NULL); | 2664 ASSERT(stack_trace_ == NULL); |
| 2661 stack_trace_ = CollectStackTrace(); | 2665 stack_trace_ = CollectStackTrace(); |
| 2662 SignalPausedEvent(frame, NULL); | 2666 SignalPausedEvent(frame, NULL); |
| 2663 HandleSteppingRequest(stack_trace_); | 2667 HandleSteppingRequest(stack_trace_); |
| 2664 stack_trace_ = NULL; | 2668 stack_trace_ = NULL; |
| 2665 | 2669 |
| 2666 // If any error occurred while in the debug message loop, return it here. | 2670 // If any error occurred while in the debug message loop, return it here. |
| 2667 const Error& error = | 2671 const Error& error = |
| 2668 Error::Handle(zone(), isolate_->object_store()->sticky_error()); | 2672 Error::Handle(isolate_->object_store()->sticky_error()); |
| 2669 isolate_->object_store()->clear_sticky_error(); | 2673 isolate_->object_store()->clear_sticky_error(); |
| 2670 return error.raw(); | 2674 return error.raw(); |
| 2671 } | 2675 } |
| 2672 | 2676 |
| 2673 | 2677 |
| 2674 RawError* Debugger::SignalBpReached() { | 2678 RawError* Debugger::SignalBpReached() { |
| 2675 // We ignore this breakpoint when the VM is executing code invoked | 2679 // We ignore this breakpoint when the VM is executing code invoked |
| 2676 // by the debugger to evaluate variables values, or when we see a nested | 2680 // by the debugger to evaluate variables values, or when we see a nested |
| 2677 // breakpoint or exception event. | 2681 // breakpoint or exception event. |
| 2678 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { | 2682 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2747 stack_trace_ = stack_trace; | 2751 stack_trace_ = stack_trace; |
| 2748 SignalPausedEvent(top_frame, bpt_hit); | 2752 SignalPausedEvent(top_frame, bpt_hit); |
| 2749 HandleSteppingRequest(stack_trace_); | 2753 HandleSteppingRequest(stack_trace_); |
| 2750 stack_trace_ = NULL; | 2754 stack_trace_ = NULL; |
| 2751 if (cbpt->IsInternal()) { | 2755 if (cbpt->IsInternal()) { |
| 2752 RemoveInternalBreakpoints(); | 2756 RemoveInternalBreakpoints(); |
| 2753 } | 2757 } |
| 2754 | 2758 |
| 2755 // If any error occurred while in the debug message loop, return it here. | 2759 // If any error occurred while in the debug message loop, return it here. |
| 2756 const Error& error = | 2760 const Error& error = |
| 2757 Error::Handle(zone(), isolate_->object_store()->sticky_error()); | 2761 Error::Handle(isolate_->object_store()->sticky_error()); |
| 2758 isolate_->object_store()->clear_sticky_error(); | 2762 isolate_->object_store()->clear_sticky_error(); |
| 2759 return error.raw(); | 2763 return error.raw(); |
| 2760 } | 2764 } |
| 2761 | 2765 |
| 2762 | 2766 |
| 2763 void Debugger::BreakHere(const String& msg) { | 2767 void Debugger::BreakHere(const String& msg) { |
| 2764 // We ignore this breakpoint when the VM is executing code invoked | 2768 // We ignore this breakpoint when the VM is executing code invoked |
| 2765 // by the debugger to evaluate variables values, or when we see a nested | 2769 // by the debugger to evaluate variables values, or when we see a nested |
| 2766 // breakpoint or exception event. | 2770 // breakpoint or exception event. |
| 2767 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { | 2771 if (ignore_breakpoints_ || IsPaused() || !HasEventHandler()) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2804 if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { | 2808 if (!ServiceIsolate::IsServiceIsolateDescendant(isolate_)) { |
| 2805 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); | 2809 SignalIsolateEvent(DebuggerEvent::kIsolateCreated); |
| 2806 } | 2810 } |
| 2807 } | 2811 } |
| 2808 | 2812 |
| 2809 | 2813 |
| 2810 // Return innermost closure contained in 'function' that contains | 2814 // Return innermost closure contained in 'function' that contains |
| 2811 // the given token position. | 2815 // the given token position. |
| 2812 RawFunction* Debugger::FindInnermostClosure(const Function& function, | 2816 RawFunction* Debugger::FindInnermostClosure(const Function& function, |
| 2813 intptr_t token_pos) { | 2817 intptr_t token_pos) { |
| 2814 const Class& owner = Class::Handle(zone(), function.Owner()); | 2818 const Class& owner = Class::Handle(function.Owner()); |
| 2815 if (owner.closures() == GrowableObjectArray::null()) { | 2819 if (owner.closures() == GrowableObjectArray::null()) { |
| 2816 return Function::null(); | 2820 return Function::null(); |
| 2817 } | 2821 } |
| 2818 // Note that we need to check that the closure is in the same | 2822 // Note that we need to check that the closure is in the same |
| 2819 // script as the outer function. We could have closures originating | 2823 // script as the outer function. We could have closures originating |
| 2820 // in mixin classes whose source code is contained in a different | 2824 // in mixin classes whose source code is contained in a different |
| 2821 // script. | 2825 // script. |
| 2822 const Script& outer_origin = Script::Handle(zone(), function.script()); | 2826 Zone* zone = Thread::Current()->zone(); |
| 2827 const Script& outer_origin = Script::Handle(zone, function.script()); |
| 2823 const GrowableObjectArray& closures = | 2828 const GrowableObjectArray& closures = |
| 2824 GrowableObjectArray::Handle(zone(), owner.closures()); | 2829 GrowableObjectArray::Handle(zone, owner.closures()); |
| 2825 const intptr_t num_closures = closures.Length(); | 2830 const intptr_t num_closures = closures.Length(); |
| 2826 Function& closure = Function::Handle(zone()); | 2831 Function& closure = Function::Handle(zone); |
| 2827 Function& best_fit = Function::Handle(zone()); | 2832 Function& best_fit = Function::Handle(zone); |
| 2828 for (intptr_t i = 0; i < num_closures; i++) { | 2833 for (intptr_t i = 0; i < num_closures; i++) { |
| 2829 closure ^= closures.At(i); | 2834 closure ^= closures.At(i); |
| 2830 if ((function.token_pos() < closure.token_pos()) && | 2835 if ((function.token_pos() < closure.token_pos()) && |
| 2831 (closure.end_token_pos() < function.end_token_pos()) && | 2836 (closure.end_token_pos() < function.end_token_pos()) && |
| 2832 (closure.token_pos() <= token_pos) && | 2837 (closure.token_pos() <= token_pos) && |
| 2833 (token_pos <= closure.end_token_pos()) && | 2838 (token_pos <= closure.end_token_pos()) && |
| 2834 (closure.script() == outer_origin.raw())) { | 2839 (closure.script() == outer_origin.raw())) { |
| 2835 SelectBestFit(&best_fit, &closure); | 2840 SelectBestFit(&best_fit, &closure); |
| 2836 } | 2841 } |
| 2837 } | 2842 } |
| 2838 return best_fit.raw(); | 2843 return best_fit.raw(); |
| 2839 } | 2844 } |
| 2840 | 2845 |
| 2841 | 2846 |
| 2842 void Debugger::NotifyCompilation(const Function& func) { | 2847 void Debugger::NotifyCompilation(const Function& func) { |
| 2843 if (breakpoint_locations_ == NULL) { | 2848 if (breakpoint_locations_ == NULL) { |
| 2844 // Return with minimal overhead if there are no breakpoints. | 2849 // Return with minimal overhead if there are no breakpoints. |
| 2845 return; | 2850 return; |
| 2846 } | 2851 } |
| 2847 if (!func.is_debuggable()) { | 2852 if (!func.is_debuggable()) { |
| 2848 // Nothing to do if the function is not debuggable. If there is | 2853 // Nothing to do if the function is not debuggable. If there is |
| 2849 // a pending breakpoint in an inner function (that is debuggable), | 2854 // a pending breakpoint in an inner function (that is debuggable), |
| 2850 // we'll resolve the breakpoint when the inner function is compiled. | 2855 // we'll resolve the breakpoint when the inner function is compiled. |
| 2851 return; | 2856 return; |
| 2852 } | 2857 } |
| 2853 // Iterate over all source breakpoints to check whether breakpoints | 2858 // Iterate over all source breakpoints to check whether breakpoints |
| 2854 // need to be set in the newly compiled function. | 2859 // need to be set in the newly compiled function. |
| 2855 Script& script = Script::Handle(zone()); | 2860 Zone* zone = Thread::Current()->zone(); |
| 2861 Script& script = Script::Handle(zone); |
| 2856 for (BreakpointLocation* loc = breakpoint_locations_; | 2862 for (BreakpointLocation* loc = breakpoint_locations_; |
| 2857 loc != NULL; | 2863 loc != NULL; |
| 2858 loc = loc->next()) { | 2864 loc = loc->next()) { |
| 2859 script = loc->script(); | 2865 script = loc->script(); |
| 2860 if (FunctionContains(func, script, loc->token_pos())) { | 2866 if (FunctionContains(func, script, loc->token_pos())) { |
| 2861 Function& inner_function = Function::Handle(zone()); | 2867 Function& inner_function = Function::Handle(zone); |
| 2862 inner_function = FindInnermostClosure(func, loc->token_pos()); | 2868 inner_function = FindInnermostClosure(func, loc->token_pos()); |
| 2863 if (!inner_function.IsNull()) { | 2869 if (!inner_function.IsNull()) { |
| 2864 // The local function of a function we just compiled cannot | 2870 // The local function of a function we just compiled cannot |
| 2865 // be compiled already. | 2871 // be compiled already. |
| 2866 ASSERT(!inner_function.HasCode()); | 2872 ASSERT(!inner_function.HasCode()); |
| 2867 if (FLAG_verbose_debug) { | 2873 if (FLAG_verbose_debug) { |
| 2868 OS::Print("Pending BP remains unresolved in inner function '%s'\n", | 2874 OS::Print("Pending BP remains unresolved in inner function '%s'\n", |
| 2869 inner_function.ToFullyQualifiedCString()); | 2875 inner_function.ToFullyQualifiedCString()); |
| 2870 } | 2876 } |
| 2871 continue; | 2877 continue; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2932 } | 2938 } |
| 2933 } | 2939 } |
| 2934 } | 2940 } |
| 2935 | 2941 |
| 2936 | 2942 |
| 2937 void Debugger::NotifyDoneLoading() { | 2943 void Debugger::NotifyDoneLoading() { |
| 2938 if (latent_locations_ == NULL) { | 2944 if (latent_locations_ == NULL) { |
| 2939 // Common, fast path. | 2945 // Common, fast path. |
| 2940 return; | 2946 return; |
| 2941 } | 2947 } |
| 2942 Zone* zn = zone(); | 2948 Zone* zone = Thread::Current()->zone(); |
| 2943 Library& lib = Library::Handle(zn); | 2949 Library& lib = Library::Handle(zone); |
| 2944 Script& script = Script::Handle(zn); | 2950 Script& script = Script::Handle(zone); |
| 2945 String& url = String::Handle(zn); | 2951 String& url = String::Handle(zone); |
| 2946 BreakpointLocation* loc = latent_locations_; | 2952 BreakpointLocation* loc = latent_locations_; |
| 2947 BreakpointLocation* prev_loc = NULL; | 2953 BreakpointLocation* prev_loc = NULL; |
| 2948 const GrowableObjectArray& libs = | 2954 const GrowableObjectArray& libs = |
| 2949 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); | 2955 GrowableObjectArray::Handle(isolate_->object_store()->libraries()); |
| 2950 while (loc != NULL) { | 2956 while (loc != NULL) { |
| 2951 url = loc->url(); | 2957 url = loc->url(); |
| 2952 bool found_match = false; | 2958 bool found_match = false; |
| 2953 for (intptr_t i = 0; i < libs.Length(); i++) { | 2959 for (intptr_t i = 0; i < libs.Length(); i++) { |
| 2954 lib ^= libs.At(i); | 2960 lib ^= libs.At(i); |
| 2955 script = lib.LookupScript(url); | 2961 script = lib.LookupScript(url); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3208 loc = loc->next(); | 3214 loc = loc->next(); |
| 3209 } | 3215 } |
| 3210 return NULL; | 3216 return NULL; |
| 3211 } | 3217 } |
| 3212 | 3218 |
| 3213 | 3219 |
| 3214 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, | 3220 BreakpointLocation* Debugger::GetLatentBreakpoint(const String& url, |
| 3215 intptr_t line, | 3221 intptr_t line, |
| 3216 intptr_t column) { | 3222 intptr_t column) { |
| 3217 BreakpointLocation* bpt = latent_locations_; | 3223 BreakpointLocation* bpt = latent_locations_; |
| 3218 String& bpt_url = String::Handle(zone()); | 3224 String& bpt_url = String::Handle(); |
| 3219 while (bpt != NULL) { | 3225 while (bpt != NULL) { |
| 3220 bpt_url = bpt->url(); | 3226 bpt_url = bpt->url(); |
| 3221 if (bpt_url.Equals(url) && | 3227 if (bpt_url.Equals(url) && |
| 3222 (bpt->requested_line_number() == line) && | 3228 (bpt->requested_line_number() == line) && |
| 3223 (bpt->requested_column_number() == column)) { | 3229 (bpt->requested_column_number() == column)) { |
| 3224 return bpt; | 3230 return bpt; |
| 3225 } | 3231 } |
| 3226 bpt = bpt->next(); | 3232 bpt = bpt->next(); |
| 3227 } | 3233 } |
| 3228 // No breakpoint for this location requested. Allocate new one. | 3234 // No breakpoint for this location requested. Allocate new one. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3240 } | 3246 } |
| 3241 | 3247 |
| 3242 | 3248 |
| 3243 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 3249 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 3244 ASSERT(bpt->next() == NULL); | 3250 ASSERT(bpt->next() == NULL); |
| 3245 bpt->set_next(code_breakpoints_); | 3251 bpt->set_next(code_breakpoints_); |
| 3246 code_breakpoints_ = bpt; | 3252 code_breakpoints_ = bpt; |
| 3247 } | 3253 } |
| 3248 | 3254 |
| 3249 } // namespace dart | 3255 } // namespace dart |
| OLD | NEW |