| Index: runtime/vm/dart_api_impl_test.cc
|
| diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
|
| index a177a486e722953aede61631b9dd4e74b5d61444..cb7e97c4f067e4f106ecd472f8938c7c34c8225e 100644
|
| --- a/runtime/vm/dart_api_impl_test.cc
|
| +++ b/runtime/vm/dart_api_impl_test.cc
|
| @@ -62,6 +62,336 @@ TEST_CASE(ErrorHandleBasics) {
|
| }
|
|
|
|
|
| +TEST_CASE(StacktraceInfo) {
|
| + const char* kScriptChars =
|
| + "bar() => throw new Error();\n"
|
| + "foo() => bar();\n"
|
| + "testMain() => foo();\n";
|
| +
|
| + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
| + Dart_Handle error = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
|
| +
|
| + EXPECT(Dart_IsError(error));
|
| +
|
| + Dart_StackTrace stacktrace;
|
| + Dart_Handle result = Dart_GetStackTraceFromError(error, &stacktrace);
|
| + EXPECT_VALID(result);
|
| +
|
| + intptr_t frame_count = 0;
|
| + result = Dart_StackTraceLength(stacktrace, &frame_count);
|
| + EXPECT_VALID(result);
|
| + EXPECT_EQ(3, frame_count);
|
| +
|
| + Dart_Handle function_name;
|
| + Dart_Handle script_url;
|
| + intptr_t line_number = 0;
|
| + intptr_t column_number = 0;
|
| + const char* cstr = "";
|
| +
|
| + Dart_ActivationFrame frame;
|
| + result = Dart_GetActivationFrame(stacktrace, 0, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("bar", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(1, line_number);
|
| + EXPECT_EQ(10, column_number);
|
| +
|
| + result = Dart_GetActivationFrame(stacktrace, 1, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("foo", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(2, line_number);
|
| + EXPECT_EQ(13, column_number);
|
| +
|
| + result = Dart_GetActivationFrame(stacktrace, 2, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("testMain", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(3, line_number);
|
| + EXPECT_EQ(18, column_number);
|
| +
|
| + // Out-of-bounds frames.
|
| + result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| + result = Dart_GetActivationFrame(stacktrace, -1, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| +}
|
| +
|
| +
|
| +TEST_CASE(DeepStacktraceInfo) {
|
| + const char* kScriptChars =
|
| + "foo(n) => n == 1 ? throw new Error() : foo(n-1);\n"
|
| + "testMain() => foo(50);\n";
|
| +
|
| + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
| + Dart_Handle error = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
|
| +
|
| + EXPECT(Dart_IsError(error));
|
| +
|
| + Dart_StackTrace stacktrace;
|
| + Dart_Handle result = Dart_GetStackTraceFromError(error, &stacktrace);
|
| + EXPECT_VALID(result);
|
| +
|
| + intptr_t frame_count = 0;
|
| + result = Dart_StackTraceLength(stacktrace, &frame_count);
|
| + EXPECT_VALID(result);
|
| + EXPECT_EQ(51, frame_count);
|
| + // Test something bigger than the preallocated size to verify nothing was
|
| + // truncated.
|
| + EXPECT(51 > Stacktrace::kPreallocatedStackdepth);
|
| +
|
| + Dart_Handle function_name;
|
| + Dart_Handle script_url;
|
| + intptr_t line_number = 0;
|
| + intptr_t column_number = 0;
|
| + const char* cstr = "";
|
| +
|
| + // Top frame at positioned at throw.
|
| + Dart_ActivationFrame frame;
|
| + result = Dart_GetActivationFrame(stacktrace, 0, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("foo", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(1, line_number);
|
| + EXPECT_EQ(20, column_number);
|
| +
|
| + // Middle frames positioned at the recursive call.
|
| + for (intptr_t frame_index = 1;
|
| + frame_index < (frame_count - 1);
|
| + frame_index++) {
|
| + result = Dart_GetActivationFrame(stacktrace, frame_index, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("foo", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(1, line_number);
|
| + EXPECT_EQ(43, column_number);
|
| + }
|
| +
|
| + // Bottom frame positioned at testMain().
|
| + result = Dart_GetActivationFrame(stacktrace, frame_count - 1, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("testMain", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(2, line_number);
|
| + EXPECT_EQ(18, column_number);
|
| +
|
| + // Out-of-bounds frames.
|
| + result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| + result = Dart_GetActivationFrame(stacktrace, -1, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| +}
|
| +
|
| +
|
| +TEST_CASE(StackOverflowStacktraceInfo) {
|
| + const char* kScriptChars =
|
| + "class C {\n"
|
| + " static foo() => foo();\n"
|
| + "}\n"
|
| + "testMain() => C.foo();\n";
|
| +
|
| + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
| + Dart_Handle error = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
|
| +
|
| + EXPECT(Dart_IsError(error));
|
| +
|
| + Dart_StackTrace stacktrace;
|
| + Dart_Handle result = Dart_GetStackTraceFromError(error, &stacktrace);
|
| + EXPECT_VALID(result);
|
| +
|
| + intptr_t frame_count = 0;
|
| + result = Dart_StackTraceLength(stacktrace, &frame_count);
|
| + EXPECT_VALID(result);
|
| + EXPECT_EQ(Stacktrace::kPreallocatedStackdepth - 1, frame_count);
|
| +
|
| + Dart_Handle function_name;
|
| + Dart_Handle script_url;
|
| + intptr_t line_number = 0;
|
| + intptr_t column_number = 0;
|
| + const char* cstr = "";
|
| +
|
| + // Top frame at recursive call.
|
| + Dart_ActivationFrame frame;
|
| + result = Dart_GetActivationFrame(stacktrace, 0, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("C.foo", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(2, line_number);
|
| + EXPECT_EQ(3, column_number);
|
| +
|
| + // Out-of-bounds frames.
|
| + result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| + result = Dart_GetActivationFrame(stacktrace, -1, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| +}
|
| +
|
| +
|
| +TEST_CASE(OutOfMemoryStacktraceInfo) {
|
| + const char* kScriptChars =
|
| + "var number_of_ints = 134000000;\n"
|
| + "testMain() {\n"
|
| + " new List<int>(number_of_ints)\n"
|
| + "}\n";
|
| +
|
| + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
|
| + Dart_Handle error = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
|
| +
|
| + EXPECT(Dart_IsError(error));
|
| +
|
| + Dart_StackTrace stacktrace;
|
| + Dart_Handle result = Dart_GetStackTraceFromError(error, &stacktrace);
|
| + EXPECT(Dart_IsError(result)); // No Stacktrace for OutOfMemory.
|
| +}
|
| +
|
| +
|
| +void CurrentStackTraceNative(Dart_NativeArguments args) {
|
| + Dart_EnterScope();
|
| +
|
| + Dart_StackTrace stacktrace;
|
| + Dart_Handle result = Dart_GetStackTrace(&stacktrace);
|
| + EXPECT_VALID(result);
|
| +
|
| + intptr_t frame_count = 0;
|
| + result = Dart_StackTraceLength(stacktrace, &frame_count);
|
| + EXPECT_VALID(result);
|
| + EXPECT_EQ(52, frame_count);
|
| + // Test something bigger than the preallocated size to verify nothing was
|
| + // truncated.
|
| + EXPECT(52 > Stacktrace::kPreallocatedStackdepth);
|
| +
|
| + Dart_Handle function_name;
|
| + Dart_Handle script_url;
|
| + intptr_t line_number = 0;
|
| + intptr_t column_number = 0;
|
| + const char* cstr = "";
|
| +
|
| + // Top frame is inspectStack().
|
| + Dart_ActivationFrame frame;
|
| + result = Dart_GetActivationFrame(stacktrace, 0, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("inspectStack", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(1, line_number);
|
| + EXPECT_EQ(47, column_number);
|
| +
|
| + // Second frame is foo() positioned at call to inspectStack().
|
| + result = Dart_GetActivationFrame(stacktrace, 1, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("foo", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(2, line_number);
|
| + EXPECT_EQ(32, column_number);
|
| +
|
| + // Middle frames positioned at the recursive call.
|
| + for (intptr_t frame_index = 2;
|
| + frame_index < (frame_count - 1);
|
| + frame_index++) {
|
| + result = Dart_GetActivationFrame(stacktrace, frame_index, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("foo", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(2, line_number);
|
| + EXPECT_EQ(40, column_number);
|
| + }
|
| +
|
| + // Bottom frame positioned at testMain().
|
| + result = Dart_GetActivationFrame(stacktrace, frame_count - 1, &frame);
|
| + EXPECT_VALID(result);
|
| + result = Dart_ActivationFrameInfo(
|
| + frame, &function_name, &script_url, &line_number, &column_number);
|
| + EXPECT_VALID(result);
|
| + Dart_StringToCString(function_name, &cstr);
|
| + EXPECT_STREQ("testMain", cstr);
|
| + Dart_StringToCString(script_url, &cstr);
|
| + EXPECT_STREQ("dart:test-lib", cstr);
|
| + EXPECT_EQ(3, line_number);
|
| + EXPECT_EQ(18, column_number);
|
| +
|
| + // Out-of-bounds frames.
|
| + result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| + result = Dart_GetActivationFrame(stacktrace, -1, &frame);
|
| + EXPECT(Dart_IsError(result));
|
| +
|
| + Dart_SetReturnValue(args, Dart_NewInteger(42));
|
| + Dart_ExitScope();
|
| +}
|
| +
|
| +
|
| +static Dart_NativeFunction CurrentStackTraceNativeLookup(
|
| + Dart_Handle name, int argument_count) {
|
| + return reinterpret_cast<Dart_NativeFunction>(&CurrentStackTraceNative);
|
| +}
|
| +
|
| +
|
| +TEST_CASE(CurrentStacktraceInfo) {
|
| + const char* kScriptChars =
|
| + "inspectStack() native 'CurrentStackTraceNatve';\n"
|
| + "foo(n) => n == 1 ? inspectStack() : foo(n-1);\n"
|
| + "testMain() => foo(50);\n";
|
| +
|
| + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars,
|
| + &CurrentStackTraceNativeLookup);
|
| + Dart_Handle result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
|
| + EXPECT_VALID(result);
|
| + EXPECT(Dart_IsInteger(result));
|
| + int64_t value = 0;
|
| + EXPECT_VALID(Dart_IntegerToInt64(result, &value));
|
| + EXPECT_EQ(42, value);
|
| +}
|
| +
|
| +
|
| TEST_CASE(ErrorHandleTypes) {
|
| Isolate* isolate = Isolate::Current();
|
| const String& compile_message = String::Handle(String::New("CompileError"));
|
|
|