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