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

Side by Side Diff: base/process/launch_posix.cc

Issue 863253002: Update from https://crrev.com/312600 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 11 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <dirent.h> 7 #include <dirent.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <sched.h>
11 #include <setjmp.h>
10 #include <signal.h> 12 #include <signal.h>
11 #include <stdlib.h> 13 #include <stdlib.h>
12 #include <sys/resource.h> 14 #include <sys/resource.h>
15 #include <sys/syscall.h>
13 #include <sys/time.h> 16 #include <sys/time.h>
14 #include <sys/types.h> 17 #include <sys/types.h>
15 #include <sys/wait.h> 18 #include <sys/wait.h>
16 #include <unistd.h> 19 #include <unistd.h>
17 20
18 #include <iterator> 21 #include <iterator>
19 #include <limits> 22 #include <limits>
20 #include <set> 23 #include <set>
21 24
22 #include "base/allocator/type_profiler_control.h" 25 #include "base/allocator/type_profiler_control.h"
23 #include "base/command_line.h" 26 #include "base/command_line.h"
24 #include "base/compiler_specific.h" 27 #include "base/compiler_specific.h"
25 #include "base/debug/debugger.h" 28 #include "base/debug/debugger.h"
26 #include "base/debug/stack_trace.h" 29 #include "base/debug/stack_trace.h"
27 #include "base/files/dir_reader_posix.h" 30 #include "base/files/dir_reader_posix.h"
28 #include "base/files/file_util.h" 31 #include "base/files/file_util.h"
29 #include "base/files/scoped_file.h" 32 #include "base/files/scoped_file.h"
30 #include "base/logging.h" 33 #include "base/logging.h"
31 #include "base/memory/scoped_ptr.h" 34 #include "base/memory/scoped_ptr.h"
32 #include "base/posix/eintr_wrapper.h" 35 #include "base/posix/eintr_wrapper.h"
33 #include "base/process/kill.h" 36 #include "base/process/kill.h"
34 #include "base/process/process_metrics.h" 37 #include "base/process/process_metrics.h"
35 #include "base/strings/stringprintf.h" 38 #include "base/strings/stringprintf.h"
36 #include "base/synchronization/waitable_event.h" 39 #include "base/synchronization/waitable_event.h"
37 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" 40 #include "base/third_party/dynamic_annotations/dynamic_annotations.h"
41 #include "base/third_party/valgrind/valgrind.h"
38 #include "base/threading/platform_thread.h" 42 #include "base/threading/platform_thread.h"
39 #include "base/threading/thread_restrictions.h" 43 #include "base/threading/thread_restrictions.h"
44 #include "build/build_config.h"
40 45
41 #if defined(OS_LINUX) 46 #if defined(OS_LINUX)
42 #include <sys/prctl.h> 47 #include <sys/prctl.h>
43 #endif 48 #endif
44 49
45 #if defined(OS_CHROMEOS) 50 #if defined(OS_CHROMEOS)
46 #include <sys/ioctl.h> 51 #include <sys/ioctl.h>
47 #endif 52 #endif
48 53
49 #if defined(OS_FREEBSD) 54 #if defined(OS_FREEBSD)
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 // Now ask the kernel again and check that no restorer will leak. 182 // Now ask the kernel again and check that no restorer will leak.
178 if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) { 183 if (sys_rt_sigaction(signum, NULL, &act) || act.k_sa_restorer) {
179 RAW_LOG(FATAL, "Cound not fix sa_restorer."); 184 RAW_LOG(FATAL, "Cound not fix sa_restorer.");
180 } 185 }
181 #endif // !defined(NDEBUG) 186 #endif // !defined(NDEBUG)
182 } 187 }
183 } 188 }
184 #endif // !defined(OS_LINUX) || 189 #endif // !defined(OS_LINUX) ||
185 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__)) 190 // (!defined(__i386__) && !defined(__x86_64__) && !defined(__arm__))
186 191
192 #if defined(OS_LINUX)
193 bool IsRunningOnValgrind() {
194 return RUNNING_ON_VALGRIND;
195 }
196
197 // This function runs on the stack specified on the clone call. It uses longjmp
198 // to switch back to the original stack so the child can return from sys_clone.
199 int CloneHelper(void* arg) {
200 jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
201 longjmp(*env_ptr, 1);
202
203 // Should not be reached.
204 RAW_CHECK(false);
205 return 1;
206 }
207
208 // This function is noinline to ensure that stack_buf is below the stack pointer
209 // that is saved when setjmp is called below. This is needed because when
210 // compiled with FORTIFY_SOURCE, glibc's longjmp checks that the stack is moved
211 // upwards. See crbug.com/442912 for more details.
212 #if defined(ADDRESS_SANITIZER)
213 // Disable AddressSanitizer instrumentation for this function to make sure
214 // |stack_buf| is allocated on thread stack instead of ASan's fake stack.
215 // Under ASan longjmp() will attempt to clean up the area between the old and
216 // new stack pointers and print a warning that may confuse the user.
217 __attribute__((no_sanitize_address))
218 #endif
219 NOINLINE pid_t CloneAndLongjmpInChild(unsigned long flags,
220 pid_t* ptid,
221 pid_t* ctid,
222 jmp_buf* env) {
223 // We use the libc clone wrapper instead of making the syscall
224 // directly because making the syscall may fail to update the libc's
225 // internal pid cache. The libc interface unfortunately requires
226 // specifying a new stack, so we use setjmp/longjmp to emulate
227 // fork-like behavior.
228 char stack_buf[PTHREAD_STACK_MIN];
229 #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \
230 defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY)
231 // The stack grows downward.
232 void* stack = stack_buf + sizeof(stack_buf);
233 #else
234 #error "Unsupported architecture"
235 #endif
236 return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid);
237 }
238 #endif // defined(OS_LINUX)
239
187 } // anonymous namespace 240 } // anonymous namespace
188 241
189 // Functor for |ScopedDIR| (below). 242 // Functor for |ScopedDIR| (below).
190 struct ScopedDIRClose { 243 struct ScopedDIRClose {
191 inline void operator()(DIR* x) const { 244 inline void operator()(DIR* x) const {
192 if (x) 245 if (x)
193 closedir(x); 246 closedir(x);
194 } 247 }
195 }; 248 };
196 249
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 bool GetAppOutputWithExitCode(const CommandLine& cl, 717 bool GetAppOutputWithExitCode(const CommandLine& cl,
665 std::string* output, 718 std::string* output,
666 int* exit_code) { 719 int* exit_code) {
667 // Run |execve()| with the current environment and store "unlimited" data. 720 // Run |execve()| with the current environment and store "unlimited" data.
668 GetAppOutputInternalResult result = GetAppOutputInternal( 721 GetAppOutputInternalResult result = GetAppOutputInternal(
669 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true, 722 cl.argv(), NULL, output, std::numeric_limits<std::size_t>::max(), true,
670 exit_code); 723 exit_code);
671 return result == EXECUTE_SUCCESS; 724 return result == EXECUTE_SUCCESS;
672 } 725 }
673 726
727 #if defined(OS_LINUX)
728 pid_t ForkWithFlags(unsigned long flags, pid_t* ptid, pid_t* ctid) {
729 const bool clone_tls_used = flags & CLONE_SETTLS;
730 const bool invalid_ctid =
731 (flags & (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)) && !ctid;
732 const bool invalid_ptid = (flags & CLONE_PARENT_SETTID) && !ptid;
733
734 // We do not support CLONE_VM.
735 const bool clone_vm_used = flags & CLONE_VM;
736
737 if (clone_tls_used || invalid_ctid || invalid_ptid || clone_vm_used) {
738 RAW_LOG(FATAL, "Invalid usage of ForkWithFlags");
739 }
740
741 // Valgrind's clone implementation does not support specifiying a child_stack
742 // without CLONE_VM, so we cannot use libc's clone wrapper when running under
743 // Valgrind. As a result, the libc pid cache may be incorrect under Valgrind.
744 // See crbug.com/442817 for more details.
745 if (IsRunningOnValgrind()) {
746 // See kernel/fork.c in Linux. There is different ordering of sys_clone
747 // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options.
748 #if defined(ARCH_CPU_X86_64)
749 return syscall(__NR_clone, flags, nullptr, ptid, ctid, nullptr);
750 #elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \
751 defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY)
752 // CONFIG_CLONE_BACKWARDS defined.
753 return syscall(__NR_clone, flags, nullptr, ptid, nullptr, ctid);
754 #else
755 #error "Unsupported architecture"
756 #endif
757 }
758
759 jmp_buf env;
760 if (setjmp(env) == 0) {
761 return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
762 }
763
764 return 0;
765 }
766 #endif // defined(OS_LINUX)
767
674 } // namespace base 768 } // namespace base
OLDNEW
« no previous file with comments | « base/process/launch.h ('k') | base/process/process.h » ('j') | testing/test.gni » ('J')

Powered by Google App Engine
This is Rietveld 408576698