Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(846)

Unified Diff: test/cctest/test-debug.cc

Issue 1321543004: [futex] Allow debugger to break in the middle of a futexWait Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: enable debugging scope Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/debug/debug.cc ('K') | « src/futex-emulation.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/cctest/test-debug.cc
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 1e3f0ab707eab90451e4c762516ad0909bf53b6e..58c6bd87f9818f52d342fd095b882772b69b6897 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -36,6 +36,7 @@
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
#include "src/frames.h"
+#include "src/futex-emulation.h"
#include "src/utils.h"
#include "test/cctest/cctest.h"
@@ -7626,3 +7627,147 @@ TEST(DebugBreakInLexicalScopes) {
"x * y",
30);
}
+
+
+Barriers futex_barriers;
+
+
+class FutexV8Thread : public v8::base::Thread {
+ public:
+ FutexV8Thread(void* sab_data, size_t sab_size)
+ : Thread(Options("V8Thread")), sab_data_(sab_data), sab_size_(sab_size) {}
+ void Run();
+ v8::Isolate* isolate() { return isolate_; }
+
+ private:
+ v8::Isolate* isolate_;
+ void* sab_data_;
+ size_t sab_size_;
+};
+
+
+class FutexDebuggerThread : public v8::base::Thread {
+ public:
+ explicit FutexDebuggerThread(v8::Isolate* v8_isolate, void* sab_data,
+ size_t sab_size)
+ : Thread(Options("DebuggerThread")),
+ v8_isolate_(v8_isolate),
+ sab_data_(sab_data),
+ sab_size_(sab_size) {}
+ void Run();
+
+ private:
+ v8::Isolate* v8_isolate_;
+ void* sab_data_;
+ size_t sab_size_;
+};
+
+
+static void FutexMessageHandler(const v8::Debug::Message& message) {
+ static char print_buffer[1000];
+ v8::String::Value json(message.GetJSON());
+ Utf16ToAscii(*json, json.length(), print_buffer);
+ if (IsBreakEventMessage(print_buffer)) {
+ // Check that we are inside the futex.
+ int source_line = GetSourceLineFromBreakEventMessage(print_buffer);
+ CHECK(source_line == 1);
+ futex_barriers.barrier_2.Wait();
+ }
+}
+
+
+void FutexV8Thread::Run() {
+ const char* source =
+ "var i32a = new Int32Array(sab);\n"
+ "Atomics.futexWait(i32a, 0, 0, Infinity)\n";
+
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ isolate_ = v8::Isolate::New(create_params);
+ futex_barriers.barrier_3.Wait();
+ {
+ v8::Isolate::Scope isolate_scope(isolate_);
+ DebugLocalContext env(isolate_);
+ v8::HandleScope scope(isolate_);
+ v8::Debug::SetMessageHandler(&FutexMessageHandler);
+ v8::Handle<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(env->GetIsolate());
+ global_template->Set(
+ v8::String::NewFromUtf8(env->GetIsolate(), "sab"),
+ v8::SharedArrayBuffer::New(isolate_, sab_data_, sab_size_));
+
+ v8::Handle<v8::Context> context =
+ v8::Context::New(isolate_, NULL, global_template);
+ v8::Context::Scope context_scope(context);
+
+ CompileRun(source);
+ }
+ futex_barriers.barrier_4.Wait();
+ isolate_->Dispose();
+}
+
+
+void FutexDebuggerThread::Run() {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ v8::Isolate* debug_isolate = v8::Isolate::New(create_params);
+ {
+ v8::Isolate::Scope isolate_scope(debug_isolate);
+ DebugLocalContext env(debug_isolate);
+ v8::HandleScope scope(debug_isolate);
+ v8::Handle<v8::SharedArrayBuffer> sab(
+ v8::SharedArrayBuffer::New(debug_isolate, sab_data_, sab_size_));
+
+ i::Handle<i::JSArrayBuffer> i_sab = v8::Utils::OpenHandle(*sab);
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(debug_isolate);
+ // Spin loop until v8 thread is waiting on futex.
+ while (true) {
+ i::Object* num_waiters =
+ i::FutexEmulation::NumWaitersForTesting(i_isolate, i_sab, 0);
+ if (num_waiters->IsSmi() && i::Smi::cast(num_waiters)->value() > 0) {
+ break;
+ }
+ }
+
+ v8::Debug::DebugBreak(v8_isolate_);
+ futex_barriers.barrier_2.Wait();
+
+ i::FutexEmulation::Wake(i_isolate, i_sab, 0, 1);
+ {
+ const int kBufferSize = 1000;
+ uint16_t buffer[kBufferSize];
+ const char* command_continue =
+ "{\"seq\":0,"
+ "\"type\":\"request\","
+ "\"command\":\"continue\"}";
+
+ v8::Debug::SendCommand(v8_isolate_, buffer,
+ AsciiToUtf16(command_continue, buffer));
+ }
+ futex_barriers.barrier_4.Wait();
+ }
+ debug_isolate->Dispose();
+}
+
+
+TEST(FutexDebugging) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ i::FLAG_harmony_atomics = true;
+
+ size_t size = 16;
+ v8::ArrayBuffer::Allocator* array_buffer_allocator =
+ CcTest::array_buffer_allocator();
+ void* data = array_buffer_allocator->Allocate(size);
+
+ FutexV8Thread v8_thread(data, size);
+
+ // Create a V8 environment
+ v8_thread.Start();
+ futex_barriers.barrier_3.Wait();
+ FutexDebuggerThread debugger_thread(v8_thread.isolate(), data, size);
+ debugger_thread.Start();
+
+ v8_thread.Join();
+ debugger_thread.Join();
+ array_buffer_allocator->Free(data, size);
+}
« src/debug/debug.cc ('K') | « src/futex-emulation.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698