OLD | NEW |
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> | 10 #include <sched.h> |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 pid_t* ptid, | 731 pid_t* ptid, |
732 pid_t* ctid, | 732 pid_t* ctid, |
733 jmp_buf* env) { | 733 jmp_buf* env) { |
734 // We use the libc clone wrapper instead of making the syscall | 734 // We use the libc clone wrapper instead of making the syscall |
735 // directly because making the syscall may fail to update the libc's | 735 // directly because making the syscall may fail to update the libc's |
736 // internal pid cache. The libc interface unfortunately requires | 736 // internal pid cache. The libc interface unfortunately requires |
737 // specifying a new stack, so we use setjmp/longjmp to emulate | 737 // specifying a new stack, so we use setjmp/longjmp to emulate |
738 // fork-like behavior. | 738 // fork-like behavior. |
739 char stack_buf[PTHREAD_STACK_MIN] ALIGNAS(16); | 739 char stack_buf[PTHREAD_STACK_MIN] ALIGNAS(16); |
740 #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ | 740 #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ |
741 defined(ARCH_CPU_MIPS64_FAMILY) || defined(ARCH_CPU_MIPS_FAMILY) | 741 defined(ARCH_CPU_MIPS_FAMILY) |
742 // The stack grows downward. | 742 // The stack grows downward. |
743 void* stack = stack_buf + sizeof(stack_buf); | 743 void* stack = stack_buf + sizeof(stack_buf); |
744 #else | 744 #else |
745 #error "Unsupported architecture" | 745 #error "Unsupported architecture" |
746 #endif | 746 #endif |
747 return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid); | 747 return clone(&CloneHelper, stack, flags, env, ptid, nullptr, ctid); |
748 } | 748 } |
749 | 749 |
750 } // anonymous namespace | 750 } // anonymous namespace |
751 | 751 |
(...skipping 13 matching lines...) Expand all Loading... |
765 // Valgrind's clone implementation does not support specifiying a child_stack | 765 // Valgrind's clone implementation does not support specifiying a child_stack |
766 // without CLONE_VM, so we cannot use libc's clone wrapper when running under | 766 // without CLONE_VM, so we cannot use libc's clone wrapper when running under |
767 // Valgrind. As a result, the libc pid cache may be incorrect under Valgrind. | 767 // Valgrind. As a result, the libc pid cache may be incorrect under Valgrind. |
768 // See crbug.com/442817 for more details. | 768 // See crbug.com/442817 for more details. |
769 if (IsRunningOnValgrind()) { | 769 if (IsRunningOnValgrind()) { |
770 // See kernel/fork.c in Linux. There is different ordering of sys_clone | 770 // See kernel/fork.c in Linux. There is different ordering of sys_clone |
771 // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options. | 771 // parameters depending on CONFIG_CLONE_BACKWARDS* configuration options. |
772 #if defined(ARCH_CPU_X86_64) | 772 #if defined(ARCH_CPU_X86_64) |
773 return syscall(__NR_clone, flags, nullptr, ptid, ctid, nullptr); | 773 return syscall(__NR_clone, flags, nullptr, ptid, ctid, nullptr); |
774 #elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \ | 774 #elif defined(ARCH_CPU_X86) || defined(ARCH_CPU_ARM_FAMILY) || \ |
775 defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_MIPS64_FAMILY) | 775 defined(ARCH_CPU_MIPS_FAMILY) |
776 // CONFIG_CLONE_BACKWARDS defined. | 776 // CONFIG_CLONE_BACKWARDS defined. |
777 return syscall(__NR_clone, flags, nullptr, ptid, nullptr, ctid); | 777 return syscall(__NR_clone, flags, nullptr, ptid, nullptr, ctid); |
778 #else | 778 #else |
779 #error "Unsupported architecture" | 779 #error "Unsupported architecture" |
780 #endif | 780 #endif |
781 } | 781 } |
782 | 782 |
783 jmp_buf env; | 783 jmp_buf env; |
784 if (setjmp(env) == 0) { | 784 if (setjmp(env) == 0) { |
785 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); | 785 return CloneAndLongjmpInChild(flags, ptid, ctid, &env); |
786 } | 786 } |
787 | 787 |
788 return 0; | 788 return 0; |
789 } | 789 } |
790 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) | 790 #endif // defined(OS_LINUX) || defined(OS_NACL_NONSFI) |
791 | 791 |
792 } // namespace base | 792 } // namespace base |
OLD | NEW |