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(buf, p + 1, 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(cur, p, copy_sz); 98 cur += copy_sz; 99 sz -= copy_sz; 100 line_flush(); 101 } 102 } 103 104 void fn1() { 105 buffered_write("a\n", 2); 106 } 107 108 void fn2() { 109 buffered_write("a\n", 2); 110 } 111 112 void fn3() { 113 buffered_write("a\n", 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