blob: 22c0dfa70a61480ab2520a46b9bb13adf96138f7 [file] [log] [blame]
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +00001//===-- xray_utils.cc -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of XRay, a dynamic runtime instrumentation system.
11//
12//===----------------------------------------------------------------------===//
13#include "xray_utils.h"
14
Petr Hosek6a8cede2018-10-16 01:24:46 +000015#include "sanitizer_common/sanitizer_allocator_internal.h"
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000016#include "sanitizer_common/sanitizer_common.h"
Petr Hosek6a8cede2018-10-16 01:24:46 +000017#include "xray_allocator.h"
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000018#include "xray_defs.h"
19#include "xray_flags.h"
20#include <cstdio>
Krzysztof Parzyszek520e51d2017-01-25 14:20:30 +000021#include <errno.h>
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000022#include <fcntl.h>
23#include <iterator>
Dean Michael Berrisb81372b2018-06-08 07:48:03 +000024#include <stdlib.h>
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000025#include <sys/types.h>
26#include <tuple>
27#include <unistd.h>
28#include <utility>
29
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000030namespace __xray {
31
Dean Michael Berrisea9042c2017-02-07 23:35:34 +000032void printToStdErr(const char *Buffer) XRAY_NEVER_INSTRUMENT {
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000033 fprintf(stderr, "%s", Buffer);
34}
35
Petr Hosek6a8cede2018-10-16 01:24:46 +000036LogWriter::~LogWriter() {
37 internal_close(Fd);
38}
39
40void LogWriter::WriteAll(const char *Begin, const char *End) XRAY_NEVER_INSTRUMENT {
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000041 if (Begin == End)
42 return;
43 auto TotalBytes = std::distance(Begin, End);
44 while (auto Written = write(Fd, Begin, TotalBytes)) {
45 if (Written < 0) {
46 if (errno == EINTR)
47 continue; // Try again.
48 Report("Failed to write; errno = %d\n", errno);
49 return;
50 }
51 TotalBytes -= Written;
52 if (TotalBytes == 0)
53 break;
54 Begin += Written;
55 }
56}
57
Petr Hosek6a8cede2018-10-16 01:24:46 +000058void LogWriter::Flush() XRAY_NEVER_INSTRUMENT {
59 fsync(Fd);
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000060}
61
Petr Hosek6a8cede2018-10-16 01:24:46 +000062LogWriter *LogWriter::Open() XRAY_NEVER_INSTRUMENT {
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000063 // Open a temporary file once for the log.
Dean Michael Berrisb81372b2018-06-08 07:48:03 +000064 char TmpFilename[256] = {};
65 char TmpWildcardPattern[] = "XXXXXX";
66 auto **Argv = GetArgv();
67 const char *Progname = !Argv ? "(unknown)" : Argv[0];
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000068 const char *LastSlash = internal_strrchr(Progname, '/');
69
70 if (LastSlash != nullptr)
71 Progname = LastSlash + 1;
72
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000073 int NeededLength = internal_snprintf(
Douglas Yung22d49482018-10-01 20:03:53 +000074 TmpFilename, sizeof(TmpFilename), "%s%s.%s",
75 flags()->xray_logfile_base, Progname, TmpWildcardPattern);
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000076 if (NeededLength > int(sizeof(TmpFilename))) {
77 Report("XRay log file name too long (%d): %s\n", NeededLength, TmpFilename);
Petr Hosek6a8cede2018-10-16 01:24:46 +000078 return nullptr;
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000079 }
80 int Fd = mkstemp(TmpFilename);
81 if (Fd == -1) {
82 Report("XRay: Failed opening temporary file '%s'; not logging events.\n",
83 TmpFilename);
Petr Hosek6a8cede2018-10-16 01:24:46 +000084 return nullptr;
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000085 }
Dean Michael Berris5eaaff62018-06-05 06:12:42 +000086 if (Verbosity())
Dean Michael Berriseec462f2017-12-13 06:37:13 +000087 Report("XRay: Log file in '%s'\n", TmpFilename);
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000088
Petr Hosek6a8cede2018-10-16 01:24:46 +000089 LogWriter *LW = allocate<LogWriter>();
90 new (LW) LogWriter(Fd);
91 return LW;
92}
93
94void LogWriter::Close(LogWriter *LW) {
95 LW->~LogWriter();
96 deallocate(LW);
Dean Michael Berrise7dbebf2017-01-25 03:50:46 +000097}
98
99} // namespace __xray