[ASan] Make binary name reader cross-platform.

Differential Revision: http://reviews.llvm.org/D10213

llvm-svn: 239020
This commit is contained in:
Yury Gribov 2015-06-04 07:29:43 +00:00
parent 8bdcb69413
commit c019a57099
11 changed files with 51 additions and 35 deletions

View File

@ -367,6 +367,8 @@ static void AsanInitInternal() {
// initialization steps look at flags().
InitializeFlags();
CacheBinaryName();
AsanCheckIncompatibleRT();
AsanCheckDynamicRTPrereqs();

View File

@ -373,6 +373,7 @@ void __msan_init() {
InitTlsSize();
InitializeFlags();
CacheBinaryName();
__sanitizer_set_report_path(common_flags()->log_path);
InitializeInterceptors();

View File

@ -338,6 +338,24 @@ bool TemplateMatch(const char *templ, const char *str) {
return true;
}
static char binary_name_cache_str[kMaxPathLength];
static const char *binary_basename_cache_str;
const char *GetBinaryName() {
return binary_name_cache_str;
}
const char *GetBinaryBasename() {
return binary_basename_cache_str;
}
// Call once to make sure that binary_name_cache_str is initialized
void CacheBinaryName() {
CHECK_EQ('\0', binary_name_cache_str[0]);
ReadBinaryName(binary_name_cache_str, sizeof(binary_name_cache_str));
binary_basename_cache_str = StripModuleName(binary_name_cache_str);
}
} // namespace __sanitizer
using namespace __sanitizer; // NOLINT

View File

@ -238,6 +238,10 @@ const char *StripPathPrefix(const char *filepath,
const char *StripModuleName(const char *module);
// OS
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
const char *GetBinaryName();
const char *GetBinaryBasename();
void CacheBinaryName();
void DisableCoreDumperIfNecessary();
void DumpProcessMap();
bool FileExists(const char *filename);
@ -248,8 +252,6 @@ char *FindPathToBinary(const char *name);
bool IsPathSeparator(const char c);
bool IsAbsolutePath(const char *path);
// Returns the path to the main executable.
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
u32 GetUid();
void ReExec();
bool StackSizeIsUnlimited();

View File

@ -706,47 +706,32 @@ uptr GetPageSize() {
#endif
}
static char proc_self_exe_cache_str[kMaxPathLength];
static uptr proc_self_exe_cache_len = 0;
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
if (proc_self_exe_cache_len > 0) {
// If available, use the cached module name.
uptr module_name_len =
internal_snprintf(buf, buf_len, "%s", proc_self_exe_cache_str);
CHECK_LT(module_name_len, buf_len);
return module_name_len;
}
#if SANITIZER_FREEBSD
const int Mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
const int Mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
const char *default_module_name = "kern.proc.pathname";
size_t Size = buf_len;
bool IsErr = (sysctl(Mib, 4, buf, &Size, NULL, 0) != 0);
bool IsErr = (sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0);
int readlink_error = IsErr ? errno : 0;
uptr module_name_len = Size;
#else
const char *default_module_name = "/proc/self/exe";
uptr module_name_len = internal_readlink(
"/proc/self/exe", buf, buf_len);
default_module_name, buf, buf_len);
int readlink_error;
bool IsErr = internal_iserror(module_name_len, &readlink_error);
#endif
if (IsErr) {
// 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, "
// We can't read binary name for some reason, assume it's unknown.
Report("WARNING: reading executable name 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");
module_name_len = internal_snprintf(buf, buf_len, "%s",
default_module_name);
CHECK_LT(module_name_len, buf_len);
}
return module_name_len;
}
void CacheBinaryName() {
if (!proc_self_exe_cache_len) {
proc_self_exe_cache_len =
ReadBinaryName(proc_self_exe_cache_str, kMaxPathLength);
}
}
// Match full names of the form /path/to/base_name{-,.}*
bool LibraryNameIs(const char *full_name, const char *base_name) {
const char *name = full_name;

View File

@ -81,9 +81,6 @@ uptr ThreadSelfOffset();
// information).
bool LibraryNameIs(const char *full_name, const char *base_name);
// Cache the value of /proc/self/exe.
void CacheBinaryName();
// Call cb for each region mapped by map.
void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
} // namespace __sanitizer

View File

@ -369,6 +369,13 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
# endif // SANITIZER_WORDSIZE
}
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
// FIXME: Actually implement this function.
CHECK_GT(buf_len, 0);
buf[0] = 0;
return 0;
}
} // namespace __sanitizer
#endif // SANITIZER_MAC

View File

@ -354,12 +354,7 @@ const char *Symbolizer::PlatformDemangle(const char *name) {
return DemangleCXXABI(name);
}
void Symbolizer::PlatformPrepareForSandboxing() {
#if SANITIZER_LINUX && !SANITIZER_ANDROID
// Cache /proc/self/exe on Linux.
CacheBinaryName();
#endif
}
void Symbolizer::PlatformPrepareForSandboxing() {}
static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {
const char *path = common_flags()->external_symbolizer_path;

View File

@ -641,6 +641,13 @@ SignalContext SignalContext::Create(void *siginfo, void *context) {
return SignalContext(context, access_addr, pc, sp, bp);
}
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
// FIXME: Actually implement this function.
CHECK_GT(buf_len, 0);
buf[0] = 0;
return 0;
}
} // namespace __sanitizer
#endif // _WIN32

View File

@ -319,6 +319,7 @@ void Initialize(ThreadState *thr) {
ctx = new(ctx_placeholder) Context;
const char *options = GetEnv(kTsanOptionsEnv);
InitializeFlags(&ctx->flags, options);
CacheBinaryName();
#ifndef SANITIZER_GO
InitializeAllocator();
#endif

View File

@ -37,6 +37,7 @@ static void CommonInit() {
static void CommonStandaloneInit() {
SanitizerToolName = "UndefinedBehaviorSanitizer";
InitializeFlags();
CacheBinaryName();
__sanitizer_set_report_path(common_flags()->log_path);
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
CommonInit();