xref: /llvm-project/compiler-rt/test/dfsan/stack_trace.c (revision df9400c579df37e25dc48162ebde7583fe943952)
1 // RUN: %clang_dfsan -gmlt %s -o %t && %run %t >%t.out 2>&1
2 // RUN: FileCheck %s < %t.out
3 
4 #include <assert.h>
5 #include <sanitizer/dfsan_interface.h>
6 #include <stdio.h>
7 #include <string.h>
8 
9 #define NOINLINE __attribute__((noinline))
10 
bar(int depth,char * buf,size_t len)11 NOINLINE size_t bar(int depth, char *buf, size_t len) {
12   if (!depth) {
13     return dfsan_sprint_stack_trace(buf, len);
14   }
15 
16   return bar(depth - 1, buf, len);
17 }
18 
baz(int depth,char * buf,size_t len)19 NOINLINE size_t baz(int depth, char *buf, size_t len) {
20   return bar(depth, buf, len);
21 }
22 
main(int argc,char * argv[])23 int main(int argc, char *argv[]) {
24   char buf[3000];
25   size_t length = dfsan_sprint_stack_trace(buf, sizeof(buf));
26   assert(length < sizeof(buf));
27   printf("==OUTPUT==\n%s==EOS==\n", buf);
28 
29   // CHECK: ==OUTPUT==
30   // CHECK: #0 {{.*}} in main [[FILEPATH:.*]]/stack_trace.c:[[# @LINE - 5 ]]
31   // CHECK: ==EOS==
32 
33   length = baz(8, buf, sizeof(buf));
34   printf("==OUTPUT==\n%s==EOS==\n", buf);
35 
36   // CHECK: ==OUTPUT==
37   // CHECK: #0 {{.*}} in bar.dfsan [[FILEPATH]]/stack_trace.c:13
38   // CHECK-COUNT-8: #{{[1-9]+}} {{.*}} in bar.dfsan [[FILEPATH]]/stack_trace.c:16
39   // CHECK: #9 {{.*}} in baz.dfsan [[FILEPATH]]/stack_trace.c:20
40   // CHECK: #10 {{.*}} in main [[FILEPATH]]/stack_trace.c:[[# @LINE - 7 ]]
41   // CHECK: ==EOS==
42 
43   char tinybuf[8];
44   size_t same_length = baz(8, tinybuf, sizeof(tinybuf));
45 
46   printf("==TRUNCATED OUTPUT==\n%s==EOS==\n", tinybuf);
47   // CHECK: ==TRUNCATED OUTPUT==
48   // CHECK:     #0 ==EOS==
49 
50   printf("Returned length: %zu\n", length);
51   printf("Actual length: %zu\n", strlen(buf));
52   printf("Returned length with truncation: %zu\n", same_length);
53 
54   // CHECK: Returned length: [[#LEN:]]
55   // CHECK: Actual length: [[#LEN]]
56   // CHECK: Returned length with truncation: [[#LEN]]
57 
58   buf[0] = '\0';
59   length = baz(8, buf, 0);
60   printf("Output=\"%s\"\n", buf);
61   printf("Returned length: %zu\n", length);
62   // CHECK: Output=""
63   // CHECK: Returned length: [[#LEN]]
64 }
65