1// This test program creates a very large number of unique histories.
2
3// Heap origin.
4// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O3 %s -o %t
5
6// RUN: env MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1
7// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
8
9// RUN: env MSAN_OPTIONS=origin_history_size=2 not %run %t >%t.out 2>&1
10// RUN: FileCheck %s --check-prefix=CHECK2 < %t.out
11
12// RUN: env MSAN_OPTIONS=origin_history_per_stack_limit=1 not %run %t >%t.out 2>&1
13// RUN: FileCheck %s --check-prefix=CHECK-PER-STACK --check-prefix=CHECK-%short-stack < %t.out
14
15// RUN: env MSAN_OPTIONS=origin_history_size=7,origin_history_per_stack_limit=0 not %run %t >%t.out 2>&1
16// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
17
18// Stack origin.
19// RUN: %clangxx_msan -DSTACK -fsanitize-memory-track-origins=2 -O3 %s -o %t
20
21// RUN: env MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1
22// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
23
24// RUN: env MSAN_OPTIONS=origin_history_size=2 not %run %t >%t.out 2>&1
25// RUN: FileCheck %s --check-prefix=CHECK2 < %t.out
26
27// RUN: env MSAN_OPTIONS=origin_history_per_stack_limit=1 not %run %t >%t.out 2>&1
28// RUN: FileCheck %s --check-prefix=CHECK-PER-STACK --check-prefix=CHECK-%short-stack < %t.out
29
30// RUN: env MSAN_OPTIONS=origin_history_size=7,origin_history_per_stack_limit=0 not %run %t >%t.out 2>&1
31// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
32
33// Heap origin, with calls.
34// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t
35
36// RUN: env MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1
37// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
38
39// RUN: env MSAN_OPTIONS=origin_history_size=2 not %run %t >%t.out 2>&1
40// RUN: FileCheck %s --check-prefix=CHECK2 < %t.out
41
42// RUN: env MSAN_OPTIONS=origin_history_per_stack_limit=1 not %run %t >%t.out 2>&1
43// RUN: FileCheck %s --check-prefix=CHECK-PER-STACK --check-prefix=CHECK-%short-stack < %t.out
44
45// RUN: env MSAN_OPTIONS=origin_history_size=7,origin_history_per_stack_limit=0 not %run %t >%t.out 2>&1
46// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
47
48// Stack origin, with calls.
49// RUN: %clangxx_msan -DSTACK -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t
50
51// RUN: env MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1
52// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
53
54// RUN: env MSAN_OPTIONS=origin_history_size=2 not %run %t >%t.out 2>&1
55// RUN: FileCheck %s --check-prefix=CHECK2 < %t.out
56
57// RUN: env MSAN_OPTIONS=origin_history_per_stack_limit=1 not %run %t >%t.out 2>&1
58// RUN: FileCheck %s --check-prefix=CHECK-PER-STACK --check-prefix=CHECK-%short-stack < %t.out
59
60// RUN: env MSAN_OPTIONS=origin_history_size=7,origin_history_per_stack_limit=0 not %run %t >%t.out 2>&1
61// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66#include <unistd.h>
67
68static char *buf, *cur, *end;
69void init() {
70 buf = new char[1000];
71#ifdef STACK
72 char stackbuf[1000];
73 char *volatile p = stackbuf;
74 memcpy(buf, p, 1000);
75#endif
76 cur = buf;
77 end = buf + 1000;
78}
79
80void line_flush() {
81 char *p;
82 for (p = cur - 1; p >= buf; --p)
83 if (*p == '\n')
84 break;
85 if (p >= buf) {
86 size_t write_sz = p - buf + 1;
87 // write(2, buf, write_sz);
88 memmove(dest: buf, src: p + 1, n: end - p - 1);
89 cur -= write_sz;
90 }
91}
92
93void buffered_write(const char *p, size_t sz) {
94 while (sz > 0) {
95 size_t copy_sz = end - cur;
96 if (sz < copy_sz) copy_sz = sz;
97 memcpy(dest: cur, src: p, n: copy_sz);
98 cur += copy_sz;
99 sz -= copy_sz;
100 line_flush();
101 }
102}
103
104void fn1() {
105 buffered_write(p: "a\n", sz: 2);
106}
107
108void fn2() {
109 buffered_write(p: "a\n", sz: 2);
110}
111
112void fn3() {
113 buffered_write(p: "a\n", sz: 2);
114}
115
116int main(void) {
117 init();
118 for (int i = 0; i < 2000; ++i) {
119 fn1();
120 fn2();
121 fn3();
122 }
123 return buf[50];
124}
125
126// CHECK7: WARNING: MemorySanitizer: use-of-uninitialized-value
127// CHECK7-NOT: Uninitialized value was stored to memory at
128// CHECK7: Uninitialized value was stored to memory at
129// CHECK7-NOT: Uninitialized value was stored to memory at
130// CHECK7: Uninitialized value was stored to memory at
131// CHECK7-NOT: Uninitialized value was stored to memory at
132// CHECK7: Uninitialized value was stored to memory at
133// CHECK7-NOT: Uninitialized value was stored to memory at
134// CHECK7: Uninitialized value was stored to memory at
135// CHECK7-NOT: Uninitialized value was stored to memory at
136// CHECK7: Uninitialized value was stored to memory at
137// CHECK7-NOT: Uninitialized value was stored to memory at
138// CHECK7: Uninitialized value was stored to memory at
139// CHECK7-NOT: Uninitialized value was stored to memory at
140// CHECK7: Uninitialized value was created
141
142// CHECK2: WARNING: MemorySanitizer: use-of-uninitialized-value
143// CHECK2-NOT: Uninitialized value was stored to memory at
144// CHECK2: Uninitialized value was stored to memory at
145// CHECK2-NOT: Uninitialized value was stored to memory at
146// CHECK2: Uninitialized value was created
147
148// For architectures with short stack all the stacks in the chain are same
149// because the stack trace does not contain frames upto the functions fn1, fn2,
150// fn3 from where the uninitialized stores actually originate. Since we report
151// uninitialized value store once for each stack frame
152// (origin_history_per_stack_limit = 1) we expect only one instance of
153// "Uninitialized value was stored to memory at".
154
155// CHECK-PER-STACK: WARNING: MemorySanitizer: use-of-uninitialized-value
156// CHECK-PER-STACK: Uninitialized value was stored to memory at
157// CHECK-SHORT-STACK: in __msan_memmove
158// CHECK-FULL-STACK: in fn3
159// CHECK-FULL-STACK: Uninitialized value was stored to memory at
160// CHECK-FULL-STACK: in fn2
161// CHECK-FULL-STACK: Uninitialized value was stored to memory at
162// CHECK-FULL-STACK: in fn1
163// CHECK-PER-STACK: Uninitialized value was created
164
165// CHECK-UNLIMITED: WARNING: MemorySanitizer: use-of-uninitialized-value
166// CHECK-UNLIMITED: Uninitialized value was stored to memory at
167// CHECK-UNLIMITED: Uninitialized value was stored to memory at
168// CHECK-UNLIMITED: Uninitialized value was stored to memory at
169// CHECK-UNLIMITED: Uninitialized value was stored to memory at
170// CHECK-UNLIMITED: Uninitialized value was stored to memory at
171// CHECK-UNLIMITED: Uninitialized value was stored to memory at
172// CHECK-UNLIMITED: Uninitialized value was stored to memory at
173// CHECK-UNLIMITED: Uninitialized value was stored to memory at
174// CHECK-UNLIMITED: Uninitialized value was stored to memory at
175// CHECK-UNLIMITED: Uninitialized value was stored to memory at
176// CHECK-UNLIMITED: Uninitialized value was stored to memory at
177// CHECK-UNLIMITED: Uninitialized value was stored to memory at
178// CHECK-UNLIMITED: Uninitialized value was stored to memory at
179// CHECK-UNLIMITED: Uninitialized value was stored to memory at
180// CHECK-UNLIMITED: Uninitialized value was stored to memory at
181// CHECK-UNLIMITED: Uninitialized value was stored to memory at
182// CHECK-UNLIMITED: Uninitialized value was stored to memory at
183// CHECK-UNLIMITED: Uninitialized value was stored to memory at
184// CHECK-UNLIMITED: Uninitialized value was created
185

source code of compiler-rt/test/msan/chained_origin_limits.cpp