| 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 19 matching lines...) Expand all Loading... |
| 30 #include <stdlib.h> | 30 #include <stdlib.h> |
| 31 | 31 |
| 32 #define V8_DISABLE_DEPRECATIONS 1 | 32 #define V8_DISABLE_DEPRECATIONS 1 |
| 33 #include "v8.h" | 33 #include "v8.h" |
| 34 | 34 |
| 35 #include "api.h" | 35 #include "api.h" |
| 36 #include "cctest.h" | 36 #include "cctest.h" |
| 37 #include "compilation-cache.h" | 37 #include "compilation-cache.h" |
| 38 #include "debug.h" | 38 #include "debug.h" |
| 39 #include "deoptimizer.h" | 39 #include "deoptimizer.h" |
| 40 #include "frames.h" |
| 40 #include "platform.h" | 41 #include "platform.h" |
| 42 #include "platform/condition-variable.h" |
| 43 #include "platform/socket.h" |
| 41 #include "stub-cache.h" | 44 #include "stub-cache.h" |
| 42 #include "utils.h" | 45 #include "utils.h" |
| 43 #undef V8_DISABLE_DEPRECATIONS | 46 #undef V8_DISABLE_DEPRECATIONS |
| 44 | 47 |
| 45 | 48 |
| 49 using ::v8::internal::Mutex; |
| 50 using ::v8::internal::LockGuard; |
| 51 using ::v8::internal::ConditionVariable; |
| 52 using ::v8::internal::Semaphore; |
| 46 using ::v8::internal::EmbeddedVector; | 53 using ::v8::internal::EmbeddedVector; |
| 47 using ::v8::internal::Object; | 54 using ::v8::internal::Object; |
| 48 using ::v8::internal::OS; | 55 using ::v8::internal::OS; |
| 49 using ::v8::internal::Handle; | 56 using ::v8::internal::Handle; |
| 50 using ::v8::internal::Heap; | 57 using ::v8::internal::Heap; |
| 51 using ::v8::internal::JSGlobalProxy; | 58 using ::v8::internal::JSGlobalProxy; |
| 52 using ::v8::internal::Code; | 59 using ::v8::internal::Code; |
| 53 using ::v8::internal::Debug; | 60 using ::v8::internal::Debug; |
| 54 using ::v8::internal::Debugger; | 61 using ::v8::internal::Debugger; |
| 55 using ::v8::internal::CommandMessage; | 62 using ::v8::internal::CommandMessage; |
| 56 using ::v8::internal::CommandMessageQueue; | 63 using ::v8::internal::CommandMessageQueue; |
| 64 using ::v8::internal::StackFrame; |
| 57 using ::v8::internal::StepAction; | 65 using ::v8::internal::StepAction; |
| 58 using ::v8::internal::StepIn; // From StepAction enum | 66 using ::v8::internal::StepIn; // From StepAction enum |
| 59 using ::v8::internal::StepNext; // From StepAction enum | 67 using ::v8::internal::StepNext; // From StepAction enum |
| 60 using ::v8::internal::StepOut; // From StepAction enum | 68 using ::v8::internal::StepOut; // From StepAction enum |
| 61 using ::v8::internal::Vector; | 69 using ::v8::internal::Vector; |
| 62 using ::v8::internal::StrLength; | 70 using ::v8::internal::StrLength; |
| 63 | 71 |
| 64 // Size of temp buffer for formatting small strings. | 72 // Size of temp buffer for formatting small strings. |
| 65 #define SMALL_STRING_BUFFER_SIZE 80 | 73 #define SMALL_STRING_BUFFER_SIZE 80 |
| 66 | 74 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 } else { | 385 } else { |
| 378 v8::Script::Compile( | 386 v8::Script::Compile( |
| 379 v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run(); | 387 v8::String::New("debug.Debug.clearBreakOnUncaughtException()"))->Run(); |
| 380 } | 388 } |
| 381 } | 389 } |
| 382 | 390 |
| 383 | 391 |
| 384 // Prepare to step to next break location. | 392 // Prepare to step to next break location. |
| 385 static void PrepareStep(StepAction step_action) { | 393 static void PrepareStep(StepAction step_action) { |
| 386 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); | 394 v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug(); |
| 387 debug->PrepareStep(step_action, 1); | 395 debug->PrepareStep(step_action, 1, StackFrame::NO_ID); |
| 388 } | 396 } |
| 389 | 397 |
| 390 | 398 |
| 391 // This function is in namespace v8::internal to be friend with class | 399 // This function is in namespace v8::internal to be friend with class |
| 392 // v8::internal::Debug. | 400 // v8::internal::Debug. |
| 393 namespace v8 { | 401 namespace v8 { |
| 394 namespace internal { | 402 namespace internal { |
| 395 | 403 |
| 396 // Collect the currently debugged functions. | 404 // Collect the currently debugged functions. |
| 397 Handle<FixedArray> GetDebuggedFunctions() { | 405 Handle<FixedArray> GetDebuggedFunctions() { |
| (...skipping 3792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4190 // Set the debug break flag. | 4198 // Set the debug break flag. |
| 4191 v8::Debug::DebugBreak(); | 4199 v8::Debug::DebugBreak(); |
| 4192 | 4200 |
| 4193 // Call all functions with different argument count. | 4201 // Call all functions with different argument count. |
| 4194 break_point_hit_count = 0; | 4202 break_point_hit_count = 0; |
| 4195 f->Call(env->Global(), 0, NULL); | 4203 f->Call(env->Global(), 0, NULL); |
| 4196 CHECK_EQ(1, break_point_hit_count); | 4204 CHECK_EQ(1, break_point_hit_count); |
| 4197 | 4205 |
| 4198 { | 4206 { |
| 4199 v8::Debug::DebugBreak(); | 4207 v8::Debug::DebugBreak(); |
| 4200 v8::internal::DisableBreak disable_break(true); | 4208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); |
| 4209 v8::internal::DisableBreak disable_break(isolate, true); |
| 4201 f->Call(env->Global(), 0, NULL); | 4210 f->Call(env->Global(), 0, NULL); |
| 4202 CHECK_EQ(1, break_point_hit_count); | 4211 CHECK_EQ(1, break_point_hit_count); |
| 4203 } | 4212 } |
| 4204 | 4213 |
| 4205 f->Call(env->Global(), 0, NULL); | 4214 f->Call(env->Global(), 0, NULL); |
| 4206 CHECK_EQ(2, break_point_hit_count); | 4215 CHECK_EQ(2, break_point_hit_count); |
| 4207 | 4216 |
| 4208 // Get rid of the debug event listener. | 4217 // Get rid of the debug event listener. |
| 4209 v8::Debug::SetDebugEventListener2(NULL); | 4218 v8::Debug::SetDebugEventListener2(NULL); |
| 4210 CheckDebuggerUnloaded(); | 4219 CheckDebuggerUnloaded(); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4659 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); | 4668 "obj_mirror.property('a').value().value() == 1")->BooleanValue()); |
| 4660 CHECK(CompileRun( | 4669 CHECK(CompileRun( |
| 4661 "obj_mirror.property('b').value().value() == 2")->BooleanValue()); | 4670 "obj_mirror.property('b').value().value() == 2")->BooleanValue()); |
| 4662 } | 4671 } |
| 4663 | 4672 |
| 4664 | 4673 |
| 4665 // Multithreaded tests of JSON debugger protocol | 4674 // Multithreaded tests of JSON debugger protocol |
| 4666 | 4675 |
| 4667 // Support classes | 4676 // Support classes |
| 4668 | 4677 |
| 4669 // Provides synchronization between k threads, where k is an input to the | 4678 // Provides synchronization between N threads, where N is a template parameter. |
| 4670 // constructor. The Wait() call blocks a thread until it is called for the | 4679 // The Wait() call blocks a thread until it is called for the Nth time, then all |
| 4671 // k'th time, then all calls return. Each ThreadBarrier object can only | 4680 // calls return. Each ThreadBarrier object can only be used once. |
| 4672 // be used once. | 4681 template <int N> |
| 4673 class ThreadBarrier { | 4682 class ThreadBarrier V8_FINAL { |
| 4674 public: | 4683 public: |
| 4675 explicit ThreadBarrier(int num_threads); | 4684 ThreadBarrier() : num_blocked_(0) {} |
| 4676 ~ThreadBarrier(); | 4685 |
| 4677 void Wait(); | 4686 ~ThreadBarrier() { |
| 4687 LockGuard<Mutex> lock_guard(&mutex_); |
| 4688 if (num_blocked_ != 0) { |
| 4689 CHECK_EQ(N, num_blocked_); |
| 4690 } |
| 4691 } |
| 4692 |
| 4693 void Wait() { |
| 4694 LockGuard<Mutex> lock_guard(&mutex_); |
| 4695 CHECK_LT(num_blocked_, N); |
| 4696 num_blocked_++; |
| 4697 if (N == num_blocked_) { |
| 4698 // Signal and unblock all waiting threads. |
| 4699 cv_.NotifyAll(); |
| 4700 printf("BARRIER\n\n"); |
| 4701 fflush(stdout); |
| 4702 } else { // Wait for the semaphore. |
| 4703 while (num_blocked_ < N) { |
| 4704 cv_.Wait(&mutex_); |
| 4705 } |
| 4706 } |
| 4707 CHECK_EQ(N, num_blocked_); |
| 4708 } |
| 4709 |
| 4678 private: | 4710 private: |
| 4679 int num_threads_; | 4711 ConditionVariable cv_; |
| 4712 Mutex mutex_; |
| 4680 int num_blocked_; | 4713 int num_blocked_; |
| 4681 v8::internal::Mutex lock_; | 4714 |
| 4682 v8::internal::Semaphore sem_; | 4715 STATIC_CHECK(N > 0); |
| 4683 bool invalid_; | 4716 |
| 4717 DISALLOW_COPY_AND_ASSIGN(ThreadBarrier); |
| 4684 }; | 4718 }; |
| 4685 | 4719 |
| 4686 ThreadBarrier::ThreadBarrier(int num_threads) | |
| 4687 : num_threads_(num_threads), num_blocked_(0), sem_(0) { | |
| 4688 invalid_ = false; // A barrier may only be used once. Then it is invalid. | |
| 4689 } | |
| 4690 | |
| 4691 | |
| 4692 // Do not call, due to race condition with Wait(). | |
| 4693 // Could be resolved with Pthread condition variables. | |
| 4694 ThreadBarrier::~ThreadBarrier() { | |
| 4695 } | |
| 4696 | |
| 4697 | |
| 4698 void ThreadBarrier::Wait() { | |
| 4699 lock_.Lock(); | |
| 4700 CHECK(!invalid_); | |
| 4701 if (num_blocked_ == num_threads_ - 1) { | |
| 4702 // Signal and unblock all waiting threads. | |
| 4703 for (int i = 0; i < num_threads_ - 1; ++i) { | |
| 4704 sem_.Signal(); | |
| 4705 } | |
| 4706 invalid_ = true; | |
| 4707 printf("BARRIER\n\n"); | |
| 4708 fflush(stdout); | |
| 4709 lock_.Unlock(); | |
| 4710 } else { // Wait for the semaphore. | |
| 4711 ++num_blocked_; | |
| 4712 lock_.Unlock(); // Potential race condition with destructor because | |
| 4713 sem_.Wait(); // these two lines are not atomic. | |
| 4714 } | |
| 4715 } | |
| 4716 | |
| 4717 | 4720 |
| 4718 // A set containing enough barriers and semaphores for any of the tests. | 4721 // A set containing enough barriers and semaphores for any of the tests. |
| 4719 class Barriers { | 4722 class Barriers { |
| 4720 public: | 4723 public: |
| 4721 Barriers(); | 4724 Barriers() : semaphore_1(0), semaphore_2(0) {} |
| 4722 void Initialize(); | 4725 ThreadBarrier<2> barrier_1; |
| 4723 ThreadBarrier barrier_1; | 4726 ThreadBarrier<2> barrier_2; |
| 4724 ThreadBarrier barrier_2; | 4727 ThreadBarrier<2> barrier_3; |
| 4725 ThreadBarrier barrier_3; | 4728 ThreadBarrier<2> barrier_4; |
| 4726 ThreadBarrier barrier_4; | 4729 ThreadBarrier<2> barrier_5; |
| 4727 ThreadBarrier barrier_5; | 4730 v8::internal::Semaphore semaphore_1; |
| 4728 v8::internal::Semaphore* semaphore_1; | 4731 v8::internal::Semaphore semaphore_2; |
| 4729 v8::internal::Semaphore* semaphore_2; | |
| 4730 }; | 4732 }; |
| 4731 | 4733 |
| 4732 Barriers::Barriers() : barrier_1(2), barrier_2(2), | |
| 4733 barrier_3(2), barrier_4(2), barrier_5(2) {} | |
| 4734 | |
| 4735 void Barriers::Initialize() { | |
| 4736 semaphore_1 = new v8::internal::Semaphore(0); | |
| 4737 semaphore_2 = new v8::internal::Semaphore(0); | |
| 4738 } | |
| 4739 | |
| 4740 | 4734 |
| 4741 // We match parts of the message to decide if it is a break message. | 4735 // We match parts of the message to decide if it is a break message. |
| 4742 bool IsBreakEventMessage(char *message) { | 4736 bool IsBreakEventMessage(char *message) { |
| 4743 const char* type_event = "\"type\":\"event\""; | 4737 const char* type_event = "\"type\":\"event\""; |
| 4744 const char* event_break = "\"event\":\"break\""; | 4738 const char* event_break = "\"event\":\"break\""; |
| 4745 // Does the message contain both type:event and event:break? | 4739 // Does the message contain both type:event and event:break? |
| 4746 return strstr(message, type_event) != NULL && | 4740 return strstr(message, type_event) != NULL && |
| 4747 strstr(message, event_break) != NULL; | 4741 strstr(message, event_break) != NULL; |
| 4748 } | 4742 } |
| 4749 | 4743 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4841 void Run(); | 4835 void Run(); |
| 4842 }; | 4836 }; |
| 4843 | 4837 |
| 4844 | 4838 |
| 4845 static void MessageHandler(const v8::Debug::Message& message) { | 4839 static void MessageHandler(const v8::Debug::Message& message) { |
| 4846 v8::Handle<v8::String> json = message.GetJSON(); | 4840 v8::Handle<v8::String> json = message.GetJSON(); |
| 4847 v8::String::AsciiValue ascii(json); | 4841 v8::String::AsciiValue ascii(json); |
| 4848 if (IsBreakEventMessage(*ascii)) { | 4842 if (IsBreakEventMessage(*ascii)) { |
| 4849 // Lets test script wait until break occurs to send commands. | 4843 // Lets test script wait until break occurs to send commands. |
| 4850 // Signals when a break is reported. | 4844 // Signals when a break is reported. |
| 4851 message_queue_barriers.semaphore_2->Signal(); | 4845 message_queue_barriers.semaphore_2.Signal(); |
| 4852 } | 4846 } |
| 4853 | 4847 |
| 4854 // Allow message handler to block on a semaphore, to test queueing of | 4848 // Allow message handler to block on a semaphore, to test queueing of |
| 4855 // messages while blocked. | 4849 // messages while blocked. |
| 4856 message_queue_barriers.semaphore_1->Wait(); | 4850 message_queue_barriers.semaphore_1.Wait(); |
| 4857 } | 4851 } |
| 4858 | 4852 |
| 4859 | 4853 |
| 4860 void MessageQueueDebuggerThread::Run() { | 4854 void MessageQueueDebuggerThread::Run() { |
| 4861 const int kBufferSize = 1000; | 4855 const int kBufferSize = 1000; |
| 4862 uint16_t buffer_1[kBufferSize]; | 4856 uint16_t buffer_1[kBufferSize]; |
| 4863 uint16_t buffer_2[kBufferSize]; | 4857 uint16_t buffer_2[kBufferSize]; |
| 4864 const char* command_1 = | 4858 const char* command_1 = |
| 4865 "{\"seq\":117," | 4859 "{\"seq\":117," |
| 4866 "\"type\":\"request\"," | 4860 "\"type\":\"request\"," |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4881 "\"type\":\"request\"," | 4875 "\"type\":\"request\"," |
| 4882 "\"command\":\"continue\"}"; | 4876 "\"command\":\"continue\"}"; |
| 4883 const char* command_single_step = | 4877 const char* command_single_step = |
| 4884 "{\"seq\":107," | 4878 "{\"seq\":107," |
| 4885 "\"type\":\"request\"," | 4879 "\"type\":\"request\"," |
| 4886 "\"command\":\"continue\"," | 4880 "\"command\":\"continue\"," |
| 4887 "\"arguments\":{\"stepaction\":\"next\"}}"; | 4881 "\"arguments\":{\"stepaction\":\"next\"}}"; |
| 4888 | 4882 |
| 4889 /* Interleaved sequence of actions by the two threads:*/ | 4883 /* Interleaved sequence of actions by the two threads:*/ |
| 4890 // Main thread compiles and runs source_1 | 4884 // Main thread compiles and runs source_1 |
| 4891 message_queue_barriers.semaphore_1->Signal(); | 4885 message_queue_barriers.semaphore_1.Signal(); |
| 4892 message_queue_barriers.barrier_1.Wait(); | 4886 message_queue_barriers.barrier_1.Wait(); |
| 4893 // Post 6 commands, filling the command queue and making it expand. | 4887 // Post 6 commands, filling the command queue and making it expand. |
| 4894 // These calls return immediately, but the commands stay on the queue | 4888 // These calls return immediately, but the commands stay on the queue |
| 4895 // until the execution of source_2. | 4889 // until the execution of source_2. |
| 4896 // Note: AsciiToUtf16 executes before SendCommand, so command is copied | 4890 // Note: AsciiToUtf16 executes before SendCommand, so command is copied |
| 4897 // to buffer before buffer is sent to SendCommand. | 4891 // to buffer before buffer is sent to SendCommand. |
| 4898 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); | 4892 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); |
| 4899 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); | 4893 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); |
| 4900 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4894 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
| 4901 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4895 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
| 4902 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4896 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
| 4903 message_queue_barriers.barrier_2.Wait(); | 4897 message_queue_barriers.barrier_2.Wait(); |
| 4904 // Main thread compiles and runs source_2. | 4898 // Main thread compiles and runs source_2. |
| 4905 // Queued commands are executed at the start of compilation of source_2( | 4899 // Queued commands are executed at the start of compilation of source_2( |
| 4906 // beforeCompile event). | 4900 // beforeCompile event). |
| 4907 // Free the message handler to process all the messages from the queue. 7 | 4901 // Free the message handler to process all the messages from the queue. 7 |
| 4908 // messages are expected: 2 afterCompile events and 5 responses. | 4902 // messages are expected: 2 afterCompile events and 5 responses. |
| 4909 // All the commands added so far will fail to execute as long as call stack | 4903 // All the commands added so far will fail to execute as long as call stack |
| 4910 // is empty on beforeCompile event. | 4904 // is empty on beforeCompile event. |
| 4911 for (int i = 0; i < 6 ; ++i) { | 4905 for (int i = 0; i < 6 ; ++i) { |
| 4912 message_queue_barriers.semaphore_1->Signal(); | 4906 message_queue_barriers.semaphore_1.Signal(); |
| 4913 } | 4907 } |
| 4914 message_queue_barriers.barrier_3.Wait(); | 4908 message_queue_barriers.barrier_3.Wait(); |
| 4915 // Main thread compiles and runs source_3. | 4909 // Main thread compiles and runs source_3. |
| 4916 // Don't stop in the afterCompile handler. | 4910 // Don't stop in the afterCompile handler. |
| 4917 message_queue_barriers.semaphore_1->Signal(); | 4911 message_queue_barriers.semaphore_1.Signal(); |
| 4918 // source_3 includes a debugger statement, which causes a break event. | 4912 // source_3 includes a debugger statement, which causes a break event. |
| 4919 // Wait on break event from hitting "debugger" statement | 4913 // Wait on break event from hitting "debugger" statement |
| 4920 message_queue_barriers.semaphore_2->Wait(); | 4914 message_queue_barriers.semaphore_2.Wait(); |
| 4921 // These should execute after the "debugger" statement in source_2 | 4915 // These should execute after the "debugger" statement in source_2 |
| 4922 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); | 4916 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_1, buffer_1)); |
| 4923 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); | 4917 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_2, buffer_2)); |
| 4924 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); | 4918 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_3, buffer_2)); |
| 4925 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2)); | 4919 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_single_step, buffer_2)); |
| 4926 // Run after 2 break events, 4 responses. | 4920 // Run after 2 break events, 4 responses. |
| 4927 for (int i = 0; i < 6 ; ++i) { | 4921 for (int i = 0; i < 6 ; ++i) { |
| 4928 message_queue_barriers.semaphore_1->Signal(); | 4922 message_queue_barriers.semaphore_1.Signal(); |
| 4929 } | 4923 } |
| 4930 // Wait on break event after a single step executes. | 4924 // Wait on break event after a single step executes. |
| 4931 message_queue_barriers.semaphore_2->Wait(); | 4925 message_queue_barriers.semaphore_2.Wait(); |
| 4932 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); | 4926 v8::Debug::SendCommand(buffer_1, AsciiToUtf16(command_2, buffer_1)); |
| 4933 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); | 4927 v8::Debug::SendCommand(buffer_2, AsciiToUtf16(command_continue, buffer_2)); |
| 4934 // Run after 2 responses. | 4928 // Run after 2 responses. |
| 4935 for (int i = 0; i < 2 ; ++i) { | 4929 for (int i = 0; i < 2 ; ++i) { |
| 4936 message_queue_barriers.semaphore_1->Signal(); | 4930 message_queue_barriers.semaphore_1.Signal(); |
| 4937 } | 4931 } |
| 4938 // Main thread continues running source_3 to end, waits for this thread. | 4932 // Main thread continues running source_3 to end, waits for this thread. |
| 4939 } | 4933 } |
| 4940 | 4934 |
| 4941 | 4935 |
| 4942 // This thread runs the v8 engine. | 4936 // This thread runs the v8 engine. |
| 4943 TEST(MessageQueues) { | 4937 TEST(MessageQueues) { |
| 4944 MessageQueueDebuggerThread message_queue_debugger_thread; | 4938 MessageQueueDebuggerThread message_queue_debugger_thread; |
| 4945 | 4939 |
| 4946 // Create a V8 environment | 4940 // Create a V8 environment |
| 4947 DebugLocalContext env; | 4941 DebugLocalContext env; |
| 4948 v8::HandleScope scope(env->GetIsolate()); | 4942 v8::HandleScope scope(env->GetIsolate()); |
| 4949 message_queue_barriers.Initialize(); | |
| 4950 v8::Debug::SetMessageHandler2(MessageHandler); | 4943 v8::Debug::SetMessageHandler2(MessageHandler); |
| 4951 message_queue_debugger_thread.Start(); | 4944 message_queue_debugger_thread.Start(); |
| 4952 | 4945 |
| 4953 const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; | 4946 const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; |
| 4954 const char* source_2 = "e = 17;"; | 4947 const char* source_2 = "e = 17;"; |
| 4955 const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; | 4948 const char* source_3 = "a = 4; debugger; a = 5; a = 6; a = 7;"; |
| 4956 | 4949 |
| 4957 // See MessageQueueDebuggerThread::Run for interleaved sequence of | 4950 // See MessageQueueDebuggerThread::Run for interleaved sequence of |
| 4958 // API calls and events in the two threads. | 4951 // API calls and events in the two threads. |
| 4959 CompileRun(source_1); | 4952 CompileRun(source_1); |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5175 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); | 5168 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); |
| 5176 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5169 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
| 5177 } | 5170 } |
| 5178 | 5171 |
| 5179 | 5172 |
| 5180 TEST(ThreadedDebugging) { | 5173 TEST(ThreadedDebugging) { |
| 5181 DebuggerThread debugger_thread; | 5174 DebuggerThread debugger_thread; |
| 5182 V8Thread v8_thread; | 5175 V8Thread v8_thread; |
| 5183 | 5176 |
| 5184 // Create a V8 environment | 5177 // Create a V8 environment |
| 5185 threaded_debugging_barriers.Initialize(); | |
| 5186 | |
| 5187 v8_thread.Start(); | 5178 v8_thread.Start(); |
| 5188 debugger_thread.Start(); | 5179 debugger_thread.Start(); |
| 5189 | 5180 |
| 5190 v8_thread.Join(); | 5181 v8_thread.Join(); |
| 5191 debugger_thread.Join(); | 5182 debugger_thread.Join(); |
| 5192 } | 5183 } |
| 5193 | 5184 |
| 5194 | 5185 |
| 5195 /* Test RecursiveBreakpoints */ | 5186 /* Test RecursiveBreakpoints */ |
| 5196 /* In this test, the debugger evaluates a function with a breakpoint, after | 5187 /* In this test, the debugger evaluates a function with a breakpoint, after |
| (...skipping 25 matching lines...) Expand all Loading... |
| 5222 int evaluate_int_result; | 5213 int evaluate_int_result; |
| 5223 | 5214 |
| 5224 static void BreakpointsMessageHandler(const v8::Debug::Message& message) { | 5215 static void BreakpointsMessageHandler(const v8::Debug::Message& message) { |
| 5225 static char print_buffer[1000]; | 5216 static char print_buffer[1000]; |
| 5226 v8::String::Value json(message.GetJSON()); | 5217 v8::String::Value json(message.GetJSON()); |
| 5227 Utf16ToAscii(*json, json.length(), print_buffer); | 5218 Utf16ToAscii(*json, json.length(), print_buffer); |
| 5228 | 5219 |
| 5229 if (IsBreakEventMessage(print_buffer)) { | 5220 if (IsBreakEventMessage(print_buffer)) { |
| 5230 break_event_breakpoint_id = | 5221 break_event_breakpoint_id = |
| 5231 GetBreakpointIdFromBreakEventMessage(print_buffer); | 5222 GetBreakpointIdFromBreakEventMessage(print_buffer); |
| 5232 breakpoints_barriers->semaphore_1->Signal(); | 5223 breakpoints_barriers->semaphore_1.Signal(); |
| 5233 } else if (IsEvaluateResponseMessage(print_buffer)) { | 5224 } else if (IsEvaluateResponseMessage(print_buffer)) { |
| 5234 evaluate_int_result = GetEvaluateIntResult(print_buffer); | 5225 evaluate_int_result = GetEvaluateIntResult(print_buffer); |
| 5235 breakpoints_barriers->semaphore_1->Signal(); | 5226 breakpoints_barriers->semaphore_1.Signal(); |
| 5236 } | 5227 } |
| 5237 } | 5228 } |
| 5238 | 5229 |
| 5239 | 5230 |
| 5240 void BreakpointsV8Thread::Run() { | 5231 void BreakpointsV8Thread::Run() { |
| 5241 const char* source_1 = "var y_global = 3;\n" | 5232 const char* source_1 = "var y_global = 3;\n" |
| 5242 "function cat( new_value ) {\n" | 5233 "function cat( new_value ) {\n" |
| 5243 " var x = new_value;\n" | 5234 " var x = new_value;\n" |
| 5244 " y_global = y_global + 4;\n" | 5235 " y_global = y_global + 4;\n" |
| 5245 " x = 3 * x + 1;\n" | 5236 " x = 3 * x + 1;\n" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5334 | 5325 |
| 5335 // v8 thread initializes, runs source_1 | 5326 // v8 thread initializes, runs source_1 |
| 5336 breakpoints_barriers->barrier_1.Wait(); | 5327 breakpoints_barriers->barrier_1.Wait(); |
| 5337 // 1:Set breakpoint in cat() (will get id 1). | 5328 // 1:Set breakpoint in cat() (will get id 1). |
| 5338 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); | 5329 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); |
| 5339 // 2:Set breakpoint in dog() (will get id 2). | 5330 // 2:Set breakpoint in dog() (will get id 2). |
| 5340 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5331 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
| 5341 breakpoints_barriers->barrier_2.Wait(); | 5332 breakpoints_barriers->barrier_2.Wait(); |
| 5342 // V8 thread starts compiling source_2. | 5333 // V8 thread starts compiling source_2. |
| 5343 // Automatic break happens, to run queued commands | 5334 // Automatic break happens, to run queued commands |
| 5344 // breakpoints_barriers->semaphore_1->Wait(); | 5335 // breakpoints_barriers->semaphore_1.Wait(); |
| 5345 // Commands 1 through 3 run, thread continues. | 5336 // Commands 1 through 3 run, thread continues. |
| 5346 // v8 thread runs source_2 to breakpoint in cat(). | 5337 // v8 thread runs source_2 to breakpoint in cat(). |
| 5347 // message callback receives break event. | 5338 // message callback receives break event. |
| 5348 breakpoints_barriers->semaphore_1->Wait(); | 5339 breakpoints_barriers->semaphore_1.Wait(); |
| 5349 // Must have hit breakpoint #1. | 5340 // Must have hit breakpoint #1. |
| 5350 CHECK_EQ(1, break_event_breakpoint_id); | 5341 CHECK_EQ(1, break_event_breakpoint_id); |
| 5351 // 4:Evaluate dog() (which has a breakpoint). | 5342 // 4:Evaluate dog() (which has a breakpoint). |
| 5352 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_3, buffer)); | 5343 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_3, buffer)); |
| 5353 // V8 thread hits breakpoint in dog(). | 5344 // V8 thread hits breakpoint in dog(). |
| 5354 breakpoints_barriers->semaphore_1->Wait(); // wait for break event | 5345 breakpoints_barriers->semaphore_1.Wait(); // wait for break event |
| 5355 // Must have hit breakpoint #2. | 5346 // Must have hit breakpoint #2. |
| 5356 CHECK_EQ(2, break_event_breakpoint_id); | 5347 CHECK_EQ(2, break_event_breakpoint_id); |
| 5357 // 5:Evaluate (x + 1). | 5348 // 5:Evaluate (x + 1). |
| 5358 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_4, buffer)); | 5349 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_4, buffer)); |
| 5359 // Evaluate (x + 1) finishes. | 5350 // Evaluate (x + 1) finishes. |
| 5360 breakpoints_barriers->semaphore_1->Wait(); | 5351 breakpoints_barriers->semaphore_1.Wait(); |
| 5361 // Must have result 108. | 5352 // Must have result 108. |
| 5362 CHECK_EQ(108, evaluate_int_result); | 5353 CHECK_EQ(108, evaluate_int_result); |
| 5363 // 6:Continue evaluation of dog(). | 5354 // 6:Continue evaluation of dog(). |
| 5364 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_5, buffer)); | 5355 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_5, buffer)); |
| 5365 // Evaluate dog() finishes. | 5356 // Evaluate dog() finishes. |
| 5366 breakpoints_barriers->semaphore_1->Wait(); | 5357 breakpoints_barriers->semaphore_1.Wait(); |
| 5367 // Must have result 107. | 5358 // Must have result 107. |
| 5368 CHECK_EQ(107, evaluate_int_result); | 5359 CHECK_EQ(107, evaluate_int_result); |
| 5369 // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint | 5360 // 7:Continue evaluation of source_2, finish cat(17), hit breakpoint |
| 5370 // in cat(19). | 5361 // in cat(19). |
| 5371 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_6, buffer)); | 5362 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_6, buffer)); |
| 5372 // Message callback gets break event. | 5363 // Message callback gets break event. |
| 5373 breakpoints_barriers->semaphore_1->Wait(); // wait for break event | 5364 breakpoints_barriers->semaphore_1.Wait(); // wait for break event |
| 5374 // Must have hit breakpoint #1. | 5365 // Must have hit breakpoint #1. |
| 5375 CHECK_EQ(1, break_event_breakpoint_id); | 5366 CHECK_EQ(1, break_event_breakpoint_id); |
| 5376 // 8: Evaluate dog() with breaks disabled. | 5367 // 8: Evaluate dog() with breaks disabled. |
| 5377 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_7, buffer)); | 5368 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_7, buffer)); |
| 5378 // Evaluate dog() finishes. | 5369 // Evaluate dog() finishes. |
| 5379 breakpoints_barriers->semaphore_1->Wait(); | 5370 breakpoints_barriers->semaphore_1.Wait(); |
| 5380 // Must have result 116. | 5371 // Must have result 116. |
| 5381 CHECK_EQ(116, evaluate_int_result); | 5372 CHECK_EQ(116, evaluate_int_result); |
| 5382 // 9: Continue evaluation of source2, reach end. | 5373 // 9: Continue evaluation of source2, reach end. |
| 5383 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer)); | 5374 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_8, buffer)); |
| 5384 } | 5375 } |
| 5385 | 5376 |
| 5386 | 5377 |
| 5387 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { | 5378 void TestRecursiveBreakpointsGeneric(bool global_evaluate) { |
| 5388 i::FLAG_debugger_auto_break = true; | 5379 i::FLAG_debugger_auto_break = true; |
| 5389 | 5380 |
| 5390 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); | 5381 BreakpointsDebuggerThread breakpoints_debugger_thread(global_evaluate); |
| 5391 BreakpointsV8Thread breakpoints_v8_thread; | 5382 BreakpointsV8Thread breakpoints_v8_thread; |
| 5392 | 5383 |
| 5393 // Create a V8 environment | 5384 // Create a V8 environment |
| 5394 Barriers stack_allocated_breakpoints_barriers; | 5385 Barriers stack_allocated_breakpoints_barriers; |
| 5395 stack_allocated_breakpoints_barriers.Initialize(); | |
| 5396 breakpoints_barriers = &stack_allocated_breakpoints_barriers; | 5386 breakpoints_barriers = &stack_allocated_breakpoints_barriers; |
| 5397 | 5387 |
| 5398 breakpoints_v8_thread.Start(); | 5388 breakpoints_v8_thread.Start(); |
| 5399 breakpoints_debugger_thread.Start(); | 5389 breakpoints_debugger_thread.Start(); |
| 5400 | 5390 |
| 5401 breakpoints_v8_thread.Join(); | 5391 breakpoints_v8_thread.Join(); |
| 5402 breakpoints_debugger_thread.Join(); | 5392 breakpoints_debugger_thread.Join(); |
| 5403 } | 5393 } |
| 5404 | 5394 |
| 5405 | 5395 |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5778 Barriers* host_dispatch_barriers; | 5768 Barriers* host_dispatch_barriers; |
| 5779 | 5769 |
| 5780 static void HostDispatchMessageHandler(const v8::Debug::Message& message) { | 5770 static void HostDispatchMessageHandler(const v8::Debug::Message& message) { |
| 5781 static char print_buffer[1000]; | 5771 static char print_buffer[1000]; |
| 5782 v8::String::Value json(message.GetJSON()); | 5772 v8::String::Value json(message.GetJSON()); |
| 5783 Utf16ToAscii(*json, json.length(), print_buffer); | 5773 Utf16ToAscii(*json, json.length(), print_buffer); |
| 5784 } | 5774 } |
| 5785 | 5775 |
| 5786 | 5776 |
| 5787 static void HostDispatchDispatchHandler() { | 5777 static void HostDispatchDispatchHandler() { |
| 5788 host_dispatch_barriers->semaphore_1->Signal(); | 5778 host_dispatch_barriers->semaphore_1.Signal(); |
| 5789 } | 5779 } |
| 5790 | 5780 |
| 5791 | 5781 |
| 5792 void HostDispatchV8Thread::Run() { | 5782 void HostDispatchV8Thread::Run() { |
| 5793 const char* source_1 = "var y_global = 3;\n" | 5783 const char* source_1 = "var y_global = 3;\n" |
| 5794 "function cat( new_value ) {\n" | 5784 "function cat( new_value ) {\n" |
| 5795 " var x = new_value;\n" | 5785 " var x = new_value;\n" |
| 5796 " y_global = 4;\n" | 5786 " y_global = 4;\n" |
| 5797 " x = 3 * x + 1;\n" | 5787 " x = 3 * x + 1;\n" |
| 5798 " y_global = 5;\n" | 5788 " y_global = 5;\n" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5830 | 5820 |
| 5831 // v8 thread initializes, runs source_1 | 5821 // v8 thread initializes, runs source_1 |
| 5832 host_dispatch_barriers->barrier_1.Wait(); | 5822 host_dispatch_barriers->barrier_1.Wait(); |
| 5833 // 1: Set breakpoint in cat(). | 5823 // 1: Set breakpoint in cat(). |
| 5834 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); | 5824 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_1, buffer)); |
| 5835 | 5825 |
| 5836 host_dispatch_barriers->barrier_2.Wait(); | 5826 host_dispatch_barriers->barrier_2.Wait(); |
| 5837 // v8 thread starts compiling source_2. | 5827 // v8 thread starts compiling source_2. |
| 5838 // Break happens, to run queued commands and host dispatches. | 5828 // Break happens, to run queued commands and host dispatches. |
| 5839 // Wait for host dispatch to be processed. | 5829 // Wait for host dispatch to be processed. |
| 5840 host_dispatch_barriers->semaphore_1->Wait(); | 5830 host_dispatch_barriers->semaphore_1.Wait(); |
| 5841 // 2: Continue evaluation | 5831 // 2: Continue evaluation |
| 5842 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); | 5832 v8::Debug::SendCommand(buffer, AsciiToUtf16(command_2, buffer)); |
| 5843 } | 5833 } |
| 5844 | 5834 |
| 5845 | 5835 |
| 5846 TEST(DebuggerHostDispatch) { | 5836 TEST(DebuggerHostDispatch) { |
| 5847 HostDispatchDebuggerThread host_dispatch_debugger_thread; | 5837 HostDispatchDebuggerThread host_dispatch_debugger_thread; |
| 5848 HostDispatchV8Thread host_dispatch_v8_thread; | 5838 HostDispatchV8Thread host_dispatch_v8_thread; |
| 5849 i::FLAG_debugger_auto_break = true; | 5839 i::FLAG_debugger_auto_break = true; |
| 5850 | 5840 |
| 5851 // Create a V8 environment | 5841 // Create a V8 environment |
| 5852 Barriers stack_allocated_host_dispatch_barriers; | 5842 Barriers stack_allocated_host_dispatch_barriers; |
| 5853 stack_allocated_host_dispatch_barriers.Initialize(); | |
| 5854 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers; | 5843 host_dispatch_barriers = &stack_allocated_host_dispatch_barriers; |
| 5855 | 5844 |
| 5856 host_dispatch_v8_thread.Start(); | 5845 host_dispatch_v8_thread.Start(); |
| 5857 host_dispatch_debugger_thread.Start(); | 5846 host_dispatch_debugger_thread.Start(); |
| 5858 | 5847 |
| 5859 host_dispatch_v8_thread.Join(); | 5848 host_dispatch_v8_thread.Join(); |
| 5860 host_dispatch_debugger_thread.Join(); | 5849 host_dispatch_debugger_thread.Join(); |
| 5861 } | 5850 } |
| 5862 | 5851 |
| 5863 | 5852 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5877 public: | 5866 public: |
| 5878 DebugMessageDispatchDebuggerThread() | 5867 DebugMessageDispatchDebuggerThread() |
| 5879 : Thread("DebugMessageDispatchDebuggerThread") { } | 5868 : Thread("DebugMessageDispatchDebuggerThread") { } |
| 5880 void Run(); | 5869 void Run(); |
| 5881 }; | 5870 }; |
| 5882 | 5871 |
| 5883 Barriers* debug_message_dispatch_barriers; | 5872 Barriers* debug_message_dispatch_barriers; |
| 5884 | 5873 |
| 5885 | 5874 |
| 5886 static void DebugMessageHandler() { | 5875 static void DebugMessageHandler() { |
| 5887 debug_message_dispatch_barriers->semaphore_1->Signal(); | 5876 debug_message_dispatch_barriers->semaphore_1.Signal(); |
| 5888 } | 5877 } |
| 5889 | 5878 |
| 5890 | 5879 |
| 5891 void DebugMessageDispatchV8Thread::Run() { | 5880 void DebugMessageDispatchV8Thread::Run() { |
| 5892 v8::V8::Initialize(); | 5881 v8::V8::Initialize(); |
| 5893 DebugLocalContext env; | 5882 DebugLocalContext env; |
| 5894 v8::HandleScope scope(env->GetIsolate()); | 5883 v8::HandleScope scope(env->GetIsolate()); |
| 5895 | 5884 |
| 5896 // Set up debug message dispatch handler. | 5885 // Set up debug message dispatch handler. |
| 5897 v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler); | 5886 v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler); |
| 5898 | 5887 |
| 5899 CompileRun("var y = 1 + 2;\n"); | 5888 CompileRun("var y = 1 + 2;\n"); |
| 5900 debug_message_dispatch_barriers->barrier_1.Wait(); | 5889 debug_message_dispatch_barriers->barrier_1.Wait(); |
| 5901 debug_message_dispatch_barriers->semaphore_1->Wait(); | 5890 debug_message_dispatch_barriers->semaphore_1.Wait(); |
| 5902 debug_message_dispatch_barriers->barrier_2.Wait(); | 5891 debug_message_dispatch_barriers->barrier_2.Wait(); |
| 5903 } | 5892 } |
| 5904 | 5893 |
| 5905 | 5894 |
| 5906 void DebugMessageDispatchDebuggerThread::Run() { | 5895 void DebugMessageDispatchDebuggerThread::Run() { |
| 5907 debug_message_dispatch_barriers->barrier_1.Wait(); | 5896 debug_message_dispatch_barriers->barrier_1.Wait(); |
| 5908 SendContinueCommand(); | 5897 SendContinueCommand(); |
| 5909 debug_message_dispatch_barriers->barrier_2.Wait(); | 5898 debug_message_dispatch_barriers->barrier_2.Wait(); |
| 5910 } | 5899 } |
| 5911 | 5900 |
| 5912 | 5901 |
| 5913 TEST(DebuggerDebugMessageDispatch) { | 5902 TEST(DebuggerDebugMessageDispatch) { |
| 5914 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; | 5903 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; |
| 5915 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; | 5904 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; |
| 5916 | 5905 |
| 5917 i::FLAG_debugger_auto_break = true; | 5906 i::FLAG_debugger_auto_break = true; |
| 5918 | 5907 |
| 5919 // Create a V8 environment | 5908 // Create a V8 environment |
| 5920 Barriers stack_allocated_debug_message_dispatch_barriers; | 5909 Barriers stack_allocated_debug_message_dispatch_barriers; |
| 5921 stack_allocated_debug_message_dispatch_barriers.Initialize(); | |
| 5922 debug_message_dispatch_barriers = | 5910 debug_message_dispatch_barriers = |
| 5923 &stack_allocated_debug_message_dispatch_barriers; | 5911 &stack_allocated_debug_message_dispatch_barriers; |
| 5924 | 5912 |
| 5925 debug_message_dispatch_v8_thread.Start(); | 5913 debug_message_dispatch_v8_thread.Start(); |
| 5926 debug_message_dispatch_debugger_thread.Start(); | 5914 debug_message_dispatch_debugger_thread.Start(); |
| 5927 | 5915 |
| 5928 debug_message_dispatch_v8_thread.Join(); | 5916 debug_message_dispatch_v8_thread.Join(); |
| 5929 debug_message_dispatch_debugger_thread.Join(); | 5917 debug_message_dispatch_debugger_thread.Join(); |
| 5930 } | 5918 } |
| 5931 | 5919 |
| 5932 | 5920 |
| 5933 TEST(DebuggerAgent) { | 5921 TEST(DebuggerAgent) { |
| 5934 v8::V8::Initialize(); | 5922 v8::V8::Initialize(); |
| 5935 i::Debugger* debugger = i::Isolate::Current()->debugger(); | 5923 i::Debugger* debugger = i::Isolate::Current()->debugger(); |
| 5936 // Make sure these ports is not used by other tests to allow tests to run in | 5924 // Make sure these ports is not used by other tests to allow tests to run in |
| 5937 // parallel. | 5925 // parallel. |
| 5938 const int kPort1 = 5858 + FlagDependentPortOffset(); | 5926 const int kPort1 = 5858 + FlagDependentPortOffset(); |
| 5939 const int kPort2 = 5857 + FlagDependentPortOffset(); | 5927 const int kPort2 = 5857 + FlagDependentPortOffset(); |
| 5940 const int kPort3 = 5856 + FlagDependentPortOffset(); | 5928 const int kPort3 = 5856 + FlagDependentPortOffset(); |
| 5941 | 5929 |
| 5942 // Make a string with the port2 number. | 5930 // Make a string with the port2 number. |
| 5943 const int kPortBufferLen = 6; | 5931 const int kPortBufferLen = 6; |
| 5944 char port2_str[kPortBufferLen]; | 5932 char port2_str[kPortBufferLen]; |
| 5945 OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2); | 5933 OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2); |
| 5946 | 5934 |
| 5947 bool ok; | 5935 bool ok; |
| 5948 | 5936 |
| 5949 // Initialize the socket library. | |
| 5950 i::Socket::SetUp(); | |
| 5951 | |
| 5952 // Test starting and stopping the agent without any client connection. | 5937 // Test starting and stopping the agent without any client connection. |
| 5953 debugger->StartAgent("test", kPort1); | 5938 debugger->StartAgent("test", kPort1); |
| 5954 debugger->StopAgent(); | 5939 debugger->StopAgent(); |
| 5955 // Test starting the agent, connecting a client and shutting down the agent | 5940 // Test starting the agent, connecting a client and shutting down the agent |
| 5956 // with the client connected. | 5941 // with the client connected. |
| 5957 ok = debugger->StartAgent("test", kPort2); | 5942 ok = debugger->StartAgent("test", kPort2); |
| 5958 CHECK(ok); | 5943 CHECK(ok); |
| 5959 debugger->WaitForAgent(); | 5944 debugger->WaitForAgent(); |
| 5960 i::Socket* client = i::OS::CreateSocket(); | 5945 i::Socket* client = new i::Socket; |
| 5961 ok = client->Connect("localhost", port2_str); | 5946 ok = client->Connect("localhost", port2_str); |
| 5962 CHECK(ok); | 5947 CHECK(ok); |
| 5963 // It is important to wait for a message from the agent. Otherwise, | 5948 // It is important to wait for a message from the agent. Otherwise, |
| 5964 // we can close the server socket during "accept" syscall, making it failing | 5949 // we can close the server socket during "accept" syscall, making it failing |
| 5965 // (at least on Linux), and the test will work incorrectly. | 5950 // (at least on Linux), and the test will work incorrectly. |
| 5966 char buf; | 5951 char buf; |
| 5967 ok = client->Receive(&buf, 1) == 1; | 5952 ok = client->Receive(&buf, 1) == 1; |
| 5968 CHECK(ok); | 5953 CHECK(ok); |
| 5969 debugger->StopAgent(); | 5954 debugger->StopAgent(); |
| 5970 delete client; | 5955 delete client; |
| 5971 | 5956 |
| 5972 // Test starting and stopping the agent with the required port already | 5957 // Test starting and stopping the agent with the required port already |
| 5973 // occoupied. | 5958 // occoupied. |
| 5974 i::Socket* server = i::OS::CreateSocket(); | 5959 i::Socket* server = new i::Socket; |
| 5975 server->Bind(kPort3); | 5960 ok = server->Bind(kPort3); |
| 5961 CHECK(ok); |
| 5976 | 5962 |
| 5977 debugger->StartAgent("test", kPort3); | 5963 debugger->StartAgent("test", kPort3); |
| 5978 debugger->StopAgent(); | 5964 debugger->StopAgent(); |
| 5979 | 5965 |
| 5980 delete server; | 5966 delete server; |
| 5981 } | 5967 } |
| 5982 | 5968 |
| 5983 | 5969 |
| 5984 class DebuggerAgentProtocolServerThread : public i::Thread { | 5970 class DebuggerAgentProtocolServerThread : public i::Thread { |
| 5985 public: | 5971 public: |
| (...skipping 20 matching lines...) Expand all Loading... |
| 6006 i::Socket* server_; // Server socket used for bind/accept. | 5992 i::Socket* server_; // Server socket used for bind/accept. |
| 6007 i::Socket* client_; // Single client connection used by the test. | 5993 i::Socket* client_; // Single client connection used by the test. |
| 6008 i::Semaphore listening_; // Signalled when the server is in listen mode. | 5994 i::Semaphore listening_; // Signalled when the server is in listen mode. |
| 6009 }; | 5995 }; |
| 6010 | 5996 |
| 6011 | 5997 |
| 6012 void DebuggerAgentProtocolServerThread::Run() { | 5998 void DebuggerAgentProtocolServerThread::Run() { |
| 6013 bool ok; | 5999 bool ok; |
| 6014 | 6000 |
| 6015 // Create the server socket and bind it to the requested port. | 6001 // Create the server socket and bind it to the requested port. |
| 6016 server_ = i::OS::CreateSocket(); | 6002 server_ = new i::Socket; |
| 6017 CHECK(server_ != NULL); | 6003 CHECK(server_ != NULL); |
| 6018 ok = server_->Bind(port_); | 6004 ok = server_->Bind(port_); |
| 6019 CHECK(ok); | 6005 CHECK(ok); |
| 6020 | 6006 |
| 6021 // Listen for new connections. | 6007 // Listen for new connections. |
| 6022 ok = server_->Listen(1); | 6008 ok = server_->Listen(1); |
| 6023 CHECK(ok); | 6009 CHECK(ok); |
| 6024 listening_.Signal(); | 6010 listening_.Signal(); |
| 6025 | 6011 |
| 6026 // Accept a connection. | 6012 // Accept a connection. |
| 6027 client_ = server_->Accept(); | 6013 client_ = server_->Accept(); |
| 6028 CHECK(client_ != NULL); | 6014 CHECK(client_ != NULL); |
| 6029 | 6015 |
| 6030 // Receive a debugger agent protocol message. | 6016 // Receive a debugger agent protocol message. |
| 6031 i::DebuggerAgentUtil::ReceiveMessage(client_); | 6017 i::DebuggerAgentUtil::ReceiveMessage(client_); |
| 6032 } | 6018 } |
| 6033 | 6019 |
| 6034 | 6020 |
| 6035 TEST(DebuggerAgentProtocolOverflowHeader) { | 6021 TEST(DebuggerAgentProtocolOverflowHeader) { |
| 6036 // Make sure this port is not used by other tests to allow tests to run in | 6022 // Make sure this port is not used by other tests to allow tests to run in |
| 6037 // parallel. | 6023 // parallel. |
| 6038 const int kPort = 5860 + FlagDependentPortOffset(); | 6024 const int kPort = 5860 + FlagDependentPortOffset(); |
| 6039 static const char* kLocalhost = "localhost"; | 6025 static const char* kLocalhost = "localhost"; |
| 6040 | 6026 |
| 6041 // Make a string with the port number. | 6027 // Make a string with the port number. |
| 6042 const int kPortBufferLen = 6; | 6028 const int kPortBufferLen = 6; |
| 6043 char port_str[kPortBufferLen]; | 6029 char port_str[kPortBufferLen]; |
| 6044 OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort); | 6030 OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort); |
| 6045 | 6031 |
| 6046 // Initialize the socket library. | |
| 6047 i::Socket::SetUp(); | |
| 6048 | |
| 6049 // Create a socket server to receive a debugger agent message. | 6032 // Create a socket server to receive a debugger agent message. |
| 6050 DebuggerAgentProtocolServerThread* server = | 6033 DebuggerAgentProtocolServerThread* server = |
| 6051 new DebuggerAgentProtocolServerThread(kPort); | 6034 new DebuggerAgentProtocolServerThread(kPort); |
| 6052 server->Start(); | 6035 server->Start(); |
| 6053 server->WaitForListening(); | 6036 server->WaitForListening(); |
| 6054 | 6037 |
| 6055 // Connect. | 6038 // Connect. |
| 6056 i::Socket* client = i::OS::CreateSocket(); | 6039 i::Socket* client = new i::Socket; |
| 6057 CHECK(client != NULL); | 6040 CHECK(client != NULL); |
| 6058 bool ok = client->Connect(kLocalhost, port_str); | 6041 bool ok = client->Connect(kLocalhost, port_str); |
| 6059 CHECK(ok); | 6042 CHECK(ok); |
| 6060 | 6043 |
| 6061 // Send headers which overflow the receive buffer. | 6044 // Send headers which overflow the receive buffer. |
| 6062 static const int kBufferSize = 1000; | 6045 static const int kBufferSize = 1000; |
| 6063 char buffer[kBufferSize]; | 6046 char buffer[kBufferSize]; |
| 6064 | 6047 |
| 6065 // Long key and short value: XXXX....XXXX:0\r\n. | 6048 // Long key and short value: XXXX....XXXX:0\r\n. |
| 6066 for (int i = 0; i < kBufferSize - 4; i++) { | 6049 for (int i = 0; i < kBufferSize - 4; i++) { |
| 6067 buffer[i] = 'X'; | 6050 buffer[i] = 'X'; |
| 6068 } | 6051 } |
| 6069 buffer[kBufferSize - 4] = ':'; | 6052 buffer[kBufferSize - 4] = ':'; |
| 6070 buffer[kBufferSize - 3] = '0'; | 6053 buffer[kBufferSize - 3] = '0'; |
| 6071 buffer[kBufferSize - 2] = '\r'; | 6054 buffer[kBufferSize - 2] = '\r'; |
| 6072 buffer[kBufferSize - 1] = '\n'; | 6055 buffer[kBufferSize - 1] = '\n'; |
| 6073 client->Send(buffer, kBufferSize); | 6056 int result = client->Send(buffer, kBufferSize); |
| 6057 CHECK_EQ(kBufferSize, result); |
| 6074 | 6058 |
| 6075 // Short key and long value: X:XXXX....XXXX\r\n. | 6059 // Short key and long value: X:XXXX....XXXX\r\n. |
| 6076 buffer[0] = 'X'; | 6060 buffer[0] = 'X'; |
| 6077 buffer[1] = ':'; | 6061 buffer[1] = ':'; |
| 6078 for (int i = 2; i < kBufferSize - 2; i++) { | 6062 for (int i = 2; i < kBufferSize - 2; i++) { |
| 6079 buffer[i] = 'X'; | 6063 buffer[i] = 'X'; |
| 6080 } | 6064 } |
| 6081 buffer[kBufferSize - 2] = '\r'; | 6065 buffer[kBufferSize - 2] = '\r'; |
| 6082 buffer[kBufferSize - 1] = '\n'; | 6066 buffer[kBufferSize - 1] = '\n'; |
| 6083 client->Send(buffer, kBufferSize); | 6067 result = client->Send(buffer, kBufferSize); |
| 6068 CHECK_EQ(kBufferSize, result); |
| 6084 | 6069 |
| 6085 // Add empty body to request. | 6070 // Add empty body to request. |
| 6086 const char* content_length_zero_header = "Content-Length:0\r\n"; | 6071 const char* content_length_zero_header = "Content-Length:0\r\n"; |
| 6087 client->Send(content_length_zero_header, | 6072 int length = StrLength(content_length_zero_header); |
| 6088 StrLength(content_length_zero_header)); | 6073 result = client->Send(content_length_zero_header, length); |
| 6089 client->Send("\r\n", 2); | 6074 CHECK_EQ(length, result); |
| 6075 result = client->Send("\r\n", 2); |
| 6076 CHECK_EQ(2, result); |
| 6090 | 6077 |
| 6091 // Wait until data is received. | 6078 // Wait until data is received. |
| 6092 server->Join(); | 6079 server->Join(); |
| 6093 | 6080 |
| 6094 // Check for empty body. | 6081 // Check for empty body. |
| 6095 CHECK(server->body() == NULL); | 6082 CHECK(server->body() == NULL); |
| 6096 | 6083 |
| 6097 // Close the client before the server to avoid TIME_WAIT issues. | 6084 // Close the client before the server to avoid TIME_WAIT issues. |
| 6098 client->Shutdown(); | 6085 client->Shutdown(); |
| 6099 delete client; | 6086 delete client; |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6627 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); | 6614 v8::Script::Compile(v8::String::New("eval('a=1')"))->Run(); |
| 6628 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); | 6615 v8::Script::Compile(v8::String::New("eval('a=2')"))->Run(); |
| 6629 | 6616 |
| 6630 // Leave context | 6617 // Leave context |
| 6631 { | 6618 { |
| 6632 v8::HandleScope scope(isolate); | 6619 v8::HandleScope scope(isolate); |
| 6633 v8::Local<v8::Context> local_context = | 6620 v8::Local<v8::Context> local_context = |
| 6634 v8::Local<v8::Context>::New(isolate, context); | 6621 v8::Local<v8::Context>::New(isolate, context); |
| 6635 local_context->Exit(); | 6622 local_context->Exit(); |
| 6636 } | 6623 } |
| 6637 context.Dispose(isolate); | 6624 context.Dispose(); |
| 6638 | 6625 |
| 6639 // Do garbage collection to collect the script above which is no longer | 6626 // Do garbage collection to collect the script above which is no longer |
| 6640 // referenced. | 6627 // referenced. |
| 6641 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); | 6628 HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); |
| 6642 | 6629 |
| 6643 CHECK_EQ(2, script_collected_message_count); | 6630 CHECK_EQ(2, script_collected_message_count); |
| 6644 | 6631 |
| 6645 v8::Debug::SetMessageHandler2(NULL); | 6632 v8::Debug::SetMessageHandler2(NULL); |
| 6646 } | 6633 } |
| 6647 | 6634 |
| (...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7547 TEST(LiveEditDisabled) { | 7534 TEST(LiveEditDisabled) { |
| 7548 v8::internal::FLAG_allow_natives_syntax = true; | 7535 v8::internal::FLAG_allow_natives_syntax = true; |
| 7549 LocalContext env; | 7536 LocalContext env; |
| 7550 v8::HandleScope scope(env->GetIsolate()); | 7537 v8::HandleScope scope(env->GetIsolate()); |
| 7551 v8::Debug::SetLiveEditEnabled(false); | 7538 v8::Debug::SetLiveEditEnabled(false); |
| 7552 CompileRun("%LiveEditCompareStrings('', '')"); | 7539 CompileRun("%LiveEditCompareStrings('', '')"); |
| 7553 } | 7540 } |
| 7554 | 7541 |
| 7555 | 7542 |
| 7556 #endif // ENABLE_DEBUGGER_SUPPORT | 7543 #endif // ENABLE_DEBUGGER_SUPPORT |
| OLD | NEW |