1 //===--- rtsan_diagnostics.cpp - Realtime Sanitizer -------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 //===----------------------------------------------------------------------===// 10 11 #include "rtsan/rtsan_diagnostics.h" 12 13 #include "sanitizer_common/sanitizer_flags.h" 14 #include "sanitizer_common/sanitizer_report_decorator.h" 15 #include "sanitizer_common/sanitizer_stacktrace.h" 16 17 using namespace __sanitizer; 18 using namespace __rtsan; 19 20 // We must define our own implementation of this method for our runtime. 21 // This one is just copied from UBSan. 22 namespace __sanitizer { 23 void BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, void *context, 24 bool request_fast, u32 max_depth) { 25 uptr top = 0; 26 uptr bottom = 0; 27 GetThreadStackTopAndBottom(false, &top, &bottom); 28 bool fast = StackTrace::WillUseFastUnwind(request_fast); 29 Unwind(max_depth, pc, bp, context, top, bottom, fast); 30 } 31 } // namespace __sanitizer 32 33 namespace { 34 class Decorator : public SanitizerCommonDecorator { 35 public: 36 Decorator() : SanitizerCommonDecorator() {} 37 const char *FunctionName() const { return Green(); } 38 const char *Reason() const { return Blue(); } 39 }; 40 } // namespace 41 42 static const char *GetErrorTypeStr(const DiagnosticsInfo &info) { 43 switch (info.type) { 44 case DiagnosticsInfoType::InterceptedCall: 45 return "unsafe-library-call"; 46 case DiagnosticsInfoType::BlockingCall: 47 return "blocking-call"; 48 } 49 CHECK(false); 50 return "(unknown error)"; 51 } 52 53 static void PrintError(const Decorator &decorator, 54 const DiagnosticsInfo &info) { 55 56 Printf("%s", decorator.Error()); 57 Report("ERROR: RealtimeSanitizer: %s\n", GetErrorTypeStr(info)); 58 } 59 60 static void PrintReason(const Decorator &decorator, 61 const DiagnosticsInfo &info) { 62 Printf("%s", decorator.Reason()); 63 64 switch (info.type) { 65 case DiagnosticsInfoType::InterceptedCall: { 66 Printf("Intercepted call to real-time unsafe function " 67 "`%s%s%s` in real-time context!", 68 decorator.FunctionName(), info.func_name, decorator.Reason()); 69 break; 70 } 71 case DiagnosticsInfoType::BlockingCall: { 72 Printf("Call to blocking function " 73 "`%s%s%s` in real-time context!", 74 decorator.FunctionName(), info.func_name, decorator.Reason()); 75 break; 76 } 77 } 78 79 Printf("\n"); 80 } 81 82 void __rtsan::PrintDiagnostics(const DiagnosticsInfo &info) { 83 ScopedErrorReportLock::CheckLocked(); 84 85 Decorator d; 86 PrintError(d, info); 87 PrintReason(d, info); 88 Printf("%s", d.Default()); 89 } 90 91 void __rtsan::PrintErrorSummary(const DiagnosticsInfo &info, 92 const BufferedStackTrace &stack) { 93 ScopedErrorReportLock::CheckLocked(); 94 ReportErrorSummary(GetErrorTypeStr(info), &stack); 95 } 96