Index: lib/ubsan/ubsan_handlers_cxx.cc =================================================================== --- lib/ubsan/ubsan_handlers_cxx.cc +++ lib/ubsan/ubsan_handlers_cxx.cc @@ -18,6 +18,8 @@ #include "ubsan_type_hash.h" #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_stacktrace.h" +#include "sanitizer_common/sanitizer_symbolizer.h" using namespace __sanitizer; using namespace __ubsan; @@ -26,9 +28,33 @@ extern const char *TypeCheckKinds[]; } +#define MAX_STACK_DUMP_DEPTH 50 + +int ubsan_vptr_inited = 0; + +static void DumpCurrentCallStack() { + StackTrace stack; + stack.Unwind(MAX_STACK_DUMP_DEPTH, GET_CALLER_PC(), GET_CURRENT_FRAME(), 0, 0, 0, false); + stack.Print(); +} + +static void ubsan_vptr_init() { + // Initialize symbolizer with an empty string to avoid aggressive online symbolizations. + Symbolizer::Init(); + + // FIXME: ubsan_vptr_init() is not thread safe. + ubsan_vptr_inited = 1; +} + static void HandleDynamicTypeCacheMiss( DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash, bool Abort) { + + // Proactively trying to initialize since UBsan does not interpose any + // starting functions. + if (ubsan_vptr_inited == 0) + ubsan_vptr_init(); + if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash)) // Just a cache miss. The type matches after all. return; @@ -60,6 +86,8 @@ << MangledName(DTI.getSubobjectTypeName()) << Range(Pointer, Pointer + sizeof(uptr), "vptr for %2 base class of %1"); + DumpCurrentCallStack(); + if (Abort) Die(); }