//===----------------------------------------------------------------------===//
#include "msan.h"
+#include "msan_chained_origin_depot.h"
+#include "msan_origin.h"
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
namespace __msan {
-class Decorator: private __sanitizer::AnsiColorDecorator {
+class Decorator: public __sanitizer::SanitizerCommonDecorator {
public:
- Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { }
+ Decorator() : SanitizerCommonDecorator() { }
const char *Warning() { return Red(); }
const char *Origin() { return Magenta(); }
const char *Name() { return Green(); }
Printf(
" %sUninitialized value was created by an allocation of '%s%s%s'"
" in the stack frame of function '%s%s%s'%s\n",
- d.Origin(), d.Name(), s, d.Origin(), d.Name(),
- Symbolizer::Get()->Demangle(sep + 1), d.Origin(), d.End());
+ d.Origin(), d.Name(), s, d.Origin(), d.Name(), sep + 1, d.Origin(),
+ d.End());
InternalFree(s);
if (pc) {
// For some reason function address in LLVM IR is 1 less then the address
// of the first instruction.
- pc += 1;
- StackTrace::PrintStack(&pc, 1);
+ pc = StackTrace::GetNextInstructionPc(pc);
+ StackTrace(&pc, 1).Print();
}
}
-static void DescribeOrigin(u32 origin) {
- VPrintf(1, " raw origin id: %d\n", origin);
- uptr pc;
- while (true) {
- if (const char *so = GetOriginDescrIfStack(origin, &pc)) {
- DescribeStackOrigin(so, pc);
- break;
- }
- Decorator d;
- uptr size = 0;
- const uptr *trace = StackDepotGet(origin, &size);
- CHECK_GT(size, 0);
- if (TRACE_IS_CHAINED(trace[size - 1])) {
- // Linked origin.
- // FIXME: copied? modified? passed through? observed?
- Printf(" %sUninitialized value was stored to memory at%s\n", d.Origin(),
- d.End());
- StackTrace::PrintStack(trace, size - 1);
- origin = TRACE_TO_CHAINED_ID(trace[size - 1]);
- } else {
- Printf(" %sUninitialized value was created by a heap allocation%s\n",
- d.Origin(), d.End());
- StackTrace::PrintStack(trace, size);
- break;
+static void DescribeOrigin(u32 id) {
+ VPrintf(1, " raw origin id: %d\n", id);
+ Decorator d;
+ Origin o = Origin::FromRawId(id);
+ while (o.isChainedOrigin()) {
+ StackTrace stack;
+ o = o.getNextChainedOrigin(&stack);
+ Printf(" %sUninitialized value was stored to memory at%s\n", d.Origin(),
+ d.End());
+ stack.Print();
+ }
+ if (o.isStackOrigin()) {
+ uptr pc;
+ const char *so = GetStackOriginDescr(o.getStackId(), &pc);
+ DescribeStackOrigin(so, pc);
+ } else {
+ StackTrace stack = o.getStackTraceForHeapOrigin();
+ switch (stack.tag) {
+ case StackTrace::TAG_ALLOC:
+ Printf(" %sUninitialized value was created by a heap allocation%s\n",
+ d.Origin(), d.End());
+ break;
+ case StackTrace::TAG_DEALLOC:
+ Printf(" %sUninitialized value was created by a heap deallocation%s\n",
+ d.Origin(), d.End());
+ break;
+ case STACK_TRACE_TAG_POISON:
+ Printf(" %sMemory was marked as uninitialized%s\n", d.Origin(),
+ d.End());
+ break;
+ default:
+ Printf(" %sUninitialized value was created%s\n", d.Origin(), d.End());
+ break;
}
+ stack.Print();
}
}
Decorator d;
Printf("%s", d.Warning());
- Report(" WARNING: MemorySanitizer: use-of-uninitialized-value\n");
+ Report("WARNING: MemorySanitizer: use-of-uninitialized-value\n");
Printf("%s", d.End());
stack->Print();
if (origin) {
void ReportExpectedUMRNotFound(StackTrace *stack) {
SpinMutexLock l(&CommonSanitizerReportMutex);
- Printf(" WARNING: Expected use of uninitialized value not found\n");
+ Printf("WARNING: Expected use of uninitialized value not found\n");
stack->Print();
}
+void ReportStats() {
+ SpinMutexLock l(&CommonSanitizerReportMutex);
+
+ if (__msan_get_track_origins() > 0) {
+ StackDepotStats *stack_depot_stats = StackDepotGetStats();
+ // FIXME: we want this at normal exit, too!
+ // FIXME: but only with verbosity=1 or something
+ Printf("Unique heap origins: %zu\n", stack_depot_stats->n_uniq_ids);
+ Printf("Stack depot allocated bytes: %zu\n", stack_depot_stats->allocated);
+
+ StackDepotStats *chained_origin_depot_stats = ChainedOriginDepotGetStats();
+ Printf("Unique origin histories: %zu\n",
+ chained_origin_depot_stats->n_uniq_ids);
+ Printf("History depot allocated bytes: %zu\n",
+ chained_origin_depot_stats->allocated);
+ }
+}
+
void ReportAtExitStatistics() {
SpinMutexLock l(&CommonSanitizerReportMutex);
Printf("MemorySanitizer: %d warnings reported.\n", msan_report_count);
Printf("%s", d.End());
}
-
- StackDepotStats *stack_depot_stats = StackDepotGetStats();
- // FIXME: we want this at normal exit, too!
- // FIXME: but only with verbosity=1 or something
- Printf("Unique heap origins: %zu\n", stack_depot_stats->n_uniq_ids);
- Printf("Stack depot mapped bytes: %zu\n", stack_depot_stats->mapped);
}
class OriginSet {
} else {
unsigned char v = *(unsigned char *)s;
if (v) last_quad_poisoned = true;
- Printf("%02x", v);
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ Printf("%x%x", v & 0xf, v >> 4);
+#else
+ Printf("%x%x", v >> 4, v & 0xf);
+#endif
}
// Group end.
if (pos % 4 == 3 && with_origins) {
}
}
+void ReportUMRInsideAddressRange(const char *what, const void *start, uptr size,
+ uptr offset) {
+ Decorator d;
+ Printf("%s", d.Warning());
+ Printf("%sUninitialized bytes in %s%s%s at offset %zu inside [%p, %zu)%s\n",
+ d.Warning(), d.Name(), what, d.Warning(), offset, start, size,
+ d.End());
+ if (__sanitizer::Verbosity())
+ DescribeMemoryRange(start, size);
+}
+
} // namespace __msan