blob: e5737450a568f581b3ca54580f38470dd9621738 [file] [log] [blame]
Louis Dionne10f4e4a2021-10-12 12:46:21 -04001// TODO: Investigate these failures on x86_64 macOS back deployment
2// UNSUPPORTED: target=x86_64-apple-darwin{{.+}}
Louis Dionne9915ba52021-09-30 15:11:48 -04003
Logan Chiena54f0962015-05-29 15:33:38 +00004#include <libunwind.h>
5#include <stdlib.h>
Vitaly Buka83f8edb2021-08-11 10:35:23 -07006#include <string.h>
Logan Chiena54f0962015-05-29 15:33:38 +00007
8void backtrace(int lower_bound) {
9 unw_context_t context;
10 unw_getcontext(&context);
11
12 unw_cursor_t cursor;
13 unw_init_local(&cursor, &context);
14
15 int n = 0;
16 do {
17 ++n;
18 if (n > 100) {
19 abort();
20 }
21 } while (unw_step(&cursor) > 0);
22
23 if (n < lower_bound) {
24 abort();
25 }
26}
27
28void test1(int i) {
29 backtrace(i);
30}
31
32void test2(int i, int j) {
33 backtrace(i);
34 test1(j);
35}
36
37void test3(int i, int j, int k) {
38 backtrace(i);
39 test2(j, k);
40}
41
Saleem Abdulrasool78b42cc2019-09-20 15:53:42 +000042void test_no_info() {
43 unw_context_t context;
44 unw_getcontext(&context);
45
46 unw_cursor_t cursor;
47 unw_init_local(&cursor, &context);
48
49 unw_proc_info_t info;
50 int ret = unw_get_proc_info(&cursor, &info);
51 if (ret != UNW_ESUCCESS)
52 abort();
53
54 // Set the IP to an address clearly outside any function.
John Brawn57be2d22019-10-03 17:01:04 +000055 unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)0);
Saleem Abdulrasool78b42cc2019-09-20 15:53:42 +000056
57 ret = unw_get_proc_info(&cursor, &info);
58 if (ret != UNW_ENOINFO)
59 abort();
60}
61
Vitaly Buka83f8edb2021-08-11 10:35:23 -070062void test_reg_names() {
63 unw_context_t context;
64 unw_getcontext(&context);
65
66 unw_cursor_t cursor;
67 unw_init_local(&cursor, &context);
68
69 int max_reg_num = -100;
70#if defined(__i386__)
71 max_reg_num = 7;
72#elif defined(__x86_64__)
73 max_reg_num = 32;
74#endif
75
76 const char prefix[] = "unknown";
77 for (int i = -2; i < max_reg_num; ++i) {
78 if (strncmp(prefix, unw_regname(&cursor, i), sizeof(prefix) - 1) == 0)
79 abort();
80 }
81
82 if (strncmp(prefix, unw_regname(&cursor, max_reg_num + 1),
83 sizeof(prefix) - 1) != 0)
84 abort();
85}
86
87#if defined(__x86_64__)
88void test_reg_get_set() {
89 unw_context_t context;
90 unw_getcontext(&context);
91
92 unw_cursor_t cursor;
93 unw_init_local(&cursor, &context);
94
95 for (int i = 0; i < 17; ++i) {
96 const unw_word_t set_value = 7;
97 if (unw_set_reg(&cursor, i, set_value) != UNW_ESUCCESS)
98 abort();
99
100 unw_word_t get_value = 0;
101 if (unw_get_reg(&cursor, i, &get_value) != UNW_ESUCCESS)
102 abort();
103
104 if (set_value != get_value)
105 abort();
106 }
107}
108
109void test_fpreg_get_set() {
110 unw_context_t context;
111 unw_getcontext(&context);
112
113 unw_cursor_t cursor;
114 unw_init_local(&cursor, &context);
115
116 // get/set is not implemented for x86_64 fpregs.
117 for (int i = 17; i < 33; ++i) {
118 const unw_fpreg_t set_value = 7;
119 if (unw_set_fpreg(&cursor, i, set_value) != UNW_EBADREG)
120 abort();
121
122 unw_fpreg_t get_value = 0;
123 if (unw_get_fpreg(&cursor, i, &get_value) != UNW_EBADREG)
124 abort();
125 }
126}
127#else
128void test_reg_get_set() {}
129void test_fpreg_get_set() {}
130#endif
131
Louis Dionnecbfe0172020-10-08 13:36:33 -0400132int main(int, char**) {
Logan Chiena54f0962015-05-29 15:33:38 +0000133 test1(1);
134 test2(1, 2);
135 test3(1, 2, 3);
Saleem Abdulrasool78b42cc2019-09-20 15:53:42 +0000136 test_no_info();
Vitaly Buka83f8edb2021-08-11 10:35:23 -0700137 test_reg_names();
138 test_reg_get_set();
139 test_fpreg_get_set();
Louis Dionnecbfe0172020-10-08 13:36:33 -0400140 return 0;
Logan Chiena54f0962015-05-29 15:33:38 +0000141}