1 //===-- ubsan_monitor.cc ----------------------------------------*- C++ -*-===// 2 // 3 // This file is distributed under the University of Illinois Open Source 4 // License. See LICENSE.TXT for details. 5 // 6 //===----------------------------------------------------------------------===// 7 // 8 // Hooks which allow a monitor process to inspect UBSan's diagnostics. 9 // 10 //===----------------------------------------------------------------------===// 11 12 #include "ubsan_monitor.h" 13 14 using namespace __ubsan; 15 16 UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind, 17 Location &Loc, 18 InternalScopedString &Msg) 19 : IssueKind(IssueKind), Loc(Loc), Buffer(Msg.length() + 1) { 20 // We have the common sanitizer reporting lock, so it's safe to register a 21 // new UB report. 22 RegisterUndefinedBehaviorReport(this); 23 24 // Make a copy of the diagnostic. 25 Buffer.append("%s", Msg.data()); 26 27 // Let the monitor know that a report is available. 28 __ubsan_on_report(); 29 } 30 31 static UndefinedBehaviorReport *CurrentUBR; 32 33 void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) { 34 CurrentUBR = UBR; 35 } 36 37 SANITIZER_WEAK_DEFAULT_IMPL 38 void __ubsan::__ubsan_on_report(void) {} 39 40 void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind, 41 const char **OutMessage, 42 const char **OutFilename, 43 unsigned *OutLine, 44 unsigned *OutCol, 45 char **OutMemoryAddr) { 46 if (!OutIssueKind || !OutMessage || !OutFilename || !OutLine || !OutCol || 47 !OutMemoryAddr) 48 UNREACHABLE("Invalid arguments passed to __ubsan_get_current_report_data"); 49 50 InternalScopedString &Buf = CurrentUBR->Buffer; 51 52 // Ensure that the first character of the diagnostic text can't start with a 53 // lowercase letter. 54 char FirstChar = Buf.data()[0]; 55 if (FirstChar >= 'a' && FirstChar <= 'z') 56 Buf.data()[0] = FirstChar - 'a' + 'A'; 57 58 *OutIssueKind = CurrentUBR->IssueKind; 59 *OutMessage = Buf.data(); 60 if (!CurrentUBR->Loc.isSourceLocation()) { 61 *OutFilename = "<unknown>"; 62 *OutLine = *OutCol = 0; 63 } else { 64 SourceLocation SL = CurrentUBR->Loc.getSourceLocation(); 65 *OutFilename = SL.getFilename(); 66 *OutLine = SL.getLine(); 67 *OutCol = SL.getColumn(); 68 } 69 70 if (CurrentUBR->Loc.isMemoryLocation()) 71 *OutMemoryAddr = (char *)CurrentUBR->Loc.getMemoryLocation(); 72 else 73 *OutMemoryAddr = nullptr; 74 } 75