16ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===-- ubsan_diag.cc -----------------------------------------------------===// 26ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 36ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// The LLVM Compiler Infrastructure 46ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 56ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// This file is distributed under the University of Illinois Open Source 66ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// License. See LICENSE.TXT for details. 76ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 86ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===----------------------------------------------------------------------===// 96ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 106ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// Diagnostic reporting for the UBSan runtime. 116ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 126ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===----------------------------------------------------------------------===// 136ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 146ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "ubsan_diag.h" 15f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith#include "sanitizer_common/sanitizer_common.h" 16f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith#include "sanitizer_common/sanitizer_libc.h" 178f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov#include "sanitizer_common/sanitizer_report_decorator.h" 185f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith#include "sanitizer_common/sanitizer_stacktrace.h" 195f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith#include "sanitizer_common/sanitizer_symbolizer.h" 206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include <stdio.h> 216ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 226ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithusing namespace __ubsan; 236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 245f1164955fb28a9bcb826abc195aa2119feb0f97Richard SmithLocation __ubsan::getCallerLocation(uptr CallerLoc) { 255f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith if (!CallerLoc) 265f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith return Location(); 275f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 28d2f08ffcb97726452f4ba11c199a1e06dc2a7e54Alexey Samsonov uptr Loc = StackTrace::GetPreviousInstructionPc(CallerLoc); 295f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 305f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith AddressInfo Info; 31d2f08ffcb97726452f4ba11c199a1e06dc2a7e54Alexey Samsonov if (!SymbolizeCode(Loc, &Info, 1) || !Info.module || !*Info.module) 32d2f08ffcb97726452f4ba11c199a1e06dc2a7e54Alexey Samsonov return Location(Loc); 335f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 347ed46ff7af911da0dd2067734d1408c6986c6657Alexey Samsonov if (!Info.file) 355f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith return ModuleLocation(Info.module, Info.module_offset); 365f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 375f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith return SourceLocation(Info.file, Info.line, Info.column); 385f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith} 395f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 406ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard SmithDiag &Diag::operator<<(const TypeDescriptor &V) { 416ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return AddArg(V.getTypeName()); 426ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 436ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 446ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard SmithDiag &Diag::operator<<(const Value &V) { 456ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (V.getType().isSignedIntegerTy()) 466ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith AddArg(V.getSIntValue()); 476ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else if (V.getType().isUnsignedIntegerTy()) 486ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith AddArg(V.getUIntValue()); 4958561700a4abad310911a24a867da49a14fae91eRichard Smith else if (V.getType().isFloatTy()) 5058561700a4abad310911a24a867da49a14fae91eRichard Smith AddArg(V.getFloatValue()); 516ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 526ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith AddArg("<unknown>"); 536ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return *this; 546ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 556ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 560ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith/// Hexadecimal printing for numbers too large for Printf to handle directly. 576ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithstatic void PrintHex(UIntMax Val) { 58ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#if HAVE_INT128_T 59f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Printf("0x%08x%08x%08x%08x", 606ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith (unsigned int)(Val >> 96), 616ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith (unsigned int)(Val >> 64), 626ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith (unsigned int)(Val >> 32), 636ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith (unsigned int)(Val)); 646ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#else 656ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith UNREACHABLE("long long smaller than 64 bits?"); 666ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#endif 676ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 686ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 695f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smithstatic void renderLocation(Location Loc) { 705f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith switch (Loc.getKind()) { 715f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith case Location::LK_Source: { 725f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith SourceLocation SLoc = Loc.getSourceLocation(); 735f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith if (SLoc.isInvalid()) 748f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("<unknown>:"); 755f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith else { 765f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith Printf("%s:%d:", SLoc.getFilename(), SLoc.getLine()); 775f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith if (SLoc.getColumn()) 785f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith Printf("%d:", SLoc.getColumn()); 795f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith } 805f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith break; 815f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith } 825f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith case Location::LK_Module: 835f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith Printf("%s:0x%zx:", Loc.getModuleLocation().getModuleName(), 845f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith Loc.getModuleLocation().getOffset()); 855f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith break; 865f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith case Location::LK_Memory: 87c193953bf3993760a0be8ae20cf716795d2102cdRichard Smith Printf("%p:", Loc.getMemoryLocation()); 885f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith break; 895f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith case Location::LK_Null: 908f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("<unknown>:"); 9125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith break; 925f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith } 935f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith} 945f1164955fb28a9bcb826abc195aa2119feb0f97Richard Smith 9525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smithstatic void renderText(const char *Message, const Diag::Arg *Args) { 966ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith for (const char *Msg = Message; *Msg; ++Msg) { 97f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith if (*Msg != '%') { 98f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith char Buffer[64]; 99f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith unsigned I; 100f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith for (I = 0; Msg[I] && Msg[I] != '%' && I != 63; ++I) 101f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Buffer[I] = Msg[I]; 102f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Buffer[I] = '\0'; 1038f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf(Buffer); 104f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Msg += I - 1; 105f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith } else { 10625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith const Diag::Arg &A = Args[*++Msg - '0']; 1076ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith switch (A.Kind) { 10825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith case Diag::AK_String: 109f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Printf("%s", A.String); 1106ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith break; 1110ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith case Diag::AK_Mangled: { 1128f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("'%s'", Demangle(A.String)); 1130ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith break; 1140ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith } 11525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith case Diag::AK_SInt: 1166ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith // 'long long' is guaranteed to be at least 64 bits wide. 1176ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (A.SInt >= INT64_MIN && A.SInt <= INT64_MAX) 118f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Printf("%lld", (long long)A.SInt); 1196ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 1206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith PrintHex(A.SInt); 1216ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith break; 12225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith case Diag::AK_UInt: 1236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith if (A.UInt <= UINT64_MAX) 124f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Printf("%llu", (unsigned long long)A.UInt); 1256ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith else 1266ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith PrintHex(A.UInt); 1276ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith break; 12825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith case Diag::AK_Float: { 129f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith // FIXME: Support floating-point formatting in sanitizer_common's 130f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith // printf, and stop using snprintf here. 131f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith char Buffer[32]; 132f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith snprintf(Buffer, sizeof(Buffer), "%Lg", (long double)A.Float); 133f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith Printf("%s", Buffer); 13458561700a4abad310911a24a867da49a14fae91eRichard Smith break; 135f4932204d7cf89cc2402b1e30fb728cf84ff7b7fRichard Smith } 13625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith case Diag::AK_Pointer: 137c193953bf3993760a0be8ae20cf716795d2102cdRichard Smith Printf("%p", A.Pointer); 1386ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith break; 1396ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1406ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1416ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 14225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith} 14325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 14425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith/// Find the earliest-starting range in Ranges which ends after Loc. 14525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smithstatic Range *upperBound(MemoryLocation Loc, Range *Ranges, 14625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith unsigned NumRanges) { 14725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Range *Best = 0; 14825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith for (unsigned I = 0; I != NumRanges; ++I) 14925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (Ranges[I].getEnd().getMemoryLocation() > Loc && 15025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith (!Best || 15125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Best->getStart().getMemoryLocation() > 15225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Ranges[I].getStart().getMemoryLocation())) 15325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Best = &Ranges[I]; 15425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith return Best; 15525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith} 15625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 15725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith/// Render a snippet of the address space near a location. 1588f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonovstatic void renderMemorySnippet(const __sanitizer::AnsiColorDecorator &Decor, 1598f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov MemoryLocation Loc, 16025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Range *Ranges, unsigned NumRanges, 16125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith const Diag::Arg *Args) { 16225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith const unsigned BytesToShow = 32; 16325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith const unsigned MinBytesNearLoc = 4; 16425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 16525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // Show at least the 8 bytes surrounding Loc. 16625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith MemoryLocation Min = Loc - MinBytesNearLoc, Max = Loc + MinBytesNearLoc; 16725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith for (unsigned I = 0; I < NumRanges; ++I) { 16825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Min = __sanitizer::Min(Ranges[I].getStart().getMemoryLocation(), Min); 16925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Max = __sanitizer::Max(Ranges[I].getEnd().getMemoryLocation(), Max); 17025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith } 17125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 17225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // If we have too many interesting bytes, prefer to show bytes after Loc. 17325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (Max - Min > BytesToShow) 17425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Min = __sanitizer::Min(Max - BytesToShow, Loc - MinBytesNearLoc); 17525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Max = Min + BytesToShow; 17625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 17725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // Emit data. 17825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith for (uptr P = Min; P != Max; ++P) { 17925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // FIXME: Check that the address is readable before printing it. 18025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith unsigned char C = *reinterpret_cast<const unsigned char*>(P); 18125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Printf("%s%02x", (P % 8 == 0) ? " " : " ", C); 18225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith } 1838f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("\n"); 18425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 18525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // Emit highlights. 1868f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf(Decor.Green()); 18725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Range *InRange = upperBound(Min, Ranges, NumRanges); 18825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith for (uptr P = Min; P != Max; ++P) { 18925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith char Pad = ' ', Byte = ' '; 19025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (InRange && InRange->getEnd().getMemoryLocation() == P) 19125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith InRange = upperBound(P, Ranges, NumRanges); 19225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (!InRange && P > Loc) 19325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith break; 19425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (InRange && InRange->getStart().getMemoryLocation() < P) 19525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Pad = '~'; 19625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (InRange && InRange->getStart().getMemoryLocation() <= P) 19725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Byte = '~'; 19825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith char Buffer[] = { Pad, Pad, P == Loc ? '^' : Byte, Byte, 0 }; 1998f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf((P % 8 == 0) ? Buffer : &Buffer[1]); 20025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith } 2018f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("%s\n", Decor.Default()); 20225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 20325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // Go over the line again, and print names for the ranges. 20425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith InRange = 0; 20525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith unsigned Spaces = 0; 20625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith for (uptr P = Min; P != Max; ++P) { 20725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (!InRange || InRange->getEnd().getMemoryLocation() == P) 20825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith InRange = upperBound(P, Ranges, NumRanges); 20925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (!InRange) 21025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith break; 21125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 21225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Spaces += (P % 8) == 0 ? 2 : 1; 21325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 21425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (InRange && InRange->getStart().getMemoryLocation() == P) { 21525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith while (Spaces--) 2168f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf(" "); 21725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith renderText(InRange->getText(), Args); 2188f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("\n"); 21925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // FIXME: We only support naming one range for now! 22025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith break; 22125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith } 22225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 22325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith Spaces += 2; 22425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith } 22525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 22625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // FIXME: Print names for anything we can identify within the line: 22725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // 22825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // * If we can identify the memory itself as belonging to a particular 22925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // global, stack variable, or dynamic allocation, then do so. 23025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // 23125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // * If we have a pointer-size, pointer-aligned range highlighted, 23225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // determine whether the value of that range is a pointer to an 23325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // entity which we can name, and if so, print that name. 23425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // 23525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith // This needs an external symbolizer, or (preferably) ASan instrumentation. 23625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith} 23725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 23825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard SmithDiag::~Diag() { 2398f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov __sanitizer::AnsiColorDecorator Decor(PrintsToTty()); 2407ed46ff7af911da0dd2067734d1408c6986c6657Alexey Samsonov SpinMutexLock l(&CommonSanitizerReportMutex); 2418f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf(Decor.Bold()); 24225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 24325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith renderLocation(Loc); 24425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 24525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith switch (Level) { 24625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith case DL_Error: 2478f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("%s runtime error: %s%s", 2488f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Decor.Red(), Decor.Default(), Decor.Bold()); 24925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith break; 25025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 25125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith case DL_Note: 2528f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("%s note: %s", Decor.Black(), Decor.Default()); 25325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith break; 25425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith } 25525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 25625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith renderText(Message, Args); 25725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 2588f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov Printf("%s\n", Decor.Default()); 25925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith 26025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith if (Loc.isMemoryLocation()) 2618f72f7cae84494d9bd0676b4a499e0f895460744Alexey Samsonov renderMemorySnippet(Decor, Loc.getMemoryLocation(), Ranges, 262c242446f7a7c6a0c1f1bf9ad403d6dac6f215f1cRichard Smith NumRanges, Args); 2636ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} 264