6
6
# define HAS_EXECINFO_H
7
7
#endif
8
8
9
+ #if defined(SENTRY_PLATFORM_MACOS ) && defined(MAC_OS_X_VERSION_10_6 )
10
+ # define HAS_LIBUNWIND
11
+ #endif
12
+
9
13
#ifdef HAS_EXECINFO_H
10
14
# include <execinfo.h>
11
15
#endif
12
16
17
+ #ifdef HAS_LIBUNWIND
18
+ # include <libunwind.h>
19
+
20
+ #define ARRAY_SIZE (a ) sizeof(a)/sizeof(a[0])
21
+
22
+ static size_t sentry__unwind_stack_libbacktrace_libnuwind (const sentry_ucontext_t * uctx , void * * ptrs , size_t max_frames )
23
+ {
24
+ unw_context_t ctx ;
25
+ if (unw_getcontext (& ctx ))
26
+ return 0 ;
27
+
28
+ unw_cursor_t cursor ;
29
+ if (unw_init_local (& cursor , & ctx ))
30
+ return 0 ;
31
+
32
+ #if defined(__x86_64__ )
33
+ if (unw_set_reg (& cursor , UNW_X86_64_RAX , uctx -> user_context -> uc_mcontext -> __ss .__rax ) ||
34
+ unw_set_reg (& cursor , UNW_X86_64_RDX , uctx -> user_context -> uc_mcontext -> __ss .__rdx ) ||
35
+ unw_set_reg (& cursor , UNW_X86_64_RCX , uctx -> user_context -> uc_mcontext -> __ss .__rcx ) ||
36
+ unw_set_reg (& cursor , UNW_X86_64_RBX , uctx -> user_context -> uc_mcontext -> __ss .__rbx ) ||
37
+ unw_set_reg (& cursor , UNW_X86_64_RSI , uctx -> user_context -> uc_mcontext -> __ss .__rsi ) ||
38
+ unw_set_reg (& cursor , UNW_X86_64_RDI , uctx -> user_context -> uc_mcontext -> __ss .__rdi ) ||
39
+ unw_set_reg (& cursor , UNW_X86_64_RBP , uctx -> user_context -> uc_mcontext -> __ss .__rbp ) ||
40
+ unw_set_reg (& cursor , UNW_X86_64_RSP , uctx -> user_context -> uc_mcontext -> __ss .__rsp ) ||
41
+ unw_set_reg (& cursor , UNW_X86_64_R8 , uctx -> user_context -> uc_mcontext -> __ss .__r8 ) ||
42
+ unw_set_reg (& cursor , UNW_X86_64_R9 , uctx -> user_context -> uc_mcontext -> __ss .__r9 ) ||
43
+ unw_set_reg (& cursor , UNW_X86_64_R10 , uctx -> user_context -> uc_mcontext -> __ss .__r10 ) ||
44
+ unw_set_reg (& cursor , UNW_X86_64_R11 , uctx -> user_context -> uc_mcontext -> __ss .__r11 ) ||
45
+ unw_set_reg (& cursor , UNW_X86_64_R12 , uctx -> user_context -> uc_mcontext -> __ss .__r12 ) ||
46
+ unw_set_reg (& cursor , UNW_X86_64_R13 , uctx -> user_context -> uc_mcontext -> __ss .__r13 ) ||
47
+ unw_set_reg (& cursor , UNW_X86_64_R14 , uctx -> user_context -> uc_mcontext -> __ss .__r14 ) ||
48
+ unw_set_reg (& cursor , UNW_X86_64_R15 , uctx -> user_context -> uc_mcontext -> __ss .__r15 ) ||
49
+ unw_set_reg (& cursor , UNW_REG_IP , uctx -> user_context -> uc_mcontext -> __ss .__rip )
50
+ )
51
+ return 0 ;
52
+
53
+ #elif defined(__arm64__ )
54
+ for (size_t i = 0 ; i < ARRAY_SIZE (uctx -> user_context -> uc_mcontext -> __ss .__x ); ++ i )
55
+ {
56
+ if (unw_set_reg (& cursor , UNW_AARCH64_X0 + i , uctx -> user_context -> uc_mcontext -> __ss .__x [i ]))
57
+ {
58
+ return 0 ;
59
+ }
60
+ }
61
+
62
+ if (unw_set_reg (& cursor , UNW_AARCH64_FP , uctx -> user_context -> uc_mcontext -> __ss .__fp ) ||
63
+ unw_set_reg (& cursor , UNW_AARCH64_LR , uctx -> user_context -> uc_mcontext -> __ss .__lr ) ||
64
+ unw_set_reg (& cursor , UNW_AARCH64_SP , uctx -> user_context -> uc_mcontext -> __ss .__sp ) ||
65
+ unw_set_reg (& cursor , UNW_REG_IP , uctx -> user_context -> uc_mcontext -> __ss .__pc )
66
+ )
67
+ return 0 ;
68
+
69
+ #endif
70
+
71
+ size_t n = 0 ;
72
+ for (int err = 1 ; err >= 0 && n < max_frames ; err = unw_step (& cursor ))
73
+ {
74
+ unw_word_t ip ;
75
+ if (unw_get_reg (& cursor , UNW_REG_IP , & ip ))
76
+ {
77
+ break ;
78
+ }
79
+
80
+ #if defined(__arm64__ )
81
+ // Strip pointer authentication, for some reason ptrauth_strip() not working
82
+ // https://developer.apple.com/documentation/security/preparing_your_app_to_work_with_pointer_authentication
83
+ ip &= 0x7fffffffffffull ;
84
+ #endif
85
+
86
+ ptrs [n ++ ] = (void * )ip ;
87
+
88
+ // last frame
89
+ if (err == 0 )
90
+ {
91
+ break ;
92
+ }
93
+ }
94
+
95
+ return n ;
96
+ }
97
+ #endif
98
+
99
+
13
100
size_t
14
101
sentry__unwind_stack_libbacktrace (
15
102
void * addr , const sentry_ucontext_t * uctx , void * * ptrs , size_t max_frames )
@@ -23,7 +110,11 @@ sentry__unwind_stack_libbacktrace(
23
110
#endif
24
111
return 0 ;
25
112
} else if (uctx ) {
113
+ #ifdef HAS_LIBUNWIND
114
+ return sentry__unwind_stack_libbacktrace_libnuwind (uctx , ptrs , max_frames );
115
+ #else
26
116
return 0 ;
117
+ #endif
27
118
}
28
119
#ifdef HAS_EXECINFO_H
29
120
return (size_t )backtrace (ptrs , (int )max_frames );
0 commit comments