(original post was here)
Consider the following clearly buggy program:
#include <string.h>
int main()
{
char string1[10] = "123456789";
char *string2 = "123456789";
strcat(string1, string2);
}
and suppose to compile it:
gcc program.c -ggdb
and run valgrind on it:
valgrind --track-origins=yes --leak-check=yes --tool=memcheck --read-var-info=yes ./a.out
In the result, no error is shown:
==29739== Memcheck, a memory error detector
==29739== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==29739== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==29739== Command: ./a.out
==29739==
==29739==
==29739== HEAP SUMMARY:
==29739== in use at exit: 0 bytes in 0 blocks
==29739== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==29739==
==29739== All heap blocks were freed -- no leaks are possible
==29739==
==29739== For counts of detected and suppressed errors, rerun with: -v
==29739== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
What am I missing?
It did not report anything wrong because you were using memcheck, which does not perform check on global or stack arrays, it only perform bounds checks and use-after-free checks for heap arrays. So in this case, you can use valgrind SGCheck to check stack arrays:
valgrind --tool=exp-sgcheck ./a.out
It indeed report the error for me.
For more information, refer the sgcheck docs:
http://valgrind.org/docs/manual/sg-manual.html
adding the log:
$ valgrind --tool=exp-sgcheck ./a.out
==10485== exp-sgcheck, a stack and global array overrun detector
==10485== NOTE: This is an Experimental-Class Valgrind Tool
==10485== Copyright (C) 2003-2015, and GNU GPL'd, by OpenWorks Ltd et al.
==10485== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==10485== Command: ./a.out
==10485==
==10485== Invalid read of size 1
==10485== at 0x4C2A374: strlen (h_intercepts.c:131)
==10485== by 0x4E9DD5B: puts (in /usr/lib64/libc-2.22.so)
==10485== by 0x4005C8: main (v.c:11)
==10485== Address 0xfff00042a expected vs actual:
==10485== Expected: stack array "string1" of size 10 in frame 2 back from here
==10485== Actual: unknown
==10485== Actual: is 0 after Expected
==10485==
==10485== Invalid read of size 1
==10485== at 0x4EA9BA2: _IO_default_xsputn (in /usr/lib64/libc-2.22.so)
==10485== by 0x4EA7816: _IO_file_xsputn##GLIBC_2.2.5 (in /usr/lib64/libc-2.22.so)
==10485== by 0x4E9DDF7: puts (in /usr/lib64/libc-2.22.so)
==10485== by 0x4005C8: main (v.c:11)
==10485== Address 0xfff00042a expected vs actual:
==10485== Expected: stack array "string1" of size 10 in frame 3 back from here
==10485== Actual: unknown
==10485== Actual: is 0 after Expected
==10485==
123456789123456789
==10485==
==10485== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Related
I'm using valgrind 3.13 on mips platform, however I write a test program and found valgrind didn't trace to file line number, for x86 it works fine. what could be the problem?
# valgrind --trace-children=yes --leak-check=yes --num-callers=20 /tmp/a.out
==2957== Memcheck, a memory error detector
==2957== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2957== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2957== Command: /tmp/a.out
==2957==
==2957== Invalid write of size 4
==2957== at 0x4000B90: ??? (in /lib/ld-uClibc.so.0)
==2957== by 0x4000B3C: ??? (in /lib/ld-uClibc.so.0)
==2957== Address 0x7e8bdcbc is on thread 1's stack
==2957== 4 bytes below stack pointer
==2957==
==2957== Conditional jump or move depends on uninitialised value(s)
==2957== at 0x48B4A44: ??? (in /lib/libc.so.0)
==2957== by 0x48ADBE4: ??? (in /lib/libc.so.0)
==2957==
buf=test buf
in func1:x[10]=10
/tmp/a.out: can't resolve symbol '__libc_freeres'
==2957==
==2957== HEAP SUMMARY:
==2957== in use at exit: 0 bytes in 0 blocks
==2957== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==2957==
==2957== All heap blocks were freed -- no leaks are possible
==2957==
==2957== For counts of detected and suppressed errors, rerun with: -v
==2957== Use --track-origins=yes to see where uninitialised values come from
==2957== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Below is my test.c, compiled with mips toolchain with option "-g -O0"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
func1()
{
int *x=malloc(10*sizeof(int *));
x[10]=10;
printf("in func1:x[10]=%d\n", x[10]);
}
main()
{
char buf[2];
char buf2[10];
strcpy(buf,"test buf\n");
printf("buf=%s\n", buf);
func1();
}
In my C code I call assembly (NASM x86_64) function (main.c).
In assembly I call C function (printf.asm)
That function prints float using printf. (c_printf.c)
I'm getting segfault.
Should I compile/link in another way? Maybe the way I call C function from assembly is incorrect?
I compile with:
gcc -c c_printf.c
nasm -f elf64 -F dwarf -g printf.asm
gcc -o main printf.o c_printf.o main.c
My code:
main.c
extern void start_asm(void);
int main(void) {
start_asm();
return 0;
}
printf.asm
global start_asm
extern printf_float
start_asm:
call printf_float
ret
c_printf.c
#include <stdio.h>
void printf_float(void) {
printf("%f\n", 42.0f);
}
Maybe valgrind output will be helpful?
==16257== Memcheck, a memory error detector
==16257== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==16257== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==16257== Command: ./main
==16257==
--16257-- WARNING: Serious error when reading debug info
--16257-- When reading debug info from /home/starsep/stack/main:
--16257-- Overrun whilst parsing .debug_abbrev section(2)
==16257==
==16257== Process terminating with default action of signal 11 (SIGSEGV)
==16257== General Protection Fault
==16257== at 0x4E8F824: printf (printf.c:28)
==16257== by 0x40055F: printf_float (in /home/starsep/stack/main)
==16257== by 0x400534: ??? (printf.asm:6)
==16257== by 0x4E5A82F: (below main) (libc-start.c:291)
==16257==
==16257== HEAP SUMMARY:
==16257== in use at exit: 0 bytes in 0 blocks
==16257== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==16257==
==16257== All heap blocks were freed -- no leaks are possible
==16257==
==16257== For counts of detected and suppressed errors, rerun with: -v
==16257== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[1] 16257 segmentation fault valgrind ./main
I'm not able to figure out why Valgrind is printing Invalid read of size 8 when using wchar_t. I'm running a 64bit Ubuntu (3.5.0-25) system with valgrind-3.7.0 and gcc 4.7.2.
#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <string.h>
int main()
{
// const wchar_t *text = L"This is a t"; // no Valgrind error
// const wchar_t *text = L"This is a teeeeeeee"; // no Valgrind error
const wchar_t *text = L"This is a test"; // Valgrind ERRROR
wchar_t *new_text = NULL;
new_text = (wchar_t*) malloc( (wcslen(text) + 1) * sizeof(wchar_t));
wcsncpy(new_text, text, wcslen(text));
new_text[wcslen(text)] = L'\0';
printf("new_text: %ls\n", new_text);
free(new_text);
return 0;
}
Compile:
$ gcc -g -std=c99 test.c -o test
$ valgrind --tool=memcheck --leak-check=full --track-origins=yes --show-reachable=yes ./test
Valgrind results:
==19495== Memcheck, a memory error detector
==19495== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==19495== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==19495== Command: ./test
==19495==
==19495== Invalid read of size 8
==19495== at 0x4ED45A7: wcslen (wcslen.S:55)
==19495== by 0x4ED5C0E: wcsrtombs (wcsrtombs.c:74)
==19495== by 0x4E7D160: vfprintf (vfprintf.c:1630)
==19495== by 0x4E858D8: printf (printf.c:35)
==19495== by 0x4006CC: main (test.c:16)
==19495== Address 0x51f1078 is 56 bytes inside a block of size 60 alloc'd
==19495== at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19495== by 0x40066F: main (test.c:12)
==19495==
new_text: This is a test
==19495==
==19495== HEAP SUMMARY:
==19495== in use at exit: 0 bytes in 0 blocks
==19495== total heap usage: 1 allocs, 1 frees, 60 bytes allocated
==19495==
==19495== All heap blocks were freed -- no leaks are possible
==19495==
==19495== For counts of detected and suppressed errors, rerun with: -v
==19495== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Now if I run the same but with a 'working string', let's say
const wchar_t *text = L"This is a t"; // no Valgrind error
// const wchar_t *text = L"This is a teeeeeeee"; // no Valgrind error
// const wchar_t *text = L"This is a test"; // Valgrind ERRROR
I get no issue:
==19571== Memcheck, a memory error detector
==19571== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==19571== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==19571== Command: ./test
==19571==
new_text: This is a t
==19571==
==19571== HEAP SUMMARY:
==19571== in use at exit: 0 bytes in 0 blocks
==19571== total heap usage: 1 allocs, 1 frees, 48 bytes allocated
==19571==
==19571== All heap blocks were freed -- no leaks are possible
==19571==
==19571== For counts of detected and suppressed errors, rerun with: -v
==19571== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
At first I thought the string size should be always be multiple of 8 (maybe some wcs read chunks of 8) but some cases failed, then I thought I'd have to append always 8 bytes for the NULL terminator ((wcslen(item) + 2) * sizeof(wchar_t)), it worked but that doesn't make any sense since sizeof(wchar_t) - in my system - is 4 bytes and should be enough to handle the L'\0' terminator.
I also read the glibc wcslen source code but nothing new. I'm now thinking of Valgrind issue. Do you guys could throw some light here? Does it worth to file a bug against Valgrind?
Thank you
This is probably caused by SSE optimisation of the wcslen function; see e.g. https://bugzilla.redhat.com/show_bug.cgi?id=798968 or https://bugs.archlinux.org/task/30643.
When optimising wcslen, it's faster to read multiple wide characters at a time and use vectorised instructions (SSE) to compare them to L'\0'. Unfortunately valgrind sees this as an uninitialised read - which it is, but it's harmless because the result of wcslen does not depend on the uninitialised value.
The fix is to update valgrind in the hope that a newer version will suppress the false positive.
The code is here:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* buf = malloc(3);
strcpy(buf, "hi");
printf("%s\n", buf);
free(buf);
}
It's compiled with:
gcc a.c && valgrind ./a.out
The error message is here:
==1421== Memcheck, a memory error detector
==1421== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==1421== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==1421== Command: ./a.out
==1421==
==1421== Invalid read of size 8
==1421== at 0x4EA96C1: ??? (in /lib/libc-2.14.1.so)
==1421== by 0x4E92D3B: puts (in /lib/libc-2.14.1.so)
==1421== by 0x4005BB: main (in /home/peter/a.out)
==1421== Address 0x51b4040 is 0 bytes inside a block of size 3 alloc'd
==1421== at 0x4C2740D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1421== by 0x400595: main (in /home/peter/a.out)
==1421==
hi
==1421==
==1421== HEAP SUMMARY:
==1421== in use at exit: 0 bytes in 0 blocks
==1421== total heap usage: 1 allocs, 1 frees, 3 bytes allocated
==1421==
==1421== All heap blocks were freed -- no leaks are possible
==1421==
==1421== For counts of detected and suppressed errors, rerun with: -v
==1421== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 6 from 6)
It is also very strange that valgrind reports no more errors if I use the following (just one more space):
printf("%s \n", buf);
Would anyone please help me?
This is a bug, but not reproducible on all machines.
On some machines, gcc optimizes simple printf() with, for example, puts(), which could possibly involve invalid read (or just valgrind thinks so).
If it really matters, you can 'complicate' the printf format. A space between %s and \n would do.
Here is a similar bug: C strings, strlen and Valgrind
This answer combines comments in the discussion. Thank you all!
I've run it in my own machine, and I get no errors:
==61755== Memcheck, a memory error detector
==61755== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==61755== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==61755== Command: ./a.out
==61755==
hi
==61755==
==61755== HEAP SUMMARY:
==61755== in use at exit: 0 bytes in 0 blocks
==61755== total heap usage: 1 allocs, 1 frees, 3 bytes allocated
==61755==
==61755== All heap blocks were freed -- no leaks are possible
==61755==
==61755== For counts of detected and suppressed errors, rerun with: -v
==61755== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
The code is here:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* buf = malloc(3);
strcpy(buf, "hi");
printf("%s\n", buf);
free(buf);
}
It's compiled with:
gcc a.c && valgrind ./a.out
The error message is here:
==1421== Memcheck, a memory error detector
==1421== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==1421== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==1421== Command: ./a.out
==1421==
==1421== Invalid read of size 8
==1421== at 0x4EA96C1: ??? (in /lib/libc-2.14.1.so)
==1421== by 0x4E92D3B: puts (in /lib/libc-2.14.1.so)
==1421== by 0x4005BB: main (in /home/peter/a.out)
==1421== Address 0x51b4040 is 0 bytes inside a block of size 3 alloc'd
==1421== at 0x4C2740D: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1421== by 0x400595: main (in /home/peter/a.out)
==1421==
hi
==1421==
==1421== HEAP SUMMARY:
==1421== in use at exit: 0 bytes in 0 blocks
==1421== total heap usage: 1 allocs, 1 frees, 3 bytes allocated
==1421==
==1421== All heap blocks were freed -- no leaks are possible
==1421==
==1421== For counts of detected and suppressed errors, rerun with: -v
==1421== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 6 from 6)
It is also very strange that valgrind reports no more errors if I use the following (just one more space):
printf("%s \n", buf);
Would anyone please help me?
This is a bug, but not reproducible on all machines.
On some machines, gcc optimizes simple printf() with, for example, puts(), which could possibly involve invalid read (or just valgrind thinks so).
If it really matters, you can 'complicate' the printf format. A space between %s and \n would do.
Here is a similar bug: C strings, strlen and Valgrind
This answer combines comments in the discussion. Thank you all!
I've run it in my own machine, and I get no errors:
==61755== Memcheck, a memory error detector
==61755== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==61755== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==61755== Command: ./a.out
==61755==
hi
==61755==
==61755== HEAP SUMMARY:
==61755== in use at exit: 0 bytes in 0 blocks
==61755== total heap usage: 1 allocs, 1 frees, 3 bytes allocated
==61755==
==61755== All heap blocks were freed -- no leaks are possible
==61755==
==61755== For counts of detected and suppressed errors, rerun with: -v
==61755== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)