diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp --- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp @@ -52,16 +52,19 @@ class AtosSymbolizerProcess : public SymbolizerProcess { public: - explicit AtosSymbolizerProcess(const char *path, pid_t parent_pid) + explicit AtosSymbolizerProcess(const char *path) : SymbolizerProcess(path, /*use_posix_spawn*/ true) { - // Put the string command line argument in the object so that it outlives - // the call to GetArgV. - internal_snprintf(pid_str_, sizeof(pid_str_), "%d", parent_pid); + pid_str_[0] = '\0'; } private: bool StartSymbolizerSubprocess() override { // Configure sandbox before starting atos process. + + // Put the string command line argument in the object so that it outlives + // the call to GetArgV. + internal_snprintf(pid_str_, sizeof(pid_str_), "%d", internal_getpid()); + return SymbolizerProcess::StartSymbolizerSubprocess(); } @@ -138,7 +141,7 @@ } AtosSymbolizer::AtosSymbolizer(const char *path, LowLevelAllocator *allocator) - : process_(new(*allocator) AtosSymbolizerProcess(path, getpid())) {} + : process_(new (*allocator) AtosSymbolizerProcess(path)) {} bool AtosSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { if (!process_) return false; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace-in-code-loaded-after-fork.cpp b/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace-in-code-loaded-after-fork.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Darwin/print-stack-trace-in-code-loaded-after-fork.cpp @@ -0,0 +1,56 @@ +// RUN: %clangxx %s -g -DSHARED_LIB -shared -o %t_shared_lib.dylib +// RUN: %clangxx %s -g -USHARED_LIB -o %t_loader +// RUN: %env_tool_opts=verbosity=3 %run %t_loader %t_shared_lib.dylib > %t_loader_output.txt 2>&1 +// RUN: FileCheck -input-file=%t_loader_output.txt %s +// RUN: FileCheck -check-prefix=CHECK-STACKTRACE -input-file=%t_loader_output.txt %s + +#include + +#ifdef SHARED_LIB +#include + +extern "C" void PrintStack() { + fprintf(stderr, "Calling __sanitizer_print_stack_trace\n"); + // CHECK-STACKTRACE: #0{{( *0x.* *in *)?}} __sanitizer_print_stack_trace + // CHECK-STACKTRACE: #1{{( *0x.* *in *)?}} PrintStack {{.*}}print-stack-trace-in-code-loaded-after-fork.cpp:[[@LINE+1]] + __sanitizer_print_stack_trace(); +} +#else +#include +#include +#include +#include +#include + +typedef void (*PrintStackFnPtrTy)(void); + +int main(int argc, char **argv) { + assert(argc == 2); + pid_t pid = fork(); + if (pid != 0) { + // Parent + pid_t parent_pid = getpid(); + fprintf(stderr, "parent: %d\n", parent_pid); + int status = 0; + pid_t child = waitpid(pid, &status, /*options=*/0); + assert(pid == child); + bool clean_exit = WIFEXITED(status) && WEXITSTATUS(status) == 0; + return !clean_exit; + } + // Child. + pid = getpid(); + // CHECK: child: [[CHILD_PID:[0-9]+]] + fprintf(stderr, "child: %d\n", pid); + const char *library_to_load = argv[1]; + void *handle = dlopen(library_to_load, RTLD_NOW | RTLD_LOCAL); + assert(handle); + PrintStackFnPtrTy PrintStackFnPtr = (PrintStackFnPtrTy)dlsym(handle, "PrintStack"); + assert(PrintStackFnPtr); + // Check that the symbolizer is told examine the child process. + // CHECK: Launching Symbolizer process: {{.+}}atos -p [[CHILD_PID]] + // CHECK-STACKTRACE: #2{{( *0x.* *in *)?}} main {{.*}}print-stack-trace-in-code-loaded-after-fork.cpp:[[@LINE+1]] + PrintStackFnPtr(); + return 0; +} + +#endif