aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTiancong Wang <tcwang@google.com>2020-02-12 13:41:01 -0800
committerTiancong Wang <tcwang@google.com>2020-02-13 18:13:48 +0000
commit22e3075e965be294d2b080752a113788c3cf136a (patch)
tree91618629b7ee190ce9e9622ba288a0bd5cfb18e7
parent43c9066b1889baaa0a6077399deb6a4d503551e6 (diff)
downloadtoolchain-utils-22e3075e965be294d2b080752a113788c3cf136a.tar.gz
compiler_wrapper: Use syscall.exec on platforms other than Chrome OS
In crbug.com/1000863, it's reported that golang exec don't play well on Chrome OS, portage sandbox to be exact. That's when we start to use libc's exec. However, the wrapper is also used on non-Chrome OS platforms, such as Android, and linking against libc has no benefit, and might be the root cause of a recent bug. This patch adds code to selectively use Golang's or libc's exec, depending on the platform. BUG=chromium:1000863 BUG=b:144783188 TEST=Build the wrapper locally with Chrome OS and Android configurations Change-Id: Ifd6fa8223205536450b65f728060d7c5556d7619 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/2051669 Tested-by: Tiancong Wang <tcwang@google.com> Commit-Queue: Tiancong Wang <tcwang@google.com> Reviewed-by: George Burgess <gbiv@chromium.org>
-rwxr-xr-xcompiler_wrapper/build.py8
-rw-r--r--compiler_wrapper/env.go2
-rw-r--r--compiler_wrapper/go_exec.go23
-rw-r--r--compiler_wrapper/libc_exec.go7
4 files changed, 37 insertions, 3 deletions
diff --git a/compiler_wrapper/build.py b/compiler_wrapper/build.py
index 4257abfc..037b940f 100755
--- a/compiler_wrapper/build.py
+++ b/compiler_wrapper/build.py
@@ -39,10 +39,16 @@ def calc_go_args(args, version):
'-X',
'main.Version=' + version,
]
+
+ # If the wrapper is intended for Chrome OS, we need to use libc's exec.
+ extra_args = []
+ if 'cros' in args.config:
+ extra_args = ['-tags', 'libc_exec']
+
return [
'go', 'build', '-o',
os.path.abspath(args.output_file), '-ldflags', ' '.join(ldFlags)
- ]
+ ] + extra_args
def read_version(build_dir):
diff --git a/compiler_wrapper/env.go b/compiler_wrapper/env.go
index 4d83b17a..56b3a913 100644
--- a/compiler_wrapper/env.go
+++ b/compiler_wrapper/env.go
@@ -71,7 +71,7 @@ func (env *processEnv) stderr() io.Writer {
}
func (env *processEnv) exec(cmd *command) error {
- return libcExec(env, cmd)
+ return execCmd(env, cmd)
}
func (env *processEnv) run(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
diff --git a/compiler_wrapper/go_exec.go b/compiler_wrapper/go_exec.go
new file mode 100644
index 00000000..2f2e5ad9
--- /dev/null
+++ b/compiler_wrapper/go_exec.go
@@ -0,0 +1,23 @@
+// Copyright 2020 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// +build !libc_exec
+
+package main
+
+import (
+ "os/exec"
+ "syscall"
+)
+
+// Implement exec for users that don't need to dynamically link with glibc
+// See b/144783188 and libc_exec.go.
+
+func execCmd(env env, cmd *command) error {
+ execCmd := exec.Command(cmd.Path, cmd.Args...)
+ mergedEnv := mergeEnvValues(env.environ(), cmd.EnvUpdates)
+
+ ret := syscall.Exec(execCmd.Path, execCmd.Args, mergedEnv)
+ return newErrorwithSourceLocf("exec error: %v", ret)
+}
diff --git a/compiler_wrapper/libc_exec.go b/compiler_wrapper/libc_exec.go
index 268221dc..f8db9d86 100644
--- a/compiler_wrapper/libc_exec.go
+++ b/compiler_wrapper/libc_exec.go
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// +build libc_exec
+
package main
// #include <errno.h>
@@ -26,7 +28,10 @@ import (
// LD_PRELOAD to work properly (e.g. gentoo sandbox).
// Note that this changes the go binary to be a dynamically linked one.
// See crbug.com/1000863 for details.
-func libcExec(env env, cmd *command) error {
+// To use this version of exec, please add '-tags libc_exec' when building Go binary.
+// Without the tags, libc_exec.go will be used.
+
+func execCmd(env env, cmd *command) error {
freeList := []unsafe.Pointer{}
defer func() {
for _, ptr := range freeList {