1*cb055e51SLouis Dionne // TODO: Figure out why this fails with Memory Sanitizer.
2*cb055e51SLouis Dionne // XFAIL: msan
3*cb055e51SLouis Dionne 
47fab97f3SLogan Chien #include <assert.h>
57fab97f3SLogan Chien #include <stdlib.h>
67fab97f3SLogan Chien #include <unwind.h>
77fab97f3SLogan Chien 
87fab97f3SLogan Chien #define EXPECTED_NUM_FRAMES 50
97fab97f3SLogan Chien #define NUM_FRAMES_UPPER_BOUND 100
107fab97f3SLogan Chien 
117fab97f3SLogan Chien _Unwind_Reason_Code callback(_Unwind_Context *context, void *cnt) {
126e50d93aSJonathan Roelofs   (void)context;
137fab97f3SLogan Chien   int *i = (int *)cnt;
147fab97f3SLogan Chien   ++*i;
157fab97f3SLogan Chien   if (*i > NUM_FRAMES_UPPER_BOUND) {
167fab97f3SLogan Chien     abort();
177fab97f3SLogan Chien   }
187fab97f3SLogan Chien   return _URC_NO_REASON;
197fab97f3SLogan Chien }
207fab97f3SLogan Chien 
217fab97f3SLogan Chien void test_backtrace() {
227fab97f3SLogan Chien   int n = 0;
237fab97f3SLogan Chien   _Unwind_Backtrace(&callback, &n);
247fab97f3SLogan Chien   if (n < EXPECTED_NUM_FRAMES) {
257fab97f3SLogan Chien     abort();
267fab97f3SLogan Chien   }
277fab97f3SLogan Chien }
287fab97f3SLogan Chien 
297fab97f3SLogan Chien int test(int i) {
307fab97f3SLogan Chien   if (i == 0) {
317fab97f3SLogan Chien     test_backtrace();
327fab97f3SLogan Chien     return 0;
337fab97f3SLogan Chien   } else {
347fab97f3SLogan Chien     return i + test(i - 1);
357fab97f3SLogan Chien   }
367fab97f3SLogan Chien }
377fab97f3SLogan Chien 
38504bc07dSLouis Dionne int main(int, char**) {
397fab97f3SLogan Chien   int total = test(50);
407fab97f3SLogan Chien   assert(total == 1275);
41504bc07dSLouis Dionne   return 0;
427fab97f3SLogan Chien }
43