diff options
3 files changed, 50 insertions, 1 deletions
diff --git a/compiler-rt/lib/asan/asan_mac.cc b/compiler-rt/lib/asan/asan_mac.cc index f6f6b146568..8a0cb9eb0f9 100644 --- a/compiler-rt/lib/asan/asan_mac.cc +++ b/compiler-rt/lib/asan/asan_mac.cc @@ -106,7 +106,23 @@ void MaybeReexec() { _NSGetExecutablePath(program_name, &buf_size); // Ok to use setenv() since the wrappers don't depend on the value of // asan_inited. - setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0); + if (dyld_insert_libraries) { + // Append the runtime dylib name to the existing value of + // DYLD_INSERT_LIBRARIES. + uptr old_env_len = internal_strlen(dyld_insert_libraries); + uptr fname_len = internal_strlen(info.dli_fname); + LowLevelAllocator allocator_for_env; + char *new_env = + (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2); + internal_strncpy(new_env, dyld_insert_libraries, old_env_len); + new_env[old_env_len] = ':'; + // Copy fname_len and add a trailing zero. + internal_strncpy(new_env + old_env_len + 1, info.dli_fname, fname_len + 1); + setenv(kDyldInsertLibraries, new_env, /*overwrite*/1); + } else { + // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name. + setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0); + } if (flags()->verbosity >= 1) { Report("exec()-ing the program with\n"); Report("%s=%s\n", kDyldInsertLibraries, info.dli_fname); diff --git a/compiler-rt/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc b/compiler-rt/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc new file mode 100644 index 00000000000..789eda6d108 --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc @@ -0,0 +1,20 @@ +#include <stdio.h> +// Make sure ASan doesn't hang in an exec loop if DYLD_INSERT_LIBRARIES is set. +// This is a regression test for +// https://code.google.com/p/address-sanitizer/issues/detail?id=159 + +// RUN: %clangxx_asan -m64 %s -o %t +// RUN: %clangxx -m64 %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ +// RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib + +// If the test hangs, kill it after 15 seconds. +// RUN: DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \ +// RUN: alarm 15 %t 2>&1 | FileCheck %s || exit 1 +#include <stdlib.h> + +int main() { + const char kEnvName[] = "DYLD_INSERT_LIBRARIES"; + printf("%s=%s\n", kEnvName, getenv(kEnvName)); + // CHECK: {{DYLD_INSERT_LIBRARIES=.*darwin-dummy-shared-lib-so.dylib.*}} + return 0; +} diff --git a/compiler-rt/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc b/compiler-rt/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc new file mode 100644 index 00000000000..5d939991476 --- /dev/null +++ b/compiler-rt/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc @@ -0,0 +1,13 @@ +//===----------- darwin-dummy-shared-lib-so.cc ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +//===----------------------------------------------------------------------===// +void foo() {} |