Skip to content

Commit 6479006

Browse files
authored
[asan] Use InternalMmapVectorNoCtor for error_message_buffer, reallocate if needed (llvm#77488)
- Add a param `raw_report` which defaults to false for function `UnmapOrDie()` like we do for `MmapOrDie()` - Add a template param `raw_report` which defaults to false for class `InternalMmapVectorNoCtor`. `raw_report` will be passed to `MmapOrDie()` and `UnmapOrDie()` when they are called in class `InternalMmapVectorNoCtor` member functions. - Use `InternalMmapVectorNoCtor<char, true>` for `error_message_buffer` and reallocate if needed.
1 parent 80f3bb4 commit 6479006

File tree

3 files changed

+26
-24
lines changed

3 files changed

+26
-24
lines changed

compiler-rt/lib/asan/asan_report.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "sanitizer_common/sanitizer_common.h"
2525
#include "sanitizer_common/sanitizer_flags.h"
2626
#include "sanitizer_common/sanitizer_interface_internal.h"
27+
#include "sanitizer_common/sanitizer_placement_new.h"
2728
#include "sanitizer_common/sanitizer_report_decorator.h"
2829
#include "sanitizer_common/sanitizer_stackdepot.h"
2930
#include "sanitizer_common/sanitizer_symbolizer.h"
@@ -32,8 +33,11 @@ namespace __asan {
3233

3334
// -------------------- User-specified callbacks ----------------- {{{1
3435
static void (*error_report_callback)(const char*);
35-
static char *error_message_buffer = nullptr;
36-
static uptr error_message_buffer_pos = 0;
36+
using ErrorMessageBuffer = InternalMmapVectorNoCtor<char, true>;
37+
static ALIGNED(
38+
alignof(ErrorMessageBuffer)) char error_message_buffer_placeholder
39+
[sizeof(ErrorMessageBuffer)];
40+
static ErrorMessageBuffer *error_message_buffer = nullptr;
3741
static Mutex error_message_buf_mutex;
3842
static const unsigned kAsanBuggyPcPoolSize = 25;
3943
static __sanitizer::atomic_uintptr_t AsanBuggyPcPool[kAsanBuggyPcPoolSize];
@@ -42,17 +46,14 @@ void AppendToErrorMessageBuffer(const char *buffer) {
4246
Lock l(&error_message_buf_mutex);
4347
if (!error_message_buffer) {
4448
error_message_buffer =
45-
(char*)MmapOrDieQuietly(kErrorMessageBufferSize, __func__);
46-
error_message_buffer_pos = 0;
49+
new (error_message_buffer_placeholder) ErrorMessageBuffer();
50+
error_message_buffer->Initialize(kErrorMessageBufferSize);
4751
}
48-
uptr length = internal_strlen(buffer);
49-
RAW_CHECK(kErrorMessageBufferSize >= error_message_buffer_pos);
50-
uptr remaining = kErrorMessageBufferSize - error_message_buffer_pos;
51-
internal_strncpy(error_message_buffer + error_message_buffer_pos,
52-
buffer, remaining);
53-
error_message_buffer[kErrorMessageBufferSize - 1] = '\0';
54-
// FIXME: reallocate the buffer instead of truncating the message.
55-
error_message_buffer_pos += Min(remaining, length);
52+
uptr error_message_buffer_len = error_message_buffer->size();
53+
uptr buffer_len = internal_strlen(buffer);
54+
error_message_buffer->resize(error_message_buffer_len + buffer_len);
55+
internal_memcpy(error_message_buffer->data() + error_message_buffer_len,
56+
buffer, buffer_len);
5657
}
5758

5859
// ---------------------- Helper functions ----------------------- {{{1
@@ -158,14 +159,14 @@ class ScopedInErrorReport {
158159

159160
// Copy the message buffer so that we could start logging without holding a
160161
// lock that gets acquired during printing.
161-
InternalMmapVector<char> buffer_copy(kErrorMessageBufferSize);
162+
InternalScopedString buffer_copy;
162163
{
163164
Lock l(&error_message_buf_mutex);
164-
internal_memcpy(buffer_copy.data(),
165-
error_message_buffer, kErrorMessageBufferSize);
165+
error_message_buffer->push_back('\0');
166+
buffer_copy.Append(error_message_buffer->data());
166167
// Clear error_message_buffer so that if we find other errors
167168
// we don't re-log this error.
168-
error_message_buffer_pos = 0;
169+
error_message_buffer->clear();
169170
}
170171

171172
LogFullErrorReport(buffer_copy.data());

compiler-rt/lib/sanitizer_common/sanitizer_common.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void *MmapOrDie(uptr size, const char *mem_type, bool raw_report = false);
9494
inline void *MmapOrDieQuietly(uptr size, const char *mem_type) {
9595
return MmapOrDie(size, mem_type, /*raw_report*/ true);
9696
}
97-
void UnmapOrDie(void *addr, uptr size);
97+
void UnmapOrDie(void *addr, uptr size, bool raw_report = false);
9898
// Behaves just like MmapOrDie, but tolerates out of memory condition, in that
9999
// case returns nullptr.
100100
void *MmapOrDieOnFatalError(uptr size, const char *mem_type);
@@ -510,7 +510,7 @@ inline int ToLower(int c) {
510510
// A low-level vector based on mmap. May incur a significant memory overhead for
511511
// small vectors.
512512
// WARNING: The current implementation supports only POD types.
513-
template<typename T>
513+
template <typename T, bool raw_report = false>
514514
class InternalMmapVectorNoCtor {
515515
public:
516516
using value_type = T;
@@ -520,7 +520,7 @@ class InternalMmapVectorNoCtor {
520520
data_ = 0;
521521
reserve(initial_capacity);
522522
}
523-
void Destroy() { UnmapOrDie(data_, capacity_bytes_); }
523+
void Destroy() { UnmapOrDie(data_, capacity_bytes_, raw_report); }
524524
T &operator[](uptr i) {
525525
CHECK_LT(i, size_);
526526
return data_[i];
@@ -596,7 +596,8 @@ class InternalMmapVectorNoCtor {
596596
CHECK_LE(size_, new_capacity);
597597
uptr new_capacity_bytes =
598598
RoundUpTo(new_capacity * sizeof(T), GetPageSizeCached());
599-
T *new_data = (T *)MmapOrDie(new_capacity_bytes, "InternalMmapVector");
599+
T *new_data =
600+
(T *)MmapOrDie(new_capacity_bytes, "InternalMmapVector", raw_report);
600601
internal_memcpy(new_data, data_, size_ * sizeof(T));
601602
UnmapOrDie(data_, capacity_bytes_);
602603
data_ = new_data;

compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
5454
return (void *)res;
5555
}
5656

57-
void UnmapOrDie(void *addr, uptr size) {
57+
void UnmapOrDie(void *addr, uptr size, bool raw_report) {
5858
if (!addr || !size) return;
5959
uptr res = internal_munmap(addr, size);
6060
int reserrno;
6161
if (UNLIKELY(internal_iserror(res, &reserrno)))
62-
ReportMunmapFailureAndDie(addr, size, reserrno);
62+
ReportMunmapFailureAndDie(addr, size, reserrno, raw_report);
6363
DecreaseTotalMmap(size);
6464
}
6565

@@ -85,8 +85,8 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
8585
CHECK(IsPowerOfTwo(size));
8686
CHECK(IsPowerOfTwo(alignment));
8787
uptr map_size = size + alignment;
88-
// mmap maps entire pages and rounds up map_size needs to be a an integral
89-
// number of pages.
88+
// mmap maps entire pages and rounds up map_size needs to be a an integral
89+
// number of pages.
9090
// We need to be aware of this size for calculating end and for unmapping
9191
// fragments before and after the alignment region.
9292
map_size = RoundUpTo(map_size, GetPageSizeCached());

0 commit comments

Comments
 (0)