I have just started using valgrind and am not very good with pointers so what I essentially want to do is pass the snake_thread s[1] variable as reference to all the functions so that I don't have to free the memory in each of the functions individually.
==20== HEAP SUMMARY:
==20== in use at exit: 17,704 bytes in 65 blocks
==20== total heap usage: 75 allocs, 10 frees, 32,646 bytes allocated
==20==
==20== 56 bytes in 1 blocks are still reachable in loss record 1 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10A068: initialize (snake_map_test.c:249)
==20== by 0x1098C1: main (snake_map_test.c:126)
==20==
==20== 56 bytes in 1 blocks are still reachable in loss record 2 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10A089: initialize (snake_map_test.c:250)
==20== by 0x1098C1: main (snake_map_test.c:126)
==20==
==20== 160 bytes in 1 blocks are still reachable in loss record 3 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10B992: Read_args (snake_map_test.c:571)
==20== by 0x109887: main (snake_map_test.c:122)
==20==
==20== 272 bytes in 1 blocks are possibly lost in loss record 4 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x40149CA: allocate_dtv (dl-tls.c:286)
==20== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
==20== by 0x485C322: allocate_stack (allocatestack.c:622)
==20== by 0x485C322: pthread_create##GLIBC_2.2.5 (pthread_create.c:660)
==20== by 0x10972E: main (snake_map_test.c:111)
==20==
==20== 272 bytes in 1 blocks are possibly lost in loss record 5 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x40149CA: allocate_dtv (dl-tls.c:286)
==20== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
==20== by 0x485C322: allocate_stack (allocatestack.c:622)
==20== by 0x485C322: pthread_create##GLIBC_2.2.5 (pthread_create.c:660)
==20== by 0x1098F8: main (snake_map_test.c:130)
==20==
==20== 400 bytes in 20 blocks are still reachable in loss record 6 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10BA1C: Read_args (snake_map_test.c:575)
==20== by 0x109887: main (snake_map_test.c:122)
==20==
==20== 5,880 bytes in 1 blocks are still reachable in loss record 7 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x10A048: initialize (snake_map_test.c:248)
==20== by 0x1098C1: main (snake_map_test.c:126)
==20==
==20== 10,608 bytes in 39 blocks are possibly lost in loss record 8 of 8
==20== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==20== by 0x40149CA: allocate_dtv (dl-tls.c:286)
==20== by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
==20== by 0x485C322: allocate_stack (allocatestack.c:622)
==20== by 0x485C322: pthread_create##GLIBC_2.2.5 (pthread_create.c:660)
==20== by 0x109DD4: run_snake_threads (snake_map_test.c:217)
==20== by 0x485B608: start_thread (pthread_create.c:477)
==20== by 0x4997292: clone (clone.S:95)
==20==
==20== LEAK SUMMARY:
==20== definitely lost: 0 bytes in 0 blocks
==20== indirectly lost: 0 bytes in 0 blocks
==20== possibly lost: 11,152 bytes in 41 blocks
==20== still reachable: 6,552 bytes in 24 blocks
==20== suppressed: 0 bytes in 0 blocks
==20==
==20== Use --track-origins=yes to see where uninitialised values come from
==20== For lists of detected and suppressed errors, rerun with: -s
==20== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
These are the relevant functions
void* update(void* arg)
{
snake* s=(snake*)arg;
if (GAMEOVER == false)
{
if (s->dir == LEFT)
s->headX--;
else if (s->dir == RIGHT)
s->headX++;
else if (s->dir == DOWN)
s->headY++;
else if (s->dir == UP)
s->headY--;
}
pthread_exit(0);
}
void* run_snake_threads(void* arg)
{
snake_thread* s = (snake_thread*)arg;
while (GAMEOVER == false)
{
pthread_testcancel(); //cancellation point
map_init(s,s->food);
if(print_flag==1)
print(s->map);
for (int i = 0; i < s->info->size; i++)
{
input(s->snake_list, &s->snake_list[i], s->map, s->info,&s->food[i]);
int err = pthread_create(&(s->pid[i]), NULL, update, (void*)&(s->snake_list[i]));
if (err != 0) ERR("Couldn't create thread");
spawn_food(&s->snake_list[i], s->map,s->food,s->info);
update_tail(&s->snake_list[i]);
set_gameover(&s->snake_list[i], s->map);
usleep(s->snake_list[i].sleep_time);
}
}
free(s->food);
free(s->pid);
free(s->snake_list);
pthread_exit(0);
}
void initialize(snake_thread* s,int argc,char** argv)
{
s->snake_list = calloc(s->info->size,sizeof(snake) );
s->pid = calloc(s->info->size, sizeof(pthread_t) );
s->food=calloc(s->info->size,sizeof(snake_food));
//does some stuff and passes s to other functions
}
void Read_args(int argc, char** argv,snake_thread* s)
{
int c;
if (argc > 1)
while ((c = getopt(argc, argv, "x:y:f:")) != -1)
switch (c)
{
case 'x':
s->info->width_provided = true;
s->map->width = atoi(optarg);
break;
case 'y':
s->info->height_provided = true;
s->map->height = atoi(optarg);
break;
case 'f':
s->info->file_name_provided = true;
strcpy(s->info->file,optarg);
break;
default:
usage(argv[0]);
break;
}
else usage(argv[0]);
if(!(s->info->file))
{
strcpy(s->info->file,getenv("$SNAKEFILE"));
if(!(s->info->file))
{
printf("Warning, No save file provided\n");
}
}
init_size(argc,s->info);
//if(argc>optind) ERR("optind err");
s->map->map_elem_pos = calloc(s->map->height,sizeof(char*));
if (s->map->map_elem_pos == NULL) ERR("Malloc error for elements of map");
for (int i = 0; i < s->map->height; i++)
s->map->map_elem_pos[i] = calloc(s->map->width,sizeof(char));
}
int main(int argc, char** argv)
{
pthread_t pid;
snake_thread s[1]
Read_args(argc, argv, s);
if (access(s->info->file, F_OK) != 0)
initialize(s,argc,argv);
int err = pthread_create(&s->pid2, NULL, run_snake_threads, (void*)s);
if (err) ERR("Couldn't create thread");
pthread_join(s->pid2, NULL);
}
Related
I am currently working on cs50 pset5.
I have encountered a memory leak when I attempt to free all the memory I have located in the program.
The error seems to occur in my unload function, where it malloc for pointer cursor.
If anyone can provide me directions on how to approach this issue, please let me know.
I have also provided comments to my code to highlight what it is doing.
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table
const unsigned int N = 50;
node *table[N] = {NULL};
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
// allocate memory for struct type `node` pointer
node *cursor = (node*)malloc(sizeof(node)); // MEMORY LEAK happens here !!!! :(
node *tmp = (node*)malloc(sizeof(node));
// if memory cannot be allocated successfully, return false
if (cursor == NULL || tmp == NULL)
{
return false;
}
// iterate the table for N'times (N = 50, for now)
for (int i = 0; i < N; i++)
{
// if the table has nothing inside the i'th bucket, return false
// this means, table has no linked list inside i'th bucket
if (table[i] == NULL)
{
continue;
}
else
{
// assign tmp pointer to the head node, and cursor to anything next to tmp
tmp = table[i];
cursor = tmp;
cursor = cursor->next;
// free memory for tmp pointer
free(tmp);
// continue traversing the linked list until cursor pointer points to NULL (end of the linked list)
while (cursor != NULL)
{
tmp = cursor;
cursor = cursor->next;
free(tmp);
}
}
}
// free memory for cursor
free(cursor);
return true;
}
The error I get, after running, help50 valgrind ./speller dictionaries/small texts/cat.txt.
==14685== Memcheck, a memory error detector
==14685== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14685== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==14685== Command: ./speller dictionaries/small texts/cat.txt
==14685==
32
==14685== Invalid write of size 1
==14685== at 0x40121F: hash (dictionary.c:67)
==14685== by 0x401354: load (dictionary.c:99)
==14685== by 0x400A2B: main (speller.c:41)
==14685== Address 0x55cc88a is 2 bytes after a block of size 8 alloc'd
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x4011D5: hash (dictionary.c:61)
==14685== by 0x401354: load (dictionary.c:99)
==14685== by 0x400A2B: main (speller.c:41)
==14685==
==14685== Invalid read of size 1
==14685== at 0x40122C: hash (dictionary.c:68)
==14685== by 0x401354: load (dictionary.c:99)
==14685== by 0x400A2B: main (speller.c:41)
==14685== Address 0x55cc88a is 2 bytes after a block of size 8 alloc'd
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x4011D5: hash (dictionary.c:61)
==14685== by 0x401354: load (dictionary.c:99)
==14685== by 0x400A2B: main (speller.c:41)
==14685==
19
MISSPELLED WORDS
47
A
32
20
is
27
not
47
a
==14685== Invalid write of size 1
==14685== at 0x40121F: hash (dictionary.c:67)
==14685== by 0x401124: check (dictionary.c:32)
==14685== by 0x400D50: main (speller.c:114)
==14685== Address 0x55cdf9a is 2 bytes after a block of size 8 alloc'd
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x4011D5: hash (dictionary.c:61)
==14685== by 0x401124: check (dictionary.c:32)
==14685== by 0x400D50: main (speller.c:114)
==14685==
==14685== Invalid read of size 1
==14685== at 0x40122C: hash (dictionary.c:68)
==14685== by 0x401124: check (dictionary.c:32)
==14685== by 0x400D50: main (speller.c:114)
==14685== Address 0x55cdf9a is 2 bytes after a block of size 8 alloc'd
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x4011D5: hash (dictionary.c:61)
==14685== by 0x401124: check (dictionary.c:32)
==14685== by 0x400D50: main (speller.c:114)
==14685==
19
WORDS MISSPELLED: 4
WORDS IN DICTIONARY: 2
WORDS IN TEXT: 6
TIME IN load: 0.03
TIME IN check: 0.00
TIME IN size: 0.00
TIME IN unload: 0.00
TIME IN TOTAL: 0.03
==14685==
==14685== HEAP SUMMARY:
==14685== in use at exit: 1,000 bytes in 9 blocks
==14685== total heap usage: 23 allocs, 14 frees, 10,944 bytes allocated
==14685==
==14685== 56 bytes in 1 blocks are definitely lost in loss record 1 of 4
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x4013F1: unload (dictionary.c:128)
==14685== by 0x400ED0: main (speller.c:154)
==14685==
==14685== 56 bytes in 1 blocks are definitely lost in loss record 2 of 4
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x4013FF: unload (dictionary.c:129)
==14685== by 0x400ED0: main (speller.c:154)
==14685==
==14685== 336 bytes in 6 blocks are definitely lost in loss record 3 of 4
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x401131: check (dictionary.c:33)
==14685== by 0x400D50: main (speller.c:114)
==14685==
==14685== 552 bytes in 1 blocks are still reachable in loss record 4 of 4
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x5258E49: __fopen_internal (iofopen.c:65)
==14685== by 0x5258E49: fopen##GLIBC_2.2.5 (iofopen.c:89)
==14685== by 0x4012DE: load (dictionary.c:83)
==14685== by 0x400A2B: main (speller.c:41)
==14685==
==14685== LEAK SUMMARY:
==14685== definitely lost: 448 bytes in 8 blocks
==14685== indirectly lost: 0 bytes in 0 blocks
==14685== possibly lost: 0 bytes in 0 blocks
==14685== still reachable: 552 bytes in 1 blocks
==14685== suppressed: 0 bytes in 0 blocks
==14685==
==14685== For counts of detected and suppressed errors, rerun with: -v
==14685== ERROR SUMMARY: 15 errors from 7 contexts (suppressed: 0 from 0)
Asking for help...
==14685== 56 bytes in 1 blocks are definitely lost in loss record 1 of 4
==14685== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14685== by 0x4013F1: unload (dictionary.c:128)
==14685== by 0x400ED0: main (speller.c:154)
Looks like your program leaked 56 bytes of memory. Did you forget to free memory that you allocated via malloc? Take a closer look at line 128 of dictionary.c.
So why does memory leak happen?
A memory leak happens when a programmer creates a memory from heap but forgets to free it.
However, in my code, I have free'd both cursor and tmp pointer after it's used.
I do not know why I am encountering the error, although I am freeing it at the end of the function.
Yes, "MEMORY LEAK happens here !!!!" as you say.
You allocated two buffers, but later their pointers are overwritten by table[i] without being freed. This is memory leak.
To avoid memory leak, stop allocating unused buffers.
The part
// allocate memory for struct type `node` pointer
node *cursor = (node*)malloc(sizeof(node)); // MEMORY LEAK happens here !!!! :(
node *tmp = (node*)malloc(sizeof(node));
// if memory cannot be allocated successfully, return false
if (cursor == NULL || tmp == NULL)
{
return false;
}
should be just
// allocate memory for struct type `node` pointer
node *cursor;
node *tmp;
The memory for pointer is allocated on the stack.
Also the part
// free memory for cursor
free(cursor);
should be removed because the list is already freed and the memory for cursor will be automatically freed (from the stack) on returning from the function.
I have a multi-threaded application which uses joinable threads.
In order to create the threads (which are in total nthreads workers+1 additional thread) I use a regular call to pthread_create.
However, when I try to debug memory leaks, I get a x bytes in y blocks are possibly lost in loss record z of w error, caused by the pthread_create calls.
Here is the part of the code of the program relevant to the issue :
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
int main(){
int i=0;
int nthreads=8;
pthread_t tid_w[nthreads+1];
if( pthread_create(&tid_w[0], NULL, dispatcher, (void*) (size_t) i)<0){
perror("Creating dispatcher thread");
return -1;
}
for(i=1; i<nthreads+1; i++){
if( pthread_create(&tid_w[i], NULL, worker, (void*) (size_t) i)<0){
perror("Creating worker thread");
return -1;
}
}
// thread joining
for(i=0; i<nthreads+1; i++){
if( pthread_join(tid_w[i], NULL)<0){
perror("Joining thread");
return -1;
}
}
return 0;
}
This is the output of valgrind (3.11)
==14418==
==14418== HEAP SUMMARY:
==14418== in use at exit: 14,496 bytes in 21 blocks
==14418== total heap usage: 25 allocs, 4 frees, 15,724 bytes allocated
==14418==
==14418== 560 bytes in 1 blocks are possibly lost in loss record 12 of 14
==14418== at 0x4C2DB95: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14418== by 0x40134C4: allocate_dtv (dl-tls.c:322)
==14418== by 0x40134C4: _dl_allocate_tls (dl-tls.c:544)
==14418== by 0x4E400D2: allocate_stack (allocatestack.c:588)
==14418== by 0x4E400D2: pthread_create##GLIBC_2.2.5 (pthread_create.c:537)
==14418== by 0x4018AE: main (chatty.c:132)
==14418==
==14418== 4,480 bytes in 8 blocks are possibly lost in loss record 13 of 14
==14418== at 0x4C2DB95: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14418== by 0x40134C4: allocate_dtv (dl-tls.c:322)
==14418== by 0x40134C4: _dl_allocate_tls (dl-tls.c:544)
==14418== by 0x4E400D2: allocate_stack (allocatestack.c:588)
==14418== by 0x4E400D2: pthread_create##GLIBC_2.2.5 (pthread_create.c:537)
==14418== by 0x401909: main (chatty.c:138)
==14418==
==14418== LEAK SUMMARY:
==14418== definitely lost: 0 bytes in 0 blocks
==14418== indirectly lost: 0 bytes in 0 blocks
==14418== possibly lost: 5,040 bytes in 9 blocks
==14418== still reachable: 9,456 bytes in 12 blocks
==14418== suppressed: 0 bytes in 0 blocks
==14418== Reachable blocks (those to which a pointer was found) are not shown.
==14418== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==14418==
==14418== For counts of detected and suppressed errors, rerun with: -v
==14418== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Line numbers might not match because I have removed a few socket-related parts from the code.
I also have read a lot about pthread_create causing memory leaks but it seems like the issue presents itself when in use of detached threads, which is not my case.
Any idea on how to solve the issue?
Trynig some test code for libmagic:
#include <magic.h>
#include <stdio.h>
int main(int argc, char **argv) {
magic_t cookie;
cookie = magic_open(MAGIC_MIME_TYPE);
if (cookie == NULL) {
perror(magic_error(cookie));
return 1;
}
if (magic_load(cookie, NULL) == -1) {
perror(magic_error(cookie));
return 1;
}
const char *string = magic_file(cookie, *(argv+1));
if (string == NULL) {
perror(magic_error(cookie));
return 1;
}
printf("%s\n", string);
magic_close(cookie);
return 0;
}
The code is pretty much ripped from here:
http://vivithemage.co.uk/blog/?p=105
The code runs ok, but using valgrind --leak-check=full ./libmagic /path/to/some/image/file a memleak from the library is reported:
==6153== HEAP SUMMARY:
==6153== in use at exit: 48 bytes in 3 blocks
==6153== total heap usage: 36 allocs, 33 frees, 990,559 bytes allocated
==6153==
==6153== 48 bytes in 1 blocks are definitely lost in loss record 2 of 2
==6153== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6153== by 0x4E43D3D: ??? (in /usr/lib/x86_64-linux-gnu/libmagic.so.1.0.0)
==6153== by 0x4E447ED: ??? (in /usr/lib/x86_64-linux-gnu/libmagic.so.1.0.0)
==6153== by 0x4008A8: main (libmagic.c:15)
==6153==
==6153== LEAK SUMMARY:
==6153== definitely lost: 48 bytes in 1 blocks
==6153== indirectly lost: 0 bytes in 2 blocks
==6153== possibly lost: 0 bytes in 0 blocks
==6153== still reachable: 0 bytes in 0 blocks
==6153== suppressed: 0 bytes in 0 blocks
Do I need something else than magic_close() to wrap up, or is there some weakness in the library?
magic.h says MAGIC_VERSION 524, I'm using gcc 5.4.0
I just came across the same issue today, it seems there was an defect reported about it:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=840754
According to the discussion there it should be fixed in the latest version.
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 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.