1 //===-- sanitizer_common.h --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is shared between run-time libraries of sanitizers.
12 // It declares common functions and classes that are used in both runtimes.
13 // Implementation of some functions are provided in sanitizer_common, while
14 // others must be defined by run-time library itself.
15 //===----------------------------------------------------------------------===//
16 #ifndef SANITIZER_COMMON_H
17 #define SANITIZER_COMMON_H
19 #include "sanitizer_flags.h"
20 #include "sanitizer_interface_internal.h"
21 #include "sanitizer_internal_defs.h"
22 #include "sanitizer_libc.h"
23 #include "sanitizer_list.h"
24 #include "sanitizer_mutex.h"
26 #if defined(_MSC_VER) && !defined(__clang__)
27 extern "C" void _ReadWriteBarrier();
28 #pragma intrinsic(_ReadWriteBarrier)
31 namespace __sanitizer {
34 struct BufferedStackTrace;
39 const uptr kWordSize = SANITIZER_WORDSIZE / 8;
40 const uptr kWordSizeInBits = 8 * kWordSize;
42 const uptr kCacheLineSize = SANITIZER_CACHE_LINE_SIZE;
44 const uptr kMaxPathLength = 4096;
46 const uptr kMaxThreadStackSize = 1 << 30; // 1Gb
48 static const uptr kErrorMessageBufferSize = 1 << 16;
50 // Denotes fake PC values that come from JIT/JAVA/etc.
51 // For such PC values __tsan_symbolize_external_ex() will be called.
52 const u64 kExternalPCBit = 1ULL << 60;
54 extern const char *SanitizerToolName; // Can be changed by the tool.
56 extern atomic_uint32_t current_verbosity;
57 INLINE void SetVerbosity(int verbosity) {
58 atomic_store(¤t_verbosity, verbosity, memory_order_relaxed);
60 INLINE int Verbosity() {
61 return atomic_load(¤t_verbosity, memory_order_relaxed);
65 extern uptr PageSizeCached;
66 INLINE uptr GetPageSizeCached() {
68 PageSizeCached = GetPageSize();
69 return PageSizeCached;
71 uptr GetMmapGranularity();
72 uptr GetMaxVirtualAddress();
73 uptr GetMaxUserVirtualAddress();
77 void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
79 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
80 uptr *tls_addr, uptr *tls_size);
83 void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);
84 INLINE void *MmapOrDieQuietly(uptr size, const char *mem_type) {
85 return MmapOrDie(size, mem_type, /*raw_report*/ true);
87 void UnmapOrDie(void *addr, uptr size);
88 // Behaves just like MmapOrDie, but tolerates out of memory condition, in that
89 // case returns nullptr.
90 void *MmapOrDieOnFatalError(uptr size, const char *mem_type);
91 bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name = nullptr)
93 void *MmapNoReserveOrDie(uptr size, const char *mem_type);
94 void *MmapFixedOrDie(uptr fixed_addr, uptr size);
95 // Behaves just like MmapFixedOrDie, but tolerates out of memory condition, in
96 // that case returns nullptr.
97 void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size);
98 void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr);
99 void *MmapNoAccess(uptr size);
100 // Map aligned chunk of address space; size and alignment are powers of two.
101 // Dies on all but out of memory errors, in the latter case returns nullptr.
102 void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
103 const char *mem_type);
104 // Disallow access to a memory range. Use MmapFixedNoAccess to allocate an
105 // unaccessible memory.
106 bool MprotectNoAccess(uptr addr, uptr size);
107 bool MprotectReadOnly(uptr addr, uptr size);
109 void MprotectMallocZones(void *addr, int prot);
111 // Find an available address space.
112 uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding,
113 uptr *largest_gap_found, uptr *max_occupied_addr);
115 // Used to check if we can map shadow memory to a fixed location.
116 bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
117 // Releases memory pages entirely within the [beg, end] address range. Noop if
118 // the provided range does not contain at least one entire page.
119 void ReleaseMemoryPagesToOS(uptr beg, uptr end);
120 void IncreaseTotalMmap(uptr size);
121 void DecreaseTotalMmap(uptr size);
123 bool NoHugePagesInRegion(uptr addr, uptr length);
124 bool DontDumpShadowMemory(uptr addr, uptr length);
125 // Check if the built VMA size matches the runtime one.
127 void RunMallocHooks(const void *ptr, uptr size);
128 void RunFreeHooks(const void *ptr);
130 class ReservedAddressRange {
132 uptr Init(uptr size, const char *name = nullptr, uptr fixed_addr = 0);
133 uptr Map(uptr fixed_addr, uptr size);
134 uptr MapOrDie(uptr fixed_addr, uptr size);
135 void Unmap(uptr addr, uptr size);
136 void *base() const { return base_; }
137 uptr size() const { return size_; }
146 typedef void (*fill_profile_f)(uptr start, uptr rss, bool file,
147 /*out*/uptr *stats, uptr stats_size);
149 // Parse the contents of /proc/self/smaps and generate a memory profile.
150 // |cb| is a tool-specific callback that fills the |stats| array containing
151 // |stats_size| elements.
152 void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size);
154 // Simple low-level (mmap-based) allocator for internal use. Doesn't have
155 // constructor, so all instances of LowLevelAllocator should be
156 // linker initialized.
157 class LowLevelAllocator {
159 // Requires an external lock.
160 void *Allocate(uptr size);
162 char *allocated_end_;
163 char *allocated_current_;
165 // Set the min alignment of LowLevelAllocator to at least alignment.
166 void SetLowLevelAllocateMinAlignment(uptr alignment);
167 typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
168 // Allows to register tool-specific callbacks for LowLevelAllocator.
169 // Passing NULL removes the callback.
170 void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback);
173 void CatastrophicErrorWrite(const char *buffer, uptr length);
174 void RawWrite(const char *buffer);
175 bool ColorizeReports();
176 void RemoveANSIEscapeSequencesFromString(char *buffer);
177 void Printf(const char *format, ...);
178 void Report(const char *format, ...);
179 void SetPrintfAndReportCallback(void (*callback)(const char *));
180 #define VReport(level, ...) \
182 if ((uptr)Verbosity() >= (level)) Report(__VA_ARGS__); \
184 #define VPrintf(level, ...) \
186 if ((uptr)Verbosity() >= (level)) Printf(__VA_ARGS__); \
189 // Lock sanitizer error reporting and protects against nested errors.
190 class ScopedErrorReportLock {
192 ScopedErrorReportLock();
193 ~ScopedErrorReportLock();
195 static void CheckLocked();
198 extern uptr stoptheworld_tracer_pid;
199 extern uptr stoptheworld_tracer_ppid;
201 bool IsAccessibleMemoryRange(uptr beg, uptr size);
203 // Error report formatting.
204 const char *StripPathPrefix(const char *filepath,
205 const char *strip_file_prefix);
206 // Strip the directories from the module name.
207 const char *StripModuleName(const char *module);
210 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
211 uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);
212 uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len);
213 const char *GetProcessName();
214 void UpdateProcessName();
215 void CacheBinaryName();
216 void DisableCoreDumperIfNecessary();
217 void DumpProcessMap();
218 void PrintModuleMap();
219 const char *GetEnv(const char *name);
220 bool SetEnv(const char *name, const char *value);
227 bool StackSizeIsUnlimited();
228 uptr GetStackSizeLimitInBytes();
229 void SetStackSizeLimitInBytes(uptr limit);
230 bool AddressSpaceIsUnlimited();
231 void SetAddressSpaceUnlimited();
232 void AdjustStackSize(void *attr);
233 void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args);
234 void SetSandboxingCallback(void (*f)());
236 void InitializeCoverage(bool enabled, const char *coverage_dir);
242 void SleepForSeconds(int seconds);
243 void SleepForMillis(int millis);
245 u64 MonotonicNanoTime();
246 int Atexit(void (*function)(void));
247 bool TemplateMatch(const char *templ, const char *str);
250 void NORETURN Abort();
253 CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2);
254 void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type,
255 const char *mmap_type, error_t err,
256 bool raw_report = false);
258 // Specific tools may override behavior of "Die" and "CheckFailed" functions
259 // to do tool-specific job.
260 typedef void (*DieCallbackType)(void);
262 // It's possible to add several callbacks that would be run when "Die" is
263 // called. The callbacks will be run in the opposite order. The tools are
264 // strongly recommended to setup all callbacks during initialization, when there
265 // is only a single thread.
266 bool AddDieCallback(DieCallbackType callback);
267 bool RemoveDieCallback(DieCallbackType callback);
269 void SetUserDieCallback(DieCallbackType callback);
271 typedef void (*CheckFailedCallbackType)(const char *, int, const char *,
273 void SetCheckFailedCallback(CheckFailedCallbackType callback);
275 // Callback will be called if soft_rss_limit_mb is given and the limit is
276 // exceeded (exceeded==true) or if rss went down below the limit
277 // (exceeded==false).
278 // The callback should be registered once at the tool init time.
279 void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded));
281 // Functions related to signal handling.
282 typedef void (*SignalHandlerType)(int, void *, void *);
283 HandleSignalMode GetHandleSignalMode(int signum);
284 void InstallDeadlySignalHandlers(SignalHandlerType handler);
287 // Each sanitizer uses slightly different implementation of stack unwinding.
288 typedef void (*UnwindSignalStackCallbackType)(const SignalContext &sig,
289 const void *callback_context,
290 BufferedStackTrace *stack);
291 // Print deadly signal report and die.
292 void HandleDeadlySignal(void *siginfo, void *context, u32 tid,
293 UnwindSignalStackCallbackType unwind,
294 const void *unwind_context);
296 // Part of HandleDeadlySignal, exposed for asan.
297 void StartReportDeadlySignal();
298 // Part of HandleDeadlySignal, exposed for asan.
299 void ReportDeadlySignal(const SignalContext &sig, u32 tid,
300 UnwindSignalStackCallbackType unwind,
301 const void *unwind_context);
303 // Alternative signal stack (POSIX-only).
304 void SetAlternateSignalStack();
305 void UnsetAlternateSignalStack();
307 // We don't want a summary too long.
308 const int kMaxSummaryLength = 1024;
309 // Construct a one-line string:
310 // SUMMARY: SanitizerToolName: error_message
311 // and pass it to __sanitizer_report_error_summary.
312 // If alt_tool_name is provided, it's used in place of SanitizerToolName.
313 void ReportErrorSummary(const char *error_message,
314 const char *alt_tool_name = nullptr);
315 // Same as above, but construct error_message as:
316 // error_type file:line[:column][ function]
317 void ReportErrorSummary(const char *error_type, const AddressInfo &info,
318 const char *alt_tool_name = nullptr);
319 // Same as above, but obtains AddressInfo by symbolizing top stack trace frame.
320 void ReportErrorSummary(const char *error_type, const StackTrace *trace,
321 const char *alt_tool_name = nullptr);
323 void ReportMmapWriteExec(int prot);
326 #if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__)
328 unsigned char _BitScanForward(unsigned long *index, unsigned long mask); // NOLINT
329 unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); // NOLINT
331 unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask); // NOLINT
332 unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask); // NOLINT
337 INLINE uptr MostSignificantSetBitIndex(uptr x) {
339 unsigned long up; // NOLINT
340 #if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
342 up = SANITIZER_WORDSIZE - 1 - __builtin_clzll(x);
344 up = SANITIZER_WORDSIZE - 1 - __builtin_clzl(x);
346 #elif defined(_WIN64)
347 _BitScanReverse64(&up, x);
349 _BitScanReverse(&up, x);
354 INLINE uptr LeastSignificantSetBitIndex(uptr x) {
356 unsigned long up; // NOLINT
357 #if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__)
359 up = __builtin_ctzll(x);
361 up = __builtin_ctzl(x);
363 #elif defined(_WIN64)
364 _BitScanForward64(&up, x);
366 _BitScanForward(&up, x);
371 INLINE bool IsPowerOfTwo(uptr x) {
372 return (x & (x - 1)) == 0;
375 INLINE uptr RoundUpToPowerOfTwo(uptr size) {
377 if (IsPowerOfTwo(size)) return size;
379 uptr up = MostSignificantSetBitIndex(size);
380 CHECK_LT(size, (1ULL << (up + 1)));
381 CHECK_GT(size, (1ULL << up));
382 return 1ULL << (up + 1);
385 INLINE uptr RoundUpTo(uptr size, uptr boundary) {
386 RAW_CHECK(IsPowerOfTwo(boundary));
387 return (size + boundary - 1) & ~(boundary - 1);
390 INLINE uptr RoundDownTo(uptr x, uptr boundary) {
391 return x & ~(boundary - 1);
394 INLINE bool IsAligned(uptr a, uptr alignment) {
395 return (a & (alignment - 1)) == 0;
398 INLINE uptr Log2(uptr x) {
399 CHECK(IsPowerOfTwo(x));
400 return LeastSignificantSetBitIndex(x);
403 // Don't use std::min, std::max or std::swap, to minimize dependency
405 template<class T> T Min(T a, T b) { return a < b ? a : b; }
406 template<class T> T Max(T a, T b) { return a > b ? a : b; }
407 template<class T> void Swap(T& a, T& b) {
414 INLINE bool IsSpace(int c) {
415 return (c == ' ') || (c == '\n') || (c == '\t') ||
416 (c == '\f') || (c == '\r') || (c == '\v');
418 INLINE bool IsDigit(int c) {
419 return (c >= '0') && (c <= '9');
421 INLINE int ToLower(int c) {
422 return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
425 // A low-level vector based on mmap. May incur a significant memory overhead for
427 // WARNING: The current implementation supports only POD types.
429 class InternalMmapVectorNoCtor {
431 void Initialize(uptr initial_capacity) {
435 reserve(initial_capacity);
437 void Destroy() { UnmapOrDie(data_, capacity_bytes_); }
438 T &operator[](uptr i) {
442 const T &operator[](uptr i) const {
446 void push_back(const T &element) {
447 CHECK_LE(size_, capacity());
448 if (size_ == capacity()) {
449 uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1);
450 Realloc(new_capacity);
452 internal_memcpy(&data_[size_++], &element, sizeof(T));
456 return data_[size_ - 1];
465 const T *data() const {
471 uptr capacity() const { return capacity_bytes_ / sizeof(T); }
472 void reserve(uptr new_size) {
473 // Never downsize internal buffer.
474 if (new_size > capacity())
477 void resize(uptr new_size) {
478 if (new_size > size_) {
480 internal_memset(&data_[size_], 0, sizeof(T) * (new_size - size_));
485 void clear() { size_ = 0; }
486 bool empty() const { return size() == 0; }
488 const T *begin() const {
494 const T *end() const {
495 return data() + size();
498 return data() + size();
501 void swap(InternalMmapVectorNoCtor &other) {
502 Swap(data_, other.data_);
503 Swap(capacity_bytes_, other.capacity_bytes_);
504 Swap(size_, other.size_);
508 void Realloc(uptr new_capacity) {
509 CHECK_GT(new_capacity, 0);
510 CHECK_LE(size_, new_capacity);
511 uptr new_capacity_bytes =
512 RoundUpTo(new_capacity * sizeof(T), GetPageSizeCached());
513 T *new_data = (T *)MmapOrDie(new_capacity_bytes, "InternalMmapVector");
514 internal_memcpy(new_data, data_, size_ * sizeof(T));
515 UnmapOrDie(data_, capacity_bytes_);
517 capacity_bytes_ = new_capacity_bytes;
521 uptr capacity_bytes_;
525 template <typename T>
526 bool operator==(const InternalMmapVectorNoCtor<T> &lhs,
527 const InternalMmapVectorNoCtor<T> &rhs) {
528 if (lhs.size() != rhs.size()) return false;
529 return internal_memcmp(lhs.data(), rhs.data(), lhs.size() * sizeof(T)) == 0;
532 template <typename T>
533 bool operator!=(const InternalMmapVectorNoCtor<T> &lhs,
534 const InternalMmapVectorNoCtor<T> &rhs) {
535 return !(lhs == rhs);
539 class InternalMmapVector : public InternalMmapVectorNoCtor<T> {
541 InternalMmapVector() { InternalMmapVectorNoCtor<T>::Initialize(1); }
542 explicit InternalMmapVector(uptr cnt) {
543 InternalMmapVectorNoCtor<T>::Initialize(cnt);
546 ~InternalMmapVector() { InternalMmapVectorNoCtor<T>::Destroy(); }
547 // Disallow copies and moves.
548 InternalMmapVector(const InternalMmapVector &) = delete;
549 InternalMmapVector &operator=(const InternalMmapVector &) = delete;
550 InternalMmapVector(InternalMmapVector &&) = delete;
551 InternalMmapVector &operator=(InternalMmapVector &&) = delete;
554 class InternalScopedString : public InternalMmapVector<char> {
556 explicit InternalScopedString(uptr max_length)
557 : InternalMmapVector<char>(max_length), length_(0) {
560 uptr length() { return length_; }
565 void append(const char *format, ...);
573 bool operator()(const T &a, const T &b) const { return a < b; }
576 // HeapSort for arrays and InternalMmapVector.
577 template <class T, class Compare = CompareLess<T>>
578 void Sort(T *v, uptr size, Compare comp = {}) {
581 // Stage 1: insert elements to the heap.
582 for (uptr i = 1; i < size; i++) {
584 for (j = i; j > 0; j = p) {
586 if (comp(v[p], v[j]))
592 // Stage 2: swap largest element with the last one,
593 // and sink the new top.
594 for (uptr i = size - 1; i > 0; i--) {
597 for (j = 0; j < i; j = max_ind) {
598 uptr left = 2 * j + 1;
599 uptr right = 2 * j + 2;
601 if (left < i && comp(v[max_ind], v[left]))
603 if (right < i && comp(v[max_ind], v[right]))
606 Swap(v[j], v[max_ind]);
613 // Works like std::lower_bound: finds the first element that is not less
615 template <class Container, class Value, class Compare>
616 uptr InternalLowerBound(const Container &v, uptr first, uptr last,
617 const Value &val, Compare comp) {
618 while (last > first) {
619 uptr mid = (first + last) / 2;
620 if (comp(v[mid], val))
640 // Opens the file 'file_name" and reads up to 'max_len' bytes.
641 // The resulting buffer is mmaped and stored in '*buff'.
642 // Returns true if file was successfully opened and read.
643 bool ReadFileToVector(const char *file_name,
644 InternalMmapVectorNoCtor<char> *buff,
645 uptr max_len = 1 << 26, error_t *errno_p = nullptr);
647 // Opens the file 'file_name" and reads up to 'max_len' bytes.
648 // This function is less I/O efficient than ReadFileToVector as it may reread
649 // file multiple times to avoid mmap during read attempts. It's used to read
650 // procmap, so short reads with mmap in between can produce inconsistent result.
651 // The resulting buffer is mmaped and stored in '*buff'.
652 // The size of the mmaped region is stored in '*buff_size'.
653 // The total number of read bytes is stored in '*read_len'.
654 // Returns true if file was successfully opened and read.
655 bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
656 uptr *read_len, uptr max_len = 1 << 26,
657 error_t *errno_p = nullptr);
659 // When adding a new architecture, don't forget to also update
660 // script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cc.
661 inline const char *ModuleArchToString(ModuleArch arch) {
663 case kModuleArchUnknown:
665 case kModuleArchI386:
667 case kModuleArchX86_64:
669 case kModuleArchX86_64H:
671 case kModuleArchARMV6:
673 case kModuleArchARMV7:
675 case kModuleArchARMV7S:
677 case kModuleArchARMV7K:
679 case kModuleArchARM64:
682 CHECK(0 && "Invalid module arch");
686 const uptr kModuleUUIDSize = 16;
687 const uptr kMaxSegName = 16;
689 // Represents a binary loaded into virtual memory (e.g. this can be an
690 // executable or a shared object).
694 : full_name_(nullptr),
696 max_executable_address_(0),
697 arch_(kModuleArchUnknown),
698 instrumented_(false) {
699 internal_memset(uuid_, 0, kModuleUUIDSize);
702 void set(const char *module_name, uptr base_address);
703 void set(const char *module_name, uptr base_address, ModuleArch arch,
704 u8 uuid[kModuleUUIDSize], bool instrumented);
706 void addAddressRange(uptr beg, uptr end, bool executable, bool writable,
707 const char *name = nullptr);
708 bool containsAddress(uptr address) const;
710 const char *full_name() const { return full_name_; }
711 uptr base_address() const { return base_address_; }
712 uptr max_executable_address() const { return max_executable_address_; }
713 ModuleArch arch() const { return arch_; }
714 const u8 *uuid() const { return uuid_; }
715 bool instrumented() const { return instrumented_; }
717 struct AddressRange {
723 char name[kMaxSegName];
725 AddressRange(uptr beg, uptr end, bool executable, bool writable,
730 executable(executable),
732 internal_strncpy(this->name, (name ? name : ""), ARRAY_SIZE(this->name));
736 const IntrusiveList<AddressRange> &ranges() const { return ranges_; }
739 char *full_name_; // Owned.
741 uptr max_executable_address_;
743 u8 uuid_[kModuleUUIDSize];
745 IntrusiveList<AddressRange> ranges_;
748 // List of LoadedModules. OS-dependent implementation is responsible for
749 // filling this information.
750 class ListOfModules {
752 ListOfModules() : initialized(false) {}
753 ~ListOfModules() { clear(); }
755 void fallbackInit(); // Uses fallback init if available, otherwise clears
756 const LoadedModule *begin() const { return modules_.begin(); }
757 LoadedModule *begin() { return modules_.begin(); }
758 const LoadedModule *end() const { return modules_.end(); }
759 LoadedModule *end() { return modules_.end(); }
760 uptr size() const { return modules_.size(); }
761 const LoadedModule &operator[](uptr i) const {
762 CHECK_LT(i, modules_.size());
768 for (auto &module : modules_) module.clear();
772 initialized ? clear() : modules_.Initialize(kInitialCapacity);
776 InternalMmapVectorNoCtor<LoadedModule> modules_;
777 // We rarely have more than 16K loaded modules.
778 static const uptr kInitialCapacity = 1 << 14;
782 // Callback type for iterating over a set of memory ranges.
783 typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
785 enum AndroidApiLevel {
786 ANDROID_NOT_ANDROID = 0,
788 ANDROID_LOLLIPOP_MR1 = 22,
789 ANDROID_POST_LOLLIPOP = 23
792 void WriteToSyslog(const char *buffer);
795 void LogFullErrorReport(const char *buffer);
797 INLINE void LogFullErrorReport(const char *buffer) {}
800 #if SANITIZER_LINUX || SANITIZER_MAC
801 void WriteOneLineToSyslog(const char *s);
802 void LogMessageOnPrintf(const char *str);
804 INLINE void WriteOneLineToSyslog(const char *s) {}
805 INLINE void LogMessageOnPrintf(const char *str) {}
809 // Initialize Android logging. Any writes before this are silently lost.
810 void AndroidLogInit();
811 void SetAbortMessage(const char *);
813 INLINE void AndroidLogInit() {}
814 // FIXME: MacOS implementation could use CRSetCrashLogMessage.
815 INLINE void SetAbortMessage(const char *) {}
818 #if SANITIZER_ANDROID
819 void SanitizerInitializeUnwinder();
820 AndroidApiLevel AndroidGetApiLevel();
822 INLINE void AndroidLogWrite(const char *buffer_unused) {}
823 INLINE void SanitizerInitializeUnwinder() {}
824 INLINE AndroidApiLevel AndroidGetApiLevel() { return ANDROID_NOT_ANDROID; }
827 INLINE uptr GetPthreadDestructorIterations() {
828 #if SANITIZER_ANDROID
829 return (AndroidGetApiLevel() == ANDROID_LOLLIPOP_MR1) ? 8 : 4;
830 #elif SANITIZER_POSIX
833 // Unused on Windows.
838 void *internal_start_thread(void(*func)(void*), void *arg);
839 void internal_join_thread(void *th);
840 void MaybeStartBackgroudThread();
842 // Make the compiler think that something is going on there.
843 // Use this inside a loop that looks like memset/memcpy/etc to prevent the
844 // compiler from recognising it and turning it into an actual call to
845 // memset/memcpy/etc.
846 static inline void SanitizerBreakOptimization(void *arg) {
847 #if defined(_MSC_VER) && !defined(__clang__)
850 __asm__ __volatile__("" : : "r" (arg) : "memory");
854 struct SignalContext {
861 bool is_memory_access;
862 enum WriteFlag { UNKNOWN, READ, WRITE } write_flag;
864 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
866 SignalContext() = default;
868 // Creates signal context in a platform-specific manner.
869 // SignalContext is going to keep pointers to siginfo and context without
871 SignalContext(void *siginfo, void *context)
875 is_memory_access(IsMemoryAccess()),
876 write_flag(GetWriteFlag()) {
880 static void DumpAllRegisters(void *context);
882 // Type of signal e.g. SIGSEGV or EXCEPTION_ACCESS_VIOLATION.
885 // String description of the signal.
886 const char *Describe() const;
888 // Returns true if signal is stack overflow.
889 bool IsStackOverflow() const;
892 // Platform specific initialization.
894 uptr GetAddress() const;
895 WriteFlag GetWriteFlag() const;
896 bool IsMemoryAccess() const;
901 template <typename Fn>
902 class RunOnDestruction {
904 explicit RunOnDestruction(Fn fn) : fn_(fn) {}
905 ~RunOnDestruction() { fn_(); }
911 // A simple scope guard. Usage:
912 // auto cleanup = at_scope_exit([]{ do_cleanup; });
913 template <typename Fn>
914 RunOnDestruction<Fn> at_scope_exit(Fn fn) {
915 return RunOnDestruction<Fn>(fn);
918 // Linux on 64-bit s390 had a nasty bug that crashes the whole machine
919 // if a process uses virtual memory over 4TB (as many sanitizers like
920 // to do). This function will abort the process if running on a kernel
921 // that looks vulnerable.
922 #if SANITIZER_LINUX && SANITIZER_S390_64
923 void AvoidCVE_2016_2143();
925 INLINE void AvoidCVE_2016_2143() {}
928 struct StackDepotStats {
933 // The default value for allocator_release_to_os_interval_ms common flag to
934 // indicate that sanitizer allocator should not attempt to release memory to OS.
935 const s32 kReleaseToOSIntervalNever = -1;
937 void CheckNoDeepBind(const char *filename, int flag);
939 // Returns the requested amount of random data (up to 256 bytes) that can then
940 // be used to seed a PRNG. Defaults to blocking like the underlying syscall.
941 bool GetRandom(void *buffer, uptr length, bool blocking = true);
943 // Returns the number of logical processors on the system.
944 u32 GetNumberOfCPUs();
945 extern u32 NumberOfCPUsCached;
946 INLINE u32 GetNumberOfCPUsCached() {
947 if (!NumberOfCPUsCached)
948 NumberOfCPUsCached = GetNumberOfCPUs();
949 return NumberOfCPUsCached;
952 } // namespace __sanitizer
954 inline void *operator new(__sanitizer::operator_new_size_type size,
955 __sanitizer::LowLevelAllocator &alloc) {
956 return alloc.Allocate(size);
959 #endif // SANITIZER_COMMON_H