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