48c8ffa7f3
This is a cut of the work that Todd and I collaborated on in the reload branch. In this CL, we've dropped the loader port hacks, in other words, on stack reloading in the standalone embedder does not work yet. - [x] Support for hot reloading of isolate source code - [x] Unit test harness and many tests - [x] Service protocol and Observatory support - [x] Product build does not include support for hot reloading. R=rmacnak@google.com Review URL: https://codereview.chromium.org/1965823002 .
145 lines
4.2 KiB
C++
145 lines
4.2 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/dart_api_impl.h"
|
|
#include "vm/debugger.h"
|
|
#include "vm/unit_test.h"
|
|
|
|
namespace dart {
|
|
|
|
#ifndef PRODUCT
|
|
|
|
DECLARE_FLAG(bool, remove_script_timestamps_for_test);
|
|
|
|
// Search for the formatted string in buffer.
|
|
//
|
|
// TODO(turnidge): This function obscures the line number of failing
|
|
// EXPECTs. Rework this.
|
|
static void ExpectSubstringF(const char* buff, const char* fmt, ...) {
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
intptr_t len = OS::VSNPrint(NULL, 0, fmt, args);
|
|
va_end(args);
|
|
|
|
char* buffer = Thread::Current()->zone()->Alloc<char>(len + 1);
|
|
va_list args2;
|
|
va_start(args2, fmt);
|
|
OS::VSNPrint(buffer, (len + 1), fmt, args2);
|
|
va_end(args2);
|
|
|
|
EXPECT_SUBSTRING(buffer, buff);
|
|
}
|
|
|
|
|
|
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";
|
|
SetFlagScope<bool> sfs(&FLAG_remove_script_timestamps_for_test, true);
|
|
Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
|
EXPECT_VALID(lib);
|
|
Library& vmlib = Library::Handle();
|
|
vmlib ^= Api::UnwrapHandle(lib);
|
|
EXPECT(!vmlib.IsNull());
|
|
|
|
Isolate* isolate = Isolate::Current();
|
|
Debugger* debugger = isolate->debugger();
|
|
|
|
// Empty case.
|
|
{
|
|
JSONStream js;
|
|
{
|
|
JSONArray jsarr(&js);
|
|
debugger->PrintBreakpointsToJSONArray(&jsarr);
|
|
}
|
|
EXPECT_STREQ("[]", js.ToCString());
|
|
}
|
|
|
|
// Test with a couple of breakpoints.
|
|
Dart_Handle url = NewString(TestCase::url());
|
|
EXPECT_VALID(Dart_SetBreakpoint(url, 2));
|
|
EXPECT_VALID(Dart_SetBreakpoint(url, 3));
|
|
{
|
|
JSONStream js;
|
|
{
|
|
JSONArray jsarr(&js);
|
|
debugger->PrintBreakpointsToJSONArray(&jsarr);
|
|
}
|
|
ExpectSubstringF(
|
|
js.ToCString(),
|
|
"[{\"type\":\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/2\","
|
|
"\"breakpointNumber\":2,\"resolved\":false,"
|
|
"\"location\":{\"type\":\"UnresolvedSourceLocation\","
|
|
"\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
|
|
"\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\\/0\","
|
|
"\"uri\":\"test-lib\","
|
|
"\"_kind\":\"script\"},\"line\":3}},"
|
|
"{\"type\":\"Breakpoint\",\"fixedId\":true,\"id\":\"breakpoints\\/1\","
|
|
"\"breakpointNumber\":1,\"resolved\":false,"
|
|
"\"location\":{\"type\":\"UnresolvedSourceLocation\","
|
|
"\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
|
|
"\"id\":\"libraries\\/%" Pd "\\/scripts\\/test-lib\\/0\","
|
|
"\"uri\":\"test-lib\","
|
|
"\"_kind\":\"script\"},\"line\":2}}]",
|
|
vmlib.index(), vmlib.index());
|
|
}
|
|
}
|
|
|
|
|
|
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 ServiceEvent* event = debugger->PauseEvent();
|
|
EXPECT(event != NULL);
|
|
EXPECT(event->kind() == ServiceEvent::kPauseBreakpoint);
|
|
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();
|
|
|
|
// No pause event.
|
|
EXPECT(!debugger->IsPaused());
|
|
EXPECT(debugger->PauseEvent() == NULL);
|
|
|
|
saw_paused_event = false;
|
|
Dart_SetPausedEventHandler(InspectPausedEvent);
|
|
|
|
// Set a breakpoint and run.
|
|
EXPECT_VALID(Dart_SetBreakpoint(NewString(TestCase::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);
|
|
}
|
|
|
|
#endif // !PRODUCT
|
|
|
|
} // namespace dart
|