sanitizer_common.cc revision dedba5d6b0664218b1b1109f024a1ab151642776
1230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//===-- sanitizer_common.cc -----------------------------------------------===//
2230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//
3230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//                     The LLVM Compiler Infrastructure
4230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//
5230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// This file is distributed under the University of Illinois Open Source
6230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// License. See LICENSE.TXT for details.
7230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//
8230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//===----------------------------------------------------------------------===//
9230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//
10230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// This file is shared between AddressSanitizer and ThreadSanitizer
11230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov// run-time libraries.
12230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov//===----------------------------------------------------------------------===//
13230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
14230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_common.h"
15230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_libc.h"
164c49666e611f06241bb8462cea7674d877241492Alexey Samsonov
17230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovnamespace __sanitizer {
18230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
19f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryanyuptr GetPageSizeCached() {
20f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  static uptr PageSize;
21f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  if (!PageSize)
22f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany    PageSize = GetPageSize();
23f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  return PageSize;
24f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany}
25f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany
26dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenkostatic bool log_to_file = false;  // Set to true by __sanitizer_set_report_path
27dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko
28dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// By default, dump to stderr. If |log_to_file| is true and |report_fd_pid|
29dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// isn't equal to the current PID, try to obtain file descriptor by opening
30dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// file "report_path_prefix.<PID>".
31f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonovstatic fd_t report_fd = kStderrFd;
32dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenkostatic char report_path_prefix[4096];  // Set via __sanitizer_set_report_path.
33dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// PID of process that opened |report_fd|. If a fork() occurs, the PID of the
34dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// child thread will be different from |report_fd_pid|.
35dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenkostatic int report_fd_pid = 0;
3681dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany
37591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovstatic void (*DieCallback)(void);
38591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid SetDieCallback(void (*callback)(void)) {
39591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  DieCallback = callback;
40591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
41591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
42591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid NORETURN Die() {
43591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  if (DieCallback) {
44591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov    DieCallback();
45591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  }
46591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  Exit(1);
47591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
48591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
49591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovstatic CheckFailedCallbackType CheckFailedCallback;
50591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid SetCheckFailedCallback(CheckFailedCallbackType callback) {
51591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  CheckFailedCallback = callback;
52591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
53591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
54591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid NORETURN CheckFailed(const char *file, int line, const char *cond,
55591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov                          u64 v1, u64 v2) {
56591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  if (CheckFailedCallback) {
57591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov    CheckFailedCallback(file, line, cond, v1, v2);
58591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  }
59e3c35c7e30ce24b76f1e67eb049cf9e84c9b89d8Dmitry Vyukov  Report("Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\n", file, line, cond,
60e3c35c7e30ce24b76f1e67eb049cf9e84c9b89d8Dmitry Vyukov                                                            v1, v2);
61591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  Die();
62591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
63591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
6484d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonovstatic void MaybeOpenReportFile() {
65dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  if (!log_to_file || (report_fd_pid == GetPid())) return;
66dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  char report_path_full[4096];
67dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  internal_snprintf(report_path_full, sizeof(report_path_full),
68dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko                    "%s.%d", report_path_prefix, GetPid());
69dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  fd_t fd = internal_open(report_path_full, true);
7084d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  if (fd == kInvalidFd) {
7184d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov    report_fd = kStderrFd;
72dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko    log_to_file = false;
73dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko    Report("ERROR: Can't open file: %s\n", report_path_full);
7484d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov    Die();
7584d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  }
76dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  if (report_fd != kInvalidFd) {
77dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko    // We're in the child. Close the parent's log.
78dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko    internal_close(report_fd);
79dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  }
8084d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  report_fd = fd;
81dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  report_fd_pid = GetPid();
8284d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov}
8384d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov
8484d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonovbool PrintsToTty() {
8584d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  MaybeOpenReportFile();
8684d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  return internal_isatty(report_fd);
8784d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov}
8884d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov
89230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid RawWrite(const char *buffer) {
90230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  static const char *kRawWriteError = "RawWrite can't output requested buffer!";
91230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  uptr length = (uptr)internal_strlen(buffer);
9284d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  MaybeOpenReportFile();
9381dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  if (length != internal_write(report_fd, buffer, length)) {
9481dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany    internal_write(report_fd, kRawWriteError, internal_strlen(kRawWriteError));
95230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov    Die();
96230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  }
97230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
98230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
99cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonovuptr ReadFileToBuffer(const char *file_name, char **buff,
100cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov                      uptr *buff_size, uptr max_len) {
101f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  uptr PageSize = GetPageSizeCached();
102f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  uptr kMinFileLen = PageSize;
103cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  uptr read_len = 0;
104cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  *buff = 0;
105cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  *buff_size = 0;
106cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  // The files we usually open are not seekable, so try different buffer sizes.
107cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  for (uptr size = kMinFileLen; size <= max_len; size *= 2) {
108cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    fd_t fd = internal_open(file_name, /*write*/ false);
109cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    if (fd == kInvalidFd) return 0;
110cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    UnmapOrDie(*buff, *buff_size);
111cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    *buff = (char*)MmapOrDie(size, __FUNCTION__);
112cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    *buff_size = size;
113cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    // Read up to one page at a time.
114cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    read_len = 0;
115cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    bool reached_eof = false;
116f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany    while (read_len + PageSize <= size) {
117f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany      uptr just_read = internal_read(fd, *buff + read_len, PageSize);
118cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      if (just_read == 0) {
119cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov        reached_eof = true;
120cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov        break;
121cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      }
122cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      read_len += just_read;
123cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    }
124cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    internal_close(fd);
125cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    if (reached_eof)  // We've read the whole file.
126cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      break;
127cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  }
128cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  return read_len;
129cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov}
130cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov
1310dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// We don't want to use std::sort to avoid including <algorithm>, as
1320dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// we may end up with two implementation of std::sort - one in instrumented
1330dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// code, and the other in runtime.
1340dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// qsort() from stdlib won't work as it calls malloc(), which results
1350dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// in deadlock in ASan allocator.
1360dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// We re-implement in-place sorting w/o recursion as straightforward heapsort.
1374c49666e611f06241bb8462cea7674d877241492Alexey Samsonovvoid SortArray(uptr *array, uptr size) {
1380dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  if (size < 2)
1390dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    return;
1400dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  // Stage 1: insert elements to the heap.
1410dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  for (uptr i = 1; i < size; i++) {
1420dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    uptr j, p;
1430dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    for (j = i; j > 0; j = p) {
1440dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      p = (j - 1) / 2;
1450dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (array[j] > array[p])
1460dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        Swap(array[j], array[p]);
1470dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      else
1480dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        break;
1490dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    }
1500dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  }
1510dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  // Stage 2: swap largest element with the last one,
1520dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  // and sink the new top.
1530dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  for (uptr i = size - 1; i > 0; i--) {
1540dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    Swap(array[0], array[i]);
1550dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    uptr j, max_ind;
1560dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    for (j = 0; j < i; j = max_ind) {
1570dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      uptr left = 2 * j + 1;
1580dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      uptr right = 2 * j + 2;
1590dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      max_ind = j;
1600dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (left < i && array[left] > array[max_ind])
1610dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        max_ind = left;
1620dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (right < i && array[right] > array[max_ind])
1630dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        max_ind = right;
1640dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (max_ind != j)
1650dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        Swap(array[j], array[max_ind]);
1660dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      else
1670dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        break;
1680dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    }
1690dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  }
1704c49666e611f06241bb8462cea7674d877241492Alexey Samsonov}
1714c49666e611f06241bb8462cea7674d877241492Alexey Samsonov
172cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We want to map a chunk of address space aligned to 'alignment'.
173cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We do it by maping a bit more and then unmaping redundant pieces.
174cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We probably can do it with fewer syscalls in some OS-dependent way.
175cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryanyvoid *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) {
1762dae63aea3589fded1ef17b5a6c7f0c9352559a2Bill Wendling// uptr PageSize = GetPageSizeCached();
177cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  CHECK(IsPowerOfTwo(size));
178cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  CHECK(IsPowerOfTwo(alignment));
179cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr map_size = size + alignment;
180cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr map_res = (uptr)MmapOrDie(map_size, mem_type);
181cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr map_end = map_res + map_size;
182cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr res = map_res;
183cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  if (res & (alignment - 1))  // Not aligned.
1843617ad70f3ade71b944b35fa3faaadfb97700deaDmitry Vyukov    res = (map_res + alignment) & ~(alignment - 1);
185cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr end = res + size;
186cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  if (res != map_res)
187cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany    UnmapOrDie((void*)map_res, res - map_res);
188cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  if (end != map_end)
189cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany    UnmapOrDie((void*)end, map_end - end);
190cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  return (void*)res;
191cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany}
192cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany
193230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}  // namespace __sanitizer
19481dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany
195ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovusing namespace __sanitizer;  // NOLINT
196ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov
197ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovextern "C" {
19881dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryanyvoid __sanitizer_set_report_path(const char *path) {
19981dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  if (!path) return;
20081dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  uptr len = internal_strlen(path);
201dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  if (len > sizeof(report_path_prefix) - 100) {
20281dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany    Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n",
20381dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany           path[0], path[1], path[2], path[3],
20481dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany           path[4], path[5], path[6], path[7]);
20581dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany    Die();
20681dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  }
207dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  internal_strncpy(report_path_prefix, path, sizeof(report_path_prefix));
208dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  report_path_prefix[len] = '\0';
209f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov  report_fd = kInvalidFd;
210dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  log_to_file = true;
21181dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany}
212ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov
213ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovvoid __sanitizer_set_report_fd(int fd) {
214f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov  if (report_fd != kStdoutFd &&
215f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov      report_fd != kStderrFd &&
216f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov      report_fd != kInvalidFd)
217f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov    internal_close(report_fd);
218f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov  report_fd = fd;
219ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov}
22025742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko
22125742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenkovoid NOINLINE __sanitizer_sandbox_on_notify(void *reserved) {
22225742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko  (void)reserved;
22325742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko  PrepareForSandboxing();
22425742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko}
225ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov}  // extern "C"
226