uninitialised value and clang optimizations - c

I have created a program to print "Hello World" string as bellow:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void callString(char *_string);
int main()
{
char *myString;
// Allocating memory
myString = (char *)malloc(
(unsigned long)strlen(myString)
* sizeof(char)
);
myString = "Hello World!";
callString(myString);
// should I free(myString) here?
return 0;
}
static void
callString(char *_string)
{
printf("%s\n", _string);
}
Compiling and running reports:
$ clang -Wall -Weverything -g hello.c -o hello
$ ./hello
Hello World!
Looks good, but then, if I try to profile memory using Valgrind, I get:
$ valgrind \
--track-origins=yes \
--leak-check=full \
--leak-resolution=high \
--num-callers=50 \
./hello
==31692== Memcheck, a memory error detector
==31692== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==31692== Using Valgrind-3.14.0.GIT and LibVEX; rerun with -h for copyright info
==31692== Command: ./hello
==31692==
==31692== Use of uninitialised value of size 8
==31692== at 0x483ACC2: __strlen_sse2 (vg_replace_strmem.c:462)
==31692== by 0x109177: main (hello.c:9)
==31692== Uninitialised value was created by a stack allocation
==31692== at 0x109160: main (hello.c:7)
==31692==
==31692== Use of uninitialised value of size 8
==31692== at 0x483ACD4: __strlen_sse2 (vg_replace_strmem.c:462)
==31692== by 0x109177: main (hello.c:9)
==31692== Uninitialised value was created by a stack allocation
==31692== at 0x109160: main (hello.c:7)
==31692==
Hello World!
==31692==
==31692== HEAP SUMMARY:
==31692== in use at exit: 1 bytes in 1 blocks
==31692== total heap usage: 2 allocs, 1 frees, 1,025 bytes allocated
==31692==
==31692== 1 bytes in 1 blocks are definitely lost in loss record 1 of 1
==31692== at 0x483777F: malloc (vg_replace_malloc.c:299)
==31692== by 0x109183: main (hello.c:9)
==31692==
==31692== LEAK SUMMARY:
==31692== definitely lost: 1 bytes in 1 blocks
==31692== indirectly lost: 0 bytes in 0 blocks
==31692== possibly lost: 0 bytes in 0 blocks
==31692== still reachable: 0 bytes in 0 blocks
==31692== suppressed: 0 bytes in 0 blocks
==31692==
==31692== For counts of detected and suppressed errors, rerun with: -v
==31692== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
If I compile with optimization flags at -O3 level, I get green signal.
$ valgrind \
--track-origins=yes \
--leak-check=full \
--leak-resolution=high \
--num-callers=50 \
./hello
==32000== Memcheck, a memory error detector
==32000== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==32000== Using Valgrind-3.14.0.GIT and LibVEX; rerun with -h for copyright info
==32000== Command: ./hello
==32000==
Hello World!
==32000==
==32000== HEAP SUMMARY:
==32000== in use at exit: 0 bytes in 0 blocks
==32000== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==32000==
==32000== All heap blocks were freed -- no leaks are possible
==32000==
==32000== For counts of detected and suppressed errors, rerun with: -v
==32000== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
It looks like optimization fixes some of memory issues here. What's wrong with the code snippet? Which one is referred to "Use of uninitialised value"? myString? How can I initialize that?
Edit: As #Lundin advised, I have learnt the lesson not to assign strings with = directly. Thanks. Fixed code part =
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void callString(char *_string);
int main()
{
char *myString;
myString = (char *)malloc(
(unsigned long)strlen(myString)+1 * sizeof(char)
);
strncpy(myString, "Hello World", 11);
callString(myString);
free(myString);
return 0;
}
static void
callString(char *_string)
{
printf("%s\n", _string);
}
Thanks #Mat too

