1 //===-- xray_utils.cc -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of XRay, a dynamic runtime instrumentation system.
12 //===----------------------------------------------------------------------===//
13 #include "xray_utils.h"
15 #include "sanitizer_common/sanitizer_common.h"
16 #include "xray_defs.h"
17 #include "xray_flags.h"
23 #include <sys/types.h>
30 void printToStdErr(const char *Buffer) XRAY_NEVER_INSTRUMENT {
31 fprintf(stderr, "%s", Buffer);
34 void retryingWriteAll(int Fd, const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
37 auto TotalBytes = std::distance(Begin, End);
38 while (auto Written = write(Fd, Begin, TotalBytes)) {
41 continue; // Try again.
42 Report("Failed to write; errno = %d\n", errno);
45 TotalBytes -= Written;
52 std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin,
53 char *End) XRAY_NEVER_INSTRUMENT {
54 auto BytesToRead = std::distance(Begin, End);
56 ssize_t TotalBytesRead = 0;
57 while (BytesToRead && (BytesRead = read(Fd, Begin, BytesToRead))) {
58 if (BytesRead == -1) {
61 Report("Read error; errno = %d\n", errno);
62 return std::make_pair(TotalBytesRead, false);
65 TotalBytesRead += BytesRead;
66 BytesToRead -= BytesRead;
69 return std::make_pair(TotalBytesRead, true);
72 bool readValueFromFile(const char *Filename,
73 long long *Value) XRAY_NEVER_INSTRUMENT {
74 int Fd = open(Filename, O_RDONLY | O_CLOEXEC);
77 static constexpr size_t BufSize = 256;
78 char Line[BufSize] = {};
81 std::tie(BytesRead, Success) = retryingReadSome(Fd, Line, Line + BufSize);
85 const char *End = nullptr;
86 long long Tmp = internal_simple_strtoll(Line, &End, 10);
88 if (Line[0] != '\0' && (*End == '\n' || *End == '\0')) {
95 int getLogFD() XRAY_NEVER_INSTRUMENT {
96 // Open a temporary file once for the log.
97 char TmpFilename[256] = {};
98 char TmpWildcardPattern[] = "XXXXXX";
99 auto **Argv = GetArgv();
100 const char *Progname = !Argv ? "(unknown)" : Argv[0];
101 const char *LastSlash = internal_strrchr(Progname, '/');
103 if (LastSlash != nullptr)
104 Progname = LastSlash + 1;
106 const int HalfLength = sizeof(TmpFilename) / 2 - sizeof(TmpWildcardPattern);
107 int NeededLength = internal_snprintf(
108 TmpFilename, sizeof(TmpFilename), "%.*s%.*s.%s", HalfLength,
109 flags()->xray_logfile_base, HalfLength, Progname, TmpWildcardPattern);
110 if (NeededLength > int(sizeof(TmpFilename))) {
111 Report("XRay log file name too long (%d): %s\n", NeededLength, TmpFilename);
114 int Fd = mkstemp(TmpFilename);
116 Report("XRay: Failed opening temporary file '%s'; not logging events.\n",
121 Report("XRay: Log file in '%s'\n", TmpFilename);
126 } // namespace __xray