The following code compiles correctly and valgrind reports no leaks:
# include <libxml/encoding.h>
# include <libxml/xmlwriter.h>
int main(void) {
xmlTextWriterPtr XMLWriter = xmlNewTextWriterFilename("example.xml", 0);
xmlTextWriterStartDocument(XMLWriter, NULL, NULL, NULL);
xmlTextWriterEndDocument(XMLWriter);
xmlFreeTextWriter(XMLWriter);
xmlCleanupParser();
return 0;
}
-----------------------------------------
==26059== HEAP SUMMARY:
==26059== in use at exit: 0 bytes in 0 blocks
==26059== total heap usage: 16 allocs, 16 frees, 4,774 bytes allocated
==26059==
==26059== All heap blocks were freed -- no leaks are possible
Once the encoding is specified in the xmlNewTextWriterFilename call, however, hilary ensues:
# include <libxml/encoding.h>
# include <libxml/xmlwriter.h>
int main(void) {
xmlTextWriterPtr XMLWriter = xmlNewTextWriterFilename("example.xml", 0);
xmlTextWriterStartDocument(XMLWriter, NULL, "UTF-8", NULL);
xmlTextWriterEndDocument(XMLWriter);
xmlFreeTextWriter(XMLWriter);
xmlCleanupParser();
return 0;
}
-----------------------------------------
==26082== HEAP SUMMARY:
==26082== in use at exit: 422 bytes in 17 blocks
==26082== total heap usage: 36 allocs, 19 frees, 9,224 bytes allocated
==26082==
==26082== 5 bytes in 1 blocks are still reachable in loss record 1 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x494942FF: ???
==26082==
==26082== 6 bytes in 1 blocks are still reachable in loss record 2 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x37: ???
==26082==
==26082== 6 bytes in 1 blocks are still reachable in loss record 3 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x39350048: ???
==26082==
==26082== 7 bytes in 1 blocks are still reachable in loss record 4 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x45003630: ???
==26082==
==26082== 9 bytes in 1 blocks are still reachable in loss record 5 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x454C3630: ???
==26082==
==26082== 9 bytes in 1 blocks are still reachable in loss record 6 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x45423630: ???
==26082==
==26082== 9 bytes in 1 blocks are still reachable in loss record 7 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x49494352: ???
==26082==
==26082== 11 bytes in 1 blocks are still reachable in loss record 8 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x40EC23B: xmlStrndup (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x39353837: ???
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 9 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EB28: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 10 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EB44: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 11 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EB6C: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 12 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EB94: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 13 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EBB6: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 14 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EBCC: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 15 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EBE2: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 20 bytes in 1 blocks are still reachable in loss record 16 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406E9D1: xmlNewCharEncodingHandler (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x406EC02: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== 200 bytes in 1 blocks are still reachable in loss record 17 of 17
==26082== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==26082== by 0x406EABE: xmlInitCharEncodingHandlers (in /usr/lib/i386-linux-gnu/libxml2.so.2.7.8)
==26082== by 0x41B54D2: (below main) (libc-start.c:226)
==26082==
==26082== LEAK SUMMARY:
==26082== definitely lost: 0 bytes in 0 blocks
==26082== indirectly lost: 0 bytes in 0 blocks
==26082== possibly lost: 0 bytes in 0 blocks
==26082== still reachable: 422 bytes in 17 blocks
==26082== suppressed: 0 bytes in 0 blocks
What do? This is homework stuff - can't ignore valgrind results.
Add a call to xmlCleanupCharEncodingHandlers() right before the call to xmlCleanupParser().
On my Mac OS 10.7.5 dev machine (libxml 20703), this fixes the reported "still reachable" leaks in libxml2.
By the way, ??? means that the debugging symbols for the object file are not available. It can be very helpful when tracking down memory leaks to have this information. The procedure for installing debugging information depends on the Linux distribution. On Ubuntu, for example, you can install the libxml2 debugging information with sudo apt-get install libxml2-dbg. See https://live.gnome.org/GettingTraces/DistroSpecificInstructions
Related
I would like to implement an application which is in charge of running several tasks in parallel.
Before adding real tasks, I tried to set the base but the program returns various error when executing by valgrind.
==4827== Thread 3:
==4827== Invalid free() / delete / delete[] / realloc()
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Address 0x5420070 is 48 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827== Thread 1:
==4827== Invalid read of size 8
==4827== at 0x400CD3: main (in /home/test)
==4827== Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827== Invalid read of size 8
==4827== at 0x400CFF: main (in /home/test)
==4827== Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827== Invalid read of size 8
==4827== at 0x400D30: main (in /home/test)
==4827== Address 0x5420060 is 32 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
tstop
==4827== Invalid write of size 8
==4827== at 0x400D5B: main (in /home/test)
==4827== Address 0x5420068 is 40 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
tstop
==4827== Invalid free() / delete / delete[] / realloc()
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400D8C: main (in /home/test)
==4827== Address 0x5420040 is 0 bytes inside a block of size 96 free'd
==4827== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400E31: my_handler (in /home/test)
==4827== by 0x4E416F9: start_thread (pthread_create.c:333)
==4827== Block was alloc'd at
==4827== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4827== by 0x400B75: main (in /home/test)
==4827==
==4827==
==4827== HEAP SUMMARY:
==4827== in use at exit: 1,614 bytes in 4 blocks
==4827== total heap usage: 9 allocs, 7 frees, 3,334 bytes allocated
==4827==
==4827== LEAK SUMMARY:
==4827== definitely lost: 0 bytes in 0 blocks
==4827== indirectly lost: 0 bytes in 0 blocks
==4827== possibly lost: 0 bytes in 0 blocks
==4827== still reachable: 1,614 bytes in 4 blocks
==4827== suppressed: 0 bytes in 0 blocks
I guess these errors are related to memory accessing already freed and invalid free().
However, I can not really understand how and why they occur.
typedef int (*init)();
typedef int (*launch)();
typedef int (*stop)();
typedef struct stTask stTask_t;
typedef struct stEngine stEngine_t;
struct stTask
{
char name[10];
init initTask;
launch launchTask;
stop stopTask;
pthread_t tId;
};
struct stEngine
{
int16_t NbTasks;
stTask_t* TaskThread;
};
static void sig_handler(int signo);
static int tinit(void);
static int tlaunch(void);
static int tstop(void);
static void* my_handler(void* params);
stTask_t array[] =
{
{"TEST", (init)tinit, (launch)tlaunch, (stop)tstop, 0},
{"TEST2", (init)tinit, (launch)tlaunch, (stop)tstop, 0}
};
int exitReq;
stEngine_t engine;
int main (int argc, char *argv[])
{
struct sigaction action;
int i;
exitReq = 0;
memset(&engine, 0, sizeof(stEngine_t));
engine.NbTasks = 2;
memset(&action, '\0', sizeof(action));
action.sa_handler = &sig_handler;
sigfillset(&action.sa_mask);
action.sa_flags = 0;
if ((sigaction(SIGTERM, &action, NULL) != 0) || (sigaction(SIGINT, &action, NULL) != 0)) {
exit(EXIT_FAILURE);
}
engine.TaskThread = malloc(engine.NbTasks * sizeof(stTask_t));
for (i = 0; i < engine.NbTasks; i++) {
engine.TaskThread[i] = array[i];
engine.TaskThread[i].initTask();
pthread_create(&engine.TaskThread[i].tId, NULL, my_handler, (void *) &engine.TaskThread[i]);
}
while (!exitReq) {
//... do stuff
sched_yield();
}
for (i = 0; i < engine.NbTasks; i++) {
(void)pthread_cancel(engine.TaskThread[i].tId);
pthread_join(engine.TaskThread[i].tId, NULL);
engine.TaskThread[i].stopTask();
engine.TaskThread[i].tId = 0;
}
free(engine.TaskThread);
memset(&engine, 0, sizeof(stEngine_t));
return 0;
}
static void sig_handler(int signo)
{
if (signo == SIGINT || signo == SIGTERM) {
exitReq = 1;
}
}
static void* my_handler(void* params)
{
stTask_t* ptask = (stTask_t*) params;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
while (!exitReq) {
ptask->launchTask();
pthread_testcancel();
}
free(ptask);
pthread_exit(NULL);
}
static int tinit(void)
{
fprintf(stdout, "%s\n", __func__);
return 0;
}
static int tlaunch(void)
{
fprintf(stdout, "%s\n", __func__);
return 0;
}
static int tstop(void)
{
fprintf(stdout, "%s\n", __func__);
return 0;
}
By adding a comment into the handling function: I got no error but several bytes are still allocated when the program is manually stopped.
//free(ptask);
I get no error but several bytes are still allocated when the program is manually stopped.
As required I pass the struc's address as last parameter of pthread_create, but I probably misunderstand something about the memory
==6017== HEAP SUMMARY:
==6017== in use at exit: 1,614 bytes in 4 blocks
==6017== total heap usage: 9 allocs, 5 frees, 3,334 bytes allocated
==6017==
==6017== LEAK SUMMARY:
==6017== definitely lost: 0 bytes in 0 blocks
==6017== indirectly lost: 0 bytes in 0 blocks
==6017== possibly lost: 0 bytes in 0 blocks
==6017== still reachable: 1,614 bytes in 4 blocks
==6017== suppressed: 0 bytes in 0 blocks
Could someone explain me why, in both cases, memory is not freed correctly ?
I've tried the following code on GeoIP 1.4.8 and 1.6.6 and it's only freeing 5 allocs out of 40 allocs reported by valgrind.
I'm aware of the "still reachable" according to this post, but I want to make sure that's the case in here. It does seem odd to me is only freeing 5 allocs. Any ideas?
==1687== HEAP SUMMARY:
==1687== in use at exit: 35,128 bytes in 35 blocks
==1687== total heap usage: 40 allocs, 5 frees, 36,847 bytes allocated
==1687==
==1687== 312 bytes in 1 blocks are still reachable in loss record 1 of 35
==1687== at 0x4C2C947: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1687== by 0x4E3DA5E: _GeoIP_setup_dbfilename (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x4E3E789: GeoIP_new (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x40075E: main (in /home/pixie/a.out)
==1687==
==1687== 1,024 bytes in 1 blocks are still reachable in loss record 2 of 35
==1687== at 0x4C2C947: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1687== by 0x4E3D9A5: _GeoIP_full_path_to (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x4E3DA70: _GeoIP_setup_dbfilename (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x4E3E789: GeoIP_new (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x40075E: main (in /home/pixie/a.out)
==1687==
==1687== 1,024 bytes in 1 blocks are still reachable in loss record 3 of 35
==1687== at 0x4C2C947: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1687== by 0x4E3D9A5: _GeoIP_full_path_to (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x4E3DA83: _GeoIP_setup_dbfilename (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x4E3E789: GeoIP_new (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x40075E: main (in /home/pixie/a.out)
==1687==
==1687== 1,024 bytes in 1 blocks are still reachable in loss record 4 of 35
==1687== at 0x4C2C947: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1687== by 0x4E3D9A5: _GeoIP_full_path_to (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x4E3DA96: _GeoIP_setup_dbfilename (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x4E3E789: GeoIP_new (in /usr/lib/libGeoIP.so.1.6.6)
==1687== by 0x40075E: main (in /home/pixie/a.out)
...
Code
#include <GeoIP.h>
int main (int argc, char **argv) {
GeoIP * gp;
gp = GeoIP_new(GEOIP_STANDARD);
printf("%s\n", GeoIP_country_code_by_addr(gp, "216.58.216.238"));
GeoIP_delete(gp);
return 0;
}
Apparently the following call does the job (not documented).
GeoIP_cleanup();
I've been getting this error whenever i run a full valgrind memory leak check and I really can't tell where the source of this error is. My code is running and appears to be correct but i've been getting this error since. Any advice would be much appreciated, thank you!
==2312== HEAP SUMMARY:
==2312== in use at exit: 26,325 bytes in 190 blocks
==2312== total heap usage: 20,531 allocs, 20,341 frees, 197,089 bytes allocated
==2312==
==2312== Searching for pointers to 190 not-freed blocks
==2312== Checked 9,805,752 bytes
==2312==
==2312== 272 (80 direct, 192 indirect) bytes in 1 blocks are definitely lost in loss record 53 of 67
==2312== at 0x100009EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2312== by 0x1001C44A2: __Balloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==2312== by 0x1001C4DEB: __d2b_D2A (in /usr/lib/system/libsystem_c.dylib)
==2312== by 0x1001C1443: __dtoa (in /usr/lib/system/libsystem_c.dylib)
==2312== by 0x1001EA07A: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==2312== by 0x10021335C: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==2312== by 0x1001E901D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==2312== by 0x1001E6EB7: printf (in /usr/lib/system/libsystem_c.dylib)
==2312== by 0x100001B02: main (in ./tldmonitor)
==2312==
==2312== LEAK SUMMARY:
==2312== definitely lost: 80 bytes in 1 blocks
==2312== indirectly lost: 192 bytes in 5 blocks
==2312== possibly lost: 0 bytes in 0 blocks
==2312== still reachable: 0 bytes in 0 blocks
==2312== suppressed: 26,053 bytes in 184 blocks
==2312==
==2312== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 16 from 16)
--2312--
--2312-- used_suppression: 1 OSX1011:21-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:944 suppressed: 4,096 bytes in 1 blocks
--2312-- used_suppression: 1 OSX1011:15-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:886 suppressed: 4,096 bytes in 1 blocks
--2312-- used_suppression: 10 OSX1011:17-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:906 suppressed: 3,392 bytes in 55 blocks
--2312-- used_suppression: 3 OSX1011:16-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:897 suppressed: 2,816 bytes in 44 blocks
--2312-- used_suppression: 2 OSX1011:4-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:778 suppressed: 4,152 bytes in 2 blocks
--2312-- used_suppression: 2 OSX1011:19-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:924 suppressed: 2,592 bytes in 2 blocks
--2312-- used_suppression: 7 OSX1011:7-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:808 suppressed: 1,680 bytes in 22 blocks
--2312-- used_suppression: 11 OSX1011:18-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:915 suppressed: 2,312 bytes in 11 blocks
--2312-- used_suppression: 20 OSX1011:10-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:839 suppressed: 2,461 bytes in 39 blocks
--2312-- used_suppression: 2 OSX1011:8-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:819 suppressed: 520 bytes in 2 blocks
--2312-- used_suppression: 2 OSX1011:20-Leak /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/default.supp:934 suppressed: 224 bytes in 5 blocks
==2312==
==2312== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 16 from 16)
After i generate a suppression block:
==2317== HEAP SUMMARY:
==2317== in use at exit: 26,325 bytes in 190 blocks
==2317== total heap usage: 20,531 allocs, 20,341 frees, 197,089 bytes allocated
==2317==
==2317== Searching for pointers to 190 not-freed blocks
==2317== Checked 9,805,752 bytes
==2317==
==2317== 272 (80 direct, 192 indirect) bytes in 1 blocks are definitely lost in loss record 53 of 67
==2317== at 0x100009EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==2317== by 0x1001C44A2: __Balloc_D2A (in /usr/lib/system/libsystem_c.dylib)
==2317== by 0x1001C4DEB: __d2b_D2A (in /usr/lib/system/libsystem_c.dylib)
==2317== by 0x1001C1443: __dtoa (in /usr/lib/system/libsystem_c.dylib)
==2317== by 0x1001EA07A: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==2317== by 0x10021335C: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==2317== by 0x1001E901D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==2317== by 0x1001E6EB7: printf (in /usr/lib/system/libsystem_c.dylib)
==2317== by 0x100001B02: main (in ./tldmonitor)
==2317==
==2317==
Turns out it was a false leak, tested my code on a linux virtual machine and no errors. Thanks.
I want to read in from the arguments a file with a name of format filename.in and output a file with the exact same filename but with .out extension instead of .in (filename.out). The key is that filename can be anything.
This code compiles correctly and does the job I want, but when I run it with valgrind I get a bunch of errors. Can anyone tell me what's causing the errors?
int main(int argc, char * argv[])
{
int i, dotIndex;
char extOut[] = ".out";
char *filenameIn, *filenameOut, *aux;
FILE *fpIn, *fpOut;
filenameIn = argv[1];
aux = strchr(filenameIn, '.');
dotIndex = aux - filenameIn;
aux = (char *)malloc((strlen(filenameIn) - 1)*sizeof(char));
for(i = 0; i < dotIndex; i++)
aux[i] = filenameIn[i];
filenameOut = (char *)malloc((strlen(aux) + 5)*sizeof(char));
strcat(aux, extOut);
strcpy(filenameOut, aux);
/* open input file */
fpIn = fopen(filenameIn,"r");
if(fpIn == NULL) {
printf("Open error of input file\n");
exit(2);
}
/* open output file */
fpOut = fopen(filenameOut,"w");
if(fpOut == NULL) {
printf("Open error of output file\n");
exit(3);
}
fclose(fpOut);
fclose(fpIn);
free(aux);
free(filenameOut);
exit(0);
}
The valgrind report:
Command: ./doorsmaze text.in
==3493==
==3493== Invalid write of size 1
==3493== at 0x402C36B: strcat (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x80487AB: main (main.c:64)
==3493== Address 0x41ef02e is 0 bytes after a block of size 6 alloc'd
==3493== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x8048716: main (main.c:55)
==3493==
==3493== Invalid write of size 1
==3493== at 0x402C390: strcat (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x80487AB: main (main.c:64)
==3493== Address 0x41ef030 is 2 bytes after a block of size 6 alloc'd
==3493== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x8048716: main (main.c:55)
==3493==
==3493== Invalid read of size 1
==3493== at 0x402C6C5: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x80487BF: main (main.c:65)
==3493== Address 0x41ef02e is 0 bytes after a block of size 6 alloc'd
==3493== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x8048716: main (main.c:55)
==3493==
==3493==
==3493== HEAP SUMMARY:
==3493== in use at exit: 0 bytes in 0 blocks
==3493== total heap usage: 4 allocs, 4 frees, 719 bytes allocated
==3493==
==3493== All heap blocks were freed -- no leaks are possible
==3493== Command: ./doorsmaze text.in
==3493==
==3493== Invalid write of size 1
==3493== at 0x402C36B: strcat (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x80487AB: main (main.c:64)
==3493== Address 0x41ef02e is 0 bytes after a block of size 6 alloc'd
==3493== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x8048716: main (main.c:55)
==3493==
==3493== Invalid write of size 1
==3493== at 0x402C390: strcat (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x80487AB: main (main.c:64)
==3493== Address 0x41ef030 is 2 bytes after a block of size 6 alloc'd
==3493== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x8048716: main (main.c:55)
==3493==
==3493== Invalid read of size 1
==3493== at 0x402C6C5: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x80487BF: main (main.c:65)
==3493== Address 0x41ef02e is 0 bytes after a block of size 6 alloc'd
==3493== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3493== by 0x8048716: main (main.c:55)
==3493==
==3493==
==3493== HEAP SUMMARY:
==3493== in use at exit: 0 bytes in 0 blocks
==3493== total heap usage: 4 allocs, 4 frees, 719 bytes allocated
==3493==
==3493== All heap blocks were freed -- no leaks are possible
==3493==
==3493== For counts of detected and suppressed errors, rerun with: -v
==3493== ERROR SUMMARY: 6 errors from 3 contexts (suppressed: 0 from 0)
==3493== For counts of detected and suppressed errors, rerun with: -v
==3493== ERROR SUMMARY: 6 errors from 3 contexts (suppressed: 0 from 0)
You have some issues in your code
You might not get the last . in the filename
aux = strchr(filenameIn, '.');
better use strrchr. You should also check for NULL, just in case the filename doesn't include an extension.
You allocate memory large enough to hold filename.in (excluding the nul byte)
aux = (char *)malloc((strlen(filenameIn) - 1)*sizeof(char));
You do your own version of strncpy(aux, filenameIn, dotIndex)
for(i = 0; i < dotIndex; i++)
aux[i] = filenameIn[i];`
You write beyond the allocated buffer, because you miss the space for the last character plus the nul byte
strcat(aux, extOut);
To fix this, you must allocate enough memory, which is the length of filename.in plus 1 char ("out" is one longer than "in") plus nul byte
aux = (char *)malloc((strlen(filenameIn) + 2)*sizeof(char));
This question is not a duplicate of many others, bekause I do use G_DEBUG=gc-friendly and G_SLICE=always-malloc
Here is the source code:
#include <glib.h>
int main (int argc, char *argv[])
{
GHashTable *ht;
ht=g_hash_table_new(g_str_hash,g_str_equal);
g_hash_table_insert(ht,"foo","bar");
g_hash_table_destroy(ht);
return 0;
}
And here is Valgrind's output on this code:
# G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --leak-check=full --show-reachable=yes ./test_vg
==1880== Memcheck, a memory error detector
==1880== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==1880== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==1880== Command: ./test_vg
==1880==
==1880==
==1880== HEAP SUMMARY:
==1880== in use at exit: 1,260 bytes in 3 blocks
==1880== total heap usage: 5 allocs, 2 frees, 1,524 bytes allocated
==1880==
==1880== 252 bytes in 1 blocks are still reachable in loss record 1 of 3
==1880== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==1880== by 0x35C8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C8255742: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C822B1D2: g_hash_table_new_full (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x400671: main (in /home/data/test_vg)
==1880==
==1880== 504 bytes in 1 blocks are still reachable in loss record 2 of 3
==1880== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==1880== by 0x35C8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C8255722: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C822B1D2: g_hash_table_new_full (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x400671: main (in /home/data/test_vg)
==1880==
==1880== 504 bytes in 1 blocks are still reachable in loss record 3 of 3
==1880== at 0x4A04A28: calloc (vg_replace_malloc.c:467)
==1880== by 0x35C8241707: g_malloc0 (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825578B: ??? (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C825669D: g_slice_alloc (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x35C822B1D2: g_hash_table_new_full (in /lib64/libglib-2.0.so.0.2200.5)
==1880== by 0x400671: main (in /home/data/test_vg)
==1880==
==1880== LEAK SUMMARY:
==1880== definitely lost: 0 bytes in 0 blocks
==1880== indirectly lost: 0 bytes in 0 blocks
==1880== possibly lost: 0 bytes in 0 blocks
==1880== still reachable: 1,260 bytes in 3 blocks
==1880== suppressed: 0 bytes in 0 blocks
==1880==
==1880== For counts of detected and suppressed errors, rerun with: -v
==1880== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Is it a memory-leak?
To answer your question: No, this is not a memory leak in the traditional sense. Your code is fine.
Even if you use G_DEBUG=gc-friendly and G_SLICE=always-malloc, GLib always leaves "still reachable" memory on exit. Don't use the --show-reachable=yes option, otherwise you'll always have a polluted Valgrind output when using GLib. However, be careful if you allocate memory to which you keep pointers in static or global variables ("still reachable" memory). In this case you might end up ignoring your own "real" leaks.
I have always had trouble with a lot of false and unreachable items when using Valgrind to check GLib 2 programs. In your case, the leaks seem to be from the creation of the hash table. I would create a second hash table and see if you get additional blocks (otherwise, it could be some internal initialization in GLib).
Some notes on using Valgrind with GLIB and GTK are at wiki.gnome.org.
Try passing --suppressions=/usr/share/glib-2.0/valgrind/glib.supp to valgrind. It suppresses the false positives from GLib.