You have 3 problems:
myString is uninitialized so calling strlen(myString) doesn't make sense. You need to set it to something meaningful before calling strlen
Your malloc call is wrong, you should not allocate strlen(...) * sizeof(char), but rather strlen(...) + 1, since strings in C are null terminated and you must allocate room for the null terminator. Also, to multiply with sizeof(char) isn't necessary since that is guaranteed to be equal to 1.
After you malloc, you can't assign the pointer to something else: myString = "Hello World!";. This is what Valgrind complains about, it is a memory leak. Strings are copied using strcpy, not with = assignment.
Also, it is good practice to free() all memory at the end of the program.

Related

How declaring a variable with malloc lead to lost bits?

First, I have ran valgrind to make sure that (on the default settings) there are zero errors. Then, I decided to check for leaks with something like: --leak-check=full
I have code that looks something like char* variable=malloc(sizeof(char)*(strlen(in)+1)); and valgrind reports that memory is "definitely lost."
The only other line of code I have access to (this is in a library callback function) is the line of code where in is declared. This is a function argument of type void * (though in this case I'm hoping we can safely assume the value to be null terminated.)
Having
#include <stdlib.h>
char * G;
int main()
{
char * l = malloc(10);
G = malloc(20);
}
The execution under valgrind gives :
pi#raspberrypi:/tmp $ valgrind --leak-check=full ./a.out
==11087== Memcheck, a memory error detector
==11087== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11087== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==11087== Command: ./a.out
==11087==
==11087==
==11087== HEAP SUMMARY:
==11087== in use at exit: 30 bytes in 2 blocks
==11087== total heap usage: 2 allocs, 0 frees, 30 bytes allocated
==11087==
==11087== 10 bytes in 1 blocks are definitely lost in loss record 1 of 2
==11087== at 0x4847568: malloc (vg_replace_malloc.c:299)
==11087== by 0x10453: main (mm.c:7)
==11087==
==11087== LEAK SUMMARY:
==11087== definitely lost: 10 bytes in 1 blocks
==11087== indirectly lost: 0 bytes in 0 blocks
==11087== possibly lost: 0 bytes in 0 blocks
==11087== still reachable: 20 bytes in 1 blocks
==11087== suppressed: 0 bytes in 0 blocks
==11087== Reachable blocks (those to which a pointer was found) are not shown.
==11087== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==11087==
==11087== For counts of detected and suppressed errors, rerun with: -v
==11087== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 3)
The malloc(10) is definitely lost because there is no way to access it at the end of the execution (here out of main)
The malloc(20) is not lost because still reachable through G

Why does Valgrind show a memory leak on a calloc statement

