From 8f778b283de5757fa8bf4da255a3a34b3a5cdbd3 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Wed, 18 Nov 2020 21:11:55 -0800 Subject: [PATCH] [sanitizer_common] Add facility to get the full report path Add a new interface __sanitizer_get_report_path which will return the full path to the report file if __sanitizer_set_report_path was previously called (otherwise it returns null). This is useful in particular for memory profiling handlers to access the path which was specified at compile time (and passed down via __memprof_profile_filename), including the pid added to the path when the file is opened. There wasn't a test for __sanitizer_set_report_path, so I added one which additionally tests the new interface. Differential Revision: https://reviews.llvm.org/D91765 --- .../include/sanitizer/common_interface_defs.h | 3 +++ .../sanitizer_common/sanitizer_common_interface.inc | 1 + compiler-rt/lib/sanitizer_common/sanitizer_file.cpp | 10 ++++++++++ compiler-rt/lib/sanitizer_common/sanitizer_file.h | 1 + .../lib/sanitizer_common/sanitizer_fuchsia.cpp | 4 ++++ .../sanitizer_common/sanitizer_interface_internal.h | 4 ++++ .../Posix/sanitizer_set_report_path_test.cpp | 20 ++++++++++++++++++++ 7 files changed, 43 insertions(+) create mode 100644 compiler-rt/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_path_test.cpp diff --git a/compiler-rt/include/sanitizer/common_interface_defs.h b/compiler-rt/include/sanitizer/common_interface_defs.h index b4f977b..cd69285 100644 --- a/compiler-rt/include/sanitizer/common_interface_defs.h +++ b/compiler-rt/include/sanitizer/common_interface_defs.h @@ -43,6 +43,9 @@ void __sanitizer_set_report_path(const char *path); // Tell the tools to write their reports to the provided file descriptor // (casted to void *). void __sanitizer_set_report_fd(void *fd); +// Get the current full report file path, if a path was specified by +// an earlier call to __sanitizer_set_report_path. Returns null otherwise. +const char *__sanitizer_get_report_path(); // Notify the tools that the sandbox is going to be turned on. The reserved // parameter will be used in the future to hold a structure with functions diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc index c78b6e1..932e547 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interface.inc @@ -13,6 +13,7 @@ INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address) INTERFACE_FUNCTION(__sanitizer_set_death_callback) INTERFACE_FUNCTION(__sanitizer_set_report_path) INTERFACE_FUNCTION(__sanitizer_set_report_fd) +INTERFACE_FUNCTION(__sanitizer_get_report_path) INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container) INTERFACE_WEAK_FUNCTION(__sanitizer_on_print) INTERFACE_WEAK_FUNCTION(__sanitizer_report_error_summary) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp index 7cce609..7c64b53 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp @@ -95,6 +95,12 @@ void ReportFile::SetReportPath(const char *path) { } } +const char *ReportFile::GetReportPath() { + SpinMutexLock l(mu); + ReopenIfNecessary(); + return full_path; +} + bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, uptr *read_len, uptr max_len, error_t *errno_p) { *buff = nullptr; @@ -213,6 +219,10 @@ void __sanitizer_set_report_fd(void *fd) { report_file.fd = (fd_t)reinterpret_cast(fd); report_file.fd_pid = internal_getpid(); } + +const char *__sanitizer_get_report_path() { + return report_file.GetReportPath(); +} } // extern "C" #endif // !SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.h b/compiler-rt/lib/sanitizer_common/sanitizer_file.h index 26681f0..08671ab 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_file.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.h @@ -26,6 +26,7 @@ struct ReportFile { void Write(const char *buffer, uptr length); bool SupportsColors(); void SetReportPath(const char *path); + const char *GetReportPath(); // Don't use fields directly. They are only declared public to allow // aggregate initialization. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index 7200ffd..5ad20d0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -529,6 +529,10 @@ void __sanitizer_set_report_path(const char *path) { void __sanitizer_set_report_fd(void *fd) { UNREACHABLE("not available on Fuchsia"); } + +const char *__sanitizer_get_report_path() { + UNREACHABLE("not available on Fuchsia"); +} } // extern "C" #endif // SANITIZER_FUCHSIA diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h b/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h index be8023e..0b001c1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_interface_internal.h @@ -28,6 +28,10 @@ extern "C" { // (casted to void *). SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_set_report_fd(void *fd); + // Get the current full report file path, if a path was specified by + // an earlier call to __sanitizer_set_report_path. Returns null otherwise. + SANITIZER_INTERFACE_ATTRIBUTE + const char *__sanitizer_get_report_path(); typedef struct { int coverage_sandboxed; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_path_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_path_test.cpp new file mode 100644 index 0000000..e5ea040 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/sanitizer_set_report_path_test.cpp @@ -0,0 +1,20 @@ +// Test __sanitizer_set_report_path and __sanitizer_get_report_path: +// RUN: %clangxx -O2 %s -o %t +// RUN: %run %t | FileCheck %s + +#include +#include +#include +#include + +volatile int *null = 0; + +int main(int argc, char **argv) { + char buff[1000]; + sprintf(buff, "%s.report_path", argv[0]); + __sanitizer_set_report_path(buff); + assert(strncmp(buff, __sanitizer_get_report_path(), strlen(buff)) == 0); + printf("Path %s\n", __sanitizer_get_report_path()); +} + +// CHECK: Path {{.*}}Posix/Output/sanitizer_set_report_path_test.cpp.tmp.report_path. -- 2.7.4