1 //===-- sanitizer_common.cc -----------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is shared between AddressSanitizer and ThreadSanitizer
10 //===----------------------------------------------------------------------===//
12 #include "sanitizer_common.h"
13 #include "sanitizer_libc.h"
15 namespace __sanitizer
{
17 static fd_t report_fd
= 2; // By default, dump to stderr.
18 static char report_path
[4096]; // Set via __sanitizer_set_report_path.
20 static void (*DieCallback
)(void);
21 void SetDieCallback(void (*callback
)(void)) {
22 DieCallback
= callback
;
32 static CheckFailedCallbackType CheckFailedCallback
;
33 void SetCheckFailedCallback(CheckFailedCallbackType callback
) {
34 CheckFailedCallback
= callback
;
37 void NORETURN
CheckFailed(const char *file
, int line
, const char *cond
,
39 if (CheckFailedCallback
) {
40 CheckFailedCallback(file
, line
, cond
, v1
, v2
);
42 Report("Sanitizer CHECK failed: %s:%d %s (%zd, %zd)\n", file
, line
, cond
,
47 void RawWrite(const char *buffer
) {
48 static const char *kRawWriteError
= "RawWrite can't output requested buffer!";
49 uptr length
= (uptr
)internal_strlen(buffer
);
50 if (report_fd
== kInvalidFd
) {
51 fd_t fd
= internal_open(report_path
, true);
52 if (fd
== kInvalidFd
) {
54 Report("ERROR: Can't open file: %s\n", report_path
);
59 if (length
!= internal_write(report_fd
, buffer
, length
)) {
60 internal_write(report_fd
, kRawWriteError
, internal_strlen(kRawWriteError
));
65 uptr
ReadFileToBuffer(const char *file_name
, char **buff
,
66 uptr
*buff_size
, uptr max_len
) {
67 const uptr kMinFileLen
= kPageSize
;
71 // The files we usually open are not seekable, so try different buffer sizes.
72 for (uptr size
= kMinFileLen
; size
<= max_len
; size
*= 2) {
73 fd_t fd
= internal_open(file_name
, /*write*/ false);
74 if (fd
== kInvalidFd
) return 0;
75 UnmapOrDie(*buff
, *buff_size
);
76 *buff
= (char*)MmapOrDie(size
, __FUNCTION__
);
78 // Read up to one page at a time.
80 bool reached_eof
= false;
81 while (read_len
+ kPageSize
<= size
) {
82 uptr just_read
= internal_read(fd
, *buff
+ read_len
, kPageSize
);
87 read_len
+= just_read
;
90 if (reached_eof
) // We've read the whole file.
96 // We don't want to use std::sort to avoid including <algorithm>, as
97 // we may end up with two implementation of std::sort - one in instrumented
98 // code, and the other in runtime.
99 // qsort() from stdlib won't work as it calls malloc(), which results
100 // in deadlock in ASan allocator.
101 // We re-implement in-place sorting w/o recursion as straightforward heapsort.
102 void SortArray(uptr
*array
, uptr size
) {
105 // Stage 1: insert elements to the heap.
106 for (uptr i
= 1; i
< size
; i
++) {
108 for (j
= i
; j
> 0; j
= p
) {
110 if (array
[j
] > array
[p
])
111 Swap(array
[j
], array
[p
]);
116 // Stage 2: swap largest element with the last one,
117 // and sink the new top.
118 for (uptr i
= size
- 1; i
> 0; i
--) {
119 Swap(array
[0], array
[i
]);
121 for (j
= 0; j
< i
; j
= max_ind
) {
122 uptr left
= 2 * j
+ 1;
123 uptr right
= 2 * j
+ 2;
125 if (left
< i
&& array
[left
] > array
[max_ind
])
127 if (right
< i
&& array
[right
] > array
[max_ind
])
130 Swap(array
[j
], array
[max_ind
]);
137 } // namespace __sanitizer
139 void __sanitizer_set_report_path(const char *path
) {
141 uptr len
= internal_strlen(path
);
142 if (len
> sizeof(__sanitizer::report_path
) - 100) {
143 Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n",
144 path
[0], path
[1], path
[2], path
[3],
145 path
[4], path
[5], path
[6], path
[7]);
148 internal_snprintf(__sanitizer::report_path
,
149 sizeof(__sanitizer::report_path
), "%s.%d", path
, GetPid());
150 __sanitizer::report_fd
= kInvalidFd
;