I've written a toy function using pointer arrays from GLib:
#include <glib-2.0/glib.h>
#include <stdio.h>
void append_string(GArray* arr) {
g_array_append_vals(arr, "foo", 1);
}
int main() {
GPtrArray *arr = g_ptr_array_new();
append_string((GArray*)arr);
g_ptr_array_free(arr, TRUE);
return 0;
}
However, running this with valgrind gives:
==5876== Memcheck, a memory error detector
==5876== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5876== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==5876== Command: ./demo
==5876==
==5876== Conditional jump or move depends on uninitialised value(s)
==5876== at 0x4E532E9: ??? (in /usr/lib/libglib-2.0.so.0.4800.0)
==5876== by 0x4E536A7: g_array_append_vals (in /usr/lib/libglib-2.0.so.0.4800.0)
==5876== by 0x400727: append_string (main_arrays.c:5)
==5876== by 0x400747: main (main_arrays.c:11)
==5876==
==5876== Conditional jump or move depends on uninitialised value(s)
==5876== at 0x4E532EE: ??? (in /usr/lib/libglib-2.0.so.0.4800.0)
==5876== by 0x4E536A7: g_array_append_vals (in /usr/lib/libglib-2.0.so.0.4800.0)
==5876== by 0x400727: append_string (main_arrays.c:5)
==5876== by 0x400747: main (main_arrays.c:11)
==5876==
==5876== Conditional jump or move depends on uninitialised value(s)
==5876== at 0x4E536C9: g_array_append_vals (in /usr/lib/libglib-2.0.so.0.4800.0)
==5876== by 0x400727: append_string (main_arrays.c:5)
==5876== by 0x400747: main (main_arrays.c:11)
==5876==
==5876==
==5876== HEAP SUMMARY:
==5876== in use at exit: 18,604 bytes in 6 blocks
==5876== total heap usage: 8 allocs, 2 frees, 18,652 bytes allocated
==5876==
==5876== LEAK SUMMARY:
==5876== definitely lost: 0 bytes in 0 blocks
==5876== indirectly lost: 0 bytes in 0 blocks
==5876== possibly lost: 0 bytes in 0 blocks
==5876== still reachable: 18,604 bytes in 6 blocks
==5876== suppressed: 0 bytes in 0 blocks
==5876== Rerun with --leak-check=full to see details of leaked memory
==5876==
==5876== For counts of detected and suppressed errors, rerun with: -v
==5876== Use --track-origins=yes to see where uninitialised values come from
==5876== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
Am I misusing the API, is this a bug in GLib, or is valgrind wrong? If it's a valgrind limitation, can I silence this valgrind warning whilst still having valgrind warn on genuine issues in my code?
GArray and GPtrArray are not equivalent. There's no subtyping here, even if they have same public fields.
Use g_ptr_array_add instead:
void append_string(GPtrArray* arr) {
g_ptr_array_add(arr, "foo");
}
Related
I try to compile and run the following:
valgrind --tool=memcheck --leak-check=full ./main
The program is compiled from the following source:
#include <pthread.h>
#include <stdio.h>
void* myfunc(void* arg) {
printf("I'm in a new thread!\n");
return NULL;
}
int main() {
printf("I'm in the main thread!\n");
pthread_attr_t attr;
pthread_t thread;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&thread, &attr, &myfunc, NULL);
pthread_attr_destroy(&attr);
pthread_exit(0);
}
Sometimes, Valgrind reports that "no leaks are possible", but sometimes, Valgrind reports the following:
==59== Memcheck, a memory error detector
==59== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==59== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==59== Command: ./main
==59==
I'm in the main thread!
I'm in a new thread!
==59==
==59== HEAP SUMMARY:
==59== in use at exit: 272 bytes in 1 blocks
==59== total heap usage: 7 allocs, 6 frees, 2,990 bytes allocated
==59==
==59== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==59== at 0x4C33B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==59== by 0x4013646: allocate_dtv (dl-tls.c:286)
==59== by 0x4013646: _dl_allocate_tls (dl-tls.c:530)
==59== by 0x51E4227: allocate_stack (allocatestack.c:627)
==59== by 0x51E4227: pthread_create##GLIBC_2.2.5 (pthread_create.c:644)
==59== by 0x40074A: main (in /home/runner/p3tdz9ggpuq/main)
==59==
==59== LEAK SUMMARY:
==59== definitely lost: 0 bytes in 0 blocks
==59== indirectly lost: 0 bytes in 0 blocks
==59== possibly lost: 272 bytes in 1 blocks
==59== still reachable: 0 bytes in 0 blocks
==59== suppressed: 0 bytes in 0 blocks
==59==
==59== For counts of detected and suppressed errors, rerun with: -v
==59== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Is there any way to not have any reported "possibly lost" bytes with a detached thread?
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();
}
I'm sorry if i eventually do something wrong.
Ok my problem is the following:
I just coded something very easy, but when you take a look at the Valgrind error output it just confuses me.
Code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int num1 = 100;
double num2 = 1.2;
printf("Number 1 one is: %d.\n Number two is: %f.\n", num1, num2);
return 0;
}
Valgrind error report:
$ valgrind --leak-check=full ./yaq
==50642== Memcheck, a memory error detector
==50642== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==50642== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==50642== Command: ./yaq
==50642==
--50642-- ./yaq:
--50642-- dSYM directory has wrong UUID; consider using --dsymutil=yes
==50642== Conditional jump or move depends on uninitialised value(s)
==50642== at 0x1003FCC3F: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==50642== by 0x1001F0B96: __sfvwrite (in /usr/lib/system/libsystem_c.dylib)
==50642== by 0x1001FAFE5: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==50642== by 0x1002209AE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==50642== by 0x100220C80: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==50642== by 0x1001F6B71: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==50642== by 0x1001F49D7: printf (in /usr/lib/system/libsystem_c.dylib)
==50642== by 0x100000F32: main (in ./yaq)
==50642==
Number 1 one is: 100.
Number two is: 1.200000.
==50642==
==50642== HEAP SUMMARY:
==50642== in use at exit: 38,673 bytes in 427 blocks
==50642== total heap usage: 510 allocs, 83 frees, 44,945 bytes.
==50642== To see them, rerun with: --leak-check=full --show-leak- kinds=all
==50642==
==50642== For counts of detected and suppressed errors, rerun with: -v
==50642== Use --track-origins=yes to see where uninitialised values come from
==50642== ERROR SUMMARY: 3 errors from 1 contexts (suppressed: 17 from 17)
Why does it say 3 errors ?
Thanks in advance.
Best regards
You may be able to see them if you run with --show-leak-kinds=all:
==96034== Memcheck, a memory error detector
==96034== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==96034== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==96034== Command: ./yaq
==96034==
--96034-- ./yaq:
--96034-- dSYM directory is missing; consider using --dsymutil=yes
==96034== Conditional jump or move depends on uninitialised value(s)
==96034== by 0x10021FCA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001F5B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001F39F7: printf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x100000F32: main (in ./yaq)
==96034==
==96034== 80 bytes in 1 blocks are still reachable in loss record 48 of 85
==96034== at 0x10000859B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==96034== by 0x1001D1756: __Balloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001D2075: __d2b_D2A (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001CE88B: __dtoa (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001F6D72: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x10021F9CE: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x10021FCA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001F5B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001F39F7: printf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x100000F32: main (in ./yaq)
==96034==
==96034== 4,096 bytes in 1 blocks are still reachable in loss record 85 of 85
==96034== at 0x10000859B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==96034== by 0x1001F0856: __smakebuf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1002053A7: __swsetup (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x10021F77D: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x10021FCA0: __xvprintf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001F5B91: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x1001F39F7: printf (in /usr/lib/system/libsystem_c.dylib)
==96034== by 0x100000F32: main (in ./yaq)
==96034==
==96034== LEAK SUMMARY:
==96034== definitely lost: 0 bytes in 0 blocks
==96034== indirectly lost: 0 bytes in 0 blocks
==96034== possibly lost: 0 bytes in 0 blocks
==96034== still reachable: 4,244 bytes in 4 blocks
==96034== suppressed: 34,783 bytes in 425 blocks
==96034==
==96034== For counts of detected and suppressed errors, rerun with: -v
==96034== Use --track-origins=yes to see where uninitialised values come from
==96034== ERROR SUMMARY: 3 errors from 1 contexts (suppressed: 18 from 18)
Those are issues in the OS X system libraries. I suppressed them by generating this suppressions file with valgrind --leak-check=yes --show-leak-kinds=all --gen-suppressions=yes ./yaq. The output is a bit cleaner then:
$ valgrind --leak-check=yes --show-leak-kinds=all --suppressions=yaq.supp ./yaq [7:47:49]
==96285== Memcheck, a memory error detector
==96285== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==96285== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==96285== Command: ./yaq
==96285==
--96285-- ./yaq:
--96285-- dSYM directory is missing; consider using --dsymutil=yes
Number 1 one is: 100.
Number two is: 1.200000.
==96285==
==96285== HEAP SUMMARY:
==96285== in use at exit: 39,027 bytes in 429 blocks
==96285== total heap usage: 510 allocs, 81 frees, 45,171 bytes allocated
==96285==
==96285== LEAK SUMMARY:
==96285== definitely lost: 0 bytes in 0 blocks
==96285== indirectly lost: 0 bytes in 0 blocks
==96285== possibly lost: 0 bytes in 0 blocks
==96285== still reachable: 0 bytes in 0 blocks
==96285== suppressed: 39,027 bytes in 429 blocks
==96285==
==96285== For counts of detected and suppressed errors, rerun with: -v
==96285== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 21 from 19)
Valgrind support on OS X is currently being actively worked on. Your best approach is to ensure you are using a SVN trunk build, and update frequently.
The errors Valgrind is reporting to you are present within the OS X system libraries. These are not the fault of your program, but because even simple programs including these system libraries Valgrind continues to pick them up. Suppressions within Valgrind trunk are continually being updated to catch these issues, allowing you to focus on the real problems that may be present within your code.
The following commands will allow you to use Valgrind trunk, if you're not already:
svn co svn://svn.valgrind.org/valgrind/trunk valgrind
cd valgrind
./autogen.sh
./configure
make -j4
sudo make install
Valgrind reports definitely lost memory if I exit main with return 0;, but reports still reachable memory if I exit main with exit(0);.
test-reachable.c:
#include <stdlib.h>
int main() {
void *data = malloc(256);
exit(0);
}
test-lost.c:
#include <stdlib.h>
int main() {
void *data = malloc(256);
return 0;
}
Behavior:
$ gcc test-reachable.c -o test-reachable
$ valgrind --leak-check=yes ./test-reachable
==7696== Memcheck, a memory error detector
==7696== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7696== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7696== Command: ./test-reachable
==7696==
==7696==
==7696== HEAP SUMMARY:
==7696== in use at exit: 256 bytes in 1 blocks
==7696== total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7696==
==7696== LEAK SUMMARY:
==7696== definitely lost: 0 bytes in 0 blocks
==7696== indirectly lost: 0 bytes in 0 blocks
==7696== possibly lost: 0 bytes in 0 blocks
==7696== still reachable: 256 bytes in 1 blocks
==7696== suppressed: 0 bytes in 0 blocks
==7696== Reachable blocks (those to which a pointer was found) are not shown.
==7696== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==7696==
==7696== For counts of detected and suppressed errors, rerun with: -v
==7696== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ gcc test-lost.c -o test-lost
$ valgrind --leak-check=yes ./test-lost
==7774== Memcheck, a memory error detector
==7774== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7774== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7774== Command: ./test-lost
==7774==
==7774==
==7774== HEAP SUMMARY:
==7774== in use at exit: 256 bytes in 1 blocks
==7774== total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7774==
==7774== 256 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7774== at 0x4C2C080: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7774== by 0x40051C: main (in /tmp/test-lost)
==7774==
==7774== LEAK SUMMARY:
==7774== definitely lost: 256 bytes in 1 blocks
==7774== indirectly lost: 0 bytes in 0 blocks
==7774== possibly lost: 0 bytes in 0 blocks
==7774== still reachable: 0 bytes in 0 blocks
==7774== suppressed: 0 bytes in 0 blocks
==7774==
==7774== For counts of detected and suppressed errors, rerun with: -v
==7774== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Shouldn't these behave the same?
Shouldn't these behave the same?
No.
In test-reachable.c the memory is referenced by the stack variable data at the time of the exit of the program, so it is still reachable, while in test-lost.c the memory is not referenced anymore because the main function has already returned, the reference does not exist anymore, the memory is definitely lost.
In C++ when return in main() is called then the destructors will be called for locally scoped objects whereas if exit() is called then no destructor will be called for locally scoped objects.
I think this is similar in C with regards to objects allocated on the stack.
That probably explains why in the return case non freed memory is treated as definitely lost and in the exit(0) case the memory is reported as still reachable.
Consider this code:
#include <stdlib.h>
int* alloc()
{
return malloc(250 * sizeof(int));
}
int main()
{
int i;
int *vars[3];
for(i = 0; i < 3; ++i) {
vars[i] = alloc();
}
}
Valgrind output:
$ valgrind --leak-check=full ./lala
==16775== Memcheck, a memory error detector
==16775== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==16775== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==16775== Command: ./lala
==16775==
==16775==
==16775== HEAP SUMMARY:
==16775== in use at exit: 3,000 bytes in 3 blocks
==16775== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==16775==
==16775== 3,000 bytes in 3 blocks are definitely lost in loss record 1 of 1
==16775== at 0x4C2BBA0: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16775== by 0x4005B3: alloc (lala.c:5)
==16775== by 0x4005DF: main (lala.c:13)
==16775==
==16775== LEAK SUMMARY:
==16775== definitely lost: 3,000 bytes in 3 blocks
==16775== indirectly lost: 0 bytes in 0 blocks
==16775== possibly lost: 0 bytes in 0 blocks
==16775== still reachable: 0 bytes in 0 blocks
==16775== suppressed: 0 bytes in 0 blocks
==16775==
==16775== For counts of detected and suppressed errors, rerun with: -v
==16775== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
According to Valgrind's manual:
If --leak-check is set appropriately, for each remaining block,
Memcheck determines if the block is reachable from pointers within the
root-set. The root-set consists of (a) general purpose registers of
all threads, and (b) initialized, aligned, pointer-sized data words in
accessible client memory, including stacks.
For what I understand, since the "definitely lost" memory are still pointed to from the main() function's stack, they should be categorized as "still reachable", right?
If not, how can I configure Valgrind to try to reach memory blocks from main's stack, to determine if they are "still reachable"?
EDIT:
Please don't tell me to free the pointers at the end of main, that is not what I am asking about. For the distinction between "still reachable" and "definitely lost" on Valgrind terms, see this answer: https://stackoverflow.com/a/3857638/578749
Your memory is definitely lost when the stack of main is destroyed, that is, when it returns. Thus, the solution is not to return.
#include <stdlib.h>
int main()
{
/* your code here */
exit(0);
}
The behavior or main returning 0 or exit(0) should be equivalent.
Now the output is:
==5035== Memcheck, a memory error detector
==5035== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==5035== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==5035== Command: ./a.out
==5035==
==5035==
==5035== HEAP SUMMARY:
==5035== in use at exit: 3,000 bytes in 3 blocks
==5035== total heap usage: 3 allocs, 0 frees, 3,000 bytes allocated
==5035==
==5035== LEAK SUMMARY:
==5035== definitely lost: 0 bytes in 0 blocks
==5035== indirectly lost: 0 bytes in 0 blocks
==5035== possibly lost: 0 bytes in 0 blocks
==5035== still reachable: 3,000 bytes in 3 blocks
==5035== suppressed: 0 bytes in 0 blocks
==5035== Reachable blocks (those to which a pointer was found) are not shown.
==5035== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==5035==
==5035== For counts of detected and suppressed errors, rerun with: -v
==5035== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)