ubsan_monitor.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. Buffer.append("%s", Msg.data());
  23. // Let the monitor know that a report is available.
  24. __ubsan_on_report();
  25. }
  26. static UndefinedBehaviorReport *CurrentUBR;
  27. void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) {
  28. CurrentUBR = UBR;
  29. }
  30. SANITIZER_WEAK_DEFAULT_IMPL
  31. void __ubsan::__ubsan_on_report(void) {}
  32. void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind,
  33. const char **OutMessage,
  34. const char **OutFilename,
  35. unsigned *OutLine,
  36. unsigned *OutCol,
  37. char **OutMemoryAddr) {
  38. if (!OutIssueKind || !OutMessage || !OutFilename || !OutLine || !OutCol ||
  39. !OutMemoryAddr)
  40. UNREACHABLE("Invalid arguments passed to __ubsan_get_current_report_data");
  41. InternalScopedString &Buf = CurrentUBR->Buffer;
  42. // Ensure that the first character of the diagnostic text can't start with a
  43. // lowercase letter.
  44. char FirstChar = *Buf.data();
  45. if (FirstChar >= 'a' && FirstChar <= 'z')
  46. *Buf.data() += 'A' - 'a';
  47. *OutIssueKind = CurrentUBR->IssueKind;
  48. *OutMessage = Buf.data();
  49. if (!CurrentUBR->Loc.isSourceLocation()) {
  50. *OutFilename = "<unknown>";
  51. *OutLine = *OutCol = 0;
  52. } else {
  53. SourceLocation SL = CurrentUBR->Loc.getSourceLocation();
  54. *OutFilename = SL.getFilename();
  55. *OutLine = SL.getLine();
  56. *OutCol = SL.getColumn();
  57. }
  58. if (CurrentUBR->Loc.isMemoryLocation())
  59. *OutMemoryAddr = (char *)CurrentUBR->Loc.getMemoryLocation();
  60. else
  61. *OutMemoryAddr = nullptr;
  62. }