[sanitizer] Remove max_len parameter from InternalScopedString

InternalScopedString uses InternalMmapVector internally
so it can be resized dynamically as needed.

Reviewed By: eugenis

Differential Revision: https://reviews.llvm.org/D98751
This commit is contained in:
Vitaly Buka 2021-03-16 16:33:04 -07:00
parent f87b4109b2
commit e0dadf3de2
22 changed files with 86 additions and 62 deletions

View File

@ -48,7 +48,7 @@ void DescribeThread(AsanThreadContext *context) {
return;
}
context->announced = true;
InternalScopedString str(1024);
InternalScopedString str;
str.append("Thread %s", AsanThreadIdAndName(context).c_str());
if (context->parent_tid == kInvalidTid) {
str.append(" created by unknown thread\n");
@ -125,7 +125,7 @@ static void GetAccessToHeapChunkInformation(ChunkAccess *descr,
static void PrintHeapChunkAccess(uptr addr, const ChunkAccess &descr) {
Decorator d;
InternalScopedString str(4096);
InternalScopedString str;
str.append("%s", d.Location());
switch (descr.access_type) {
case kAccessTypeLeft:
@ -242,7 +242,7 @@ static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,
else if (addr >= prev_var_end && addr - prev_var_end >= var.beg - addr_end)
pos_descr = "underflows";
}
InternalScopedString str(1024);
InternalScopedString str;
str.append(" [%zd, %zd)", var.beg, var_end);
// Render variable name.
str.append(" '");
@ -275,7 +275,7 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) {
// Global descriptions
static void DescribeAddressRelativeToGlobal(uptr addr, uptr access_size,
const __asan_global &g) {
InternalScopedString str(4096);
InternalScopedString str;
Decorator d;
str.append("%s", d.Location());
if (addr < g.beg) {

View File

@ -343,7 +343,8 @@ void ErrorODRViolation::Print() {
Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
global1.beg);
Printf("%s", d.Default());
InternalScopedString g1_loc(256), g2_loc(256);
InternalScopedString g1_loc;
InternalScopedString g2_loc;
PrintGlobalLocation(&g1_loc, global1);
PrintGlobalLocation(&g2_loc, global2);
Printf(" [1] size=%zd '%s' %s\n", global1.size,
@ -360,7 +361,7 @@ void ErrorODRViolation::Print() {
Report(
"HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=detect_odr_violation=0\n");
InternalScopedString error_msg(256);
InternalScopedString error_msg;
error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
MaybeDemangleGlobalName(global1.name), g1_loc.data());
ReportErrorSummary(error_msg.data());
@ -554,7 +555,7 @@ static void PrintShadowMemoryForAddress(uptr addr) {
uptr shadow_addr = MemToShadow(addr);
const uptr n_bytes_per_row = 16;
uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
InternalScopedString str(4096 * 8);
InternalScopedString str;
str.append("Shadow bytes around the buggy address:\n");
for (int i = -5; i <= 5; i++) {
uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;

View File

@ -65,7 +65,7 @@ FakeStack *FakeStack::Create(uptr stack_size_log) {
void FakeStack::Destroy(int tid) {
PoisonAll(0);
if (Verbosity() >= 2) {
InternalScopedString str(kNumberOfSizeClasses * 50);
InternalScopedString str;
for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++)
str.append("%zd: %zd/%zd; ", class_id, hint_position_[class_id],
NumberOfFrames(stack_size_log(), class_id));

View File

@ -136,8 +136,6 @@ static void HWAsanCheckFailed(const char *file, int line, const char *cond,
Die();
}
static constexpr uptr kMemoryUsageBufferSize = 4096;
static void HwasanFormatMemoryUsage(InternalScopedString &s) {
HwasanThreadList &thread_list = hwasanThreadList();
auto thread_stats = thread_list.GetThreadStats();
@ -155,6 +153,8 @@ static void HwasanFormatMemoryUsage(InternalScopedString &s) {
}
#if SANITIZER_ANDROID
static constexpr uptr kMemoryUsageBufferSize = 4096;
static char *memory_usage_buffer = nullptr;
static void InitMemoryUsage() {
@ -171,7 +171,7 @@ void UpdateMemoryUsage() {
return;
if (!memory_usage_buffer)
InitMemoryUsage();
InternalScopedString s(kMemoryUsageBufferSize);
InternalScopedString s;
HwasanFormatMemoryUsage(s);
internal_strncpy(memory_usage_buffer, s.data(), kMemoryUsageBufferSize - 1);
memory_usage_buffer[kMemoryUsageBufferSize - 1] = '\0';
@ -493,7 +493,7 @@ extern "C" void *__hwasan_extra_spill_area() {
}
void __hwasan_print_memory_usage() {
InternalScopedString s(kMemoryUsageBufferSize);
InternalScopedString s;
HwasanFormatMemoryUsage(s);
Printf("%s\n", s.data());
}

View File

@ -224,7 +224,7 @@ static void PrintStackAllocations(StackAllocationsRingBuffer *sa,
// We didn't find any locals. Most likely we don't have symbols, so dump
// the information that we have for offline analysis.
InternalScopedString frame_desc(GetPageSizeCached() * 2);
InternalScopedString frame_desc;
Printf("Previously allocated frames:\n");
for (uptr i = 0; i < frames; i++) {
const uptr *record_addr = &(*sa)[i];
@ -459,7 +459,7 @@ static void PrintTagInfoAroundAddr(tag_t *tag_ptr, uptr num_rows,
RoundDownTo(reinterpret_cast<uptr>(tag_ptr), row_len));
tag_t *beg_row = center_row_beg - row_len * (num_rows / 2);
tag_t *end_row = center_row_beg + row_len * ((num_rows + 1) / 2);
InternalScopedString s(GetPageSizeCached() * 8);
InternalScopedString s;
for (tag_t *row = beg_row; row < end_row; row += row_len) {
s.append("%s", row == center_row_beg ? "=>" : " ");
s.append("%p:", row);
@ -547,7 +547,7 @@ void ReportTailOverwritten(StackTrace *stack, uptr tagged_addr, uptr orig_size,
GetStackTraceFromId(chunk.GetAllocStackId()).Print();
}
InternalScopedString s(GetPageSizeCached() * 8);
InternalScopedString s;
CHECK_GT(tail_size, 0U);
CHECK_LT(tail_size, kShadowAlignment);
u8 *tail = reinterpret_cast<u8*>(untagged_addr + orig_size);

View File

@ -895,7 +895,7 @@ void LeakReport::PrintSummary() {
bytes += leaks_[i].total_size;
allocations += leaks_[i].hit_count;
}
InternalScopedString summary(kMaxSummaryLength);
InternalScopedString summary;
summary.append("%zu byte(s) leaked in %zu allocation(s).", bytes,
allocations);
ReportErrorSummary(summary.data());

View File

@ -48,7 +48,7 @@ void DescribeThread(MemprofThreadContext *context) {
return;
}
context->announced = true;
InternalScopedString str(1024);
InternalScopedString str;
str.append("Thread %s", MemprofThreadIdAndName(context).c_str());
if (context->parent_tid == kInvalidTid) {
str.append(" created by unknown thread\n");

View File

@ -87,7 +87,7 @@ const char *StripModuleName(const char *module) {
void ReportErrorSummary(const char *error_message, const char *alt_tool_name) {
if (!common_flags()->print_summary)
return;
InternalScopedString buff(kMaxSummaryLength);
InternalScopedString buff;
buff.append("SUMMARY: %s: %s",
alt_tool_name ? alt_tool_name : SanitizerToolName, error_message);
__sanitizer_report_error_summary(buff.data());

View File

@ -44,7 +44,7 @@ const uptr kMaxPathLength = 4096;
const uptr kMaxThreadStackSize = 1 << 30; // 1Gb
static const uptr kErrorMessageBufferSize = 1 << 16;
const uptr kErrorMessageBufferSize = 1 << 16;
// Denotes fake PC values that come from JIT/JAVA/etc.
// For such PC values __tsan_symbolize_external_ex() will be called.
@ -344,8 +344,6 @@ void ReportDeadlySignal(const SignalContext &sig, u32 tid,
void SetAlternateSignalStack();
void UnsetAlternateSignalStack();
// We don't want a summary too long.
const int kMaxSummaryLength = 1024;
// Construct a one-line string:
// SUMMARY: SanitizerToolName: error_message
// and pass it to __sanitizer_report_error_summary.
@ -594,14 +592,12 @@ class InternalMmapVector : public InternalMmapVectorNoCtor<T> {
class InternalScopedString {
public:
explicit InternalScopedString(uptr max_length)
: buffer_(max_length), length_(0) {
buffer_[0] = '\0';
}
uptr length() const { return length_; }
explicit InternalScopedString() : buffer_(1) { buffer_[0] = '\0'; }
uptr length() const { return buffer_.size() - 1; }
void clear() {
buffer_.resize(1);
buffer_[0] = '\0';
length_ = 0;
}
void append(const char *format, ...);
const char *data() const { return buffer_.data(); }
@ -609,7 +605,6 @@ class InternalScopedString {
private:
InternalMmapVector<char> buffer_;
uptr length_;
};
template <class T>

View File

@ -92,7 +92,7 @@ void *BackgroundThread(void *arg) {
#endif
void WriteToSyslog(const char *msg) {
InternalScopedString msg_copy(kErrorMessageBufferSize);
InternalScopedString msg_copy;
msg_copy.append("%s", msg);
const char *p = msg_copy.data();

View File

@ -606,7 +606,7 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) {
}
if (info->dlpi_name) {
InternalScopedString module_name(kMaxPathLength);
InternalScopedString module_name;
module_name.append("%s", info->dlpi_name);
return AddModuleSegments(module_name.data(), info, data->modules);
}

View File

@ -124,7 +124,7 @@ INTERCEPTOR(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name) {
// bytes.
size_t buflen =
sizeof(COMMON_MALLOC_ZONE_NAME "-") + (name ? internal_strlen(name) : 0);
InternalScopedString new_name(buflen);
InternalScopedString new_name;
if (name && zone->introspect == sanitizer_zone.introspect) {
new_name.append(COMMON_MALLOC_ZONE_NAME "-%s", name);
name = new_name.data();

View File

@ -346,13 +346,24 @@ int internal_snprintf(char *buffer, uptr length, const char *format, ...) {
FORMAT(2, 3)
void InternalScopedString::append(const char *format, ...) {
CHECK_LT(length_, buffer_.size());
va_list args;
va_start(args, format);
VSNPrintf(buffer_.data() + length_, buffer_.size() - length_, format, args);
va_end(args);
length_ += internal_strlen(data() + length_);
CHECK_LT(length_, buffer_.size());
uptr prev_len = length();
while (true) {
buffer_.resize(buffer_.capacity());
va_list args;
va_start(args, format);
uptr sz = VSNPrintf(buffer_.data() + prev_len, buffer_.size() - prev_len,
format, args);
va_end(args);
if (sz < buffer_.size() - prev_len) {
buffer_.resize(prev_len + sz + 1);
break;
}
buffer_.reserve(buffer_.capacity() * 2);
}
CHECK_EQ(buffer_[length()], '\0');
}
} // namespace __sanitizer

View File

@ -23,8 +23,8 @@ void StackTrace::Print() const {
Printf(" <empty stack>\n\n");
return;
}
InternalScopedString frame_desc(GetPageSizeCached() * 2);
InternalScopedString dedup_token(GetPageSizeCached());
InternalScopedString frame_desc;
InternalScopedString dedup_token;
int dedup_frames = common_flags()->dedup_token_length;
bool symbolize = RenderNeedsSymbolization(common_flags()->stack_trace_format);
uptr frame_num = 0;
@ -125,7 +125,7 @@ void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf,
out_buf[out_buf_size - 1] = 0;
return;
}
InternalScopedString frame_desc(GetPageSizeCached());
InternalScopedString frame_desc;
uptr frame_num = 0;
// Reserve one byte for the final 0.
char *out_end = out_buf + out_buf_size - 1;
@ -156,7 +156,7 @@ void __sanitizer_symbolize_global(uptr data_addr, const char *fmt,
out_buf[0] = 0;
DataInfo DI;
if (!Symbolizer::GetOrInit()->SymbolizeData(data_addr, &DI)) return;
InternalScopedString data_desc(GetPageSizeCached());
InternalScopedString data_desc;
RenderData(&data_desc, fmt, &DI, common_flags()->strip_path_prefix);
internal_strncpy(out_buf, data_desc.data(), out_buf_size);
out_buf[out_buf_size - 1] = 0;

View File

@ -31,7 +31,7 @@ namespace __sanitizer {
void ReportErrorSummary(const char *error_type, const AddressInfo &info,
const char *alt_tool_name) {
if (!common_flags()->print_summary) return;
InternalScopedString buff(kMaxSummaryLength);
InternalScopedString buff;
buff.append("%s ", error_type);
RenderFrame(&buff, "%L %F", 0, info.address, &info,
common_flags()->symbolize_vs_style,
@ -150,7 +150,7 @@ static void PrintMemoryByte(InternalScopedString *str, const char *before,
static void MaybeDumpInstructionBytes(uptr pc) {
if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached()))
return;
InternalScopedString str(1024);
InternalScopedString str;
str.append("First 16 instruction bytes at pc: ");
if (IsAccessibleMemoryRange(pc, 16)) {
for (int i = 0; i < 16; ++i) {

View File

@ -224,7 +224,7 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
// Compute the command line. Wrap double quotes around everything.
const char *argv[kArgVMax];
GetArgV(path_, argv);
InternalScopedString command_line(kMaxPathLength * 3);
InternalScopedString command_line;
for (int i = 0; argv[i]; i++) {
const char *arg = argv[i];
int arglen = internal_strlen(arg);

View File

@ -350,7 +350,7 @@ TEST(SanitizerCommon, RemoveANSIEscapeSequencesFromString) {
}
TEST(SanitizerCommon, InternalScopedString) {
InternalScopedString str(10);
InternalScopedString str;
EXPECT_EQ(0U, str.length());
EXPECT_STREQ("", str.data());
@ -364,20 +364,37 @@ TEST(SanitizerCommon, InternalScopedString) {
EXPECT_STREQ("foo1234", str.data());
str.append("%d", x);
EXPECT_EQ(9U, str.length());
EXPECT_STREQ("foo123412", str.data());
EXPECT_EQ(11U, str.length());
EXPECT_STREQ("foo12341234", str.data());
str.clear();
EXPECT_EQ(0U, str.length());
EXPECT_STREQ("", str.data());
str.append("0123456789");
EXPECT_EQ(9U, str.length());
EXPECT_STREQ("012345678", str.data());
}
#if SANITIZER_LINUX || SANITIZER_FREEBSD || \
SANITIZER_MAC || SANITIZER_IOS
TEST(SanitizerCommon, InternalScopedStringLarge) {
InternalScopedString str;
std::string expected;
for (int i = 0; i < 1000; ++i) {
std::string append(i, 'a' + i % 26);
expected += append;
str.append(append.c_str());
EXPECT_EQ(expected, str.data());
}
}
TEST(SanitizerCommon, InternalScopedStringLargeFormat) {
InternalScopedString str;
std::string expected;
for (int i = 0; i < 1000; ++i) {
std::string append(i, 'a' + i % 26);
expected += append;
str.append("%s", append.c_str());
EXPECT_EQ(expected, str.data());
}
}
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_IOS
TEST(SanitizerCommon, GetRandom) {
u8 buffer_1[32], buffer_2[32];
for (bool blocking : { false, true }) {

View File

@ -16,7 +16,7 @@
namespace __sanitizer {
TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
InternalScopedString str(128);
InternalScopedString str;
RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "");
EXPECT_STREQ("/dir/file.cc:10:5", str.data());
@ -50,7 +50,7 @@ TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
}
TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
InternalScopedString str(128);
InternalScopedString str;
RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "");
EXPECT_STREQ("(/dir/exe+0x123)", str.data());
@ -76,7 +76,7 @@ TEST(SanitizerStacktracePrinter, RenderFrame) {
info.file = internal_strdup("/path/to/my/source");
info.line = 10;
info.column = 5;
InternalScopedString str(256);
InternalScopedString str;
// Dump all the AddressInfo fields.
RenderFrame(&str,

View File

@ -127,7 +127,7 @@ void PrintStack(const ReportStack *ent) {
}
SymbolizedStack *frame = ent->frames;
for (int i = 0; frame && frame->info.address; frame = frame->next, i++) {
InternalScopedString res(2 * GetPageSizeCached());
InternalScopedString res;
RenderFrame(&res, common_flags()->stack_trace_format, i,
frame->info.address, &frame->info,
common_flags()->symbolize_vs_style,

View File

@ -167,7 +167,7 @@ static void *BackgroundThread(void *arg) {
} else if (internal_strcmp(flags()->profile_memory, "stderr") == 0) {
mprof_fd = 2;
} else {
InternalScopedString filename(kMaxPathLength);
InternalScopedString filename;
filename.append("%s.%d", flags()->profile_memory, (int)internal_getpid());
fd_t fd = OpenFile(filename.data(), WrOnly);
if (fd == kInvalidFd) {

View File

@ -278,7 +278,7 @@ static void PrintMemorySnippet(const Decorator &Decor, MemoryLocation Loc,
}
// Emit data.
InternalScopedString Buffer(1024);
InternalScopedString Buffer;
for (uptr P = Min; P != Max; ++P) {
unsigned char C = *reinterpret_cast<const unsigned char*>(P);
Buffer.append("%s%02x", (P % 8 == 0) ? " " : " ", C);
@ -346,7 +346,7 @@ Diag::~Diag() {
// All diagnostics should be printed under report mutex.
ScopedReport::CheckLocked();
Decorator Decor;
InternalScopedString Buffer(1024);
InternalScopedString Buffer;
// Prepare a report that a monitor process can inspect.
if (Level == DL_Error) {

View File

@ -17,7 +17,7 @@ using namespace __ubsan;
UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind,
Location &Loc,
InternalScopedString &Msg)
: IssueKind(IssueKind), Loc(Loc), Buffer(Msg.length() + 1) {
: IssueKind(IssueKind), Loc(Loc) {
// We have the common sanitizer reporting lock, so it's safe to register a
// new UB report.
RegisterUndefinedBehaviorReport(this);