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 5770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5781 // handler. | 5781 // handler. |
5782 CompileRun("throw 1"); | 5782 CompileRun("throw 1"); |
5783 | 5783 |
5784 // The message handler should be called. | 5784 // The message handler should be called. |
5785 CHECK_EQ(1, message_handler_hit_count); | 5785 CHECK_EQ(1, message_handler_hit_count); |
5786 | 5786 |
5787 CheckDebuggerUnloaded(true); | 5787 CheckDebuggerUnloaded(true); |
5788 } | 5788 } |
5789 | 5789 |
5790 | 5790 |
5791 /* Test DebugMessageDispatch */ | |
5792 /* In this test, the V8 thread waits for a message from the debug thread. | |
5793 * The DebugMessageDispatchHandler is executed from the debugger thread | |
5794 * which signals the V8 thread to wake up. | |
5795 */ | |
5796 | |
5797 class DebugMessageDispatchV8Thread : public v8::internal::Thread { | |
5798 public: | |
5799 DebugMessageDispatchV8Thread() : Thread("DebugMessageDispatchV8Thread") { } | |
5800 void Run(); | |
5801 }; | |
5802 | |
5803 class DebugMessageDispatchDebuggerThread : public v8::internal::Thread { | |
5804 public: | |
5805 DebugMessageDispatchDebuggerThread() | |
5806 : Thread("DebugMessageDispatchDebuggerThread") { } | |
5807 void Run(); | |
5808 }; | |
5809 | |
5810 Barriers* debug_message_dispatch_barriers; | |
5811 | |
5812 | |
5813 static void DebugMessageHandler() { | |
5814 debug_message_dispatch_barriers->semaphore_1.Signal(); | |
5815 } | |
5816 | |
5817 | |
5818 void DebugMessageDispatchV8Thread::Run() { | |
5819 v8::Isolate::Scope isolate_scope(CcTest::isolate()); | |
5820 DebugLocalContext env; | |
5821 v8::HandleScope scope(env->GetIsolate()); | |
5822 | |
5823 // Set up debug message dispatch handler. | |
5824 v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler); | |
5825 | |
5826 CompileRun("var y = 1 + 2;\n"); | |
5827 debug_message_dispatch_barriers->barrier_1.Wait(); | |
5828 debug_message_dispatch_barriers->semaphore_1.Wait(); | |
5829 debug_message_dispatch_barriers->barrier_2.Wait(); | |
5830 } | |
5831 | |
5832 | |
5833 void DebugMessageDispatchDebuggerThread::Run() { | |
5834 debug_message_dispatch_barriers->barrier_1.Wait(); | |
5835 SendContinueCommand(); | |
5836 debug_message_dispatch_barriers->barrier_2.Wait(); | |
5837 } | |
5838 | |
5839 | |
5840 TEST(DebuggerDebugMessageDispatch) { | |
5841 DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread; | |
5842 DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread; | |
5843 | |
5844 // Create a V8 environment | |
5845 Barriers stack_allocated_debug_message_dispatch_barriers; | |
5846 debug_message_dispatch_barriers = | |
5847 &stack_allocated_debug_message_dispatch_barriers; | |
5848 | |
5849 debug_message_dispatch_v8_thread.Start(); | |
5850 debug_message_dispatch_debugger_thread.Start(); | |
5851 | |
5852 debug_message_dispatch_v8_thread.Join(); | |
5853 debug_message_dispatch_debugger_thread.Join(); | |
5854 } | |
5855 | |
5856 | |
5857 TEST(DebuggerAgent) { | |
5858 v8::V8::Initialize(); | |
5859 i::Debugger* debugger = CcTest::i_isolate()->debugger(); | |
5860 // Make sure these ports is not used by other tests to allow tests to run in | |
5861 // parallel. | |
5862 const int kPort1 = 5858 + FlagDependentPortOffset(); | |
5863 const int kPort2 = 5857 + FlagDependentPortOffset(); | |
5864 const int kPort3 = 5856 + FlagDependentPortOffset(); | |
5865 | |
5866 // Make a string with the port2 number. | |
5867 const int kPortBufferLen = 6; | |
5868 char port2_str[kPortBufferLen]; | |
5869 OS::SNPrintF(i::Vector<char>(port2_str, kPortBufferLen), "%d", kPort2); | |
5870 | |
5871 bool ok; | |
5872 | |
5873 // Test starting and stopping the agent without any client connection. | |
5874 debugger->StartAgent("test", kPort1); | |
5875 debugger->StopAgent(); | |
5876 // Test starting the agent, connecting a client and shutting down the agent | |
5877 // with the client connected. | |
5878 ok = debugger->StartAgent("test", kPort2); | |
5879 CHECK(ok); | |
5880 debugger->WaitForAgent(); | |
5881 i::Socket* client = new i::Socket; | |
5882 ok = client->Connect("localhost", port2_str); | |
5883 CHECK(ok); | |
5884 // It is important to wait for a message from the agent. Otherwise, | |
5885 // we can close the server socket during "accept" syscall, making it failing | |
5886 // (at least on Linux), and the test will work incorrectly. | |
5887 char buf; | |
5888 ok = client->Receive(&buf, 1) == 1; | |
5889 CHECK(ok); | |
5890 debugger->StopAgent(); | |
5891 delete client; | |
5892 | |
5893 // Test starting and stopping the agent with the required port already | |
5894 // occoupied. | |
5895 i::Socket* server = new i::Socket; | |
5896 ok = server->Bind(kPort3); | |
5897 CHECK(ok); | |
5898 | |
5899 debugger->StartAgent("test", kPort3); | |
5900 debugger->StopAgent(); | |
5901 | |
5902 delete server; | |
5903 } | |
5904 | |
5905 | |
5906 class DebuggerAgentProtocolServerThread : public i::Thread { | |
5907 public: | |
5908 explicit DebuggerAgentProtocolServerThread(int port) | |
5909 : Thread("DebuggerAgentProtocolServerThread"), | |
5910 port_(port), | |
5911 server_(NULL), | |
5912 client_(NULL), | |
5913 listening_(0) { | |
5914 } | |
5915 ~DebuggerAgentProtocolServerThread() { | |
5916 // Close both sockets. | |
5917 delete client_; | |
5918 delete server_; | |
5919 } | |
5920 | |
5921 void Run(); | |
5922 void WaitForListening() { listening_.Wait(); } | |
5923 char* body() { return body_.get(); } | |
5924 | |
5925 private: | |
5926 int port_; | |
5927 i::SmartArrayPointer<char> body_; | |
5928 i::Socket* server_; // Server socket used for bind/accept. | |
5929 i::Socket* client_; // Single client connection used by the test. | |
5930 i::Semaphore listening_; // Signalled when the server is in listen mode. | |
5931 }; | |
5932 | |
5933 | |
5934 void DebuggerAgentProtocolServerThread::Run() { | |
5935 bool ok; | |
5936 | |
5937 // Create the server socket and bind it to the requested port. | |
5938 server_ = new i::Socket; | |
5939 CHECK(server_ != NULL); | |
5940 ok = server_->Bind(port_); | |
5941 CHECK(ok); | |
5942 | |
5943 // Listen for new connections. | |
5944 ok = server_->Listen(1); | |
5945 CHECK(ok); | |
5946 listening_.Signal(); | |
5947 | |
5948 // Accept a connection. | |
5949 client_ = server_->Accept(); | |
5950 CHECK(client_ != NULL); | |
5951 | |
5952 // Receive a debugger agent protocol message. | |
5953 i::DebuggerAgentUtil::ReceiveMessage(client_); | |
5954 } | |
5955 | |
5956 | |
5957 TEST(DebuggerAgentProtocolOverflowHeader) { | |
5958 // Make sure this port is not used by other tests to allow tests to run in | |
5959 // parallel. | |
5960 const int kPort = 5860 + FlagDependentPortOffset(); | |
5961 static const char* kLocalhost = "localhost"; | |
5962 | |
5963 // Make a string with the port number. | |
5964 const int kPortBufferLen = 6; | |
5965 char port_str[kPortBufferLen]; | |
5966 OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort); | |
5967 | |
5968 // Create a socket server to receive a debugger agent message. | |
5969 DebuggerAgentProtocolServerThread* server = | |
5970 new DebuggerAgentProtocolServerThread(kPort); | |
5971 server->Start(); | |
5972 server->WaitForListening(); | |
5973 | |
5974 // Connect. | |
5975 i::Socket* client = new i::Socket; | |
5976 CHECK(client != NULL); | |
5977 bool ok = client->Connect(kLocalhost, port_str); | |
5978 CHECK(ok); | |
5979 | |
5980 // Send headers which overflow the receive buffer. | |
5981 static const int kBufferSize = 1000; | |
5982 char buffer[kBufferSize]; | |
5983 | |
5984 // Long key and short value: XXXX....XXXX:0\r\n. | |
5985 for (int i = 0; i < kBufferSize - 4; i++) { | |
5986 buffer[i] = 'X'; | |
5987 } | |
5988 buffer[kBufferSize - 4] = ':'; | |
5989 buffer[kBufferSize - 3] = '0'; | |
5990 buffer[kBufferSize - 2] = '\r'; | |
5991 buffer[kBufferSize - 1] = '\n'; | |
5992 int result = client->Send(buffer, kBufferSize); | |
5993 CHECK_EQ(kBufferSize, result); | |
5994 | |
5995 // Short key and long value: X:XXXX....XXXX\r\n. | |
5996 buffer[0] = 'X'; | |
5997 buffer[1] = ':'; | |
5998 for (int i = 2; i < kBufferSize - 2; i++) { | |
5999 buffer[i] = 'X'; | |
6000 } | |
6001 buffer[kBufferSize - 2] = '\r'; | |
6002 buffer[kBufferSize - 1] = '\n'; | |
6003 result = client->Send(buffer, kBufferSize); | |
6004 CHECK_EQ(kBufferSize, result); | |
6005 | |
6006 // Add empty body to request. | |
6007 const char* content_length_zero_header = "Content-Length:0\r\n"; | |
6008 int length = StrLength(content_length_zero_header); | |
6009 result = client->Send(content_length_zero_header, length); | |
6010 CHECK_EQ(length, result); | |
6011 result = client->Send("\r\n", 2); | |
6012 CHECK_EQ(2, result); | |
6013 | |
6014 // Wait until data is received. | |
6015 server->Join(); | |
6016 | |
6017 // Check for empty body. | |
6018 CHECK(server->body() == NULL); | |
6019 | |
6020 // Close the client before the server to avoid TIME_WAIT issues. | |
6021 client->Shutdown(); | |
6022 delete client; | |
6023 delete server; | |
6024 } | |
6025 | |
6026 | |
6027 // Test for issue http://code.google.com/p/v8/issues/detail?id=289. | 5791 // Test for issue http://code.google.com/p/v8/issues/detail?id=289. |
6028 // Make sure that DebugGetLoadedScripts doesn't return scripts | 5792 // Make sure that DebugGetLoadedScripts doesn't return scripts |
6029 // with disposed external source. | 5793 // with disposed external source. |
6030 class EmptyExternalStringResource : public v8::String::ExternalStringResource { | 5794 class EmptyExternalStringResource : public v8::String::ExternalStringResource { |
6031 public: | 5795 public: |
6032 EmptyExternalStringResource() { empty_[0] = 0; } | 5796 EmptyExternalStringResource() { empty_[0] = 0; } |
6033 virtual ~EmptyExternalStringResource() {} | 5797 virtual ~EmptyExternalStringResource() {} |
6034 virtual size_t length() const { return empty_.length(); } | 5798 virtual size_t length() const { return empty_.length(); } |
6035 virtual const uint16_t* data() const { return empty_.start(); } | 5799 virtual const uint16_t* data() const { return empty_.start(); } |
6036 private: | 5800 private: |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6776 | 6540 |
6777 // Get rid of the debug message handler. | 6541 // Get rid of the debug message handler. |
6778 v8::Debug::SetMessageHandler2(NULL); | 6542 v8::Debug::SetMessageHandler2(NULL); |
6779 CheckDebuggerUnloaded(); | 6543 CheckDebuggerUnloaded(); |
6780 } | 6544 } |
6781 | 6545 |
6782 | 6546 |
6783 static int counting_message_handler_counter; | 6547 static int counting_message_handler_counter; |
6784 | 6548 |
6785 static void CountingMessageHandler(const v8::Debug::Message& message) { | 6549 static void CountingMessageHandler(const v8::Debug::Message& message) { |
6786 counting_message_handler_counter++; | 6550 if (message.IsResponse()) counting_message_handler_counter++; |
6787 } | 6551 } |
6788 | 6552 |
6789 | 6553 |
6790 // Test that debug messages get processed when ProcessDebugMessages is called. | 6554 // Test that debug messages get processed when ProcessDebugMessages is called. |
6791 TEST(ProcessDebugMessages) { | 6555 TEST(ProcessDebugMessages) { |
6792 DebugLocalContext env; | 6556 DebugLocalContext env; |
6793 v8::Isolate* isolate = env->GetIsolate(); | 6557 v8::Isolate* isolate = env->GetIsolate(); |
6794 v8::HandleScope scope(isolate); | 6558 v8::HandleScope scope(isolate); |
6795 | 6559 |
6796 counting_message_handler_counter = 0; | 6560 counting_message_handler_counter = 0; |
(...skipping 26 matching lines...) Expand all Loading... |
6823 v8::Debug::ProcessDebugMessages(); | 6587 v8::Debug::ProcessDebugMessages(); |
6824 // At least two messages should come | 6588 // At least two messages should come |
6825 CHECK_GE(counting_message_handler_counter, 2); | 6589 CHECK_GE(counting_message_handler_counter, 2); |
6826 | 6590 |
6827 // Get rid of the debug message handler. | 6591 // Get rid of the debug message handler. |
6828 v8::Debug::SetMessageHandler2(NULL); | 6592 v8::Debug::SetMessageHandler2(NULL); |
6829 CheckDebuggerUnloaded(); | 6593 CheckDebuggerUnloaded(); |
6830 } | 6594 } |
6831 | 6595 |
6832 | 6596 |
| 6597 class SendCommandThread : public v8::internal::Thread { |
| 6598 public: |
| 6599 explicit SendCommandThread(v8::Isolate* isolate) |
| 6600 : Thread("SendCommandThread"), |
| 6601 semaphore_(0), |
| 6602 isolate_(isolate) { } |
| 6603 |
| 6604 static void ProcessDebugMessages(v8::Isolate* isolate, void* data) { |
| 6605 v8::Debug::ProcessDebugMessages(); |
| 6606 reinterpret_cast<v8::internal::Semaphore*>(data)->Signal(); |
| 6607 } |
| 6608 |
| 6609 virtual void Run() { |
| 6610 semaphore_.Wait(); |
| 6611 const int kBufferSize = 1000; |
| 6612 uint16_t buffer[kBufferSize]; |
| 6613 const char* scripts_command = |
| 6614 "{\"seq\":0," |
| 6615 "\"type\":\"request\"," |
| 6616 "\"command\":\"scripts\"}"; |
| 6617 int length = AsciiToUtf16(scripts_command, buffer); |
| 6618 // Send scripts command. |
| 6619 |
| 6620 for (int i = 0; i < 100; i++) { |
| 6621 CHECK_EQ(i, counting_message_handler_counter); |
| 6622 // Queue debug message. |
| 6623 v8::Debug::SendCommand(isolate_, buffer, length); |
| 6624 // Synchronize with the main thread to force message processing. |
| 6625 isolate_->RequestInterrupt(ProcessDebugMessages, &semaphore_); |
| 6626 semaphore_.Wait(); |
| 6627 } |
| 6628 |
| 6629 v8::V8::TerminateExecution(isolate_); |
| 6630 } |
| 6631 |
| 6632 void StartSending() { |
| 6633 semaphore_.Signal(); |
| 6634 } |
| 6635 |
| 6636 private: |
| 6637 v8::internal::Semaphore semaphore_; |
| 6638 v8::Isolate* isolate_; |
| 6639 }; |
| 6640 |
| 6641 |
| 6642 static SendCommandThread* send_command_thread_ = NULL; |
| 6643 |
| 6644 static void StartSendingCommands( |
| 6645 const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 6646 send_command_thread_->StartSending(); |
| 6647 } |
| 6648 |
| 6649 |
| 6650 TEST(ProcessDebugMessagesThreaded) { |
| 6651 DebugLocalContext env; |
| 6652 v8::Isolate* isolate = env->GetIsolate(); |
| 6653 v8::HandleScope scope(isolate); |
| 6654 |
| 6655 counting_message_handler_counter = 0; |
| 6656 |
| 6657 v8::Debug::SetMessageHandler2(CountingMessageHandler); |
| 6658 send_command_thread_ = new SendCommandThread(isolate); |
| 6659 send_command_thread_->Start(); |
| 6660 |
| 6661 v8::Handle<v8::FunctionTemplate> start = |
| 6662 v8::FunctionTemplate::New(isolate, StartSendingCommands); |
| 6663 env->Global()->Set(v8_str("start"), start->GetFunction()); |
| 6664 |
| 6665 CompileRun("start(); while (true) { }"); |
| 6666 |
| 6667 CHECK_EQ(100, counting_message_handler_counter); |
| 6668 |
| 6669 v8::Debug::SetMessageHandler2(NULL); |
| 6670 CheckDebuggerUnloaded(); |
| 6671 } |
| 6672 |
| 6673 |
6833 struct BacktraceData { | 6674 struct BacktraceData { |
6834 static int frame_counter; | 6675 static int frame_counter; |
6835 static void MessageHandler(const v8::Debug::Message& message) { | 6676 static void MessageHandler(const v8::Debug::Message& message) { |
6836 char print_buffer[1000]; | 6677 char print_buffer[1000]; |
6837 v8::String::Value json(message.GetJSON()); | 6678 v8::String::Value json(message.GetJSON()); |
6838 Utf16ToAscii(*json, json.length(), print_buffer, 1000); | 6679 Utf16ToAscii(*json, json.length(), print_buffer, 1000); |
6839 | 6680 |
6840 if (strstr(print_buffer, "backtrace") == NULL) { | 6681 if (strstr(print_buffer, "backtrace") == NULL) { |
6841 return; | 6682 return; |
6842 } | 6683 } |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7581 env->Global()->Set(v8_str("add_debug_break"), add_debug_break); | 7422 env->Global()->Set(v8_str("add_debug_break"), add_debug_break); |
7582 | 7423 |
7583 CompileRun("(function loop() {" | 7424 CompileRun("(function loop() {" |
7584 " for (var j = 0; j < 1000; j++) {" | 7425 " for (var j = 0; j < 1000; j++) {" |
7585 " for (var i = 0; i < 1000; i++) {" | 7426 " for (var i = 0; i < 1000; i++) {" |
7586 " if (i == 999) add_debug_break();" | 7427 " if (i == 999) add_debug_break();" |
7587 " }" | 7428 " }" |
7588 " }" | 7429 " }" |
7589 "})()"); | 7430 "})()"); |
7590 } | 7431 } |
OLD | NEW |