//===-- sanitizer_symbolizer_linux.cc -------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries.
// Linux-specific implementation of symbolizer parts.
//===----------------------------------------------------------------------===//
#include "sanitizer_platform.h"
#if SANITIZER_LINUX
#include "sanitizer_common.h"
#include "sanitizer_linux.h"
namespace __sanitizer {
#if SANITIZER_ANDROID
void SymbolizerPrepareForSandboxing() {
// Do nothing on Android.
}
#else
static char proc_self_exe_cache_str[kMaxPathLength];
static uptr proc_self_exe_cache_len = 0;
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
uptr module_name_len = internal_readlink(
"/proc/self/exe", buf, buf_len);
int readlink_error;
if (internal_iserror(buf_len, &readlink_error)) {
if (proc_self_exe_cache_len) {
// If available, use the cached module name.
CHECK_LE(proc_self_exe_cache_len, buf_len);
internal_strncpy(buf, proc_self_exe_cache_str, buf_len);
module_name_len = internal_strlen(proc_self_exe_cache_str);
} else {
// We can't read /proc/self/exe for some reason, assume the name of the
// binary is unknown.
Report("WARNING: readlink(\"/proc/self/exe\") failed with errno %d, "
"some stack frames may not be symbolized\n", readlink_error);
module_name_len = internal_snprintf(buf, buf_len, "/proc/self/exe");
}
CHECK_LT(module_name_len, buf_len);
buf[module_name_len] = '\0';
}
return module_name_len;
}
void SymbolizerPrepareForSandboxing() {
if (!proc_self_exe_cache_len) {
proc_self_exe_cache_len =
ReadBinaryName(proc_self_exe_cache_str, kMaxPathLength);
}
}
#endif // SANITIZER_ANDROID
} // namespace __sanitizer
#endif // SANITIZER_LINUX