I'm trying to learn a couple things (just as a hobby) and trying to learn to use Valgrind. However this doesn't seem to make sense to me. It seems Valgrind is saying that bytes are lost when I'm allocating them with calloc before I even use anything! Can someone explain what is going on here and why the second program worked? I compiled the programs in debug mode in Eclipse and ran Valgrind on the debug executable.
Here's the program:
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 int main(void) {
6
7 char* origstr = calloc(37, sizeof(char*));
8 char* newsubstr = calloc(9, sizeof(char*));
9
10 origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
11
12 strncpy(newsubstr, origstr + 8, 8);
13 printf("SubString is: %s\n", newsubstr);
14
15 free(newsubstr);
16 free(origstr);
17 return 0;
18 }
And here's what Valgrind gives me:
$ valgrind --tool=memcheck --leak-check=full ./test
==25404== Memcheck, a memory error detector
==25404== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25404== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==25404== Command: ./test
==25404==
SubString is: BrownFox
==25404== Invalid free() / delete / delete[] / realloc()
==25404== at 0x4C29E90: free (vg_replace_malloc.c:473)
==25404== by 0x400665: main (test.c:16)
==25404== Address 0x4006f8 is not stack'd, malloc'd or (recently) free'd
==25404==
==25404==
==25404== HEAP SUMMARY:
==25404== in use at exit: 296 bytes in 1 blocks
==25404== total heap usage: 2 allocs, 2 frees, 368 bytes allocated
==25404==
==25404== 296 bytes in 1 blocks are definitely lost in loss record 1 of 1
==25404== at 0x4C2AD10: calloc (vg_replace_malloc.c:623)
==25404== by 0x4005FC: main (test.c:7)
==25404==
==25404== LEAK SUMMARY:
==25404== definitely lost: 296 bytes in 1 blocks
==25404== indirectly lost: 0 bytes in 0 blocks
==25404== possibly lost: 0 bytes in 0 blocks
==25404== still reachable: 0 bytes in 0 blocks
==25404== suppressed: 0 bytes in 0 blocks
==25404==
==25404== For counts of detected and suppressed errors, rerun with: -v
==25404== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
If I remove the two free() statements, here's what Valgrind gives me:
$ valgrind --tool=memcheck --leak-check=full ./test
==25597== Memcheck, a memory error detector
==25597== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25597== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==25597== Command: ./test
==25597==
SubString is: BrownFox
==25597==
==25597== HEAP SUMMARY:
==25597== in use at exit: 368 bytes in 2 blocks
==25597== total heap usage: 2 allocs, 0 frees, 368 bytes allocated
==25597==
==25597== 72 bytes in 1 blocks are definitely lost in loss record 1 of 2
==25597== at 0x4C2AD10: calloc (vg_replace_malloc.c:623)
==25597== by 0x4005BF: main (test.c:8)
==25597==
==25597== 296 bytes in 1 blocks are definitely lost in loss record 2 of 2
==25597== at 0x4C2AD10: calloc (vg_replace_malloc.c:623)
==25597== by 0x4005AC: main (test.c:7)
==25597==
==25597== LEAK SUMMARY:
==25597== definitely lost: 368 bytes in 2 blocks
==25597== indirectly lost: 0 bytes in 0 blocks
==25597== possibly lost: 0 bytes in 0 blocks
==25597== still reachable: 0 bytes in 0 blocks
==25597== suppressed: 0 bytes in 0 blocks
==25597==
==25597== For counts of detected and suppressed errors, rerun with: -v
==25597== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Now, if I run this program:
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 int main(void) {
6
7 char* origstr;
8 char* newsubstr = calloc(9, sizeof(char*));
9
10 origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
11
12 strncpy(newsubstr, origstr + 8, 8);
13 printf("SubString is: %s\n", newsubstr);
14
15 free(newsubstr);
16
17 return 0;
18 }
It shows everything is just fine:
$ valgrind --tool=memcheck --leak-check=full ./test
==25862== Memcheck, a memory error detector
==25862== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==25862== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==25862== Command: ./test
==25862==
SubString is: BrownFox
==25862==
==25862== HEAP SUMMARY:
==25862== in use at exit: 0 bytes in 0 blocks
==25862== total heap usage: 1 allocs, 1 frees, 72 bytes allocated
==25862==
==25862== All heap blocks were freed -- no leaks are possible
==25862==
==25862== For counts of detected and suppressed errors, rerun with: -v
==25862== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Why is it that I can't calloc (allocate) origstr and then give it something? What if I wanted to allocate that variable and in the course of the program give it part of what's in another string variable or use it to capture the result of another function that returns a string? Would I then have to handle it like I did newsubstr?
This is a bit confusing to me so can someone explain how this works so I can understand it better?
origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
By doing this you change to what origstr points to . After this origstr doesn't point to memory block allocated by calloc .
And you free memory not allocated by calloc or similar functions , thus causing error in your program.
Use strcpy to copy string to origstr -
strcpy(origstr,"TheQuickBrownFoxJumpedOverTheLazyDog");
and then you can free your pointer origstr.
By assigning the string literal to origstr you don't copy the string but just change origstrs value, thus losing the pointer to calloc. freeing origstr now causes undefined behavior.
Use strcpy or strncpy instead to really store the string on the heap. But actually dropping calloc for origstr should suffice.
Notes:
as #LeeDanielCrocker mentioned in the comments to this answer, you probably intended to allocate space for chars, not for char*s, decreasing the size of the allocated memory drastically. You should replace the sizeof(char*) with a sizeof(char) (a.k.a. 1).
Because there is a memory leak. You reassign the pointer, it's actually incorrect to free() it as you have it.
To copy the contents to the allocated pointer use strcpy()
strcpy(origstr, "TheQuickBrownFoxJumpedOverTheLazyDog");
Let's see how:
You request memory with calloc()
origstring = calloc(9, sizeof(char*))
this is wrong for multiple reasons
You are allocating space for 9 pointers, not 9 characters.
You don't really need calloc() because you will overwrite the contents immediately, use malloc().
You overwrite the pointer with a string literal
origstr = "TheQuickBrownFoxJumpedOverTheLazyDog";
now you lost reference to the pointer returned earlier by calloc() and you cannot possible free() it, you should only free() pointers return by malloc()/calloc()/realloc().
The truth is, you don't need to calloc() the oristring pointer, calloc()/malloc() are not used to allow you to assign to a pointer, but to write to the memory pointed to by the pointer, or better, to point to some memory you can read/write from/to.

