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 | |
68 | static char *buf, *cur, *end; |
69 | void 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 | |
80 | void 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 | |
93 | void 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 | |
104 | void fn1() { |
105 | buffered_write(p: "a\n" , sz: 2); |
106 | } |
107 | |
108 | void fn2() { |
109 | buffered_write(p: "a\n" , sz: 2); |
110 | } |
111 | |
112 | void fn3() { |
113 | buffered_write(p: "a\n" , sz: 2); |
114 | } |
115 | |
116 | int 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 | |