[Sanitizer] Allow setting the report path to create directory

When setting the report path, recursively create the directory as
needed. This brings the profile path support for memprof on par with
normal PGO. The code was largely cloned from __llvm_profile_recursive_mkdir
in compiler-rt/lib/profile/InstrProfilingUtil.c.

Differential Revision: https://reviews.llvm.org/D109794
This commit is contained in:
Teresa Johnson 2021-09-14 16:34:52 -07:00
parent 22ea0cea59
commit 56dec4be9b
7 changed files with 38 additions and 2 deletions

View File

@ -25,6 +25,7 @@ void LogMessageOnPrintf(const char *str) {}
#endif
void WriteToSyslog(const char *buffer) {}
void Abort() { internal__exit(1); }
bool CreateDir(const char *pathname) { return false; }
#endif // !SANITIZER_WINDOWS
#if !SANITIZER_WINDOWS && !SANITIZER_MAC

View File

@ -75,6 +75,20 @@ void ReportFile::ReopenIfNecessary() {
fd_pid = pid;
}
static void RecursiveCreateParentDirs(char *path) {
if (path[0] == '\0')
return;
for (int i = 1; path[i] != '\0'; ++i) {
char save = path[i];
if (!IsPathSeparator(path[i]))
continue;
path[i] = '\0';
/* Some of these will fail, because the directory exists, ignore it. */
CreateDir(path);
path[i] = save;
}
}
void ReportFile::SetReportPath(const char *path) {
if (path) {
uptr len = internal_strlen(path);
@ -95,6 +109,7 @@ void ReportFile::SetReportPath(const char *path) {
fd = kStdoutFd;
} else {
internal_snprintf(path_prefix, kMaxPathLength, "%s", path);
RecursiveCreateParentDirs(path_prefix);
}
}

View File

@ -81,6 +81,8 @@ bool FileExists(const char *filename);
char *FindPathToBinary(const char *name);
bool IsPathSeparator(const char c);
bool IsAbsolutePath(const char *path);
// Returns true on success, false on failure.
bool CreateDir(const char *pathname);
// Starts a subprocess and returs its pid.
// If *_fd parameters are not kInvalidFd their corresponding input/output
// streams will be redirect to the file. The files will always be closed

View File

@ -151,6 +151,8 @@ int Atexit(void (*function)(void)) {
#endif
}
bool CreateDir(const char *pathname) { return mkdir(pathname, 0755) == 0; }
bool SupportsColoredOutput(fd_t fd) {
return isatty(fd) != 0;
}

View File

@ -565,6 +565,8 @@ void Abort() {
internal__exit(3);
}
bool CreateDir(const char *pathname) { return _mkdir(pathname) == 0; }
#if !SANITIZER_GO
// Read the file to extract the ImageBase field from the PE header. If ASLR is
// disabled and this virtual address is available, the loader will typically

View File

@ -326,3 +326,17 @@ TEST(SanitizerCommon, InternalMmapWithOffset) {
internal_unlink(tmpfile);
}
#endif
TEST(SanitizerCommon, ReportFile) {
StaticSpinMutex report_file_mu;
ReportFile report_file = {&report_file_mu, kStderrFd, "", "", 0};
char tmpfile[128];
temp_file_name(tmpfile, sizeof(tmpfile),
"dir/sanitizer_common.reportfile.tmp.");
report_file.SetReportPath(tmpfile);
const char *path = report_file.GetReportPath();
EXPECT_EQ(internal_strncmp(tmpfile, path, strlen(tmpfile)), 0);
// This will close tmpfile.
report_file.SetReportPath("stderr");
Unlink(tmpfile);
}

View File

@ -11,10 +11,10 @@ volatile int *null = 0;
int main(int argc, char **argv) {
char buff[1000];
sprintf(buff, "%s.report_path", argv[0]);
sprintf(buff, "%s.report_path/report", 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.
// CHECK: Path {{.*}}Posix/Output/sanitizer_set_report_path_test.cpp.tmp.report_path/report.