Skip to content

Instantly share code, notes, and snippets.

@therealkenc
Created November 3, 2016 23:37
Show Gist options
  • Save therealkenc/94e0757c80113bd89a8bc22410d308be to your computer and use it in GitHub Desktop.
Save therealkenc/94e0757c80113bd89a8bc22410d308be to your computer and use it in GitHub Desktop.
diff --git a/.gitignore b/.gitignore
index 0c609ce..3df0daa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,6 +51,10 @@ tags
Thumbs.db
v8.log
vs-chromium-project.txt
+# WSL diff additions for git performance
+/v8/
+/build/
+*.rej
# Settings directories for eclipse
/.externalToolBuilders/
/.settings/
diff --git a/base/debug/proc_maps_linux.cc b/base/debug/proc_maps_linux.cc
index 0bb44b4..de725c2 100644
--- a/base/debug/proc_maps_linux.cc
+++ b/base/debug/proc_maps_linux.cc
@@ -151,10 +151,16 @@ bool ParseProcMaps(const std::string& input,
else if (permissions[2] != '-')
return false;
- if (permissions[3] == 'p')
- region.permissions |= MappedMemoryRegion::PRIVATE;
- else if (permissions[3] != 's' && permissions[3] != 'S') // Shared memory.
- return false;
+#if !defined(WSL_HACK)
+ if (permissions[3] == 'p')
+ region.permissions |= MappedMemoryRegion::PRIVATE;
+ else if (permissions[3] != 's' && permissions[3] != 'S') // Shared memory.
+ return false;
+
+#else
+ // WSL always sets character to '-'. Pretend it's 'p'.
+ region.permissions |= MappedMemoryRegion::PRIVATE;
+#endif
// Pushing then assigning saves us a string copy.
regions.push_back(region);
diff --git a/base/files/dir_reader_posix.h b/base/files/dir_reader_posix.h
index 6a32d9f..aa28db8 100644
--- a/base/files/dir_reader_posix.h
+++ b/base/files/dir_reader_posix.h
@@ -17,7 +17,7 @@
// seems worse than falling back to enumerating all file descriptors so we will
// probably never implement this on the Mac.
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) && !defined(WSL_HACK)
#include "base/files/dir_reader_linux.h"
#else
#include "base/files/dir_reader_fallback.h"
@@ -25,7 +25,7 @@
namespace base {
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) && !defined(WSL_HACK)
typedef DirReaderLinux DirReaderPosix;
#else
typedef DirReaderFallback DirReaderPosix;
diff --git a/base/posix/unix_domain_socket_linux.cc b/base/posix/unix_domain_socket_linux.cc
index 8b3094e..c7591f0 100644
--- a/base/posix/unix_domain_socket_linux.cc
+++ b/base/posix/unix_domain_socket_linux.cc
@@ -40,16 +40,155 @@ static bool CreateSocketPair(ScopedFD* one, ScopedFD* two) {
// static
bool UnixDomainSocket::EnableReceiveProcessId(int fd) {
+#if defined(WSL_HACK)
+ LOG(FATAL) << "WSL does not have SO_PASSCRED";
+#endif
const int enable = 1;
return setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)) == 0;
}
#endif // !defined(OS_NACL_NONSFI)
+#if defined(WSL_HACK)
+// Pass just one fd using using SCM_RIGHTS.
+static bool SendCmsgHdrWithBuf(int fd, const void* buf, size_t length,
+ const int& pass_fd) {
+ struct msghdr msg = {};
+ struct iovec iov = { const_cast<void*>(buf), length };
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ static const unsigned control_len = CMSG_SPACE(sizeof(int));
+ msg.msg_controllen = control_len;
+ char control_buffer[control_len];
+ msg.msg_control = control_buffer;
+ struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ memcpy(CMSG_DATA(cmsg), &pass_fd, sizeof(int));
+ ssize_t ret = sendmsg(fd, &msg, 0);
+ if (ret < 0) {
+ PLOG(ERROR) << "SendCmsgHdrWithBuf() failed fd: " << fd;
+ }
+ return (static_cast<size_t>(ret) == length);
+}
+
+// helper to just sendmsg a buffer without SCM_RIGHTS
+static bool SendMsgBuf(int fd, const void* buf, size_t length) {
+#if 0
+ LOG(ERROR) << "SendMsgBuf() fd: " << fd
+ << " length: " << length;
+#endif
+ struct msghdr msg = {};
+ struct iovec iov = { const_cast<void*>(buf), length };
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_controllen = 0;
+ ssize_t ret = sendmsg(fd, &msg, 0);
+ if (ret < 0) {
+ PLOG(ERROR) << "SendMsgBuf() failed fd: " << fd;
+ }
+ return (static_cast<size_t>(ret) == length);
+}
+
+// On WSL we are only allowed to send one fd with SCM_RIGHTS at a time
+// (issue #514). If nfds is 0, just send the buffer without SCM_RIGHTS.
+// If nfds is > 0, send the buffer plus the first file descriptor. Then
+// sendmsg for each remaining fd, with the payload containing each
+// file descriptor being sent, followed by one sendmsg with -1 as the
+// payload and SCM_RIGHTS *not set* to know we're done. Protocol makes
+// the receiver easier to implement than the sender.
+static bool SendMsgWsl(int fd,
+ const void* buf,
+ size_t length,
+ const std::vector<int>& fds) {
+ bool success = true;
+ size_t nfds = fds.size();
+ if (nfds) {
+ success = SendCmsgHdrWithBuf(fd, buf, length, fds[0]);
+ for (size_t fd_idx = 1; success && fd_idx < nfds; fd_idx++) {
+ success = SendCmsgHdrWithBuf(fd, &fds[fd_idx], sizeof(int),
+ fds[fd_idx]);
+ }
+ if (success) {
+ static const int neg_one = -1;
+ success = SendMsgBuf(fd, &neg_one, sizeof(int));
+ }
+ } else {
+ success = SendMsgBuf(fd, buf, length);
+ }
+ return success;
+}
+
+// If we get SCM_RIGHTS cmsghdr, then passed_fd will contain the received descriptor
+// on return. Otherwise passed_fd is set to -1, *even on success* if the message
+// does does not have a cmsghdr with SCM_RIGHTS. Thus callers can test for existence of
+// passed fd (versus absense) by checking passed_fd >= 0 on return.
+//
+// Note the native implementation checks for
+static ssize_t RecvCmdgHdrWithBuf(int fd, void* buf, size_t length, int flags,
+ int& passed_fd) {
+ struct msghdr msg = {};
+ struct iovec iov = { buf, length };
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ static const unsigned control_len = CMSG_SPACE(sizeof(int));
+ msg.msg_controllen = control_len;
+ char control_buffer[control_len];
+ msg.msg_control = control_buffer;
+ const ssize_t recv_ret = recvmsg(fd, &msg, flags);
+ if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) {
+ PLOG(FATAL) << "*** RecvCmdgHdrWithBuf() we don't tollerate message truncation for now";
+ }
+ if (recv_ret < 0) {
+ PLOG(FATAL) << "*** RecvCmdgHdrWithBuf() recvmsg() failed: ";
+ } else if (msg.msg_controllen > 0) {
+ DCHECK(msg.msg_controllen == control_len);
+ struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+ DCHECK_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
+ passed_fd = *reinterpret_cast<int*>(CMSG_DATA(cmsg));
+ DCHECK_GE(passed_fd, 0);
+ // LOG(ERROR) << "RecvCmdgHdrWithBuf() fd: " << fd << " got passed_fd: " << passed_fd;
+ }
+ } else {
+ passed_fd = -1;
+ }
+ return recv_ret;
+}
+
+// We can't pass credentials on WSL issue #706. Always set out_pid to -1
+// and be careful in all callers not to depend on it. Which seems to be okay unless
+// we are running suid or namespace sandbox, which we aren't.
+static ssize_t RecvMsgWithFlagsWsl(int fd,
+ void* buf,
+ size_t length,
+ int flags,
+ std::vector<ScopedFD>* fds,
+ ProcessId* out_pid) {
+ fds->clear();
+ int passed_fd = -1;
+ ssize_t recv_ret_first = RecvCmdgHdrWithBuf(fd, buf, length, flags, passed_fd);
+ ssize_t recv_ret = recv_ret_first;
+ while (recv_ret > 0 && passed_fd >= 0) {
+ // LOG(ERROR) << "RecvMsgWithFlagsWsl() fd: " << fd << " pushing fd: " << passed_fd;
+ fds->push_back(ScopedFD(passed_fd));
+ int payload_fd = 0;
+ recv_ret = RecvCmdgHdrWithBuf(fd, &payload_fd, sizeof(int), 0, passed_fd);
+ }
+
+ if (out_pid)
+ *out_pid = -1;
+
+ return (recv_ret < 0) ? recv_ret : recv_ret_first;
+}
+#endif // defined(WSL_HACK)
+
// static
bool UnixDomainSocket::SendMsg(int fd,
const void* buf,
size_t length,
const std::vector<int>& fds) {
+#if !defined(WSL_HACK)
struct msghdr msg = {};
struct iovec iov = { const_cast<void*>(buf), length };
msg.msg_iov = &iov;
@@ -80,6 +219,9 @@ bool UnixDomainSocket::SendMsg(int fd,
const bool ret = static_cast<ssize_t>(length) == r;
delete[] control_buffer;
return ret;
+#else
+ return SendMsgWsl(fd, buf, length, fds);
+#endif
}
// static
@@ -106,6 +248,7 @@ ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd,
int flags,
std::vector<ScopedFD>* fds,
ProcessId* out_pid) {
+#if !defined(WSL_HACK)
fds->clear();
struct msghdr msg = {};
@@ -180,6 +323,9 @@ ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd,
}
return r;
+#else
+ return RecvMsgWithFlagsWsl(fd, buf, length, flags, fds, out_pid);
+#endif
}
#if !defined(OS_NACL_NONSFI)
diff --git a/base/sys_info_linux.cc b/base/sys_info_linux.cc
index 300ef2c0..74c9ede 100644
--- a/base/sys_info_linux.cc
+++ b/base/sys_info_linux.cc
@@ -35,6 +35,8 @@ int64_t AmountOfPhysicalMemory() {
uint64_t MaxSharedMemorySize() {
std::string contents;
+ // WSL doesn't have /proc/sys/kernel/shmmax
+#if !defined(WSL_HACK)
base::ReadFileToString(base::FilePath("/proc/sys/kernel/shmmax"), &contents);
DCHECK(!contents.empty());
if (!contents.empty() && contents.back() == '\n') {
@@ -45,6 +47,10 @@ uint64_t MaxSharedMemorySize() {
if (!base::StringToUint64(contents, &limit)) {
limit = 0;
}
+#else
+ // This is what /proc/sys/kernel/shmmax returns on native x86_64. Good grief...
+ uint64_t limit = 18446744073692774399ULL;
+#endif
DCHECK_GT(limit, 0u);
return limit;
}
diff --git a/build/build_config.h b/build/build_config.h
index c3d82d0..6cf867f 100644
--- a/build/build_config.h
+++ b/build/build_config.h
@@ -15,6 +15,8 @@
#ifndef BUILD_BUILD_CONFIG_H_
#define BUILD_BUILD_CONFIG_H_
+#define WSL_HACK
+
// A set of macros to use for platform detection.
#if defined(__native_client__)
// __native_client__ must be first, so that other OS_ defines are not set.
diff --git a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
index 60921f3..51d30ae 100644
--- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
+++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc
@@ -8,9 +8,20 @@
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h"
#include "content/public/browser/browser_thread.h"
+
+// WSL for some reason we get here even though GYP use_udev=0.
+// Stub out the whole implementation. It would probably be cleaner to
+// just find the caller and remove the object from gypi.
+// the chromium bug 284898 mentioned below might be instructive.
+#if defined(USE_UDEV)
+#if defined(WSL_HACK)
+#error "WSL USE_UDEV defined"
+#endif
#include "device/udev_linux/scoped_udev.h"
+#endif
namespace extensions {
+#if !defined(WSL_HACK)
// TODO(haven): Udev code may be duplicated in the Chrome codebase.
// https://code.google.com/p/chromium/issues/detail?id=284898
@@ -41,9 +52,11 @@ static int get_device_blk_size(const std::string& path) {
return blk_size;
}
+#endif // WSL_HACK
bool RemovableStorageProvider::PopulateDeviceList(
scoped_refptr<StorageDeviceList> device_list) {
+#if !defined(WSL_HACK)
device::ScopedUdevPtr udev(device::udev_new());
if (!udev) {
DLOG(ERROR) << "Can't create udev";
@@ -105,7 +118,7 @@ bool RemovableStorageProvider::PopulateDeviceList(
device_list->data.push_back(std::move(device_item));
}
-
+#endif // WSL_HACK
return true;
}
diff --git a/components/storage_monitor/storage_monitor.cc b/components/storage_monitor/storage_monitor.cc
index 6f2b23c..d2a7629 100644
--- a/components/storage_monitor/storage_monitor.cc
+++ b/components/storage_monitor/storage_monitor.cc
@@ -51,8 +51,14 @@ void StorageMonitor::ReceiverImpl::MarkInitialized() {
// static
void StorageMonitor::Create() {
+#if !defined(WSL_HACK)
delete g_storage_monitor;
g_storage_monitor = CreateInternal();
+#else
+// WSL USE_UDEV undefined causes undefined reference to
+// CreateInternal. Do absolutely nothing (ie leave
+// g_storage_monitor as null) and hope this is never called.
+#endif
}
// static
diff --git a/content/browser/appcache/chrome_appcache_service.cc b/content/browser/appcache/chrome_appcache_service.cc
index 11d107c..df75be5 100644
--- a/content/browser/appcache/chrome_appcache_service.cc
+++ b/content/browser/appcache/chrome_appcache_service.cc
@@ -32,6 +32,22 @@ void ChromeAppCacheService::InitializeOnIOThread(
"477117 ChromeAppCacheService::InitializeOnIOThread"));
DCHECK_CURRENTLY_ON(BrowserThread::IO);
+#if defined(WSL_HACK)
+/** hitting an assertion in the following stack trace for some reason
+ #2 0x7f52541e9880 base::ThreadRestrictions::AssertIOAllowed()
+ #3 0x7f52541725c9 base::PathExists()
+ #4 0x7f524e220a30 ui::ResourceBundle::GetLocaleFilePath()
+ #5 0x7f524e220901 ui::ResourceBundle::LocaleDataPakExists()
+ #6 0x7f524e213543 <unknown>
+ #7 0x7f524e213029 l10n_util::CheckAndResolveLocale()
+ #8 0x7f524e21379b <unknown>
+ #9 0x7f524e213969 l10n_util::GetApplicationLocale()
+ #10 0x000000c882a5 brightray::URLRequestContextGetter::GetURLRequestContext()
+ #11 0x7f5251cec827 content::ChromeAppCacheService::InitializeOnIOThread()
+ **/
+ base::ThreadRestrictions::SetIOAllowed(true);
+#endif
+
cache_path_ = cache_path;
resource_context_ = resource_context;
diff --git a/content/browser/zygote_host/zygote_communication_linux.cc b/content/browser/zygote_host/zygote_communication_linux.cc
index fc7b505..8bcffc3 100644
--- a/content/browser/zygote_host/zygote_communication_linux.cc
+++ b/content/browser/zygote_host/zygote_communication_linux.cc
@@ -118,8 +118,9 @@ pid_t ZygoteCommunication::ForkRequest(
PCHECK(0 == socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks));
base::ScopedFD my_sock(raw_socks[0]);
base::ScopedFD peer_sock(raw_socks[1]);
+#if !defined(WSL_HACK)
CHECK(base::UnixDomainSocket::EnableReceiveProcessId(my_sock.get()));
-
+#endif
pickle.WriteInt(kZygoteCommandFork);
pickle.WriteString(process_type);
pickle.WriteInt(argv.size());
@@ -157,10 +158,10 @@ pid_t ZygoteCommunication::ForkRequest(
peer_sock.reset();
{
- char buf[sizeof(kZygoteChildPingMessage) + 1];
std::vector<base::ScopedFD> recv_fds;
base::ProcessId real_pid;
-
+#if !defined(WSL_HACK)
+ char buf[sizeof(kZygoteChildPingMessage) + 1];
ssize_t n = base::UnixDomainSocket::RecvMsgWithPid(
my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid);
if (n != sizeof(kZygoteChildPingMessage) ||
@@ -172,8 +173,21 @@ pid_t ZygoteCommunication::ForkRequest(
NOTREACHED();
real_pid = -1;
}
+#else
+ ZygoteHelloMessage hello;
+ ssize_t n = base::UnixDomainSocket::RecvMsgWithPid(
+ my_sock.get(), &hello, sizeof(hello), &recv_fds, &real_pid);
+ if (n != sizeof(ZygoteHelloMessage) ||
+ 0 != memcmp(hello.msg_, kZygoteChildPingMessage,
+ sizeof(kZygoteChildPingMessage))) {
+ NOTREACHED();
+ real_pid = -1;
+ LOG(FATAL) << "Did not receive ping from zygote child";
+ } else {
+ real_pid = hello.pid_;
+ }
+#endif
my_sock.reset();
-
// Always send PID back to zygote.
base::Pickle pid_pickle;
pid_pickle.WriteInt(kZygoteCommandForkRealPID);
@@ -267,7 +281,9 @@ void ZygoteCommunication::Init() {
int fds[2];
CHECK(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds) == 0);
+#if !defined(WSL_HACK)
CHECK(base::UnixDomainSocket::EnableReceiveProcessId(fds[0]));
+#endif
base::FileHandleMappingVector fds_to_map;
fds_to_map.push_back(std::make_pair(fds[1], kZygoteSocketPairFd));
@@ -328,6 +344,8 @@ void ZygoteCommunication::Init() {
dummy_fd.reset();
if (using_suid_sandbox || using_namespace_sandbox) {
+ LOG(FATAL) << "ZygoteCommunication::Init() suid sandbox not supported on WSL";
+
// The SUID sandbox will execute the zygote in a new PID namespace, and
// the main zygote process will then fork from there. Watch now our
// elaborate dance to find and validate the zygote's PID.
diff --git a/content/common/send_zygote_child_ping_linux.cc b/content/common/send_zygote_child_ping_linux.cc
index f3cfcbc..6111583 100644
--- a/content/common/send_zygote_child_ping_linux.cc
+++ b/content/common/send_zygote_child_ping_linux.cc
@@ -5,6 +5,7 @@
#include "content/public/common/send_zygote_child_ping_linux.h"
#include <vector>
+#include <string.h>
#include "base/posix/unix_domain_socket_linux.h"
#include "content/common/zygote_commands_linux.h"
@@ -12,10 +13,19 @@
namespace content {
bool SendZygoteChildPing(int fd) {
+#if !defined(WSL_HACK)
return base::UnixDomainSocket::SendMsg(fd,
kZygoteChildPingMessage,
sizeof(kZygoteChildPingMessage),
std::vector<int>());
+#else
+ pid_t pid = getpid();
+ ZygoteHelloMessage hello;
+ hello.pid_ = pid;
+ strncpy(hello.msg_, kZygoteChildPingMessage, sizeof(kZygoteChildPingMessage));
+ return base::UnixDomainSocket::SendMsg(fd, &hello,
+ sizeof(ZygoteHelloMessage), std::vector<int>());
+#endif
}
} // namespace content
diff --git a/content/common/zygote_commands_linux.h b/content/common/zygote_commands_linux.h
index 0fed210..b18b4e7 100644
--- a/content/common/zygote_commands_linux.h
+++ b/content/common/zygote_commands_linux.h
@@ -51,6 +51,12 @@ enum {
kZygoteCommandForkRealPID = 4
};
+#if defined(WSL_HACK)
+struct ZygoteHelloMessage {
+ char msg_[sizeof(kZygoteChildPingMessage) + 1] = {};
+ pid_t pid_ = 0;
+};
+#endif
} // namespace content
#endif // CONTENT_COMMON_ZYGOTE_COMMANDS_LINUX_H_
diff --git a/device/serial/serial_service_impl.cc b/device/serial/serial_service_impl.cc
index a66abea..ac09458 100644
--- a/device/serial/serial_service_impl.cc
+++ b/device/serial/serial_service_impl.cc
@@ -76,9 +76,17 @@ void SerialServiceImpl::Connect(
}
SerialDeviceEnumerator* SerialServiceImpl::GetDeviceEnumerator() {
+
+#if !defined(WSL_HACK)
if (!device_enumerator_)
device_enumerator_ = SerialDeviceEnumerator::Create();
return device_enumerator_.get();
+#else
+// SerialDeviceEnumerator::Create() has no business being linked
+// when use_udev=0, but it is for some reason. Also #ifdef out
+// usage in extensions/browser/api/serial/serial_api.cc
+ return NULL;
+#endif
}
bool SerialServiceImpl::IsValidPath(const mojo::String& path) {
diff --git a/extensions/browser/api/serial/serial_api.cc b/extensions/browser/api/serial/serial_api.cc
index 3f126a8..c70c11f 100644
--- a/extensions/browser/api/serial/serial_api.cc
+++ b/extensions/browser/api/serial/serial_api.cc
@@ -86,11 +86,16 @@ bool SerialGetDevicesFunction::Prepare() {
void SerialGetDevicesFunction::Work() {
DCHECK_CURRENTLY_ON(BrowserThread::FILE);
+// There used to a similar #ifdef here for CHROME_OS in earlier
+// versions, which presumably didn't have serial ports at
+// one point either.
+#if !defined(WSL_HACK)
std::unique_ptr<device::SerialDeviceEnumerator> enumerator =
device::SerialDeviceEnumerator::Create();
mojo::Array<device::serial::DeviceInfoPtr> devices = enumerator->GetDevices();
results_ = serial::GetDevices::Results::Create(
devices.To<std::vector<serial::DeviceInfo>>());
+#endif
}
SerialConnectFunction::SerialConnectFunction() {
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc
index 113b748..d6127be 100644
--- a/net/base/network_delegate.cc
+++ b/net/base/network_delegate.cc
@@ -12,6 +12,9 @@
#include "net/proxy/proxy_info.h"
#include "net/url_request/url_request.h"
+#undef DCHECK
+#define DCHECK(x)
+
namespace net {
int NetworkDelegate::NotifyBeforeURLRequest(
diff --git a/sandbox/linux/services/thread_helpers.cc b/sandbox/linux/services/thread_helpers.cc
index 20752c8..d12a2e85 100644
--- a/sandbox/linux/services/thread_helpers.cc
+++ b/sandbox/linux/services/thread_helpers.cc
@@ -39,13 +39,20 @@ bool IsSingleThreadedImpl(int proc_fd) {
struct stat task_stat;
int fstat_ret = fstatat(proc_fd, "self/task/", &task_stat, 0);
PCHECK(0 == fstat_ret);
+ PCHECK(0 == fstat_ret);
- // At least "..", "." and the current thread should be present.
- CHECK_LE(3UL, task_stat.st_nlink);
- // Counting threads via /proc/self/task could be racy. For the purpose of
- // determining if the current proces is monothreaded it works: if at any
- // time it becomes monothreaded, it'll stay so.
- return task_stat.st_nlink == 3;
+
+ // WSL issue #1267
+#if !defined(WSL_HACK)
+ // At least "..", "." and the current thread should be present.
+ CHECK_LE(3UL, task_stat.st_nlink);
+ // Counting threads via /proc/self/task could be racy. For the purpose of
+ // determining if the current proces is monothreaded it works: if at any
+ // time it becomes monothreaded, it'll stay so.
+ return task_stat.st_nlink == 3;
+#else
+ return task_stat.st_nlink <= 3;
+#endif
}
bool IsThreadPresentInProcFS(int proc_fd,
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index db9af3c..154baad 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -901,7 +901,25 @@ bool SetAtomArrayProperty(XID window,
const std::string& name,
const std::string& type,
const std::vector<XAtom>& value) {
+#if !defined(WSL_HACK)
DCHECK(!value.empty());
+#else
+/**
+ On WSL Electron, the above check fails because value is empty.
+ Probably an invariant not being respected by Electron, which
+ normally gets ignored because DCHECK is compiled away on
+ release builds, and Electron is normally compiled with -DNDEBUG
+
+ [14429:1031/021225:FATAL:x11_util.cc(904)] Check failed: !value.empty().
+ #0 0x7fab295af97e base::debug::StackTrace::StackTrace()
+ #1 0x7fab295cf52b logging::LogMessage::~LogMessage()
+ #2 0x7fab23699a66 ui::SetAtomArrayProperty()
+ #3 0x000000b0ff8d atom::NativeWindowViews::NativeWindowViews()
+ #4 0x000000b13d73 atom::NativeWindow::Create()
+ #5 0x000000ac4276 atom::api::Window::Window()
+ #6 0x000000ac5a5e atom::api::Window::New()
+ **/
+#endif
XAtom name_atom = GetAtom(name.c_str());
XAtom type_atom = GetAtom(type.c_str());
diff --git a/ui/events/x/events_x_utils.cc b/ui/events/x/events_x_utils.cc
index aab2723..209eac6 100644
--- a/ui/events/x/events_x_utils.cc
+++ b/ui/events/x/events_x_utils.cc
@@ -343,11 +343,23 @@ base::TimeDelta TimeDeltaFromXEventTime(Time timestamp) {
g_rollover_ms = now_ms & ~static_cast<int64_t>(UINT32_MAX);
uint32_t delta = static_cast<uint32_t>(now_ms - timestamp);
+#if !defined(WSL_HACK)
// If using a mock clock, all bets are off -- in some tests, actual X11 events
// come through with real timestamps.
DCHECK(delta < 60 * 1000 || g_tick_clock.Get() != nullptr)
<< "Unexpected X11 event time, now: " << now_ticks
<< " event at: " << timestamp;
+#else
+ if (delta < 60 * 1000) {
+ LOG(ERROR) << "unexpected delta: " << delta
+ << "now_ticks: " << now_ticks
+ << "timestamp: " << timestamp
+ << "now_ms: " << now_ms;
+ }
+ if (g_tick_clock.Get() != nullptr) {
+ LOG(ERROR) << "g_tick_clock.Get() != nullptr";
+ }
+#endif
return base::TimeDelta::FromMilliseconds(now_ms - delta);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment