'MemorySanitizer false positives with long vararg list
When running the test suite of the igraph package with MemorySanitizer (clang 13.0), I am getting false positives in some (but not all) cases involving very long vararg lists, such as here:
Reducing the number of arguments passed to the function eliminates the error.
The program logic here is basically identical to the short program at the end of this post. However, that program cannot reproduce the issue with MemorySanitizer, no matter how many arguments I pass to the function. I get a stack overflow before any MemorySanitizer error is triggered. Thus, the problem must have to do with multiple nested calls, even though only one of those involves varargs.
Question: Has anyone seen similar false positives with MemorySanitizer? If yes, is this a bug in MemorySanitizer, or is there some option that controls how deep it looks into the stack to mark values as "initialized"? Is there a way to eliminate the problem without shortening the argument list?
Example program:
#include <stdio.h>
#include <stdarg.h>
/* Fills up 'arr' with int values passed to the function, up to and including the first -1 */
void f(int arr[], ...) {
va_list ap;
int i = 0;
va_start(ap, arr);
while (1) {
int num = va_arg(ap, int);
arr[i++] = num;
if (num == -1) {
break;
}
}
va_end(ap);
}
int main() {
int arr[200]; /* 'arr' is uninitialized here */
int i=0;
/* Initialize the first 101 elements of 'arr' using f(). */
f(arr, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
-1);
/* Print the initialized elements to verify whether
MemorySanitizer reports an error (a false positive). */
while (arr[i] != -1) {
printf("%d\n", arr[i]);
i++;
}
return 0;
}
For completeness, here is the MemorySanitizer output for the code I linked, although there aren't any hints I can see here.
==2908012==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7f088a65d160 in igraph_vector_int_isininterval /home/szhorvat/Repos/igraph/src/core/vector.pmt:1834:27
#1 0x7f088a745a7b in igraph_create /home/szhorvat/Repos/igraph/src/constructors/basic_constructors.c:74:23
#2 0x7f088a746454 in igraph_small /home/szhorvat/Repos/igraph/src/constructors/basic_constructors.c:149:5
#3 0x49ce86 in main /home/szhorvat/Repos/igraph/tests/unit/global_transitivity.c:57:5
#4 0x7f088a1c50b2 in __libc_start_main /build/glibc-sMfBJT/glibc-2.31/csu/../csu/libc-start.c:308:16
#5 0x41d63d in _start (/home/szhorvat/Repos/igraph/build/tests/test_global_transitivity+0x41d63d)
Uninitialized value was stored to memory at
#0 0x44be92 in __interceptor_realloc (/home/szhorvat/Repos/igraph/build/tests/test_global_transitivity+0x44be92)
#1 0x7f088a65692f in igraph_vector_int_reserve /home/szhorvat/Repos/igraph/src/core/vector.pmt:471:11
#2 0x7f088a65692f in igraph_vector_int_push_back /home/szhorvat/Repos/igraph/src/core/vector.pmt:577:9
#3 0x7f088a746393 in igraph_small /home/szhorvat/Repos/igraph/src/constructors/basic_constructors.c:145:9
#4 0x49ce86 in main /home/szhorvat/Repos/igraph/tests/unit/global_transitivity.c:57:5
#5 0x7f088a1c50b2 in __libc_start_main /build/glibc-sMfBJT/glibc-2.31/csu/../csu/libc-start.c:308:16
Uninitialized value was stored to memory at
#0 0x7f088a656ac4 in igraph_vector_int_push_back /home/szhorvat/Repos/igraph/src/core/vector.pmt:580:15
#1 0x7f088a746393 in igraph_small /home/szhorvat/Repos/igraph/src/constructors/basic_constructors.c:145:9
#2 0x49ce86 in main /home/szhorvat/Repos/igraph/tests/unit/global_transitivity.c:57:5
#3 0x7f088a1c50b2 in __libc_start_main /build/glibc-sMfBJT/glibc-2.31/csu/../csu/libc-start.c:308:16
Uninitialized value was created
<empty stack>
SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/szhorvat/Repos/igraph/src/core/vector.pmt:1834:27 in igraph_vector_int_isininterval
Exiting
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
