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