Summary: Keep reifying other errors.
Reviewers: kcc, samsonov
Subscribers: llvm-commits, kubabrecka
Differential Revision: https://reviews.llvm.org/D23717
llvm-svn: 280201
//===----------------------------------------------------------------------===//
#include "asan_errors.h"
+#include "asan_descriptions.h"
#include "asan_stack.h"
namespace __asan {
ReportErrorSummary("stack-overflow", &stack);
}
+void ErrorDoubleFree::Print() {
+ Decorator d;
+ Printf("%s", d.Warning());
+ char tname[128];
+ Report(
+ "ERROR: AddressSanitizer: attempting double-free on %p in "
+ "thread T%d%s:\n",
+ addr_description.addr, tid,
+ ThreadNameWithParenthesis(tid, tname, sizeof(tname)));
+ Printf("%s", d.EndWarning());
+ GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
+ second_free_stack->top_frame_bp);
+ stack.Print();
+ addr_description.Print();
+ ReportErrorSummary("double-free", &stack);
+}
+
} // namespace __asan
void Print();
};
+struct ErrorDoubleFree : ErrorBase {
+ u32 tid;
+ HeapAddressDescription addr_description;
+ // ErrorDoubleFree doesn't own the stack trace.
+ BufferedStackTrace *second_free_stack;
+ // VS2013 doesn't implement unrestricted unions, so we need a trivial default
+ // constructor
+ ErrorDoubleFree() = default;
+ ErrorDoubleFree(uptr addr, u32 tid_, BufferedStackTrace *stack)
+ : tid(tid_), second_free_stack(stack) {
+ CHECK_GT(second_free_stack->size, 0);
+ GetHeapAddressInformation(addr, 1, &addr_description);
+ scariness.Scare(42, "double-free");
+ }
+ void Print();
+};
+
enum ErrorKind {
kErrorKindInvalid = 0,
kErrorKindStackOverflow,
+ kErrorKindDoubleFree,
};
struct ErrorDescription {
// add a lot of code and the benefit wouldn't be that big.
union {
ErrorStackOverflow stack_overflow;
+ ErrorDoubleFree double_free;
};
ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
ErrorDescription(const ErrorStackOverflow &e) // NOLINT
: kind(kErrorKindStackOverflow),
stack_overflow(e) {}
+ ErrorDescription(const ErrorDoubleFree &e) // NOLINT
+ : kind(kErrorKindDoubleFree),
+ double_free(e) {}
bool IsValid() { return kind != kErrorKindInvalid; }
void Print() {
case kErrorKindStackOverflow:
stack_overflow.Print();
return;
+ case kErrorKindDoubleFree:
+ double_free.Print();
+ return;
case kErrorKindInvalid:
CHECK(0);
}
void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
ScopedInErrorReport in_report;
- Decorator d;
- Printf("%s", d.Warning());
- char tname[128];
- u32 curr_tid = GetCurrentTidOrInvalid();
- Report("ERROR: AddressSanitizer: attempting double-free on %p in "
- "thread T%d%s:\n",
- addr, curr_tid,
- ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname)));
- Printf("%s", d.EndWarning());
- CHECK_GT(free_stack->size, 0);
- ScarinessScore::PrintSimple(42, "double-free");
- GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
- stack.Print();
- DescribeAddressIfHeap(addr);
- ReportErrorSummary("double-free", &stack);
+ ErrorDoubleFree error{addr, GetCurrentTidOrInvalid(), free_stack}; // NOLINT
+ in_report.ReportError(error);
}
void ReportNewDeleteSizeMismatch(uptr addr, uptr alloc_size, uptr delete_size,