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
11NOINLINE size_t bar(int depth, char *buf, size_t len) {
12 if (!depth) {
13 return dfsan_sprint_stack_trace(out_buf: buf, out_buf_size: len);
14 }
15
16 return bar(depth: depth - 1, buf, len);
17}
18
19NOINLINE size_t baz(int depth, char *buf, size_t len) {
20 return bar(depth, buf, len);
21}
22
23int main(int argc, char *argv[]) {
24 char buf[3000];
25 size_t length = dfsan_sprint_stack_trace(out_buf: buf, out_buf_size: sizeof(buf));
26 assert(length < sizeof(buf));
27 printf(format: "==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(depth: 8, buf, len: sizeof(buf));
34 printf(format: "==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(depth: 8, buf: tinybuf, len: sizeof(tinybuf));
45
46 printf(format: "==TRUNCATED OUTPUT==\n%s==EOS==\n", tinybuf);
47 // CHECK: ==TRUNCATED OUTPUT==
48 // CHECK: #0 ==EOS==
49
50 printf(format: "Returned length: %zu\n", length);
51 printf(format: "Actual length: %zu\n", strlen(s: buf));
52 printf(format: "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(depth: 8, buf, len: 0);
60 printf(format: "Output=\"%s\"\n", buf);
61 printf(format: "Returned length: %zu\n", length);
62 // CHECK: Output=""
63 // CHECK: Returned length: [[#LEN]]
64}
65

source code of compiler-rt/test/dfsan/stack_trace.c