| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // Size of temp buffer for formatting small strings. | 66 // Size of temp buffer for formatting small strings. |
| 67 #define SMALL_STRING_BUFFER_SIZE 80 | 67 #define SMALL_STRING_BUFFER_SIZE 80 |
| 68 | 68 |
| 69 // --- H e l p e r C l a s s e s | 69 // --- H e l p e r C l a s s e s |
| 70 | 70 |
| 71 | 71 |
| 72 // Helper class for creating a V8 enviromnent for running tests | 72 // Helper class for creating a V8 enviromnent for running tests |
| 73 class DebugLocalContext { | 73 class DebugLocalContext { |
| 74 public: | 74 public: |
| 75 inline DebugLocalContext( | 75 inline DebugLocalContext( |
| 76 v8::Isolate* isolate, v8::ExtensionConfiguration* extensions = 0, | |
| 77 v8::Handle<v8::ObjectTemplate> global_template = | |
| 78 v8::Handle<v8::ObjectTemplate>(), | |
| 79 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) | |
| 80 : scope_(isolate), | |
| 81 context_(v8::Context::New(isolate, extensions, global_template, | |
| 82 global_object)) { | |
| 83 context_->Enter(); | |
| 84 } | |
| 85 inline DebugLocalContext( | |
| 86 v8::ExtensionConfiguration* extensions = 0, | 76 v8::ExtensionConfiguration* extensions = 0, |
| 87 v8::Handle<v8::ObjectTemplate> global_template = | 77 v8::Handle<v8::ObjectTemplate> global_template = |
| 88 v8::Handle<v8::ObjectTemplate>(), | 78 v8::Handle<v8::ObjectTemplate>(), |
| 89 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) | 79 v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) |
| 90 : scope_(CcTest::isolate()), | 80 : scope_(CcTest::isolate()), |
| 91 context_(v8::Context::New(CcTest::isolate(), extensions, | 81 context_( |
| 92 global_template, global_object)) { | 82 v8::Context::New(CcTest::isolate(), |
| 83 extensions, |
| 84 global_template, |
| 85 global_object)) { |
| 93 context_->Enter(); | 86 context_->Enter(); |
| 94 } | 87 } |
| 95 inline ~DebugLocalContext() { | 88 inline ~DebugLocalContext() { |
| 96 context_->Exit(); | 89 context_->Exit(); |
| 97 } | 90 } |
| 98 inline v8::Local<v8::Context> context() { return context_; } | 91 inline v8::Local<v8::Context> context() { return context_; } |
| 99 inline v8::Context* operator->() { return *context_; } | 92 inline v8::Context* operator->() { return *context_; } |
| 100 inline v8::Context* operator*() { return *context_; } | 93 inline v8::Context* operator*() { return *context_; } |
| 101 inline v8::Isolate* GetIsolate() { return context_->GetIsolate(); } | 94 inline v8::Isolate* GetIsolate() { return context_->GetIsolate(); } |
| 102 inline bool IsReady() { return !context_.IsEmpty(); } | 95 inline bool IsReady() { return !context_.IsEmpty(); } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 return v8::Local<v8::Function>::Cast((*env)->Global()->Get( | 130 return v8::Local<v8::Function>::Cast((*env)->Global()->Get( |
| 138 v8::String::NewFromUtf8(env->GetIsolate(), function_name))); | 131 v8::String::NewFromUtf8(env->GetIsolate(), function_name))); |
| 139 } | 132 } |
| 140 | 133 |
| 141 | 134 |
| 142 // Compile and run the supplied source and return the requested function. | 135 // Compile and run the supplied source and return the requested function. |
| 143 static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, | 136 static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, |
| 144 const char* source, | 137 const char* source, |
| 145 const char* function_name) { | 138 const char* function_name) { |
| 146 v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run(); | 139 v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run(); |
| 147 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); | 140 v8::Local<v8::Object> global = |
| 141 CcTest::isolate()->GetCurrentContext()->Global(); |
| 148 return v8::Local<v8::Function>::Cast( | 142 return v8::Local<v8::Function>::Cast( |
| 149 global->Get(v8::String::NewFromUtf8(isolate, function_name))); | 143 global->Get(v8::String::NewFromUtf8(isolate, function_name))); |
| 150 } | 144 } |
| 151 | 145 |
| 152 | 146 |
| 153 // Is there any debug info for the function? | 147 // Is there any debug info for the function? |
| 154 static bool HasDebugInfo(v8::Handle<v8::Function> fun) { | 148 static bool HasDebugInfo(v8::Handle<v8::Function> fun) { |
| 155 Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); | 149 Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); |
| 156 Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); | 150 Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); |
| 157 return Debug::HasDebugInfo(shared); | 151 return Debug::HasDebugInfo(shared); |
| (...skipping 4996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5154 * debugger thread. It then changes the value of a | 5148 * debugger thread. It then changes the value of a |
| 5155 * global object, to make the loop terminate. | 5149 * global object, to make the loop terminate. |
| 5156 */ | 5150 */ |
| 5157 | 5151 |
| 5158 Barriers threaded_debugging_barriers; | 5152 Barriers threaded_debugging_barriers; |
| 5159 | 5153 |
| 5160 class V8Thread : public v8::base::Thread { | 5154 class V8Thread : public v8::base::Thread { |
| 5161 public: | 5155 public: |
| 5162 V8Thread() : Thread(Options("V8Thread")) {} | 5156 V8Thread() : Thread(Options("V8Thread")) {} |
| 5163 void Run(); | 5157 void Run(); |
| 5164 v8::Isolate* isolate() { return isolate_; } | |
| 5165 | |
| 5166 private: | |
| 5167 v8::Isolate* isolate_; | |
| 5168 }; | 5158 }; |
| 5169 | 5159 |
| 5170 class DebuggerThread : public v8::base::Thread { | 5160 class DebuggerThread : public v8::base::Thread { |
| 5171 public: | 5161 public: |
| 5172 explicit DebuggerThread(v8::Isolate* isolate) | 5162 DebuggerThread() : Thread(Options("DebuggerThread")) {} |
| 5173 : Thread(Options("DebuggerThread")), isolate_(isolate) {} | |
| 5174 void Run(); | 5163 void Run(); |
| 5175 | |
| 5176 private: | |
| 5177 v8::Isolate* isolate_; | |
| 5178 }; | 5164 }; |
| 5179 | 5165 |
| 5180 | 5166 |
| 5181 static void ThreadedAtBarrier1( | 5167 static void ThreadedAtBarrier1( |
| 5182 const v8::FunctionCallbackInfo<v8::Value>& args) { | 5168 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 5183 threaded_debugging_barriers.barrier_1.Wait(); | 5169 threaded_debugging_barriers.barrier_1.Wait(); |
| 5184 } | 5170 } |
| 5185 | 5171 |
| 5186 | 5172 |
| 5187 static void ThreadedMessageHandler(const v8::Debug::Message& message) { | 5173 static void ThreadedMessageHandler(const v8::Debug::Message& message) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5210 " while ( flag == true ) {\n" | 5196 " while ( flag == true ) {\n" |
| 5211 " if ( x == 1 ) {\n" | 5197 " if ( x == 1 ) {\n" |
| 5212 " ThreadedAtBarrier1();\n" | 5198 " ThreadedAtBarrier1();\n" |
| 5213 " }\n" | 5199 " }\n" |
| 5214 " x = x + 1;\n" | 5200 " x = x + 1;\n" |
| 5215 " }\n" | 5201 " }\n" |
| 5216 "}\n" | 5202 "}\n" |
| 5217 "\n" | 5203 "\n" |
| 5218 "foo();\n"; | 5204 "foo();\n"; |
| 5219 | 5205 |
| 5220 isolate_ = v8::Isolate::New(); | 5206 v8::Isolate* isolate = CcTest::isolate(); |
| 5221 threaded_debugging_barriers.barrier_3.Wait(); | 5207 v8::Isolate::Scope isolate_scope(isolate); |
| 5222 { | 5208 DebugLocalContext env; |
| 5223 v8::Isolate::Scope isolate_scope(isolate_); | 5209 v8::HandleScope scope(env->GetIsolate()); |
| 5224 DebugLocalContext env(isolate_); | 5210 v8::Debug::SetMessageHandler(&ThreadedMessageHandler); |
| 5225 v8::HandleScope scope(isolate_); | 5211 v8::Handle<v8::ObjectTemplate> global_template = |
| 5226 v8::Debug::SetMessageHandler(&ThreadedMessageHandler); | 5212 v8::ObjectTemplate::New(env->GetIsolate()); |
| 5227 v8::Handle<v8::ObjectTemplate> global_template = | 5213 global_template->Set( |
| 5228 v8::ObjectTemplate::New(env->GetIsolate()); | 5214 v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), |
| 5229 global_template->Set( | 5215 v8::FunctionTemplate::New(isolate, ThreadedAtBarrier1)); |
| 5230 v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), | 5216 v8::Handle<v8::Context> context = v8::Context::New(isolate, |
| 5231 v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1)); | 5217 NULL, |
| 5232 v8::Handle<v8::Context> context = | 5218 global_template); |
| 5233 v8::Context::New(isolate_, NULL, global_template); | 5219 v8::Context::Scope context_scope(context); |
| 5234 v8::Context::Scope context_scope(context); | |
| 5235 | 5220 |
| 5236 CompileRun(source); | 5221 CompileRun(source); |
| 5237 } | |
| 5238 isolate_->Dispose(); | |
| 5239 } | 5222 } |
| 5240 | 5223 |
| 5241 | 5224 |
| 5242 void DebuggerThread::Run() { | 5225 void DebuggerThread::Run() { |
| 5243 const int kBufSize = 1000; | 5226 const int kBufSize = 1000; |
| 5244 uint16_t buffer[kBufSize]; | 5227 uint16_t buffer[kBufSize]; |
| 5245 | 5228 |
| 5246 const char* command_1 = "{\"seq\":102," | 5229 const char* command_1 = "{\"seq\":102," |
| 5247 "\"type\":\"request\"," | 5230 "\"type\":\"request\"," |
| 5248 "\"command\":\"evaluate\"," | 5231 "\"command\":\"evaluate\"," |
| 5249 "\"arguments\":{\"expression\":\"bar(false)\"}}"; | 5232 "\"arguments\":{\"expression\":\"bar(false)\"}}"; |
| 5250 const char* command_2 = "{\"seq\":103," | 5233 const char* command_2 = "{\"seq\":103," |
| 5251 "\"type\":\"request\"," | 5234 "\"type\":\"request\"," |
| 5252 "\"command\":\"continue\"}"; | 5235 "\"command\":\"continue\"}"; |
| 5253 | 5236 |
| 5237 v8::Isolate* isolate = CcTest::isolate(); |
| 5254 threaded_debugging_barriers.barrier_1.Wait(); | 5238 threaded_debugging_barriers.barrier_1.Wait(); |
| 5255 v8::Debug::DebugBreak(isolate_); | 5239 v8::Debug::DebugBreak(isolate); |
| 5256 threaded_debugging_barriers.barrier_2.Wait(); | 5240 threaded_debugging_barriers.barrier_2.Wait(); |
| 5257 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer)); | 5241 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer)); |
| 5258 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer)); | 5242 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer)); |
| 5259 } | 5243 } |
| 5260 | 5244 |
| 5261 | 5245 |
| 5262 TEST(ThreadedDebugging) { | 5246 TEST(ThreadedDebugging) { |
| 5247 DebuggerThread debugger_thread; |
| 5263 V8Thread v8_thread; | 5248 V8Thread v8_thread; |
| 5264 | 5249 |
| 5265 // Create a V8 environment | 5250 // Create a V8 environment |
| 5266 v8_thread.Start(); | 5251 v8_thread.Start(); |
| 5267 threaded_debugging_barriers.barrier_3.Wait(); | |
| 5268 DebuggerThread debugger_thread(v8_thread.isolate()); | |
| 5269 debugger_thread.Start(); | 5252 debugger_thread.Start(); |
| 5270 | 5253 |
| 5271 v8_thread.Join(); | 5254 v8_thread.Join(); |
| 5272 debugger_thread.Join(); | 5255 debugger_thread.Join(); |
| 5273 } | 5256 } |
| 5274 | 5257 |
| 5275 | 5258 |
| 5276 /* Test RecursiveBreakpoints */ | 5259 /* Test RecursiveBreakpoints */ |
| 5277 /* In this test, the debugger evaluates a function with a breakpoint, after | 5260 /* In this test, the debugger evaluates a function with a breakpoint, after |
| 5278 * hitting a breakpoint in another function. We do this with both values | 5261 * hitting a breakpoint in another function. We do this with both values |
| 5279 * of the flag enabling recursive breakpoints, and verify that the second | 5262 * of the flag enabling recursive breakpoints, and verify that the second |
| 5280 * breakpoint is hit when enabled, and missed when disabled. | 5263 * breakpoint is hit when enabled, and missed when disabled. |
| 5281 */ | 5264 */ |
| 5282 | 5265 |
| 5283 class BreakpointsV8Thread : public v8::base::Thread { | 5266 class BreakpointsV8Thread : public v8::base::Thread { |
| 5284 public: | 5267 public: |
| 5285 BreakpointsV8Thread() : Thread(Options("BreakpointsV8Thread")) {} | 5268 BreakpointsV8Thread() : Thread(Options("BreakpointsV8Thread")) {} |
| 5286 void Run(); | 5269 void Run(); |
| 5287 | |
| 5288 v8::Isolate* isolate() { return isolate_; } | |
| 5289 | |
| 5290 private: | |
| 5291 v8::Isolate* isolate_; | |
| 5292 }; | 5270 }; |
| 5293 | 5271 |
| 5294 class BreakpointsDebuggerThread : public v8::base::Thread { | 5272 class BreakpointsDebuggerThread : public v8::base::Thread { |
| 5295 public: | 5273 public: |
| 5296 BreakpointsDebuggerThread(bool global_evaluate, v8::Isolate* isolate) | 5274 explicit BreakpointsDebuggerThread(bool global_evaluate) |
| 5297 : Thread(Options("BreakpointsDebuggerThread")), | 5275 : Thread(Options("BreakpointsDebuggerThread")), |
| 5298 global_evaluate_(global_evaluate), | 5276 global_evaluate_(global_evaluate) {} |
| 5299 isolate_(isolate) {} | |
| 5300 void Run(); | 5277 void Run(); |
| 5301 | 5278 |
| 5302 private: | 5279 private: |
| 5303 bool global_evaluate_; | 5280 bool global_evaluate_; |
| 5304 v8::Isolate* isolate_; | |
| 5305 }; | 5281 }; |
| 5306 | 5282 |
| 5307 | 5283 |
| 5308 Barriers* breakpoints_barriers; | 5284 Barriers* breakpoints_barriers; |
| 5309 int break_event_breakpoint_id; | 5285 int break_event_breakpoint_id; |
| 5310 int evaluate_int_result; | 5286 int evaluate_int_result; |
| 5311 | 5287 |
| 5312 static void BreakpointsMessageHandler(const v8::Debug::Message& message) { | 5288 static void BreakpointsMessageHandler(const v8::Debug::Message& message) { |
| 5313 static char print_buffer[1000]; | 5289 static char print_buffer[1000]; |
| 5314 v8::String::Value json(message.GetJSON()); | 5290 v8::String::Value json(message.GetJSON()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 5339 " var x = 1;\n" | 5315 " var x = 1;\n" |
| 5340 " x = y_global;" | 5316 " x = y_global;" |
| 5341 " var z = 3;" | 5317 " var z = 3;" |
| 5342 " x += 100;\n" | 5318 " x += 100;\n" |
| 5343 " return x;\n" | 5319 " return x;\n" |
| 5344 "}\n" | 5320 "}\n" |
| 5345 "\n"; | 5321 "\n"; |
| 5346 const char* source_2 = "cat(17);\n" | 5322 const char* source_2 = "cat(17);\n" |
| 5347 "cat(19);\n"; | 5323 "cat(19);\n"; |
| 5348 | 5324 |
| 5349 isolate_ = v8::Isolate::New(); | 5325 v8::Isolate* isolate = CcTest::isolate(); |
| 5350 breakpoints_barriers->barrier_3.Wait(); | 5326 v8::Isolate::Scope isolate_scope(isolate); |
| 5351 { | 5327 DebugLocalContext env; |
| 5352 v8::Isolate::Scope isolate_scope(isolate_); | 5328 v8::HandleScope scope(isolate); |
| 5353 DebugLocalContext env(isolate_); | 5329 v8::Debug::SetMessageHandler(&BreakpointsMessageHandler); |
| 5354 v8::HandleScope scope(isolate_); | |
| 5355 v8::Debug::SetMessageHandler(&BreakpointsMessageHandler); | |
| 5356 | 5330 |
| 5357 CompileRun(source_1); | 5331 CompileRun(source_1); |
| 5358 breakpoints_barriers->barrier_1.Wait(); | 5332 breakpoints_barriers->barrier_1.Wait(); |
| 5359 breakpoints_barriers->barrier_2.Wait(); | 5333 breakpoints_barriers->barrier_2.Wait(); |
| 5360 CompileRun(source_2); | 5334 CompileRun(source_2); |
| 5361 } | |
| 5362 isolate_->Dispose(); | |
| 5363 } | 5335 } |
| 5364 | 5336 |
| 5365 | 5337 |
| 5366 void BreakpointsDebuggerThread::Run() { | 5338 void BreakpointsDebuggerThread::Run() { |
| 5367 const int kBufSize = 1000; | 5339 const int kBufSize = 1000; |
| 5368 uint16_t buffer[kBufSize]; | 5340 uint16_t buffer[kBufSize]; |
| 5369 | 5341 |
| 5370 const char* command_1 = "{\"seq\":101," | 5342 const char* command_1 = "{\"seq\":101," |
| 5371 "\"type\":\"request\"," | 5343 "\"type\":\"request\"," |
| 5372 "\"command\":\"setbreakpoint\"," | 5344 "\"command\":\"setbreakpoint\"," |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5418 command_7 = "{\"seq\":107," | 5390 command_7 = "{\"seq\":107," |
| 5419 "\"type\":\"request\"," | 5391 "\"type\":\"request\"," |
| 5420 "\"command\":\"evaluate\"," | 5392 "\"command\":\"evaluate\"," |
| 5421 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}"; | 5393 "\"arguments\":{\"expression\":\"dog()\",\"disable_break\":true}}"; |
| 5422 } | 5394 } |
| 5423 const char* command_8 = "{\"seq\":108," | 5395 const char* command_8 = "{\"seq\":108," |
| 5424 "\"type\":\"request\"," | 5396 "\"type\":\"request\"," |
| 5425 "\"command\":\"continue\"}"; | 5397 "\"command\":\"continue\"}"; |
| 5426 | 5398 |
| 5427 | 5399 |
| 5400 v8::Isolate* isolate = CcTest::isolate(); |
| 5401 v8::Isolate::Scope isolate_scope(isolate); |
| 5428 // v8 thread initializes, runs source_1 | 5402 // v8 thread initializes, runs source_1 |
| 5429 breakpoints_barriers->barrier_1.Wait(); | 5403 breakpoints_barriers->barrier_1.Wait(); |
| 5430 // 1:Set breakpoint in cat() (will get id 1). | 5404 // 1:Set breakpoint in cat() (will get id 1). |
| 5431 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer)); | 5405 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_1, buffer)); |
| 5432 // 2:Set breakpoint in dog() (will get id 2). | 5406 // 2:Set breakpoint in dog() (will get id 2). |
| 5433 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer)); | 5407 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_2, buffer)); |
| 5434 breakpoints_barriers->barrier_2.Wait(); | 5408 breakpoints_barriers->barrier_2.Wait(); |
| 5435 // V8 thread starts compiling source_2. | 5409 // V8 thread starts compiling source_2. |
| 5436 // Automatic break happens, to run queued commands | 5410 // Automatic break happens, to run queued commands |
| 5437 // breakpoints_barriers->semaphore_1.Wait(); | 5411 // breakpoints_barriers->semaphore_1.Wait(); |
| 5438 // Commands 1 through 3 run, thread continues. | 5412 // Commands 1 through 3 run, thread continues. |
| 5439 // v8 thread runs source_2 to breakpoint in cat(). | 5413 // v8 thread runs source_2 to breakpoint in cat(). |
| 5440 // message callback receives break event. | 5414 // message callback receives break event. |
| 5441 breakpoints_barriers->semaphore_1.Wait(); | 5415 breakpoints_barriers->semaphore_1.Wait(); |
| 5442 // Must have hit breakpoint #1. | 5416 // Must have hit breakpoint #1. |
| 5443 CHECK_EQ(1, break_event_breakpoint_id); | 5417 CHECK_EQ(1, break_event_breakpoint_id); |
| 5444 // 4:Evaluate dog() (which has a breakpoint). | 5418 // 4:Evaluate dog() (which has a breakpoint). |
| 5445 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_3, buffer)); | 5419 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_3, buffer)); |
| 5446 // V8 thread hits breakpoint in dog(). | 5420 // V8 thread hits breakpoint in dog(). |
| 5447 breakpoints_barriers->semaphore_1.Wait(); // wait for break event | 5421 breakpoints_barriers->semaphore_1.Wait(); // wait for break event |
| 5448 // Must have hit breakpoint #2. | 5422 // Must have hit breakpoint #2. |
| 5449 CHECK_EQ(2, break_event_breakpoint_id); | 5423 CHECK_EQ(2, break_event_breakpoint_id); |
| 5450 // 5:Evaluate (x + 1). | 5424 // 5:Evaluate (x + 1). |
| 5451 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_4, buffer)); | 5425 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_4, buffer)); |
| 5452 // Evaluate (x + 1) finishes. | 5426 // Evaluate (x + 1) finishes. |
| 5453 breakpoints_barriers->semaphore_1.Wait(); | 5427 breakpoints_barriers->semaphore_1.Wait(); |
| 5454 // Must have result 108. | 5428 // Must have result 108. |
| 5455 CHECK_EQ(108, evaluate_int_result); | 5429 CHECK_EQ(108, evaluate_int_result); |
| 5456 // 6:Continue evaluation of dog(). | 5430 // 6:Continue evaluation of dog(). |
| 5457 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_5, buffer)); | 5431 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_5, buffer)); |
| 5458 // Evaluate dog() finishes. | 5432 // Evaluate dog() finishes. |
| 5459 breakpoints_barriers->semaphore_1.Wait(); | 5433 breakpoints_barriers->semaphore_1.Wait(); |
| 5460 // Must have result 107. | 5434 // Must have result 107. |
| 5461 CHECK_EQ(107, evaluate_int_result); | 5435 CHECK_EQ(107, evaluate_int_result); |
| 5462 // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint | 5436 // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint |
| 5463 // in cat(19). | 5437 // in cat(19). |
| 5464 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_6, buffer)); | 5438 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_6, buffer)); |
| 5465 // Message callback gets break event. | 5439 // Message callback gets break event. |
| 5466 breakpoints_barriers->semaphore_1.Wait(); // wait for break event | 5440 breakpoints_barriers->semaphore_1.Wait(); // wait for break event |
| 5467 // Must have hit breakpoint #1. | 5441 // Must have hit breakpoint #1. |
| 5468 CHECK_EQ(1, break_event_breakpoint_id); | 5442 CHECK_EQ(1, break_event_breakpoint_id); |
| 5469 // 8: Evaluate dog() with breaks disabled. | 5443 // 8: Evaluate dog() with breaks disabled. |
| 5470 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_7, buffer)); | 5444 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_7, buffer)); |
| 5471 // Evaluate dog() finishes. | 5445 // Evaluate dog() finishes. |
| 5472 breakpoints_barriers->semaphore_1.Wait(); | 5446 breakpoints_barriers->semaphore_1.Wait(); |
| 5473 // Must have result 116. | 5447 // Must have result 116. |
| 5474 CHECK_EQ(116, evaluate_int_result); | 5448 CHECK_EQ(116, evaluate_int_result); |
| 5475 // 9: Continue evaluation of source2, reach end. | 5449 // 9: Continue evaluation of source2, reach end. |
| 5476 v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_8, buffer)); | 5450 v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_8, buffer)); |
| 5477 } | 5451 } |
| 5478 | 5452 |
| 5479 | 5453 |
| 5480 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { | 5454 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { |
| 5455 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); |
| 5481 BreakpointsV8Thread breakpoints_v8_thread; | 5456 BreakpointsV8Thread breakpoints_v8_thread; |
| 5482 | 5457 |
| 5483 // Create a V8 environment | 5458 // Create a V8 environment |
| 5484 Barriers stack_allocated_breakpoints_barriers; | 5459 Barriers stack_allocated_breakpoints_barriers; |
| 5485 breakpoints_barriers = &stack_allocated_breakpoints_barriers; | 5460 breakpoints_barriers = &stack_allocated_breakpoints_barriers; |
| 5486 | 5461 |
| 5487 breakpoints_v8_thread.Start(); | 5462 breakpoints_v8_thread.Start(); |
| 5488 breakpoints_barriers->barrier_3.Wait(); | |
| 5489 BreakpointsDebuggerThread breakpoints_debugger_thread( | |
| 5490 global_evaluate, breakpoints_v8_thread.isolate()); | |
| 5491 breakpoints_debugger_thread.Start(); | 5463 breakpoints_debugger_thread.Start(); |
| 5492 | 5464 |
| 5493 breakpoints_v8_thread.Join(); | 5465 breakpoints_v8_thread.Join(); |
| 5494 breakpoints_debugger_thread.Join(); | 5466 breakpoints_debugger_thread.Join(); |
| 5495 } | 5467 } |
| 5496 | 5468 |
| 5497 | 5469 |
| 5498 TEST(RecursiveBreakpoints) { | 5470 TEST(RecursiveBreakpoints) { |
| 5499 TestRecursiveBreakpointsGeneric(false); | 5471 TestRecursiveBreakpointsGeneric(false); |
| 5500 } | 5472 } |
| (...skipping 1981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7482 v8::Isolate* isolate = env->GetIsolate(); | 7454 v8::Isolate* isolate = env->GetIsolate(); |
| 7483 v8::HandleScope scope(isolate); | 7455 v8::HandleScope scope(isolate); |
| 7484 v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); | 7456 v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); |
| 7485 TerminationThread terminator(isolate); | 7457 TerminationThread terminator(isolate); |
| 7486 terminator.Start(); | 7458 terminator.Start(); |
| 7487 v8::TryCatch try_catch; | 7459 v8::TryCatch try_catch; |
| 7488 v8::Debug::DebugBreak(isolate); | 7460 v8::Debug::DebugBreak(isolate); |
| 7489 CompileRun("while (true);"); | 7461 CompileRun("while (true);"); |
| 7490 CHECK(try_catch.HasTerminated()); | 7462 CHECK(try_catch.HasTerminated()); |
| 7491 } | 7463 } |
| OLD | NEW |