summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/xray/xray_basic_logging.cc66
-rw-r--r--compiler-rt/lib/xray/xray_fdr_logging.cc18
-rw-r--r--compiler-rt/lib/xray/xray_profiling.cc11
-rw-r--r--compiler-rt/lib/xray/xray_utils.cc66
-rw-r--r--compiler-rt/lib/xray/xray_utils.h28
5 files changed, 84 insertions, 105 deletions
diff --git a/compiler-rt/lib/xray/xray_basic_logging.cc b/compiler-rt/lib/xray/xray_basic_logging.cc
index ee28d598f8b..2dc0e053651 100644
--- a/compiler-rt/lib/xray/xray_basic_logging.cc
+++ b/compiler-rt/lib/xray/xray_basic_logging.cc
@@ -60,7 +60,7 @@ struct alignas(64) ThreadLocalData {
void *ShadowStack = nullptr;
size_t StackSize = 0;
size_t StackEntries = 0;
- int Fd = -1;
+ LogWriter *LogWriter = nullptr;
};
struct BasicLoggingOptions {
@@ -83,10 +83,10 @@ static atomic_uint64_t ThresholdTicks{0};
static atomic_uint64_t TicksPerSec{0};
static atomic_uint64_t CycleFrequency{NanosecondsPerSecond};
-static int openLogFile() XRAY_NEVER_INSTRUMENT {
- int F = getLogFD();
- if (F == -1)
- return -1;
+static LogWriter *getLog() XRAY_NEVER_INSTRUMENT {
+ LogWriter* LW = LogWriter::Open();
+ if (LW == nullptr)
+ return LW;
static pthread_once_t DetectOnce = PTHREAD_ONCE_INIT;
pthread_once(&DetectOnce, +[] {
@@ -108,16 +108,16 @@ static int openLogFile() XRAY_NEVER_INSTRUMENT {
// before setting the values in the header.
Header.ConstantTSC = 1;
Header.NonstopTSC = 1;
- retryingWriteAll(F, reinterpret_cast<char *>(&Header),
- reinterpret_cast<char *>(&Header) + sizeof(Header));
- return F;
+ LW->WriteAll(reinterpret_cast<char *>(&Header),
+ reinterpret_cast<char *>(&Header) + sizeof(Header));
+ return LW;
}
-static int getGlobalFd() XRAY_NEVER_INSTRUMENT {
+static LogWriter *getGlobalLog() XRAY_NEVER_INSTRUMENT {
static pthread_once_t OnceInit = PTHREAD_ONCE_INIT;
- static int Fd = 0;
- pthread_once(&OnceInit, +[] { Fd = openLogFile(); });
- return Fd;
+ static LogWriter *LW = nullptr;
+ pthread_once(&OnceInit, +[] { LW = getLog(); });
+ return LW;
}
static ThreadLocalData &getThreadLocalData() XRAY_NEVER_INSTRUMENT {
@@ -129,7 +129,7 @@ static ThreadLocalData &getThreadLocalData() XRAY_NEVER_INSTRUMENT {
return false;
}
pthread_setspecific(PThreadKey, &TLD);
- TLD.Fd = getGlobalFd();
+ TLD.LogWriter = getGlobalLog();
TLD.InMemoryBuffer = reinterpret_cast<XRayRecord *>(
InternalAlloc(sizeof(XRayRecord) * GlobalOptions.ThreadBufferSize,
nullptr, alignof(XRayRecord)));
@@ -157,8 +157,8 @@ template <class RDTSC>
void InMemoryRawLog(int32_t FuncId, XRayEntryType Type,
RDTSC ReadTSC) XRAY_NEVER_INSTRUMENT {
auto &TLD = getThreadLocalData();
- int Fd = getGlobalFd();
- if (Fd == -1)
+ LogWriter *LW = getGlobalLog();
+ if (LW == nullptr)
return;
// Use a simple recursion guard, to handle cases where we're already logging
@@ -242,9 +242,9 @@ void InMemoryRawLog(int32_t FuncId, XRayEntryType Type,
auto FirstEntry = reinterpret_cast<XRayRecord *>(TLD.InMemoryBuffer);
internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
if (++TLD.BufferOffset == TLD.BufferSize) {
- SpinMutexLock L(&LogMutex);
- retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
- reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+ SpinMutexLock Lock(&LogMutex);
+ LW->WriteAll(reinterpret_cast<char *>(FirstEntry),
+ reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
TLD.BufferOffset = 0;
TLD.StackEntries = 0;
}
@@ -257,17 +257,17 @@ void InMemoryRawLogWithArg(int32_t FuncId, XRayEntryType Type, uint64_t Arg1,
auto FirstEntry =
reinterpret_cast<XRayArgPayload *>(TLD.InMemoryBuffer);
const auto &BuffLen = TLD.BufferSize;
- int Fd = getGlobalFd();
- if (Fd == -1)
+ LogWriter *LW = getGlobalLog();
+ if (LW == nullptr)
return;
// First we check whether there's enough space to write the data consecutively
// in the thread-local buffer. If not, we first flush the buffer before
// attempting to write the two records that must be consecutive.
if (TLD.BufferOffset + 2 > BuffLen) {
- SpinMutexLock L(&LogMutex);
- retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
- reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+ SpinMutexLock Lock(&LogMutex);
+ LW->WriteAll(reinterpret_cast<char *>(FirstEntry),
+ reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
TLD.BufferOffset = 0;
TLD.StackEntries = 0;
}
@@ -288,9 +288,9 @@ void InMemoryRawLogWithArg(int32_t FuncId, XRayEntryType Type, uint64_t Arg1,
R.Arg = Arg1;
internal_memcpy(FirstEntry + TLD.BufferOffset, &R, sizeof(R));
if (++TLD.BufferOffset == BuffLen) {
- SpinMutexLock L(&LogMutex);
- retryingWriteAll(Fd, reinterpret_cast<char *>(FirstEntry),
- reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
+ SpinMutexLock Lock(&LogMutex);
+ LW->WriteAll(reinterpret_cast<char *>(FirstEntry),
+ reinterpret_cast<char *>(FirstEntry + TLD.BufferOffset));
TLD.BufferOffset = 0;
TLD.StackEntries = 0;
}
@@ -347,25 +347,25 @@ static void TLDDestructor(void *P) XRAY_NEVER_INSTRUMENT {
Report("Cleaned up log for TID: %d\n", GetTid());
});
- if (TLD.Fd == -1 || TLD.BufferOffset == 0) {
+ if (TLD.LogWriter == nullptr || TLD.BufferOffset == 0) {
if (Verbosity())
- Report("Skipping buffer for TID: %d; Fd = %d; Offset = %llu\n", GetTid(),
- TLD.Fd, TLD.BufferOffset);
+ Report("Skipping buffer for TID: %d; Offset = %llu\n", GetTid(),
+ TLD.BufferOffset);
return;
}
{
SpinMutexLock L(&LogMutex);
- retryingWriteAll(TLD.Fd, reinterpret_cast<char *>(TLD.InMemoryBuffer),
- reinterpret_cast<char *>(TLD.InMemoryBuffer) +
- (sizeof(XRayRecord) * TLD.BufferOffset));
+ TLD.LogWriter->WriteAll(reinterpret_cast<char *>(TLD.InMemoryBuffer),
+ reinterpret_cast<char *>(TLD.InMemoryBuffer) +
+ (sizeof(XRayRecord) * TLD.BufferOffset));
}
// Because this thread's exit could be the last one trying to write to
// the file and that we're not able to close out the file properly, we
// sync instead and hope that the pending writes are flushed as the
// thread exits.
- fsync(TLD.Fd);
+ TLD.LogWriter->Flush();
}
XRayLogInitStatus basicLoggingInit(UNUSED size_t BufferSize,
diff --git a/compiler-rt/lib/xray/xray_fdr_logging.cc b/compiler-rt/lib/xray/xray_fdr_logging.cc
index 2d6af443d90..32188771cba 100644
--- a/compiler-rt/lib/xray/xray_fdr_logging.cc
+++ b/compiler-rt/lib/xray/xray_fdr_logging.cc
@@ -838,8 +838,8 @@ XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT {
// (fixed-sized) and let the tools reading the buffers deal with the data
// afterwards.
//
- int Fd = getLogFD();
- if (Fd == -1) {
+ LogWriter* LW = LogWriter::Open();
+ if (LW == nullptr) {
auto Result = XRayLogFlushStatus::XRAY_LOG_NOT_FLUSHING;
atomic_store(&LogFlushStatus, Result, memory_order_release);
return Result;
@@ -847,8 +847,8 @@ XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT {
XRayFileHeader Header = fdrCommonHeaderInfo();
Header.FdrData = FdrAdditionalHeaderData{BQ->ConfiguredBufferSize()};
- retryingWriteAll(Fd, reinterpret_cast<char *>(&Header),
- reinterpret_cast<char *>(&Header) + sizeof(Header));
+ LW->WriteAll(reinterpret_cast<char *>(&Header),
+ reinterpret_cast<char *>(&Header) + sizeof(Header));
// Release the current thread's buffer before we attempt to write out all the
// buffers. This ensures that in case we had only a single thread going, that
@@ -871,11 +871,11 @@ XRayLogFlushStatus fdrLoggingFlush() XRAY_NEVER_INSTRUMENT {
uint8_t(MetadataRecord::RecordKinds::BufferExtents);
internal_memcpy(ExtentsRecord.Data, &BufferExtents, sizeof(BufferExtents));
if (BufferExtents > 0) {
- retryingWriteAll(Fd, reinterpret_cast<char *>(&ExtentsRecord),
- reinterpret_cast<char *>(&ExtentsRecord) +
- sizeof(MetadataRecord));
- retryingWriteAll(Fd, reinterpret_cast<char *>(B.Data),
- reinterpret_cast<char *>(B.Data) + BufferExtents);
+ LW->WriteAll(reinterpret_cast<char *>(&ExtentsRecord),
+ reinterpret_cast<char *>(&ExtentsRecord) +
+ sizeof(MetadataRecord));
+ LW->WriteAll(reinterpret_cast<char *>(B.Data),
+ reinterpret_cast<char *>(B.Data) + BufferExtents);
}
});
diff --git a/compiler-rt/lib/xray/xray_profiling.cc b/compiler-rt/lib/xray/xray_profiling.cc
index 6615de1a33d..ccfe77bb099 100644
--- a/compiler-rt/lib/xray/xray_profiling.cc
+++ b/compiler-rt/lib/xray/xray_profiling.cc
@@ -133,21 +133,20 @@ XRayLogFlushStatus profilingFlush() XRAY_NEVER_INSTRUMENT {
if (Verbosity())
Report("profiling: No data to flush.\n");
} else {
- int Fd = getLogFD();
- if (Fd == -1) {
+ LogWriter* LW = LogWriter::Open();
+ if (LW == nullptr) {
if (Verbosity())
Report("profiling: Failed to flush to file, dropping data.\n");
} else {
// Now for each of the buffers, write out the profile data as we would
// see it in memory, verbatim.
while (B.Data != nullptr && B.Size != 0) {
- retryingWriteAll(Fd, reinterpret_cast<const char *>(B.Data),
- reinterpret_cast<const char *>(B.Data) + B.Size);
+ LW->WriteAll(reinterpret_cast<const char *>(B.Data),
+ reinterpret_cast<const char *>(B.Data) + B.Size);
B = profileCollectorService::nextBuffer(B);
}
- // Then we close out the file.
- internal_close(Fd);
}
+ LogWriter::Close(LW);
}
}
diff --git a/compiler-rt/lib/xray/xray_utils.cc b/compiler-rt/lib/xray/xray_utils.cc
index 5753354a412..22c0dfa70a6 100644
--- a/compiler-rt/lib/xray/xray_utils.cc
+++ b/compiler-rt/lib/xray/xray_utils.cc
@@ -12,7 +12,9 @@
//===----------------------------------------------------------------------===//
#include "xray_utils.h"
+#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_common.h"
+#include "xray_allocator.h"
#include "xray_defs.h"
#include "xray_flags.h"
#include <cstdio>
@@ -31,7 +33,11 @@ void printToStdErr(const char *Buffer) XRAY_NEVER_INSTRUMENT {
fprintf(stderr, "%s", Buffer);
}
-void retryingWriteAll(int Fd, const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
+LogWriter::~LogWriter() {
+ internal_close(Fd);
+}
+
+void LogWriter::WriteAll(const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
if (Begin == End)
return;
auto TotalBytes = std::distance(Begin, End);
@@ -49,50 +55,11 @@ void retryingWriteAll(int Fd, const char *Begin, const char *End) XRAY_NEVER_INS
}
}
-std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin,
- char *End) XRAY_NEVER_INSTRUMENT {
- auto BytesToRead = std::distance(Begin, End);
- ssize_t BytesRead;
- ssize_t TotalBytesRead = 0;
- while (BytesToRead && (BytesRead = read(Fd, Begin, BytesToRead))) {
- if (BytesRead == -1) {
- if (errno == EINTR)
- continue;
- Report("Read error; errno = %d\n", errno);
- return std::make_pair(TotalBytesRead, false);
- }
-
- TotalBytesRead += BytesRead;
- BytesToRead -= BytesRead;
- Begin += BytesRead;
- }
- return std::make_pair(TotalBytesRead, true);
+void LogWriter::Flush() XRAY_NEVER_INSTRUMENT {
+ fsync(Fd);
}
-bool readValueFromFile(const char *Filename,
- long long *Value) XRAY_NEVER_INSTRUMENT {
- int Fd = open(Filename, O_RDONLY | O_CLOEXEC);
- if (Fd == -1)
- return false;
- static constexpr size_t BufSize = 256;
- char Line[BufSize] = {};
- ssize_t BytesRead;
- bool Success;
- std::tie(BytesRead, Success) = retryingReadSome(Fd, Line, Line + BufSize);
- if (!Success)
- return false;
- close(Fd);
- const char *End = nullptr;
- long long Tmp = internal_simple_strtoll(Line, &End, 10);
- bool Result = false;
- if (Line[0] != '\0' && (*End == '\n' || *End == '\0')) {
- *Value = Tmp;
- Result = true;
- }
- return Result;
-}
-
-int getLogFD() XRAY_NEVER_INSTRUMENT {
+LogWriter *LogWriter::Open() XRAY_NEVER_INSTRUMENT {
// Open a temporary file once for the log.
char TmpFilename[256] = {};
char TmpWildcardPattern[] = "XXXXXX";
@@ -108,18 +75,25 @@ int getLogFD() XRAY_NEVER_INSTRUMENT {
flags()->xray_logfile_base, Progname, TmpWildcardPattern);
if (NeededLength > int(sizeof(TmpFilename))) {
Report("XRay log file name too long (%d): %s\n", NeededLength, TmpFilename);
- return -1;
+ return nullptr;
}
int Fd = mkstemp(TmpFilename);
if (Fd == -1) {
Report("XRay: Failed opening temporary file '%s'; not logging events.\n",
TmpFilename);
- return -1;
+ return nullptr;
}
if (Verbosity())
Report("XRay: Log file in '%s'\n", TmpFilename);
- return Fd;
+ LogWriter *LW = allocate<LogWriter>();
+ new (LW) LogWriter(Fd);
+ return LW;
+}
+
+void LogWriter::Close(LogWriter *LW) {
+ LW->~LogWriter();
+ deallocate(LW);
}
} // namespace __xray
diff --git a/compiler-rt/lib/xray/xray_utils.h b/compiler-rt/lib/xray/xray_utils.h
index eafa16e1a9d..3e0d28287aa 100644
--- a/compiler-rt/lib/xray/xray_utils.h
+++ b/compiler-rt/lib/xray/xray_utils.h
@@ -22,21 +22,27 @@
namespace __xray {
-// Default implementation of the reporting interface for sanitizer errors.
-void printToStdErr(const char *Buffer);
+class LogWriter {
+public:
+ explicit LogWriter(int Fd) : Fd(Fd) {}
+ ~LogWriter();
+
+ // Write a character range into a log.
+ void WriteAll(const char *Begin, const char *End);
-// EINTR-safe write routine, provided a file descriptor and a character range.
-void retryingWriteAll(int Fd, const char *Begin, const char *End);
+ void Flush();
-// Reads a long long value from a provided file.
-bool readValueFromFile(const char *Filename, long long *Value);
+ // Returns a new log instance initialized using the flag-provided values.
+ static LogWriter *Open();
+ // Closes and deallocates the log instance.
+ static void Close(LogWriter *LogWriter);
-// EINTR-safe read routine, providing a file descriptor and a character range.
-std::pair<ssize_t, bool> retryingReadSome(int Fd, char *Begin, char *End);
+private:
+ int Fd = -1;
+};
-// EINTR-safe open routine, uses flag-provided values for initialising a log
-// file.
-int getLogFD();
+// Default implementation of the reporting interface for sanitizer errors.
+void printToStdErr(const char *Buffer);
constexpr size_t gcd(size_t a, size_t b) {
return (b == 0) ? a : gcd(b, a % b);
OpenPOWER on IntegriCloud