backtrace_linux_libc.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //===-- backtrace_linux_libc.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. #include <assert.h>
  9. #include <execinfo.h>
  10. #include <stddef.h>
  11. #include <stdint.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include "gwp_asan/definitions.h"
  15. #include "gwp_asan/optional/backtrace.h"
  16. #include "gwp_asan/optional/printf.h"
  17. #include "gwp_asan/options.h"
  18. namespace {
  19. size_t Backtrace(uintptr_t *TraceBuffer, size_t Size) {
  20. static_assert(sizeof(uintptr_t) == sizeof(void *), "uintptr_t is not void*");
  21. return backtrace(reinterpret_cast<void **>(TraceBuffer), Size);
  22. }
  23. // We don't need any custom handling for the Segv backtrace - the libc unwinder
  24. // has no problems with unwinding through a signal handler. Force inlining here
  25. // to avoid the additional frame.
  26. GWP_ASAN_ALWAYS_INLINE size_t SegvBacktrace(uintptr_t *TraceBuffer, size_t Size,
  27. void * /*Context*/) {
  28. return Backtrace(TraceBuffer, Size);
  29. }
  30. static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength,
  31. gwp_asan::Printf_t Printf) {
  32. if (TraceLength == 0) {
  33. Printf(" <not found (does your allocator support backtracing?)>\n\n");
  34. return;
  35. }
  36. char **BacktraceSymbols =
  37. backtrace_symbols(reinterpret_cast<void **>(Trace), TraceLength);
  38. for (size_t i = 0; i < TraceLength; ++i) {
  39. if (!BacktraceSymbols)
  40. Printf(" #%zu %p\n", i, Trace[i]);
  41. else
  42. Printf(" #%zu %s\n", i, BacktraceSymbols[i]);
  43. }
  44. Printf("\n");
  45. if (BacktraceSymbols)
  46. free(BacktraceSymbols);
  47. }
  48. } // anonymous namespace
  49. namespace gwp_asan {
  50. namespace backtrace {
  51. options::Backtrace_t getBacktraceFunction() { return Backtrace; }
  52. PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; }
  53. SegvBacktrace_t getSegvBacktraceFunction() { return SegvBacktrace; }
  54. } // namespace backtrace
  55. } // namespace gwp_asan