llvm-project

Форк
0
/
sanitizer_unwind_win.cpp 
93 строки · 3.0 Кб
1
//===-- sanitizer_unwind_win.cpp ------------------------------------------===//
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
/// Sanitizer unwind Windows specific functions.
10
//
11
//===----------------------------------------------------------------------===//
12

13
#include "sanitizer_platform.h"
14
#if SANITIZER_WINDOWS
15

16
#define WIN32_LEAN_AND_MEAN
17
#define NOGDI
18
#include <windows.h>
19

20
#include "sanitizer_dbghelp.h"  // for StackWalk64
21
#include "sanitizer_stacktrace.h"
22
#include "sanitizer_symbolizer.h"  // for InitializeDbgHelpIfNeeded
23

24
using namespace __sanitizer;
25

26
#if !SANITIZER_GO
27
void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
28
  CHECK_GE(max_depth, 2);
29
  // FIXME: CaptureStackBackTrace might be too slow for us.
30
  // FIXME: Compare with StackWalk64.
31
  // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc
32
  size = CaptureStackBackTrace(1, Min(max_depth, kStackTraceMax),
33
    (void **)&trace_buffer[0], 0);
34
  if (size == 0)
35
    return;
36

37
  // Skip the RTL frames by searching for the PC in the stacktrace.
38
  uptr pc_location = LocatePcInTrace(pc);
39
  PopStackFrames(pc_location);
40

41
  // Replace the first frame with the PC because the frame in the
42
  // stacktrace might be incorrect.
43
  trace_buffer[0] = pc;
44
}
45

46
#ifdef __clang__
47
#pragma clang diagnostic push
48
#pragma clang diagnostic ignored "-Wframe-larger-than="
49
#endif
50
void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
51
  CHECK(context);
52
  CHECK_GE(max_depth, 2);
53
  CONTEXT ctx = *(CONTEXT *)context;
54
  STACKFRAME64 stack_frame;
55
  memset(&stack_frame, 0, sizeof(stack_frame));
56

57
  InitializeDbgHelpIfNeeded();
58

59
  size = 0;
60
#    if SANITIZER_WINDOWS64
61
#      if SANITIZER_ARM64
62
  int machine_type = IMAGE_FILE_MACHINE_ARM64;
63
  stack_frame.AddrPC.Offset = ctx.Pc;
64
  stack_frame.AddrFrame.Offset = ctx.Fp;
65
  stack_frame.AddrStack.Offset = ctx.Sp;
66
#      else
67
  int machine_type = IMAGE_FILE_MACHINE_AMD64;
68
  stack_frame.AddrPC.Offset = ctx.Rip;
69
  stack_frame.AddrFrame.Offset = ctx.Rbp;
70
  stack_frame.AddrStack.Offset = ctx.Rsp;
71
#      endif
72
#    else
73
  int machine_type = IMAGE_FILE_MACHINE_I386;
74
  stack_frame.AddrPC.Offset = ctx.Eip;
75
  stack_frame.AddrFrame.Offset = ctx.Ebp;
76
  stack_frame.AddrStack.Offset = ctx.Esp;
77
#    endif
78
  stack_frame.AddrPC.Mode = AddrModeFlat;
79
  stack_frame.AddrFrame.Mode = AddrModeFlat;
80
  stack_frame.AddrStack.Mode = AddrModeFlat;
81
  while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(),
82
                     &stack_frame, &ctx, NULL, SymFunctionTableAccess64,
83
                     SymGetModuleBase64, NULL) &&
84
         size < Min(max_depth, kStackTraceMax)) {
85
    trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset;
86
  }
87
}
88
#    ifdef __clang__
89
#      pragma clang diagnostic pop
90
#    endif
91
#  endif  // #if !SANITIZER_GO
92

93
#endif  // SANITIZER_WINDOWS
94

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.