grininmonkey
Posts: 145
Joined: Mon Jul 30, 2018 3:44 pm

pthread leak?

Fri Nov 02, 2018 6:53 pm

So I have concluded I can't really do much about the "Still Reachable" blocks reported by valgrind which is an effect of just linking freetype alone.... see my previous post on that... viewtopic.php?f=33&t=225621#p1386087

Now I am starting my threading pieces and it appears there is something similar going on but the pthread leak is reported as "possibly lost" ... but before I ignore this... wanted to check if the many examples I found online on threading where missing something I should be doing to free something ?

valgrind output .... look for main.c line...

Code: Select all

==9864== Memcheck, a memory error detector
==9864== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9864== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==9864== Command: ./test
==9864== Parent PID: 8409
==9864== 
==9864== 
==9864== HEAP SUMMARY:
==9864==     in use at exit: 18,876 bytes in 7 blocks
==9864==   total heap usage: 1,223 allocs, 1,216 frees, 12,534,503 bytes allocated
==9864== 
==9864== 4 bytes in 1 blocks are still reachable in loss record 1 of 7
==9864==    at 0x483777F: malloc (vg_replace_malloc.c:299)
==9864==    by 0x51FA5B3: ??? (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x51FA6AB: g_private_get (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x522414D: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x525F67E: g_hash_table_new_full (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x5238EE3: ??? (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x4010549: call_init.part.0 (in /usr/lib/ld-2.28.so)
==9864==    by 0x4010649: _dl_init (in /usr/lib/ld-2.28.so)
==9864==    by 0x4002039: ??? (in /usr/lib/ld-2.28.so)
==9864== 
==9864== 32 bytes in 1 blocks are still reachable in loss record 2 of 7
==9864==    at 0x4839B65: calloc (vg_replace_malloc.c:752)
==9864==    by 0x52432A9: g_malloc0 (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x525F6E7: g_hash_table_new_full (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x5238EE3: ??? (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x4010549: call_init.part.0 (in /usr/lib/ld-2.28.so)
==9864==    by 0x4010649: _dl_init (in /usr/lib/ld-2.28.so)
==9864==    by 0x4002039: ??? (in /usr/lib/ld-2.28.so)
==9864== 
==9864== 64 bytes in 1 blocks are still reachable in loss record 3 of 7
==9864==    at 0x4839B65: calloc (vg_replace_malloc.c:752)
==9864==    by 0x52432A9: g_malloc0 (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x525F6D1: g_hash_table_new_full (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x5238EE3: ??? (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x4010549: call_init.part.0 (in /usr/lib/ld-2.28.so)
==9864==    by 0x4010649: _dl_init (in /usr/lib/ld-2.28.so)
==9864==    by 0x4002039: ??? (in /usr/lib/ld-2.28.so)
==9864== 
==9864== 88 bytes in 1 blocks are still reachable in loss record 4 of 7
==9864==    at 0x483777F: malloc (vg_replace_malloc.c:299)
==9864==    by 0x52432F1: g_malloc (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x5224174: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x525F67E: g_hash_table_new_full (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x5238EE3: ??? (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x4010549: call_init.part.0 (in /usr/lib/ld-2.28.so)
==9864==    by 0x4010649: _dl_init (in /usr/lib/ld-2.28.so)
==9864==    by 0x4002039: ??? (in /usr/lib/ld-2.28.so)
==9864== 
                           ---  Here ---
==9864== 272 bytes in 1 blocks are possibly lost in loss record 5 of 7
==9864==    at 0x4839B65: calloc (vg_replace_malloc.c:752)
==9864==    by 0x40128D2: allocate_dtv (in /usr/lib/ld-2.28.so)
==9864==    by 0x4013281: _dl_allocate_tls (in /usr/lib/ld-2.28.so)
==9864==    by 0x4F0F698: pthread_create@@GLIBC_2.2.5 (in /usr/lib/libpthread-2.28.so)
==9864==    by 0x10A6ED: main (main.c:67)
                           ------ ^ ------
==9864== 
==9864== 2,032 bytes in 1 blocks are still reachable in loss record 6 of 7
==9864==    at 0x4839B65: calloc (vg_replace_malloc.c:752)
==9864==    by 0x52432A9: g_malloc0 (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x52243CE: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x525F67E: g_hash_table_new_full (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x5238EE3: ??? (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x4010549: call_init.part.0 (in /usr/lib/ld-2.28.so)
==9864==    by 0x4010649: _dl_init (in /usr/lib/ld-2.28.so)
==9864==    by 0x4002039: ??? (in /usr/lib/ld-2.28.so)
==9864== 
==9864== 16,384 bytes in 1 blocks are still reachable in loss record 7 of 7
==9864==    at 0x483777F: malloc (vg_replace_malloc.c:299)
==9864==    by 0x52432F1: g_malloc (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x5238EF5: ??? (in /usr/lib/libglib-2.0.so.0.5800.1)
==9864==    by 0x4010549: call_init.part.0 (in /usr/lib/ld-2.28.so)
==9864==    by 0x4010649: _dl_init (in /usr/lib/ld-2.28.so)
==9864==    by 0x4002039: ??? (in /usr/lib/ld-2.28.so)
==9864== 
==9864== LEAK SUMMARY:
==9864==    definitely lost: 0 bytes in 0 blocks
==9864==    indirectly lost: 0 bytes in 0 blocks
==9864==      possibly lost: 272 bytes in 1 blocks
==9864==    still reachable: 18,604 bytes in 6 blocks
==9864==         suppressed: 0 bytes in 0 blocks
==9864== 
==9864== For counts of detected and suppressed errors, rerun with: -v
==9864== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

So all I am currently doing is the following within main() .... non joining because I want it to die from the main process when the main process blocking func is terminated.

Code: Select all

		if ( screen_config.enable_mouse_event )
		{
			pthread_t thread_id;
			pthread_create(&thread_id, NULL, &open_mouse_device, NULL);
		}
Compiling with -pthread option and not -lpthread .... but tried both and have same result.

Heater
Posts: 12976
Joined: Tue Jul 17, 2012 3:02 pm

Re: pthread leak?

Fri Nov 02, 2018 8:51 pm

grininmonkey,
So all I am currently doing is the following within main() .... non joining because I want it to die from the main process when the main process blocking func is terminated.
So don't do that. Shut down your threads properly.

It's a long while since I played with valgrind but the way I see it is this:

1) Your main program starts.

2) It creates some threads.

3) Those threads malloc some memory.

4) The main thread exists.

5) As a consequence all the child threads are instantly killed.

6) BOOM. You have all that memory the child threads claimed still "in use at exit" as valgrind reports.

Often this is not a problem. The program is dead, the OS cleans up after it, who cares?

It does confuse things when using valgrind though and has caused me problems in some weird circumstances.

grininmonkey
Posts: 145
Joined: Mon Jul 30, 2018 3:44 pm

Re: pthread leak?

Fri Nov 02, 2018 9:18 pm

I am threading a function that contains a blocking while read on /dev/input/mouse0 and chains out to functions that do not allocate ....

How would I go about placing something within the while loop that does not evaluate until someone touches the screen to break and terminate?

Code: Select all

static void*
open_mouse_device(void *vargp)
{
    int *myid = (int *)vargp;
    int fd;
    struct input_event ie;
    unsigned char button,bLeft;
    int bLeft_was_down = 0;
    int x,y;

    int position_x = 0;
    int position_y = 0;

    int absolute_x = 0;
    int absolute_y = 0;

	/* TODO */
	/* 	factor needs to be added to ini  */
	int x_factor = 460;
	int y_factor = 360;

	int screen_position_x = 0;
	int screen_position_y = 0;

    if ( ( fd = open( screen_config.mouse_device_file, O_RDONLY ) ) == -1 ) {
        printf( "Device [%s] open ERROR in thread[%i]\n", screen_config.mouse_device_file, *myid );
        shutdown( 0 );
    }

    while( read( fd, &ie, sizeof( struct input_event ) ) )
    {
        unsigned char *ptr = (unsigned char*)&ie;

        button	= ptr[0];
        bLeft 	= button & 0x1;
        x		= ptr[1];
        y		= ptr[2];

		if ( x > 127 ) // Movement Left
			absolute_x -= 256 - x;

		if ( x < 129 ) // Movement Right
			absolute_x += x;

		if ( y > 127 ) // Movement Up
			absolute_y += 256 - y;

		if ( y < 129 ) // Movement Down
			absolute_y -= y;

        if ( bLeft == 1 )
        {
			position_x += absolute_x;
			position_y += absolute_y;
			absolute_x = absolute_y = 0;
			bLeft_was_down = 1;
		} else {
			if ( bLeft_was_down )
			{
				bLeft_was_down = 0;
				screen_position_x = mouse_calc_position( &position_x, &x_factor, &lfb.width );
				screen_position_y = mouse_calc_position( &position_y, &y_factor, &lfb.height );
				screen_mouse_click_handler(&screen_position_x, &screen_position_y);
			}
		}

    }

	return NULL;
}


rzusman
Posts: 346
Joined: Fri Jan 01, 2016 10:27 pm

Re: pthread leak?

Sat Nov 03, 2018 12:16 am

Don't use a blocking read. Use something like select with a timeout.

Some discussion here: https://stackoverflow.com/questions/634 ... gracefully

grininmonkey
Posts: 145
Joined: Mon Jul 30, 2018 3:44 pm

Re: pthread leak?

Sun Nov 04, 2018 5:38 pm

I tried some testing on a basic c file.... so far in combination of what I was doing and what I saw as select examples.... the following is what appears to be working in terms of non blocking reading of mouse device file... but not positive if I am on the right track...

I can set a global "RUNNING" var to 0 within main or some other func and the tread loop breaks and completes / returns....

I had to set timeout to 1 sec + 1 usec in order to not have 100% cpu pegging in the while loop.... even though most examples and reading say to avoid using a timeout as much as possible... so not sure yet if using the timeout is good or bad in this context or how to not use a timeout and avoid cpu pegging...

Next I'll study and test on joining and overall ( make sure thread exits before main exit )

Code: Select all


//GLOBAL
static int RUNNING

static int
mouse_event(int *mfd){

    struct timeval timeout;
    fd_set read_handles;
    FD_ZERO(&read_handles);
    FD_SET(*mfd, &read_handles);
    timeout.tv_sec = timeout.tv_usec = 1;
    return select( (*mfd + 1), &read_handles, NULL, NULL, &timeout);

}

static void*
open_mouse_device(void *vargp)
{
    int *myid = (int *)vargp;
    int fd;
    struct input_event ie;
    unsigned char button,bLeft;
    int bLeft_was_down = 0;

    if ( ( fd = open("/dev/input/mouse1", O_RDONLY ) ) == -1 ) {
        printf( "Device open ERROR in thread[%i]\n", *myid );
        shutdown( 0 );
    }

	while (RUNNING)
	{
		if ( mouse_event(&fd) && RUNNING)
		{
			read( fd, &ie, sizeof( struct input_event ) );
			unsigned char *ptr = (unsigned char*)&ie;

			button	= ptr[0];
			bLeft 	= button & 0x1;

			if ( bLeft == 1 )
			{
				bLeft_was_down = 1;
			} else {
				if ( bLeft_was_down )
				{
					bLeft_was_down = 0;
					printf("Mouse Button Pressed\n");
				}
			}

			printf("?");
		}

	}

	close(fd);
	printf("Stopped looking for mouse button activity.\n");

	return NULL;
}



Return to “C/C++”