ubsan_monitor.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. //===-- ubsan_monitor.cpp ---------------------------------------*- 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. // Hooks which allow a monitor process to inspect UBSan's diagnostics.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "ubsan_monitor.h"
  13. using namespace __ubsan;
  14. UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind,
  15. Location &Loc,
  16. InternalScopedString &Msg)
  17. : IssueKind(IssueKind), Loc(Loc) {
  18. // We have the common sanitizer reporting lock, so it's safe to register a
  19. // new UB report.
  20. RegisterUndefinedBehaviorReport(this);
  21. // Make a copy of the diagnostic.
  22. if (Msg.length())
  23. Buffer.Append(Msg.data());
  24. // Let the monitor know that a report is available.
  25. __ubsan_on_report();
  26. }
  27. static UndefinedBehaviorReport *CurrentUBR;
  28. void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) {
  29. CurrentUBR = UBR;
  30. }
  31. SANITIZER_WEAK_DEFAULT_IMPL
  32. void __ubsan::__ubsan_on_report(void) {}
  33. void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind,
  34. const char **OutMessage,
  35. const char **OutFilename,
  36. unsigned *OutLine,
  37. unsigned *OutCol,
  38. char **OutMemoryAddr) {
  39. if (!OutIssueKind || !OutMessage || !OutFilename || !OutLine || !OutCol ||
  40. !OutMemoryAddr)
  41. UNREACHABLE("Invalid arguments passed to __ubsan_get_current_report_data");
  42. InternalScopedString &Buf = CurrentUBR->Buffer;
  43. // Ensure that the first character of the diagnostic text can't start with a
  44. // lowercase letter.
  45. char FirstChar = *Buf.data();
  46. if (FirstChar >= 'a' && FirstChar <= 'z')
  47. *Buf.data() += 'A' - 'a';
  48. *OutIssueKind = CurrentUBR->IssueKind;
  49. *OutMessage = Buf.data();
  50. if (!CurrentUBR->Loc.isSourceLocation()) {
  51. *OutFilename = "<unknown>";
  52. *OutLine = *OutCol = 0;
  53. } else {
  54. SourceLocation SL = CurrentUBR->Loc.getSourceLocation();
  55. *OutFilename = SL.getFilename();
  56. *OutLine = SL.getLine();
  57. *OutCol = SL.getColumn();
  58. }
  59. if (CurrentUBR->Loc.isMemoryLocation())
  60. *OutMemoryAddr = (char *)CurrentUBR->Loc.getMemoryLocation();
  61. else
  62. *OutMemoryAddr = nullptr;
  63. }