sanitizer_common.cc revision 9578a3ecfc35a264ede1135033398e2a77a6cad6
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
19859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryanyconst char *SanitizerToolName = "SanitizerTool";
203614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkouptr SanitizerVerbosity = 0;
21859778a4e2dffa4024fa3e13b105fd62eca44b1cKostya Serebryany
22f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryanyuptr GetPageSizeCached() {
23f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  static uptr PageSize;
24f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  if (!PageSize)
25f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany    PageSize = GetPageSize();
26f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  return PageSize;
27f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany}
28f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany
29dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenkostatic bool log_to_file = false;  // Set to true by __sanitizer_set_report_path
30dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko
31dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// By default, dump to stderr. If |log_to_file| is true and |report_fd_pid|
32dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// isn't equal to the current PID, try to obtain file descriptor by opening
33dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// file "report_path_prefix.<PID>".
34f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonovstatic fd_t report_fd = kStderrFd;
35dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenkostatic char report_path_prefix[4096];  // Set via __sanitizer_set_report_path.
36dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// PID of process that opened |report_fd|. If a fork() occurs, the PID of the
37dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko// child thread will be different from |report_fd_pid|.
38dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenkostatic int report_fd_pid = 0;
3981dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany
40591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovstatic void (*DieCallback)(void);
41591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid SetDieCallback(void (*callback)(void)) {
42591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  DieCallback = callback;
43591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
44591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
45591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid NORETURN Die() {
46591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  if (DieCallback) {
47591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov    DieCallback();
48591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  }
49f882247088952deed954a19d745c2dd8871e2035Alexey Samsonov  internal__exit(1);
50591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
51591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
52591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovstatic CheckFailedCallbackType CheckFailedCallback;
53591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid SetCheckFailedCallback(CheckFailedCallbackType callback) {
54591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  CheckFailedCallback = callback;
55591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
56591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
57591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonovvoid NORETURN CheckFailed(const char *file, int line, const char *cond,
58591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov                          u64 v1, u64 v2) {
59591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  if (CheckFailedCallback) {
60591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov    CheckFailedCallback(file, line, cond, v1, v2);
61591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  }
62e3c35c7e30ce24b76f1e67eb049cf9e84c9b89d8Dmitry Vyukov  Report("Sanitizer CHECK failed: %s:%d %s (%lld, %lld)\n", file, line, cond,
63e3c35c7e30ce24b76f1e67eb049cf9e84c9b89d8Dmitry Vyukov                                                            v1, v2);
64591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov  Die();
65591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov}
66591616d323d73b7ea7cd8fea4eec46cedccda27eAlexey Samsonov
6784d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonovstatic void MaybeOpenReportFile() {
68dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  if (!log_to_file || (report_fd_pid == GetPid())) return;
699b42f5207c6e99e8f94b790bb4d5a04cdcc1c755Alexey Samsonov  InternalScopedBuffer<char> report_path_full(4096);
709b42f5207c6e99e8f94b790bb4d5a04cdcc1c755Alexey Samsonov  internal_snprintf(report_path_full.data(), report_path_full.size(),
71dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko                    "%s.%d", report_path_prefix, GetPid());
729578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  uptr openrv = OpenFile(report_path_full.data(), true);
739578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  if (internal_iserror(openrv)) {
7484d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov    report_fd = kStderrFd;
75dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko    log_to_file = false;
769b42f5207c6e99e8f94b790bb4d5a04cdcc1c755Alexey Samsonov    Report("ERROR: Can't open file: %s\n", report_path_full.data());
7784d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov    Die();
7884d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  }
79dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  if (report_fd != kInvalidFd) {
80dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko    // We're in the child. Close the parent's log.
81dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko    internal_close(report_fd);
82dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  }
839578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  report_fd = openrv;
84dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  report_fd_pid = GetPid();
8584d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov}
8684d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov
8784d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonovbool PrintsToTty() {
8884d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  MaybeOpenReportFile();
8984d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  return internal_isatty(report_fd);
9084d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov}
9184d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov
92230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid RawWrite(const char *buffer) {
93230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  static const char *kRawWriteError = "RawWrite can't output requested buffer!";
94230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  uptr length = (uptr)internal_strlen(buffer);
9584d57b4ce545d6c19effac01124749a9df0fd0a5Alexey Samsonov  MaybeOpenReportFile();
9681dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  if (length != internal_write(report_fd, buffer, length)) {
9781dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany    internal_write(report_fd, kRawWriteError, internal_strlen(kRawWriteError));
98230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov    Die();
99230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  }
100230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
101230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
102cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonovuptr ReadFileToBuffer(const char *file_name, char **buff,
103cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov                      uptr *buff_size, uptr max_len) {
104f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  uptr PageSize = GetPageSizeCached();
105f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany  uptr kMinFileLen = PageSize;
106cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  uptr read_len = 0;
107cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  *buff = 0;
108cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  *buff_size = 0;
109cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  // The files we usually open are not seekable, so try different buffer sizes.
110cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  for (uptr size = kMinFileLen; size <= max_len; size *= 2) {
1119578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne    uptr openrv = OpenFile(file_name, /*write*/ false);
1129578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne    if (internal_iserror(openrv)) return 0;
1139578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne    fd_t fd = openrv;
114cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    UnmapOrDie(*buff, *buff_size);
115cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    *buff = (char*)MmapOrDie(size, __FUNCTION__);
116cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    *buff_size = size;
117cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    // Read up to one page at a time.
118cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    read_len = 0;
119cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    bool reached_eof = false;
120f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany    while (read_len + PageSize <= size) {
121f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany      uptr just_read = internal_read(fd, *buff + read_len, PageSize);
122cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      if (just_read == 0) {
123cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov        reached_eof = true;
124cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov        break;
125cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      }
126cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      read_len += just_read;
127cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    }
128cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    internal_close(fd);
129cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov    if (reached_eof)  // We've read the whole file.
130cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov      break;
131cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  }
132cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov  return read_len;
133cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov}
134cffe2f5c30c27234260d004b54152916ff0c45c6Alexey Samsonov
1350dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// We don't want to use std::sort to avoid including <algorithm>, as
1360dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// we may end up with two implementation of std::sort - one in instrumented
1370dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// code, and the other in runtime.
1380dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// qsort() from stdlib won't work as it calls malloc(), which results
1390dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// in deadlock in ASan allocator.
1400dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov// We re-implement in-place sorting w/o recursion as straightforward heapsort.
1414c49666e611f06241bb8462cea7674d877241492Alexey Samsonovvoid SortArray(uptr *array, uptr size) {
1420dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  if (size < 2)
1430dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    return;
1440dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  // Stage 1: insert elements to the heap.
1450dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  for (uptr i = 1; i < size; i++) {
1460dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    uptr j, p;
1470dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    for (j = i; j > 0; j = p) {
1480dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      p = (j - 1) / 2;
1490dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (array[j] > array[p])
1500dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        Swap(array[j], array[p]);
1510dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      else
1520dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        break;
1530dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    }
1540dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  }
1550dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  // Stage 2: swap largest element with the last one,
1560dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  // and sink the new top.
1570dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  for (uptr i = size - 1; i > 0; i--) {
1580dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    Swap(array[0], array[i]);
1590dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    uptr j, max_ind;
1600dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    for (j = 0; j < i; j = max_ind) {
1610dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      uptr left = 2 * j + 1;
1620dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      uptr right = 2 * j + 2;
1630dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      max_ind = j;
1640dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (left < i && array[left] > array[max_ind])
1650dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        max_ind = left;
1660dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (right < i && array[right] > array[max_ind])
1670dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        max_ind = right;
1680dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      if (max_ind != j)
1690dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        Swap(array[j], array[max_ind]);
1700dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov      else
1710dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov        break;
1720dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov    }
1730dc3177d6c54fafb9577254a93b2f3c4169129d7Alexey Samsonov  }
1744c49666e611f06241bb8462cea7674d877241492Alexey Samsonov}
1754c49666e611f06241bb8462cea7674d877241492Alexey Samsonov
176cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We want to map a chunk of address space aligned to 'alignment'.
177cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We do it by maping a bit more and then unmaping redundant pieces.
178cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany// We probably can do it with fewer syscalls in some OS-dependent way.
179cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryanyvoid *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) {
1802dae63aea3589fded1ef17b5a6c7f0c9352559a2Bill Wendling// uptr PageSize = GetPageSizeCached();
181cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  CHECK(IsPowerOfTwo(size));
182cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  CHECK(IsPowerOfTwo(alignment));
183cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr map_size = size + alignment;
184cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr map_res = (uptr)MmapOrDie(map_size, mem_type);
185cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr map_end = map_res + map_size;
186cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr res = map_res;
187cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  if (res & (alignment - 1))  // Not aligned.
1883617ad70f3ade71b944b35fa3faaadfb97700deaDmitry Vyukov    res = (map_res + alignment) & ~(alignment - 1);
189cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  uptr end = res + size;
190cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  if (res != map_res)
191cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany    UnmapOrDie((void*)map_res, res - map_res);
192cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  if (end != map_end)
193cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany    UnmapOrDie((void*)end, map_end - end);
194cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany  return (void*)res;
195cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany}
196cc7525951f401d61e2467f1ebc1b133205516a6cKostya Serebryany
1972673fd8406197c42f16cede6d287f72169298c2eKostya Serebryanyvoid ReportErrorSummary(const char *error_type, const char *file,
1982673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany                        int line, const char *function) {
1992673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany  const int kMaxSize = 1024;  // We don't want a summary too long.
2002673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany  InternalScopedBuffer<char> buff(kMaxSize);
2012f588f9d3417aa107ebbbd8830f97501023d3f40Kostya Serebryany  internal_snprintf(buff.data(), kMaxSize, "%s: %s %s:%d %s",
2022673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany                    SanitizerToolName, error_type,
2031d333c5a34d896f239001e3fe69a660e40d15301Kostya Serebryany                    file ? file : "??", line, function ? function : "??");
2042673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany  __sanitizer_report_error_summary(buff.data());
2052673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany}
2062673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany
207230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}  // namespace __sanitizer
20881dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany
209ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovusing namespace __sanitizer;  // NOLINT
210ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov
211ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovextern "C" {
21281dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryanyvoid __sanitizer_set_report_path(const char *path) {
21381dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  if (!path) return;
21481dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  uptr len = internal_strlen(path);
215dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  if (len > sizeof(report_path_prefix) - 100) {
21681dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany    Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n",
21781dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany           path[0], path[1], path[2], path[3],
21881dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany           path[4], path[5], path[6], path[7]);
21981dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany    Die();
22081dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany  }
221dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  internal_strncpy(report_path_prefix, path, sizeof(report_path_prefix));
222dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  report_path_prefix[len] = '\0';
223f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov  report_fd = kInvalidFd;
224dedba5d6b0664218b1b1109f024a1ab151642776Alexander Potapenko  log_to_file = true;
22581dfbb76f858fbc4084771fce4967ede04ed5f44Kostya Serebryany}
226ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov
227ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonovvoid __sanitizer_set_report_fd(int fd) {
228f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov  if (report_fd != kStdoutFd &&
229f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov      report_fd != kStderrFd &&
230f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov      report_fd != kInvalidFd)
231f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov    internal_close(report_fd);
232f3457cb9c3e1ddbbea07ee97b22ca387687b72e0Alexey Samsonov  report_fd = fd;
233ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov}
23425742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko
23525742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenkovoid NOINLINE __sanitizer_sandbox_on_notify(void *reserved) {
23625742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko  (void)reserved;
23725742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko  PrepareForSandboxing();
23825742574510cfb41b97e32f63f107fbb9b328d13Alexander Potapenko}
2392673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany
2402673fd8406197c42f16cede6d287f72169298c2eKostya Serebryanyvoid __sanitizer_report_error_summary(const char *error_summary) {
2412673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany  Printf("SUMMARY: %s\n", error_summary);
2422673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany}
243ac8564e7ce11e31b1d29e92dbbcfa1a5d36bc596Alexey Samsonov}  // extern "C"
244