[asan] Reify ErrorNewDeleteSizeMismatch

Summary: Keep reifying other errors.

Reviewers: kcc, samsonov

Subscribers: llvm-commits, kubabrecka

Differential Revision: https://reviews.llvm.org/D23874

llvm-svn: 280812
This commit is contained in:
Filipe Cabecinhas 2016-09-07 14:20:54 +00:00
parent 349779cc99
commit 25ad7b52c3
5 changed files with 58 additions and 23 deletions

View File

@ -530,7 +530,7 @@ struct Allocator {
if (delete_size && flags()->new_delete_type_mismatch &&
delete_size != m->UsedSize()) {
ReportNewDeleteSizeMismatch(p, m->UsedSize(), delete_size, stack);
ReportNewDeleteSizeMismatch(p, delete_size, stack);
}
QuarantineChunk(m, ptr, stack, alloc_type);

View File

@ -52,4 +52,29 @@ void ErrorDoubleFree::Print() {
ReportErrorSummary("double-free", &stack);
}
void ErrorNewDeleteSizeMismatch::Print() {
Decorator d;
Printf("%s", d.Warning());
char tname[128];
Report(
"ERROR: AddressSanitizer: new-delete-type-mismatch on %p in thread "
"T%d%s:\n",
addr_description.addr, tid,
ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
Printf("%s object passed to delete has wrong type:\n", d.EndWarning());
Printf(
" size of the allocated type: %zd bytes;\n"
" size of the deallocated type: %zd bytes.\n",
addr_description.chunk_access.chunk_size, delete_size);
CHECK_GT(free_stack->size, 0);
scariness.Print();
GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
stack.Print();
addr_description.Print();
ReportErrorSummary("new-delete-type-mismatch", &stack);
Report(
"HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=new_delete_type_mismatch=0\n");
}
} // namespace __asan

View File

@ -62,10 +62,30 @@ struct ErrorDoubleFree : ErrorBase {
void Print();
};
struct ErrorNewDeleteSizeMismatch : ErrorBase {
u32 tid;
HeapAddressDescription addr_description;
uptr delete_size;
// ErrorNewDeleteSizeMismatch doesn't own the stack trace.
BufferedStackTrace *free_stack;
// VS2013 doesn't implement unrestricted unions, so we need a trivial default
// constructor
ErrorNewDeleteSizeMismatch() = default;
ErrorNewDeleteSizeMismatch(uptr addr, u32 tid_, uptr delete_size_,
BufferedStackTrace *stack)
: tid(tid_), delete_size(delete_size_), free_stack(stack) {
GetHeapAddressInformation(addr, 1, &addr_description);
scariness.Clear();
scariness.Scare(10, "new-delete-type-mismatch");
}
void Print();
};
enum ErrorKind {
kErrorKindInvalid = 0,
kErrorKindStackOverflow,
kErrorKindDoubleFree,
kErrorKindNewDeleteSizeMismatch,
};
struct ErrorDescription {
@ -78,6 +98,7 @@ struct ErrorDescription {
union {
ErrorStackOverflow stack_overflow;
ErrorDoubleFree double_free;
ErrorNewDeleteSizeMismatch new_delete_size_mismatch;
};
ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
ErrorDescription(const ErrorStackOverflow &e) // NOLINT
@ -86,6 +107,9 @@ struct ErrorDescription {
ErrorDescription(const ErrorDoubleFree &e) // NOLINT
: kind(kErrorKindDoubleFree),
double_free(e) {}
ErrorDescription(const ErrorNewDeleteSizeMismatch &e) // NOLINT
: kind(kErrorKindNewDeleteSizeMismatch),
new_delete_size_mismatch(e) {}
bool IsValid() { return kind != kErrorKindInvalid; }
void Print() {
@ -96,6 +120,9 @@ struct ErrorDescription {
case kErrorKindDoubleFree:
double_free.Print();
return;
case kErrorKindNewDeleteSizeMismatch:
new_delete_size_mismatch.Print();
return;
case kErrorKindInvalid:
CHECK(0);
}

View File

@ -392,29 +392,12 @@ void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
in_report.ReportError(error);
}
void ReportNewDeleteSizeMismatch(uptr addr, uptr alloc_size, uptr delete_size,
void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
BufferedStackTrace *free_stack) {
ScopedInErrorReport in_report;
Decorator d;
Printf("%s", d.Warning());
char tname[128];
u32 curr_tid = GetCurrentTidOrInvalid();
Report("ERROR: AddressSanitizer: new-delete-type-mismatch on %p in "
"thread T%d%s:\n",
addr, curr_tid,
ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));
Printf("%s object passed to delete has wrong type:\n", d.EndWarning());
Printf(" size of the allocated type: %zd bytes;\n"
" size of the deallocated type: %zd bytes.\n",
alloc_size, delete_size);
CHECK_GT(free_stack->size, 0);
ScarinessScore::PrintSimple(10, "new-delete-type-mismatch");
GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
stack.Print();
DescribeAddressIfHeap(addr);
ReportErrorSummary("new-delete-type-mismatch", &stack);
Report("HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=new_delete_type_mismatch=0\n");
ErrorNewDeleteSizeMismatch error(addr, GetCurrentTidOrInvalid(), delete_size,
free_stack);
in_report.ReportError(error);
}
void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack) {

View File

@ -52,7 +52,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
uptr access_size, u32 exp, bool fatal);
void ReportStackOverflow(const SignalContext &sig);
void ReportDeadlySignal(const char *description, const SignalContext &sig);
void ReportNewDeleteSizeMismatch(uptr addr, uptr alloc_size, uptr delete_size,
void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
BufferedStackTrace *free_stack);
void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);