diff options
author | Alexander Potapenko <glider@google.com> | 2013-02-13 17:52:55 +0000 |
---|---|---|
committer | Alexander Potapenko <glider@google.com> | 2013-02-13 17:52:55 +0000 |
commit | c5ba5ef3c57afabff927d516d83e1d908b224c6e (patch) | |
tree | 01519d7194d571b34fcf4ef729e31b61a1b50c76 | |
parent | 2680b53d900e60ea1c285997e925d1da24ce0b4c (diff) | |
download | bcm5719-llvm-c5ba5ef3c57afabff927d516d83e1d908b224c6e.tar.gz bcm5719-llvm-c5ba5ef3c57afabff927d516d83e1d908b224c6e.zip |
[ASan] When re-executing the process on OS X, make sure we update the existing DYLD_INSERT_LIBRARIES correctly.
Previously ASan used to hang in an exec loop, because it failed to overwrite the env var value
(see https://code.google.com/p/address-sanitizer/issues/detail?id=159).
llvm-svn: 175059
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() {} |