47 changes: 32 additions & 15 deletions compiler-rt/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,42 @@
//===----------------------------------------------------------------------===//

#include "sanitizer_stacktrace_printer.h"

#include "sanitizer_file.h"
#include "sanitizer_flags.h"
#include "sanitizer_fuchsia.h"

namespace __sanitizer {

// sanitizer_symbolizer_markup.cpp implements these differently.
#if !SANITIZER_SYMBOLIZER_MARKUP

static const char *StripFunctionName(const char *function, const char *prefix) {
if (!function) return nullptr;
if (!prefix) return function;
uptr prefix_len = internal_strlen(prefix);
if (0 == internal_strncmp(function, prefix, prefix_len))
return function + prefix_len;
const char *StripFunctionName(const char *function) {
if (!common_flags()->demangle)
return function;
if (!function)
return nullptr;
auto try_strip = [function](const char *prefix) -> const char * {
const uptr prefix_len = internal_strlen(prefix);
if (!internal_strncmp(function, prefix, prefix_len))
return function + prefix_len;
return nullptr;
};
if (SANITIZER_APPLE) {
if (const char *s = try_strip("wrap_"))
return s;
} else {
if (const char *s = try_strip("__interceptor_"))
return s;
}
return function;
}

// sanitizer_symbolizer_markup.cpp implements these differently.
#if !SANITIZER_SYMBOLIZER_MARKUP

static const char *DemangleFunctionName(const char *function) {
if (!function) return nullptr;
if (!common_flags()->demangle)
return function;
if (!function)
return nullptr;

// NetBSD uses indirection for old threading functions for historical reasons
// The mangled names are internal implementation detail and should not be
Expand Down Expand Up @@ -121,7 +138,7 @@ static const char kDefaultFormat[] = " #%n %p %F %L";

void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
uptr address, const AddressInfo *info, bool vs_style,
const char *strip_path_prefix, const char *strip_func_prefix) {
const char *strip_path_prefix) {
// info will be null in the case where symbolization is not needed for the
// given format. This ensures that the code below will get a hard failure
// rather than print incorrect information in case RenderNeedsSymbolization
Expand Down Expand Up @@ -157,8 +174,8 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
MaybeBuildIdToBuffer(*info, /*PrefixSpace=*/false, buffer);
break;
case 'f':
buffer->append("%s", DemangleFunctionName(StripFunctionName(
info->function, strip_func_prefix)));
buffer->append("%s",
DemangleFunctionName(StripFunctionName(info->function)));
break;
case 'q':
buffer->append("0x%zx", info->function_offset != AddressInfo::kUnknown
Expand All @@ -178,8 +195,8 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
case 'F':
// Function name and offset, if file is unknown.
if (info->function) {
buffer->append("in %s", DemangleFunctionName(StripFunctionName(
info->function, strip_func_prefix)));
buffer->append("in %s",
DemangleFunctionName(StripFunctionName(info->function)));
if (!info->file && info->function_offset != AddressInfo::kUnknown)
buffer->append("+0x%zx", info->function_offset);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

namespace __sanitizer {

// Strip interceptor prefixes from function name.
const char *StripFunctionName(const char *function);

// Render the contents of "info" structure, which represents the contents of
// stack frame "frame_no" and appends it to the "buffer". "format" is a
// string with placeholders, which is copied to the output with
Expand All @@ -26,8 +29,7 @@ namespace __sanitizer {
// will be turned into
// " frame 10: function foo::bar() at my/file.cc:10"
// You may additionally pass "strip_path_prefix" to strip prefixes of paths to
// source files and modules, and "strip_func_prefix" to strip prefixes of
// function names.
// source files and modules.
// Here's the full list of available placeholders:
// %% - represents a '%' character;
// %n - frame number (copy of frame_no);
Expand All @@ -48,8 +50,7 @@ namespace __sanitizer {
// %M - prints module basename and offset, if it is known, or PC.
void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no,
uptr address, const AddressInfo *info, bool vs_style,
const char *strip_path_prefix = "",
const char *strip_func_prefix = "");
const char *strip_path_prefix = "");

bool RenderNeedsSymbolization(const char *format);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "sanitizer_common/sanitizer_stacktrace_printer.h"

#include "gtest/gtest.h"
#include "interception/interception.h"

namespace __sanitizer {

Expand Down Expand Up @@ -71,7 +72,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
info.address = 0x400000;
info.module = internal_strdup("/path/to/my/module");
info.module_offset = 0x200;
info.function = internal_strdup("function_foo");
info.function = internal_strdup("foo");
info.function_offset = 0x100;
info.file = internal_strdup("/path/to/my/source");
info.line = 10;
Expand All @@ -83,11 +84,24 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
"%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
"Function:%f FunctionOffset:%q Source:%s Line:%l "
"Column:%c",
frame_no, info.address, &info, false, "/path/to/", "function_");
frame_no, info.address, &info, false, "/path/to/");
EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
"Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
"Column:5",
str.data());

str.clear();
// Check that RenderFrame() strips interceptor prefixes.
info.function = internal_strdup(SANITIZER_STRINGIFY(WRAP(bar)));
RenderFrame(&str,
"%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
"Function:%f FunctionOffset:%q Source:%s Line:%l "
"Column:%c",
frame_no, info.address, &info, false, "/path/to/");
EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
"Function:bar FunctionOffset:0x100 Source:my/source Line:10 "
"Column:5",
str.data());
info.Clear();
str.clear();

Expand Down
8 changes: 1 addition & 7 deletions compiler-rt/lib/tsan/rtl/tsan_report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@ static const char *ReportTypeString(ReportType typ, uptr tag) {
UNREACHABLE("missing case");
}

#if SANITIZER_APPLE
static const char *const kInterposedFunctionPrefix = "wrap_";
#else
static const char *const kInterposedFunctionPrefix = "__interceptor_";
#endif

void PrintStack(const ReportStack *ent) {
if (ent == 0 || ent->frames == 0) {
Printf(" [failed to restore the stack]\n\n");
Expand All @@ -115,7 +109,7 @@ void PrintStack(const ReportStack *ent) {
RenderFrame(&res, common_flags()->stack_trace_format, i,
frame->info.address, &frame->info,
common_flags()->symbolize_vs_style,
common_flags()->strip_path_prefix, kInterposedFunctionPrefix);
common_flags()->strip_path_prefix);
Printf("%s\n", res.data());
}
Printf("\n");
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/msan/Linux/b64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ int main(int iArgc, char *szArgv[]) {
char dst[dst_len];
int res = b64_ntop(reinterpret_cast<const unsigned char *>(src), src_len,
dst, dst_len);
// NTOP_READ: Uninitialized bytes in __interceptor___b64_ntop
// NTOP_READ: Uninitialized bytes in __b64_ntop
return 0;
}

Expand All @@ -73,7 +73,7 @@ int main(int iArgc, char *szArgv[]) {
__msan_poison(src, src_len);
unsigned char target[src_len];
int res = b64_pton(src, target, src_len);
// PTON_READ: Uninitialized bytes in __interceptor___b64_pton
// PTON_READ: Uninitialized bytes in __b64_pton
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/msan/Linux/sendmsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ int main() {

#if defined(SEND)
sent = send(sockfd[0], buf, kBufSize, 0);
// SEND: Uninitialized bytes in __interceptor_send at offset 7 inside [{{.*}}, 10)
// SEND: Uninitialized bytes in send at offset 7 inside [{{.*}}, 10)
assert(sent > 0);

ret = recv(sockfd[1], rbuf, kRecvBufSize, 0);
assert(ret == sent);
assert(__msan_test_shadow(rbuf, kRecvBufSize) == sent);
#elif defined(SENDTO)
sent = sendto(sockfd[0], buf, kBufSize, 0, nullptr, 0);
// SENDTO: Uninitialized bytes in __interceptor_sendto at offset 7 inside [{{.*}}, 10)
// SENDTO: Uninitialized bytes in sendto at offset 7 inside [{{.*}}, 10)
assert(sent > 0);

struct sockaddr_storage ss;
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/test/msan/fgets_fputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ int main(int argc, char *argv[]) {
return 0;
}

// CHECK-FPUTS: Uninitialized bytes in __interceptor_fputs at offset 0 inside
// CHECK-PUTS: Uninitialized bytes in __interceptor_puts at offset 0 inside
// CHECK-FPUTS: Uninitialized bytes in fputs at offset 0 inside
// CHECK-PUTS: Uninitialized bytes in puts at offset 0 inside
2 changes: 1 addition & 1 deletion compiler-rt/test/msan/fread_fwrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ int main(int argc, char *argv[]) {
return 0;
}

// CHECK: Uninitialized bytes in __interceptor_fwrite at offset 0 inside
// CHECK: Uninitialized bytes in fwrite at offset 0 inside
2 changes: 1 addition & 1 deletion compiler-rt/test/msan/getaddrinfo-positive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ int main(void) {
int res = getaddrinfo("localhost", NULL, NULL, &ai);
if (ai) z = 1; // OK
res = getaddrinfo("localhost", NULL, &hint, &ai);
// CHECK: Uninitialized bytes in __interceptor_getaddrinfo at offset 0 inside [0x{{.*}}, 48)
// CHECK: Uninitialized bytes in getaddrinfo at offset 0 inside [0x{{.*}}, 48)
// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
// CHECK: #0 {{.*}} in main {{.*}}getaddrinfo-positive.cpp:[[@LINE-3]]
return 0;
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/test/msan/scoped-interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ int main(int argc, char *argv[]) {
char *copy = strndup(uninit, sizeof(uninit)); // BOOM
free(copy);
break;
// CASE-0: Uninitialized bytes in __interceptor_strndup
// CASE-0: Uninitialized bytes in strndup
}
case '1': {
puts(uninit); // BOOM
puts(uninit); // Ensure previous call did not enable interceptor checks.
break;
// CASE-1: Uninitialized bytes in __interceptor_puts
// CASE-1: Uninitialized bytes in puts
}
case '2': {
int cmp = memcmp(uninit, uninit, sizeof(uninit)); // BOOM
Expand All @@ -42,7 +42,7 @@ int main(int argc, char *argv[]) {
case '3': {
size_t len = strlen(uninit); // BOOM
break;
// CASE-3: Uninitialized bytes in __interceptor_strlen
// CASE-3: Uninitialized bytes in strlen
}
default: assert(0);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/msan/strndup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ int main(int argc, char **argv) {
assert(__msan_test_shadow(copy, 4) == 2); // Poisoning is preserved.
free(copy);
return 0;
// ON: Uninitialized bytes in __interceptor_{{(__)?}}strndup at offset 2 inside [{{.*}}, 4)
// ON: Uninitialized bytes in {{(__)?}}strndup at offset 2 inside [{{.*}}, 4)
// ON: MemorySanitizer: use-of-uninitialized-value
// ON: #0 {{.*}}main {{.*}}strndup.cpp:[[@LINE-6]]
// ON-LABEL: SUMMARY
Expand Down