Version 1.23.0-dev.11.5
Cherry-pick 17b1e30d045c4bbf2b156b66a973e0fdaba136f0 into dev
Cherry-pick 8c9c54d833865201abdaadbfa25c0c17b07d9926 into dev
Cherry-pick 74229dfb1f162026c7d855ffe1b12cabe46c2116 into dev
Cherry-pick 4654381213f777d3db91a6918009f61a8ef4029d into dev
Cherry-pick e33e09a23c61afac0827336c27b0d99789119b8c into dev
diff --git a/DEPS b/DEPS
index 09f98ed..923c0f7 100644
--- a/DEPS
+++ b/DEPS
@@ -59,7 +59,7 @@
"dart2js_info_tag" : "@0.5.3+1",
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
"dart_style_tag": "@1.0.2+1",
- "dartdoc_tag" : "@v0.9.12",
+ "dartdoc_tag" : "@v0.9.14-dev",
"fixnum_tag": "@0.10.5",
"func_tag": "@0.1.1",
"glob_tag": "@1.1.3",
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index e961581..a6c16a6 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -156,7 +156,15 @@
// If the handle uses synchronous I/O (e.g. stdin), cancel any pending
// operation before closing the handle, so the read thread is not blocked.
BOOL result = CancelIoEx(handle_, NULL);
- ASSERT(result || (GetLastError() == ERROR_NOT_FOUND));
+// The Dart code 'stdin.listen(() {}).cancel()' causes this assert to be
+// triggered on Windows 7, but not on Windows 10.
+#if defined(DEBUG)
+ if (IsWindows10OrGreater()) {
+ ASSERT(result || (GetLastError() == ERROR_NOT_FOUND));
+ }
+#else
+ USE(result);
+#endif
}
if (!IsClosing()) {
// Close the socket and set the closing state. This close method can be
@@ -753,6 +761,18 @@
}
+Mutex* StdHandle::stdin_mutex_ = new Mutex();
+StdHandle* StdHandle::stdin_ = NULL;
+
+StdHandle* StdHandle::Stdin(HANDLE handle) {
+ MutexLocker ml(stdin_mutex_);
+ if (stdin_ == NULL) {
+ stdin_ = new StdHandle(handle);
+ }
+ return stdin_;
+}
+
+
static void WriteFileThread(uword args) {
StdHandle* handle = reinterpret_cast<StdHandle*>(args);
handle->RunWriteLoop();
@@ -845,19 +865,24 @@
void StdHandle::DoClose() {
- MonitorLocker ml(monitor_);
- if (write_thread_exists_) {
- write_thread_running_ = false;
- ml.Notify();
- while (write_thread_exists_) {
- ml.Wait(Monitor::kNoTimeout);
+ {
+ MonitorLocker ml(monitor_);
+ if (write_thread_exists_) {
+ write_thread_running_ = false;
+ ml.Notify();
+ while (write_thread_exists_) {
+ ml.Wait(Monitor::kNoTimeout);
+ }
+ // Join the thread.
+ DWORD res = WaitForSingleObject(thread_handle_, INFINITE);
+ CloseHandle(thread_handle_);
+ ASSERT(res == WAIT_OBJECT_0);
}
- // Join the thread.
- DWORD res = WaitForSingleObject(thread_handle_, INFINITE);
- CloseHandle(thread_handle_);
- ASSERT(res == WAIT_OBJECT_0);
+ Handle::DoClose();
}
- Handle::DoClose();
+ MutexLocker ml(stdin_mutex_);
+ stdin_->Release();
+ StdHandle::stdin_ = NULL;
}
@@ -1512,7 +1537,6 @@
}
handler_impl->HandleCompletionOrInterrupt(ok, bytes, key, overlapped);
}
-#endif
// The eventhandler thread is going down so there should be no more live
// Handles or Sockets.
@@ -1520,9 +1544,13 @@
// ReferenceCounted<Handle>::instances() == 0;
// However, we cannot at the moment. See the TODO on:
// ClientSocket::IssueDisconnect()
+ // Furthermore, if the Dart program references stdin, but does not
+ // explicitly close it, then the StdHandle for it will be leaked to here.
+ const intptr_t stdin_leaked = (StdHandle::StdinPtr() == NULL) ? 0 : 1;
DEBUG_ASSERT(ReferenceCounted<Handle>::instances() ==
- ClientSocket::disconnecting());
+ ClientSocket::disconnecting() + stdin_leaked);
DEBUG_ASSERT(ReferenceCounted<Socket>::instances() == 0);
+#endif // defined(DEBUG)
handler->NotifyShutdownDone();
}
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 6e73efe..93dd44c 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -310,6 +310,22 @@
class StdHandle : public FileHandle {
public:
+ static StdHandle* Stdin(HANDLE handle);
+
+ virtual void DoClose();
+ virtual intptr_t Write(const void* buffer, intptr_t num_bytes);
+
+ void WriteSyncCompleteAsync();
+ void RunWriteLoop();
+
+#if defined(DEBUG)
+ static StdHandle* StdinPtr() { return stdin_; }
+#endif
+
+ private:
+ static Mutex* stdin_mutex_;
+ static StdHandle* stdin_;
+
explicit StdHandle(HANDLE handle)
: FileHandle(handle),
thread_id_(Thread::kInvalidThreadId),
@@ -320,13 +336,6 @@
type_ = kStd;
}
- virtual void DoClose();
- virtual intptr_t Write(const void* buffer, intptr_t num_bytes);
-
- void WriteSyncCompleteAsync();
- void RunWriteLoop();
-
- private:
ThreadId thread_id_;
HANDLE thread_handle_;
intptr_t thread_wrote_;
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 2196619..b27d83c 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -566,10 +566,7 @@
struct stat buf;
int result = fstat(fd, &buf);
if (result == -1) {
- const int kBufferSize = 1024;
- char error_message[kBufferSize];
- Utils::StrError(errno, error_message, kBufferSize);
- FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
+ return kOther;
}
if (S_ISCHR(buf.st_mode)) {
return kTerminal;
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index fb89e8c..6824282 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -541,10 +541,7 @@
struct stat buf;
int result = fstat(fd, &buf);
if (result == -1) {
- const int kBufferSize = 1024;
- char error_message[kBufferSize];
- Utils::StrError(errno, error_message, kBufferSize);
- FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
+ return kOther;
}
if (S_ISCHR(buf.st_mode)) {
return kTerminal;
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index 194a93f..3c421ce 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -578,10 +578,7 @@
struct stat64 buf;
int result = TEMP_FAILURE_RETRY(fstat64(fd, &buf));
if (result == -1) {
- const int kBufferSize = 1024;
- char error_buf[kBufferSize];
- FATAL2("Failed stat on file descriptor %d: %s", fd,
- Utils::StrError(errno, error_buf, kBufferSize));
+ return kOther;
}
if (S_ISCHR(buf.st_mode)) {
return kTerminal;
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 9f09b79..0c8d9d6 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -540,10 +540,7 @@
struct stat buf;
int result = fstat(fd, &buf);
if (result == -1) {
- const int kBufferSize = 1024;
- char error_message[kBufferSize];
- Utils::StrError(errno, error_message, kBufferSize);
- FATAL2("Failed stat on file descriptor %d: %s", fd, error_message);
+ return kOther;
}
if (S_ISCHR(buf.st_mode)) {
return kTerminal;
diff --git a/runtime/bin/process.cc b/runtime/bin/process.cc
index f636657..8013328 100644
--- a/runtime/bin/process.cc
+++ b/runtime/bin/process.cc
@@ -161,12 +161,16 @@
&process_stdin, &process_stderr, &pid, &exit_event, &os_error_message);
if (error_code == 0) {
if (mode != kDetached) {
- Socket::SetSocketIdNativeField(stdin_handle, process_stdin, false);
- Socket::SetSocketIdNativeField(stdout_handle, process_stdout, false);
- Socket::SetSocketIdNativeField(stderr_handle, process_stderr, false);
+ Socket::SetSocketIdNativeField(stdin_handle, process_stdin,
+ Socket::kFinalizerNormal);
+ Socket::SetSocketIdNativeField(stdout_handle, process_stdout,
+ Socket::kFinalizerNormal);
+ Socket::SetSocketIdNativeField(stderr_handle, process_stderr,
+ Socket::kFinalizerNormal);
}
if (mode == kNormal) {
- Socket::SetSocketIdNativeField(exit_handle, exit_event, false);
+ Socket::SetSocketIdNativeField(exit_handle, exit_event,
+ Socket::kFinalizerNormal);
}
Process::SetProcessIdNativeField(process, pid);
} else {
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 5002524..a208613 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -147,7 +147,7 @@
// We set as a side-effect the file descriptor on the dart
// socket_object.
Socket::ReuseSocketIdNativeField(socket_object, os_socket->socketfd,
- true);
+ Socket::kFinalizerListening);
return Dart_True();
}
@@ -199,7 +199,8 @@
InsertByFd(socketfd, os_socket);
// We set as a side-effect the port on the dart socket_object.
- Socket::ReuseSocketIdNativeField(socket_object, socketfd, true);
+ Socket::ReuseSocketIdNativeField(socket_object, socketfd,
+ Socket::kFinalizerListening);
return Dart_True();
}
@@ -305,7 +306,7 @@
OSError error;
if (socket >= 0) {
Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
- false);
+ Socket::kFinalizerNormal);
Dart_SetReturnValue(args, Dart_True());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
@@ -325,7 +326,7 @@
OSError error;
if (socket >= 0) {
Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
- false);
+ Socket::kFinalizerNormal);
Dart_SetReturnValue(args, Dart_True());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError(&error));
@@ -349,7 +350,7 @@
intptr_t socket = Socket::CreateBindDatagram(addr, reuse_addr);
if (socket >= 0) {
Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
- false);
+ Socket::kFinalizerNormal);
Dart_SetReturnValue(args, Dart_True());
} else {
OSError error;
@@ -628,7 +629,7 @@
DartUtils::GetInt64ValueCheckRange(Dart_GetNativeArgument(args, 1), 0, 2);
intptr_t socket = Socket::GetStdioHandle(num);
Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), socket,
- false);
+ Socket::kFinalizerStdio);
Dart_SetReturnValue(args, Dart_NewBoolean(socket >= 0));
}
@@ -643,7 +644,8 @@
void FUNCTION_NAME(Socket_SetSocketId)(Dart_NativeArguments args) {
intptr_t id = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
- Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), id, false);
+ Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), id,
+ Socket::kFinalizerNormal);
}
@@ -671,7 +673,7 @@
intptr_t new_socket = ServerSocket::Accept(socket->fd());
if (new_socket >= 0) {
Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 1), new_socket,
- false);
+ Socket::kFinalizerNormal);
Dart_SetReturnValue(args, Dart_True());
} else if (new_socket == ServerSocket::kTemporaryFailure) {
Dart_SetReturnValue(args, Dart_False());
@@ -944,9 +946,9 @@
}
-static void SocketFinalizer(void* isolate_data,
- Dart_WeakPersistentHandle handle,
- void* data) {
+static void NormalSocketFinalizer(void* isolate_data,
+ Dart_WeakPersistentHandle handle,
+ void* data) {
Socket* socket = reinterpret_cast<Socket*>(data);
if (socket->fd() >= 0) {
const int64_t flags = 1 << kCloseCommand;
@@ -972,29 +974,53 @@
}
+static void StdioSocketFinalizer(void* isolate_data,
+ Dart_WeakPersistentHandle handle,
+ void* data) {
+ Socket* socket = reinterpret_cast<Socket*>(data);
+ if (socket->fd() >= 0) {
+ socket->SetClosedFd();
+ }
+ socket->Release();
+}
+
+
void Socket::ReuseSocketIdNativeField(Dart_Handle handle,
Socket* socket,
- bool listening) {
+ SocketFinalizer finalizer) {
Dart_Handle err = Dart_SetNativeInstanceField(
handle, kSocketIdNativeField, reinterpret_cast<intptr_t>(socket));
if (Dart_IsError(err)) {
Dart_PropagateError(err);
}
- if (listening) {
+ Dart_WeakPersistentHandleFinalizer callback;
+ switch (finalizer) {
+ case kFinalizerNormal:
+ callback = NormalSocketFinalizer;
+ break;
+ case kFinalizerListening:
+ callback = ListeningSocketFinalizer;
+ break;
+ case kFinalizerStdio:
+ callback = StdioSocketFinalizer;
+ break;
+ default:
+ callback = NULL;
+ UNREACHABLE();
+ break;
+ }
+ if (callback != NULL) {
Dart_NewWeakPersistentHandle(handle, reinterpret_cast<void*>(socket),
- sizeof(Socket), ListeningSocketFinalizer);
- } else {
- Dart_NewWeakPersistentHandle(handle, reinterpret_cast<void*>(socket),
- sizeof(Socket), SocketFinalizer);
+ sizeof(Socket), callback);
}
}
void Socket::SetSocketIdNativeField(Dart_Handle handle,
intptr_t id,
- bool listening) {
+ SocketFinalizer finalizer) {
Socket* socket = new Socket(id);
- ReuseSocketIdNativeField(handle, socket, listening);
+ ReuseSocketIdNativeField(handle, socket, finalizer);
}
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 7b8a03d..a34fd73 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -260,6 +260,12 @@
kReverseLookupRequest = 2,
};
+ enum SocketFinalizer {
+ kFinalizerNormal,
+ kFinalizerListening,
+ kFinalizerStdio,
+ };
+
explicit Socket(intptr_t fd);
intptr_t fd() const { return fd_; }
@@ -349,10 +355,10 @@
static void SetSocketIdNativeField(Dart_Handle handle,
intptr_t id,
- bool listening);
+ SocketFinalizer finalizer);
static void ReuseSocketIdNativeField(Dart_Handle handle,
Socket* socket,
- bool listening);
+ SocketFinalizer finalizer);
static Socket* GetSocketIdNativeField(Dart_Handle socket);
private:
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index a7061f7..3b0efe5 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -82,6 +82,7 @@
return (err == 0);
}
+
intptr_t Socket::Available(intptr_t fd) {
ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(fd);
return client_socket->Available();
@@ -288,7 +289,8 @@
if (handle == INVALID_HANDLE_VALUE) {
return -1;
}
- StdHandle* std_handle = new StdHandle(handle);
+ StdHandle* std_handle = StdHandle::Stdin(handle);
+ std_handle->Retain();
std_handle->MarkDoesNotSupportOverlappedIO();
std_handle->EnsureInitialized(EventHandler::delegate());
return reinterpret_cast<intptr_t>(std_handle);
diff --git a/runtime/bin/stdio_patch.dart b/runtime/bin/stdio_patch.dart
index d6d0077..d096a03 100644
--- a/runtime/bin/stdio_patch.dart
+++ b/runtime/bin/stdio_patch.dart
@@ -14,7 +14,8 @@
case _STDIO_HANDLE_TYPE_FILE:
return new Stdin._(new _FileStream.forStdin());
default:
- throw new FileSystemException("Unsupported stdin type");
+ throw new FileSystemException(
+ "Couldn't determine file type of stdin (fd 0)");
}
}
@@ -28,7 +29,8 @@
case _STDIO_HANDLE_TYPE_FILE:
return new Stdout._(new IOSink(new _StdConsumer(fd)), fd);
default:
- throw new FileSystemException("Unsupported stdin type");
+ throw new FileSystemException(
+ "Couldn't determine file type of stdio handle (fd $fd)");
}
}
diff --git a/runtime/observatory/tests/service/async_single_step_exception_test.dart b/runtime/observatory/tests/service/async_single_step_exception_test.dart
index 365aab7..4307872 100644
--- a/runtime/observatory/tests/service/async_single_step_exception_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_exception_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger
import 'dart:async';
import 'dart:developer';
diff --git a/runtime/observatory/tests/service/async_single_step_into_test.dart b/runtime/observatory/tests/service/async_single_step_into_test.dart
index 7b7f786..129ff6a 100644
--- a/runtime/observatory/tests/service/async_single_step_into_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_into_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger
import 'dart:developer';
import 'package:observatory/models.dart' as M;
diff --git a/runtime/observatory/tests/service/async_single_step_out_test.dart b/runtime/observatory/tests/service/async_single_step_out_test.dart
index 97e4942..f66360f 100644
--- a/runtime/observatory/tests/service/async_single_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_out_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger
import 'dart:developer';
import 'package:observatory/models.dart' as M;
diff --git a/runtime/observatory/tests/service/async_star_single_step_into_test.dart b/runtime/observatory/tests/service/async_star_single_step_into_test.dart
index 1575251..ddfa210 100644
--- a/runtime/observatory/tests/service/async_star_single_step_into_test.dart
+++ b/runtime/observatory/tests/service/async_star_single_step_into_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger
import 'dart:developer';
import 'package:observatory/models.dart' as M;
diff --git a/runtime/observatory/tests/service/async_star_step_out_test.dart b/runtime/observatory/tests/service/async_star_step_out_test.dart
index c57862a..a59f955 100644
--- a/runtime/observatory/tests/service/async_star_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_star_step_out_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger
import 'dart:developer';
import 'package:observatory/models.dart' as M;
diff --git a/runtime/observatory/tests/service/async_step_out_test.dart b/runtime/observatory/tests/service/async_step_out_test.dart
index 0acff6a..8c6718c 100644
--- a/runtime/observatory/tests/service/async_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_step_out_test.dart
@@ -1,7 +1,7 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug --async_debugger
import 'dart:developer';
import 'package:observatory/models.dart' as M;
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index d6b949a..4cfe843 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -14,6 +14,9 @@
[$runtime == vm && $compiler == none && $system == fuchsia]
*: Skip # Not yet triaged.
+[ $system == windows ]
+async_generator_breakpoint_test: Skip # Issue 29145
+
# Kernel version of tests
[ $compiler != dartk ]
###
@@ -84,6 +87,7 @@
get_allocation_samples_test: RuntimeError # Profiling unimplemented.
get_cpu_profile_timeline_rpc_test: RuntimeError # Profiling unimplemented.
implicit_getter_setter_test: RuntimeError # Field guards unimplemented.
+async_single_step_exception_test: RuntimeError # Issue 29218
# Debugging StringConcatenation doesn't work the same on simdbc as on other platforms (bug #28975).
next_through_catch_test: RuntimeError
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index e3de0ba..547fbb5 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -41,6 +41,9 @@
async_step_out_test: RuntimeError # Issue 29158
async_star_step_out_test: RuntimeError # Issue 29158
awaiter_async_stack_contents_test: RuntimeError # Issue 29158
+async_single_step_out_test: RuntimeError # Issue 29158
+async_generator_breakpoint_test: Skip # Issue 29158
+async_single_step_exception_test: RuntimeError # Issue 29218
###
### These tests currently crash the VM
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 56eea83..ff171ac 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -50,6 +50,7 @@
#include <winsock2.h>
#include <Rpc.h>
#include <shellapi.h>
+#include <VersionHelpers.h>
#endif // defined(_WIN32)
#if !defined(_WIN32)
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 63760c0..d53e39a 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -3242,7 +3242,7 @@
void Debugger::RememberTopFrameAwaiter() {
- if (!FLAG_async_debugger_stepping) {
+ if (!FLAG_async_debugger) {
return;
}
if (stack_trace_->Length() > 0) {
@@ -3254,7 +3254,7 @@
void Debugger::SetAsyncSteppingFramePointer() {
- if (!FLAG_async_debugger_stepping) {
+ if (!FLAG_async_debugger) {
return;
}
if (stack_trace_->FrameAt(0)->function().IsAsyncClosure() ||
@@ -3294,7 +3294,7 @@
OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_);
}
} else if (resume_action_ == kStepOut) {
- if (FLAG_async_debugger_stepping) {
+ if (FLAG_async_debugger) {
if (stack_trace->FrameAt(0)->function().IsAsyncClosure() ||
stack_trace->FrameAt(0)->function().IsAsyncGenClosure()) {
// Request to step out of an async/async* closure.
@@ -3662,7 +3662,7 @@
ActivationFrame* frame = TopDartFrame();
ASSERT(frame != NULL);
- if (FLAG_async_debugger_stepping) {
+ if (FLAG_async_debugger) {
if ((async_stepping_fp_ != 0) && (top_frame_awaiter_ != Object::null())) {
// Check if the user has single stepped out of an async function with
// an awaiter. The first check handles the case of calling into the
@@ -4299,7 +4299,7 @@
void Debugger::MaybeAsyncStepInto(const Closure& async_op) {
- if (FLAG_async_debugger_stepping && IsSingleStepping()) {
+ if (FLAG_async_debugger && IsSingleStepping()) {
// We are single stepping, set a breakpoint on the closure activation
// and resume execution so we can hit the breakpoint.
AsyncStepInto(async_op);
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index e8fcc0c..85f74c4 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -149,8 +149,8 @@
C(causal_async_stacks, false, false, bool, true, "Improved async stacks") \
C(stress_async_stacks, false, false, bool, false, \
"Stress test async stack traces") \
- C(async_debugger_stepping, false, false, bool, true, \
- "Debugger support for stepping in and out of async functions.") \
+ C(async_debugger, false, false, bool, false, \
+ "Debugger support async functions.") \
R(support_ast_printer, false, bool, true, "Support the AST printer.") \
R(support_compiler_stats, false, bool, true, "Support compiler stats.") \
C(support_debugger, false, false, bool, true, "Support the debugger.") \
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index f1dcac5..5b2ffcc 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -273,7 +273,7 @@
function_name, 2, Object::null_array());
ASSERT(!function.IsNull());
set_complete_on_async_return(function);
- if (FLAG_async_debugger_stepping) {
+ if (FLAG_async_debugger) {
// Disable debugging and inlining the _CompleteOnAsyncReturn function.
function.set_is_debuggable(false);
function.set_is_inlinable(false);
@@ -284,7 +284,7 @@
ASSERT(!cls.IsNull());
set_async_star_stream_controller(cls);
- if (FLAG_async_debugger_stepping) {
+ if (FLAG_async_debugger) {
// Disable debugging and inlining of all functions on the
// _AsyncStarStreamController class.
const Array& functions = Array::Handle(cls.functions());
diff --git a/tests/standalone/io/stdio_socket_finalizer_test.dart b/tests/standalone/io/stdio_socket_finalizer_test.dart
new file mode 100644
index 0000000..9fee3d0
--- /dev/null
+++ b/tests/standalone/io/stdio_socket_finalizer_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This test checks that stdin is *not* closed when an Isolate leaks it.
+
+import 'dart:async';
+import 'dart:io';
+import 'dart:isolate';
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+void ConnectorIsolate(SendPort sendPort) {
+ stdin;
+ sendPort.send(true);
+}
+
+main() async {
+ asyncStart();
+ ReceivePort receivePort = new ReceivePort();
+ Isolate isolate = await Isolate.spawn(ConnectorIsolate, receivePort.sendPort);
+ Completer<Null> completer = new Completer<Null>();
+ receivePort.listen((msg) {
+ Expect.isTrue(msg is bool);
+ Expect.isTrue(msg);
+ isolate.kill();
+ completer.complete(null);
+ });
+ await completer.future;
+ stdin.listen((_) {}).cancel();
+ receivePort.close();
+ asyncEnd();
+}
diff --git a/tools/VERSION b/tools/VERSION
index f52ff92..f247f6d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 23
PATCH 0
PRERELEASE 11
-PRERELEASE_PATCH 4
+PRERELEASE_PATCH 5