forked from OSchip/llvm-project
[asan] Add %d variable to external_symbolizer_path option, so that user can specify paths relative to the location of the binary.
We want way to set a path to llvm-symbolizer that isn't relative to the current working directory; this change adds a variable that expands to the path relative to the current binary. This approach came from comments in https://reviews.llvm.org/D93070 Differential Revision: https://reviews.llvm.org/D94563
This commit is contained in:
parent
e21adfa32d
commit
9ba623c655
|
@ -274,6 +274,14 @@ uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len) {
|
|||
return name_len;
|
||||
}
|
||||
|
||||
uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len) {
|
||||
ReadBinaryNameCached(buf, buf_len);
|
||||
const char *exec_name_pos = StripModuleName(buf);
|
||||
uptr name_len = exec_name_pos - buf;
|
||||
buf[name_len] = '\0';
|
||||
return name_len;
|
||||
}
|
||||
|
||||
#if !SANITIZER_GO
|
||||
void PrintCmdline() {
|
||||
char **argv = GetArgv();
|
||||
|
|
|
@ -248,6 +248,7 @@ const char *StripModuleName(const char *module);
|
|||
// OS
|
||||
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
|
||||
uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);
|
||||
uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len);
|
||||
uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len);
|
||||
const char *GetProcessName();
|
||||
void UpdateProcessName();
|
||||
|
|
|
@ -35,6 +35,7 @@ void CommonFlags::CopyFrom(const CommonFlags &other) {
|
|||
// Copy the string from "s" to "out", making the following substitutions:
|
||||
// %b = binary basename
|
||||
// %p = pid
|
||||
// %d = binary directory
|
||||
void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
|
||||
char *out_end = out + out_size;
|
||||
while (*s && out < out_end - 1) {
|
||||
|
@ -64,6 +65,12 @@ void SubstituteForFlagValue(const char *s, char *out, uptr out_size) {
|
|||
s += 2; // skip "%p"
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
uptr len = ReadBinaryDir(out, out_end - out);
|
||||
out += len;
|
||||
s += 2; // skip "%d"
|
||||
break;
|
||||
}
|
||||
default:
|
||||
*out++ = *s++;
|
||||
break;
|
||||
|
|
|
@ -400,6 +400,13 @@ const char *Symbolizer::PlatformDemangle(const char *name) {
|
|||
|
||||
static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {
|
||||
const char *path = common_flags()->external_symbolizer_path;
|
||||
|
||||
if (path && internal_strchr(path, '%')) {
|
||||
char *new_path = (char *)InternalAlloc(kMaxPathLength);
|
||||
SubstituteForFlagValue(path, new_path, kMaxPathLength);
|
||||
path = new_path;
|
||||
}
|
||||
|
||||
const char *binary_name = path ? StripModuleName(path) : "";
|
||||
if (path && path[0] == '\0') {
|
||||
VReport(2, "External symbolizer is explicitly disabled.\n");
|
||||
|
|
|
@ -288,8 +288,15 @@ static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
|
|||
return;
|
||||
}
|
||||
|
||||
// Add llvm-symbolizer in case the binary has dwarf.
|
||||
// Add llvm-symbolizer.
|
||||
const char *user_path = common_flags()->external_symbolizer_path;
|
||||
|
||||
if (user_path && internal_strchr(user_path, '%')) {
|
||||
char *new_path = (char *)InternalAlloc(kMaxPathLength);
|
||||
SubstituteForFlagValue(user_path, new_path, kMaxPathLength);
|
||||
user_path = new_path;
|
||||
}
|
||||
|
||||
const char *path =
|
||||
user_path ? user_path : FindPathToBinary("llvm-symbolizer.exe");
|
||||
if (path) {
|
||||
|
|
|
@ -1049,10 +1049,23 @@ const char *SignalContext::Describe() const {
|
|||
}
|
||||
|
||||
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
|
||||
// FIXME: Actually implement this function.
|
||||
CHECK_GT(buf_len, 0);
|
||||
buf[0] = 0;
|
||||
return 0;
|
||||
if (buf_len == 0)
|
||||
return 0;
|
||||
|
||||
// Get the UTF-16 path and convert to UTF-8.
|
||||
wchar_t binname_utf16[kMaxPathLength];
|
||||
int binname_utf16_len =
|
||||
GetModuleFileNameW(NULL, binname_utf16, ARRAY_SIZE(binname_utf16));
|
||||
if (binname_utf16_len == 0) {
|
||||
buf[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
int binary_name_len = ::WideCharToMultiByte(
|
||||
CP_UTF8, 0, binname_utf16, binname_utf16_len, buf, buf_len, NULL, NULL);
|
||||
if ((unsigned)binary_name_len == buf_len)
|
||||
--binary_name_len;
|
||||
buf[binary_name_len] = '\0';
|
||||
return binary_name_len;
|
||||
}
|
||||
|
||||
uptr ReadLongProcessName(/*out*/char *buf, uptr buf_len) {
|
||||
|
|
|
@ -461,12 +461,9 @@ TEST(SanitizerCommon, ReservedAddressRangeUnmap) {
|
|||
EXPECT_DEATH(address_range.Unmap(base_addr + (PageSize * 2), PageSize), ".*");
|
||||
}
|
||||
|
||||
// Windows has no working ReadBinaryName.
|
||||
#if !SANITIZER_WINDOWS
|
||||
TEST(SanitizerCommon, ReadBinaryNameCached) {
|
||||
char buf[256];
|
||||
EXPECT_NE((uptr)0, ReadBinaryNameCached(buf, sizeof(buf)));
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
// REQUIRES: shell
|
||||
// RUN: rm -rf %t.bin
|
||||
// RUN: mkdir %t.bin
|
||||
// RUN: cp $(which llvm-symbolizer) %t.bin
|
||||
// RUN: rm -rf %t.dir
|
||||
// RUN: mkdir %t.dir
|
||||
// RUN: %clangxx -O0 %s -o %t && cd %t.dir
|
||||
// RUN: %env_tool_opts=external_symbolizer_path=%d/external_symbolizer_path.cpp.tmp.bin/llvm-symbolizer \
|
||||
// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=FOUND
|
||||
// RUN: rm -rf %t.bin/llvm-symbolizer
|
||||
// RUN: cd ..
|
||||
// RUN: %clangxx -O0 %s -o %t && cd %t.dir
|
||||
// RUN: %env_tool_opts=external_symbolizer_path=%d/external_symbolizer_path.cpp.tmp.bin/llvm-symbolizer \
|
||||
// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=NOT-FOUND
|
||||
|
||||
#include <sanitizer/common_interface_defs.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void Symbolize() {
|
||||
char buffer[100];
|
||||
__sanitizer_symbolize_pc(__builtin_return_address(0), "%p %F %L", buffer,
|
||||
sizeof(buffer));
|
||||
printf("%s\n", buffer);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// FOUND: {{0x.* in main}}
|
||||
// NOT-FOUND: WARNING: invalid path to external symbolizer!
|
||||
Symbolize();
|
||||
}
|
Loading…
Reference in New Issue