15e8f121dd
- Identify a source breakpoint by a script and a token position rather than a function object. - When a new breakpoint is set, iterate over all compiled functions to see whether code breakpoints must be set. This change fixes issues with functions that get compiled several times, for example as implicit closures or a copies of mixin functions or local closures of mixing functions. We did not detect all duplicates of functions. Eliminated recently introduced const modifiers in SourceBreakpoint class. They tend to be in the way because several accessor methods of SourceBreakpoint compute data lazily and modify the object as a side effect. Review URL: https://codereview.chromium.org//117133005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@31372 260f80e4-7a28-3924-810f-c04153c831b5
110 lines
3.1 KiB
C++
110 lines
3.1 KiB
C++
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "vm/debugger.h"
|
|
#include "vm/unit_test.h"
|
|
|
|
namespace dart {
|
|
|
|
TEST_CASE(Debugger_PrintBreakpointsToJSONArray) {
|
|
const char* kScriptChars =
|
|
"main() {\n"
|
|
" var x = new StringBuffer();\n"
|
|
" x.add('won');\n"
|
|
" x.add('too');\n"
|
|
" return x.toString();\n"
|
|
"}\n";
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
EXPECT_VALID(lib);
|
|
|
|
Isolate* isolate = Isolate::Current();
|
|
Debugger* debugger = isolate->debugger();
|
|
const String& url = String::Handle(String::New(TestCase::url()));
|
|
|
|
// Empty case.
|
|
{
|
|
JSONStream js;
|
|
{
|
|
JSONArray jsarr(&js);
|
|
debugger->PrintBreakpointsToJSONArray(&jsarr);
|
|
}
|
|
EXPECT_STREQ("[]", js.ToCString());
|
|
}
|
|
|
|
// Test with a couple of breakpoints.
|
|
debugger->SetBreakpointAtLine(url, 2);
|
|
debugger->SetBreakpointAtLine(url, 3);
|
|
{
|
|
JSONStream js;
|
|
{
|
|
JSONArray jsarr(&js);
|
|
debugger->PrintBreakpointsToJSONArray(&jsarr);
|
|
}
|
|
EXPECT_STREQ(
|
|
"[{\"type\":\"Breakpoint\",\"id\":2,"
|
|
"\"enabled\":true,\"resolved\":false,"
|
|
"\"location\":{\"type\":\"Location\","
|
|
"\"script\":\"dart:test-lib\",\"tokenPos\":14}},"
|
|
"{\"type\":\"Breakpoint\",\"id\":1,"
|
|
"\"enabled\":true,\"resolved\":false,"
|
|
"\"location\":{\"type\":\"Location\","
|
|
"\"script\":\"dart:test-lib\",\"tokenPos\":5}}]",
|
|
js.ToCString());
|
|
}
|
|
}
|
|
|
|
|
|
static bool saw_paused_event = false;
|
|
|
|
static void InspectPausedEvent(Dart_IsolateId isolate_id,
|
|
intptr_t bp_id,
|
|
const Dart_CodeLocation& loc) {
|
|
Isolate* isolate = Isolate::Current();
|
|
Debugger* debugger = isolate->debugger();
|
|
|
|
// The debugger knows that it is paused, and why.
|
|
EXPECT(debugger->IsPaused());
|
|
const Debugger::DebuggerEvent* event = debugger->PauseEvent();
|
|
EXPECT(event != NULL);
|
|
EXPECT(event->type == Debugger::kBreakpointReached);
|
|
saw_paused_event = true;
|
|
}
|
|
|
|
|
|
TEST_CASE(Debugger_PauseEvent) {
|
|
const char* kScriptChars =
|
|
"main() {\n"
|
|
" var x = new StringBuffer();\n"
|
|
" x.write('won');\n"
|
|
" x.write('too');\n"
|
|
" return x.toString();\n"
|
|
"}\n";
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
EXPECT_VALID(lib);
|
|
|
|
Isolate* isolate = Isolate::Current();
|
|
Debugger* debugger = isolate->debugger();
|
|
const String& url = String::Handle(String::New(TestCase::url()));
|
|
|
|
// No pause event.
|
|
EXPECT(!debugger->IsPaused());
|
|
EXPECT(debugger->PauseEvent() == NULL);
|
|
|
|
saw_paused_event = false;
|
|
Dart_SetPausedEventHandler(InspectPausedEvent);
|
|
|
|
// Set a breakpoint and run.
|
|
debugger->SetBreakpointAtLine(url, 2);
|
|
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
|
|
EXPECT_VALID(result);
|
|
EXPECT(Dart_IsString(result));
|
|
|
|
// We ran the code in InspectPausedEvent.
|
|
EXPECT(saw_paused_event);
|
|
}
|
|
|
|
|
|
|
|
} // namespace dart
|