Custom allocator: Valgrind shows 7 allocs, 0 frees, no leaks

I am working on a clone of the malloc (3) functions (malloc, realloc and free for now).
I would like to add support for Valgrind. I'm using these docs. However, after adding calls to the VALGRIND_MEMPOOL_FREE, VALGRIND_MEMPOOL_ALLOC and VALGRIND_CREATE_MEMPOOL macros, I get the following from Valgrind:
==22303== HEAP SUMMARY:
==22303== in use at exit: 0 bytes in 0 blocks
==22303== total heap usage: 7 allocs, 0 frees, 2,039 bytes allocated
==22303==
==22303== All heap blocks were freed -- no leaks are possible
This is despite my realloc calling VALGRIND_MEMPOOL_FREE and my free calling VALGRIND_MEMPOOL_FREE.
What could be the cause of this ?
What could be the cause of this ?
This is due to a bug in valgrind. See the link to the valgrind bug tracker in my comment to your answer.
From the other link in my comment:
A cursory search through the source code indicates that MEMPOOL_ALLOC
calls new_block, which increments cmalloc_n_mallocs, but there is no
corresponding change to cmalloc_n_frees in MEMPOOL_FREE.
/* valgrind.c */
#include <valgrind/valgrind.h>
int main(int argc, char *argv[]) {
char pool[100];
VALGRIND_CREATE_MEMPOOL(pool, 0, 0);
VALGRIND_MEMPOOL_ALLOC(pool, pool, 8);
VALGRIND_MEMPOOL_FREE(pool, pool);
VALGRIND_DESTROY_MEMPOOL(pool);
return 0;
}
$ gcc valgrind.c -g
$ valgrind --leak-check=full --show-leak-kinds=all ./a.out
==10186== Memcheck, a memory error detector
==10186== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==10186== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==10186== Command: ./a.out
==10186==
==10186==
==10186== HEAP SUMMARY:
==10186== in use at exit: 0 bytes in 0 blocks
==10186== total heap usage: 1 allocs, 0 frees, 8 bytes allocated
==10186==
==10186== All heap blocks were freed -- no leaks are possible
==10186==
==10186== For counts of detected and suppressed errors, rerun with: -v
==10186== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
Taken from here: http://valgrind.10908.n7.nabble.com/VALGRIND-MEMPOOL-FREE-not-reflected-in-heap-summary-td42789.html
A cursory search through the source code indicates that MEMPOOL_ALLOC
calls new_block, which increments cmalloc_n_mallocs, but there is no
corresponding change to cmalloc_n_frees in MEMPOOL_FREE. Here's a
patch that increments it at the very end of MEMPOOL_FREE. This gives
me the behavior I expect.

wchar_t valgrind issue - Invalid read of size 8

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.

strcpy valgrind invalid read of size [duplicate]

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)

Resources