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: 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: 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: 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: 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: 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: 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: 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: 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 | |
34 | // Heap origin, with calls. |
35 | // RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t |
36 | |
37 | // RUN: MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1 |
38 | // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out |
39 | |
40 | // RUN: MSAN_OPTIONS=origin_history_size=2 not %run %t >%t.out 2>&1 |
41 | // RUN: FileCheck %s --check-prefix=CHECK2 < %t.out |
42 | |
43 | // RUN: MSAN_OPTIONS=origin_history_per_stack_limit=1 not %run %t >%t.out 2>&1 |
44 | // RUN: FileCheck %s --check-prefix=CHECK-PER-STACK --check-prefix=CHECK-%short-stack < %t.out |
45 | |
46 | // RUN: MSAN_OPTIONS=origin_history_size=7,origin_history_per_stack_limit=0 not %run %t >%t.out 2>&1 |
47 | // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out |
48 | |
49 | |
50 | // Stack origin, with calls. |
51 | // RUN: %clangxx_msan -DSTACK -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t |
52 | |
53 | // RUN: MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1 |
54 | // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out |
55 | |
56 | // RUN: MSAN_OPTIONS=origin_history_size=2 not %run %t >%t.out 2>&1 |
57 | // RUN: FileCheck %s --check-prefix=CHECK2 < %t.out |
58 | |
59 | // RUN: MSAN_OPTIONS=origin_history_per_stack_limit=1 not %run %t >%t.out 2>&1 |
60 | // RUN: FileCheck %s --check-prefix=CHECK-PER-STACK --check-prefix=CHECK-%short-stack < %t.out |
61 | |
62 | // RUN: MSAN_OPTIONS=origin_history_size=7,origin_history_per_stack_limit=0 not %run %t >%t.out 2>&1 |
63 | // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out |
64 | |
65 | #include <stdio.h> |
66 | #include <stdlib.h> |
67 | #include <string.h> |
68 | #include <unistd.h> |
69 | |
70 | static char *buf, *cur, *end; |
71 | void init() { |
72 | buf = new char[1000]; |
73 | #ifdef STACK |
74 | char stackbuf[1000]; |
75 | char *volatile p = stackbuf; |
76 | memcpy(buf, p, 1000); |
77 | #endif |
78 | cur = buf; |
79 | end = buf + 1000; |
80 | } |
81 | |
82 | void line_flush() { |
83 | char *p; |
84 | for (p = cur - 1; p >= buf; --p) |
85 | if (*p == '\n') |
86 | break; |
87 | if (p >= buf) { |
88 | size_t write_sz = p - buf + 1; |
89 | // write(2, buf, write_sz); |
90 | memmove(dest: buf, src: p + 1, n: end - p - 1); |
91 | cur -= write_sz; |
92 | } |
93 | } |
94 | |
95 | void buffered_write(const char *p, size_t sz) { |
96 | while (sz > 0) { |
97 | size_t copy_sz = end - cur; |
98 | if (sz < copy_sz) copy_sz = sz; |
99 | memcpy(dest: cur, src: p, n: copy_sz); |
100 | cur += copy_sz; |
101 | sz -= copy_sz; |
102 | line_flush(); |
103 | } |
104 | } |
105 | |
106 | void fn1() { |
107 | buffered_write(p: "a\n" , sz: 2); |
108 | } |
109 | |
110 | void fn2() { |
111 | buffered_write(p: "a\n" , sz: 2); |
112 | } |
113 | |
114 | void fn3() { |
115 | buffered_write(p: "a\n" , sz: 2); |
116 | } |
117 | |
118 | int main(void) { |
119 | init(); |
120 | for (int i = 0; i < 2000; ++i) { |
121 | fn1(); |
122 | fn2(); |
123 | fn3(); |
124 | } |
125 | return buf[50]; |
126 | } |
127 | |
128 | // CHECK7: WARNING: MemorySanitizer: use-of-uninitialized-value |
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 stored to memory at |
141 | // CHECK7-NOT: Uninitialized value was stored to memory at |
142 | // CHECK7: Uninitialized value was created |
143 | |
144 | // CHECK2: WARNING: MemorySanitizer: use-of-uninitialized-value |
145 | // CHECK2-NOT: Uninitialized value was stored to memory at |
146 | // CHECK2: Uninitialized value was stored to memory at |
147 | // CHECK2-NOT: Uninitialized value was stored to memory at |
148 | // CHECK2: Uninitialized value was created |
149 | |
150 | // For architectures with short stack all the stacks in the chain are same |
151 | // because the stack trace does not contain frames upto the functions fn1, fn2, |
152 | // fn3 from where the uninitialized stores actually originate. Since we report |
153 | // uninitialized value store once for each stack frame |
154 | // (origin_history_per_stack_limit = 1) we expect only one instance of |
155 | // "Uninitialized value was stored to memory at". |
156 | |
157 | // CHECK-PER-STACK: WARNING: MemorySanitizer: use-of-uninitialized-value |
158 | // CHECK-PER-STACK: Uninitialized value was stored to memory at |
159 | // CHECK-SHORT-STACK: in __msan_memmove |
160 | // CHECK-FULL-STACK: in fn3 |
161 | // CHECK-FULL-STACK: Uninitialized value was stored to memory at |
162 | // CHECK-FULL-STACK: in fn2 |
163 | // CHECK-FULL-STACK: Uninitialized value was stored to memory at |
164 | // CHECK-FULL-STACK: in fn1 |
165 | // CHECK-PER-STACK: Uninitialized value was created |
166 | |
167 | // CHECK-UNLIMITED: WARNING: MemorySanitizer: use-of-uninitialized-value |
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 stored to memory at |
185 | // CHECK-UNLIMITED: Uninitialized value was stored to memory at |
186 | // CHECK-UNLIMITED: Uninitialized value was created |
187 | |