Chromium Code Reviews| 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 "include/dart_debugger_api.h" | 5 #include "include/dart_debugger_api.h" |
| 6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
| 7 #include "vm/dart_api_impl.h" | |
| 7 #include "vm/unit_test.h" | 8 #include "vm/unit_test.h" |
| 8 | 9 |
| 9 namespace dart { | 10 namespace dart { |
| 10 | 11 |
| 11 // Only ia32 and x64 can run execution tests. | 12 // Only ia32 and x64 can run execution tests. |
| 12 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) | 13 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) |
| 13 | 14 |
| 14 static bool breakpoint_hit = false; | 15 static bool breakpoint_hit = false; |
| 16 static int breakpoint_hit_counter = 0; | |
| 15 | 17 |
| 16 static const bool verbose = false; | 18 static const bool verbose = false; |
| 17 | 19 |
| 18 #define EXPECT_NOT_ERROR(handle) \ | 20 #define EXPECT_NOT_ERROR(handle) \ |
| 19 if (Dart_IsError(handle)) { \ | 21 if (Dart_IsError(handle)) { \ |
| 20 OS::Print("Error: %s\n", Dart_GetError(handle)); \ | 22 OS::Print("Error: %s\n", Dart_GetError(handle)); \ |
| 21 } \ | 23 } \ |
| 22 EXPECT(!Dart_IsError(handle)); | 24 EXPECT(!Dart_IsError(handle)); |
| 23 | 25 |
| 24 | 26 |
| 25 void TestBreakpointHandler(Dart_Breakpoint bpt, Dart_StackTrace trace) { | 27 void TestBreakpointHandler(Dart_Breakpoint bpt, Dart_StackTrace trace) { |
| 26 const char* expected_trace[] = {"A.foo", "main"}; | 28 const char* expected_trace[] = {"A.foo", "main"}; |
| 27 const intptr_t expected_trace_length = 2; | 29 const intptr_t expected_trace_length = 2; |
| 28 breakpoint_hit = true; | 30 breakpoint_hit = true; |
| 31 breakpoint_hit_counter++; | |
| 29 intptr_t trace_len; | 32 intptr_t trace_len; |
| 30 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); | 33 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); |
| 31 EXPECT_NOT_ERROR(res); | 34 EXPECT_NOT_ERROR(res); |
| 32 EXPECT_EQ(expected_trace_length, trace_len); | 35 EXPECT_EQ(expected_trace_length, trace_len); |
| 33 for (int i = 0; i < trace_len; i++) { | 36 for (int i = 0; i < trace_len; i++) { |
| 34 Dart_ActivationFrame frame; | 37 Dart_ActivationFrame frame; |
| 35 res = Dart_GetActivationFrame(trace, i, &frame); | 38 res = Dart_GetActivationFrame(trace, i, &frame); |
| 36 EXPECT_NOT_ERROR(res); | 39 EXPECT_NOT_ERROR(res); |
| 37 Dart_Handle func_name; | 40 Dart_Handle func_name; |
| 38 res = Dart_ActivationFrameInfo(frame, &func_name, NULL, NULL); | 41 res = Dart_ActivationFrameInfo(frame, &func_name, NULL, NULL); |
| 39 EXPECT_NOT_ERROR(res); | 42 EXPECT_NOT_ERROR(res); |
| 40 EXPECT(Dart_IsString(func_name)); | 43 EXPECT(Dart_IsString(func_name)); |
| 41 const char* name_chars; | 44 const char* name_chars; |
| 42 Dart_StringToCString(func_name, &name_chars); | 45 Dart_StringToCString(func_name, &name_chars); |
| 43 EXPECT_STREQ(expected_trace[i], name_chars); | 46 EXPECT_STREQ(expected_trace[i], name_chars); |
| 44 if (verbose) printf(" >> %d: %s\n", i, name_chars); | 47 if (verbose) printf(" >> %d: %s\n", i, name_chars); |
| 45 } | 48 } |
| 46 } | 49 } |
| 47 | 50 |
| 48 | 51 |
| 49 UNIT_TEST_CASE(Breakpoint) { | 52 TEST_CASE(Debug_Breakpoint) { |
| 50 const char* kScriptChars = | 53 const char* kScriptChars = |
| 51 "void moo(s) { }\n" | 54 "void moo(s) { }\n" |
| 52 "class A {\n" | 55 "class A {\n" |
| 53 " static void foo() {\n" | 56 " static void foo() {\n" |
| 54 " moo('good news');\n" | 57 " moo('good news');\n" |
| 55 " }\n" | 58 " }\n" |
| 56 "}\n" | 59 "}\n" |
| 57 "void main() {\n" | 60 "void main() {\n" |
| 58 " A.foo();\n" | 61 " A.foo();\n" |
| 59 "}\n"; | 62 "}\n"; |
| 60 | 63 |
| 61 TestIsolateScope __test_isolate__; | |
| 62 | |
| 63 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 64 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 64 EXPECT(!Dart_IsError(lib)); | 65 EXPECT(!Dart_IsError(lib)); |
| 65 | 66 |
| 66 Dart_SetBreakpointHandler(&TestBreakpointHandler); | 67 Dart_SetBreakpointHandler(&TestBreakpointHandler); |
| 67 | 68 |
| 68 Dart_Handle c_name = Dart_NewString("A"); | 69 Dart_Handle c_name = Dart_NewString("A"); |
| 69 Dart_Handle f_name = Dart_NewString("foo"); | 70 Dart_Handle f_name = Dart_NewString("foo"); |
| 70 Dart_Breakpoint bpt; | 71 Dart_Breakpoint bpt; |
| 71 Dart_Handle res = Dart_SetBreakpointAtEntry(lib, c_name, f_name, &bpt); | 72 Dart_Handle res = Dart_SetBreakpointAtEntry(lib, c_name, f_name, &bpt); |
| 72 EXPECT_NOT_ERROR(res); | 73 EXPECT_NOT_ERROR(res); |
| 73 | 74 |
| 74 breakpoint_hit = false; | 75 breakpoint_hit = false; |
| 75 Dart_Handle retval = Dart_InvokeStatic(lib, | 76 Dart_Handle retval = Dart_InvokeStatic(lib, |
| 76 Dart_NewString(""), | 77 Dart_NewString(""), |
| 77 Dart_NewString("main"), | 78 Dart_NewString("main"), |
| 78 0, | 79 0, |
| 79 NULL); | 80 NULL); |
| 80 EXPECT(!Dart_IsError(retval)); | 81 EXPECT(!Dart_IsError(retval)); |
| 81 EXPECT(breakpoint_hit == true); | 82 EXPECT(breakpoint_hit == true); |
| 82 } | 83 } |
| 83 | 84 |
| 85 | |
| 86 static void DeleteBreakpointHandler(Dart_Breakpoint bpt, | |
| 87 Dart_StackTrace trace) { | |
| 88 const char* expected_trace[] = {"foo", "main"}; | |
| 89 const intptr_t expected_trace_length = 2; | |
| 90 breakpoint_hit = true; | |
|
siva
2012/01/20 21:26:29
Is this setting needed?
hausner
2012/01/20 22:20:32
No, not really. Removed.
| |
| 91 breakpoint_hit_counter++; | |
| 92 intptr_t trace_len; | |
| 93 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); | |
| 94 EXPECT_NOT_ERROR(res); | |
| 95 EXPECT_EQ(expected_trace_length, trace_len); | |
| 96 for (int i = 0; i < trace_len; i++) { | |
| 97 Dart_ActivationFrame frame; | |
| 98 res = Dart_GetActivationFrame(trace, i, &frame); | |
| 99 EXPECT_NOT_ERROR(res); | |
| 100 Dart_Handle func_name; | |
| 101 res = Dart_ActivationFrameInfo(frame, &func_name, NULL, NULL); | |
| 102 EXPECT_NOT_ERROR(res); | |
| 103 EXPECT(Dart_IsString(func_name)); | |
| 104 const char* name_chars; | |
| 105 Dart_StringToCString(func_name, &name_chars); | |
| 106 EXPECT_STREQ(expected_trace[i], name_chars); | |
| 107 if (verbose) printf(" >> %d: %s\n", i, name_chars); | |
| 108 } | |
| 109 // Remove the breakpoint after we've hit it twice | |
| 110 if (breakpoint_hit_counter == 2) { | |
| 111 if (verbose) printf("uninstalling breakpoint\n"); | |
| 112 Dart_Handle res = Dart_DeleteBreakpoint(bpt); | |
| 113 EXPECT_NOT_ERROR(res); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 | |
| 118 TEST_CASE(Debug_DeleteBreakpoint) { | |
| 119 const char* kScriptChars = | |
| 120 "moo(s) { }\n" | |
| 121 "\n" | |
| 122 "foo() {\n" | |
| 123 " moo('good news');\n" | |
| 124 "}\n" | |
| 125 "\n" | |
| 126 "void main() {\n" | |
| 127 " foo();\n" | |
| 128 " foo();\n" | |
| 129 " foo();\n" | |
| 130 "}\n"; | |
| 131 | |
| 132 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | |
| 133 EXPECT(!Dart_IsError(lib)); | |
| 134 | |
| 135 Dart_Handle script_url = Dart_NewString(TestCase::url()); | |
| 136 Dart_Handle line_no = Dart_NewInteger(4); // In function 'foo'. | |
| 137 | |
| 138 Dart_SetBreakpointHandler(&DeleteBreakpointHandler); | |
| 139 | |
| 140 Dart_Breakpoint bpt; | |
| 141 Dart_Handle res = Dart_SetBreakpointAtLine(script_url, line_no, &bpt); | |
| 142 EXPECT_NOT_ERROR(res); | |
| 143 | |
| 144 // Function main() calls foo() 3 times. On the second iteration, the | |
| 145 // breakpoint is removed by the handler, so we excpect the breakpoint | |
|
siva
2012/01/20 21:26:29
expect
hausner
2012/01/20 22:20:32
Done.
| |
| 146 // to fire twice only. | |
| 147 breakpoint_hit_counter = 0; | |
| 148 Dart_Handle retval = Dart_InvokeStatic(lib, | |
| 149 Dart_NewString(""), | |
| 150 Dart_NewString("main"), | |
| 151 0, | |
| 152 NULL); | |
| 153 EXPECT(!Dart_IsError(retval)); | |
| 154 EXPECT(breakpoint_hit_counter == 2); | |
| 155 } | |
| 156 | |
| 157 | |
| 158 TEST_CASE(Debug_LookupSourceLine) { | |
| 159 const char* kScriptChars = | |
| 160 /*1*/ "class A {\n" | |
| 161 /*2*/ " static void foo() {\n" | |
| 162 /*3*/ " moo('good news');\n" | |
| 163 /*4*/ " }\n" | |
| 164 /*5*/ "}\n" | |
| 165 /*6*/ "\n" | |
| 166 /*7*/ "void main() {\n" | |
| 167 /*8*/ " A.foo();\n" | |
| 168 /*9*/ "}\n" | |
| 169 /*10*/ "\n"; | |
| 170 | |
| 171 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | |
| 172 EXPECT(!Dart_IsError(lib)); | |
| 173 | |
| 174 const Library& test_lib = Library::CheckedHandle(Api::UnwrapHandle(lib)); | |
| 175 const String& script_url = String::Handle(String::New(TestCase::url())); | |
| 176 Function& func = Function::Handle(); | |
| 177 | |
| 178 // TODO(hausner): Looking up functions from source and line number | |
| 179 // needs to be refined. We currently dont find "main" on line 7. | |
| 180 for (int line = 8; line <= 9; line++) { | |
| 181 func = test_lib.LookupFunctionInSource(script_url, line); | |
| 182 EXPECT(!func.IsNull()); | |
| 183 EXPECT_STREQ("main", String::Handle(func.name()).ToCString()); | |
| 184 } | |
| 185 | |
| 186 func = test_lib.LookupFunctionInSource(script_url, 3); | |
| 187 EXPECT(!func.IsNull()); | |
| 188 EXPECT_STREQ("foo", String::Handle(func.name()).ToCString()); | |
| 189 | |
| 190 func = test_lib.LookupFunctionInSource(script_url, 1); | |
| 191 EXPECT(func.IsNull()); | |
| 192 func = test_lib.LookupFunctionInSource(script_url, 6); | |
| 193 EXPECT(func.IsNull()); | |
| 194 func = test_lib.LookupFunctionInSource(script_url, 10); | |
| 195 EXPECT(func.IsNull()); | |
| 196 } | |
| 197 | |
| 84 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). | 198 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). |
| 85 | 199 |
| 86 } // namespace dart | 200 } // namespace dart |
| OLD | NEW |