Skip to content

Commit

Permalink
[sanitizer_common] Add facility to get the full report path
Browse files Browse the repository at this point in the history
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
  • Loading branch information
teresajohnson committed Nov 19, 2020
1 parent 8ecb015 commit 8f778b2
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 0 deletions.
3 changes: 3 additions & 0 deletions compiler-rt/include/sanitizer/common_interface_defs.h
Expand Up @@ -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
Expand Down
Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -213,6 +219,10 @@ void __sanitizer_set_report_fd(void *fd) {
report_file.fd = (fd_t)reinterpret_cast<uptr>(fd);
report_file.fd_pid = internal_getpid();
}

const char *__sanitizer_get_report_path() {
return report_file.GetReportPath();
}
} // extern "C"

#endif // !SANITIZER_FUCHSIA
1 change: 1 addition & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_file.h
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp
Expand Up @@ -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
Expand Up @@ -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;
Expand Down
@@ -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 <assert.h>
#include <sanitizer/common_interface_defs.h>
#include <stdio.h>
#include <string.h>

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.

0 comments on commit 8f778b2

Please sign in to comment.