xref: /llvm-project/compiler-rt/test/dfsan/stack_trace.c (revision df9400c579df37e25dc48162ebde7583fe943952)
198504959SGeorge Balatsouras // RUN: %clang_dfsan -gmlt %s -o %t && %run %t >%t.out 2>&1
298504959SGeorge Balatsouras // RUN: FileCheck %s < %t.out
398504959SGeorge Balatsouras 
498504959SGeorge Balatsouras #include <assert.h>
598504959SGeorge Balatsouras #include <sanitizer/dfsan_interface.h>
698504959SGeorge Balatsouras #include <stdio.h>
798504959SGeorge Balatsouras #include <string.h>
898504959SGeorge Balatsouras 
998504959SGeorge Balatsouras #define NOINLINE __attribute__((noinline))
1098504959SGeorge Balatsouras 
bar(int depth,char * buf,size_t len)1198504959SGeorge Balatsouras NOINLINE size_t bar(int depth, char *buf, size_t len) {
1298504959SGeorge Balatsouras   if (!depth) {
1398504959SGeorge Balatsouras     return dfsan_sprint_stack_trace(buf, len);
1498504959SGeorge Balatsouras   }
1598504959SGeorge Balatsouras 
1698504959SGeorge Balatsouras   return bar(depth - 1, buf, len);
1798504959SGeorge Balatsouras }
1898504959SGeorge Balatsouras 
baz(int depth,char * buf,size_t len)1998504959SGeorge Balatsouras NOINLINE size_t baz(int depth, char *buf, size_t len) {
2098504959SGeorge Balatsouras   return bar(depth, buf, len);
2198504959SGeorge Balatsouras }
2298504959SGeorge Balatsouras 
main(int argc,char * argv[])2398504959SGeorge Balatsouras int main(int argc, char *argv[]) {
2498504959SGeorge Balatsouras   char buf[3000];
2598504959SGeorge Balatsouras   size_t length = dfsan_sprint_stack_trace(buf, sizeof(buf));
2698504959SGeorge Balatsouras   assert(length < sizeof(buf));
2798504959SGeorge Balatsouras   printf("==OUTPUT==\n%s==EOS==\n", buf);
2898504959SGeorge Balatsouras 
2998504959SGeorge Balatsouras   // CHECK: ==OUTPUT==
3098504959SGeorge Balatsouras   // CHECK: #0 {{.*}} in main [[FILEPATH:.*]]/stack_trace.c:[[# @LINE - 5 ]]
3198504959SGeorge Balatsouras   // CHECK: ==EOS==
3298504959SGeorge Balatsouras 
3398504959SGeorge Balatsouras   length = baz(8, buf, sizeof(buf));
3498504959SGeorge Balatsouras   printf("==OUTPUT==\n%s==EOS==\n", buf);
3598504959SGeorge Balatsouras 
3698504959SGeorge Balatsouras   // CHECK: ==OUTPUT==
37*df9400c5SFangrui Song   // CHECK: #0 {{.*}} in bar.dfsan [[FILEPATH]]/stack_trace.c:13
38*df9400c5SFangrui Song   // CHECK-COUNT-8: #{{[1-9]+}} {{.*}} in bar.dfsan [[FILEPATH]]/stack_trace.c:16
39*df9400c5SFangrui Song   // CHECK: #9 {{.*}} in baz.dfsan [[FILEPATH]]/stack_trace.c:20
4098504959SGeorge Balatsouras   // CHECK: #10 {{.*}} in main [[FILEPATH]]/stack_trace.c:[[# @LINE - 7 ]]
4198504959SGeorge Balatsouras   // CHECK: ==EOS==
4298504959SGeorge Balatsouras 
4398504959SGeorge Balatsouras   char tinybuf[8];
4498504959SGeorge Balatsouras   size_t same_length = baz(8, tinybuf, sizeof(tinybuf));
4598504959SGeorge Balatsouras 
4698504959SGeorge Balatsouras   printf("==TRUNCATED OUTPUT==\n%s==EOS==\n", tinybuf);
4798504959SGeorge Balatsouras   // CHECK: ==TRUNCATED OUTPUT==
4898504959SGeorge Balatsouras   // CHECK:     #0 ==EOS==
4998504959SGeorge Balatsouras 
5098504959SGeorge Balatsouras   printf("Returned length: %zu\n", length);
5198504959SGeorge Balatsouras   printf("Actual length: %zu\n", strlen(buf));
5298504959SGeorge Balatsouras   printf("Returned length with truncation: %zu\n", same_length);
5398504959SGeorge Balatsouras 
5498504959SGeorge Balatsouras   // CHECK: Returned length: [[#LEN:]]
5598504959SGeorge Balatsouras   // CHECK: Actual length: [[#LEN]]
5698504959SGeorge Balatsouras   // CHECK: Returned length with truncation: [[#LEN]]
5798504959SGeorge Balatsouras 
5898504959SGeorge Balatsouras   buf[0] = '\0';
5998504959SGeorge Balatsouras   length = baz(8, buf, 0);
6098504959SGeorge Balatsouras   printf("Output=\"%s\"\n", buf);
6198504959SGeorge Balatsouras   printf("Returned length: %zu\n", length);
6298504959SGeorge Balatsouras   // CHECK: Output=""
6398504959SGeorge Balatsouras   // CHECK: Returned length: [[#LEN]]
6498504959SGeorge Balatsouras }
65