FLTK logo

Re: DataReadyThread leak hunting in fltk 1.3.0-rSOMETHING

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.general  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: DataReadyThread leak hunting in fltk 1.3.0-rSOMETHING Greg Ercolano May 08, 2012  
 
Peeter: can you make an STR for this so we can track it?
I think I can confirm it's something we need to fix
in Fl_cocoa.mm.

This way you'll be notified of fixes as they happen.

In the mean time, a little investigation:

Peeter, I'm guessing your app uses the fltk method add_fd(),
as this triggers FLTK to internally use the DataReady class,
which starts a child thread running the DataReadyThread()
method to:

	a) monitor the fd with select(2)
	b) send the custom event when data is ready
	   to wake up FLTK to run the add_fd() callback.

I wrote that code a long time ago (2004), and some years
later Manolo ported it to cocoa/objective C, so probably
the two of us needs to look at it.

Afraid I don't know objective C myself, but given your
stack dump, looks like it's something to do with one of
the objective C memory allocation calls, probably "NSAutoReleasePool".

Could be some issue with that call not being thread safe
or something is missing in the use of it.

Manolo: perhaps you can weigh in on this?

The code for the method DataReady::DataReadyThread() (in Fl_cocoa.mm)
runs entirely in the context of a child thread. So anything we do
in that method has to be thread safe.

I looked at the docs for 'NSAutoReleasePool' and it has a section
on "Threads" which has a special note about POSIX threads (which we use):

	Note: If you are creating secondary threads using the POSIX thread
	APIs instead of NSThread objects, you cannot use Cocoa, including
	NSAutoreleasePool, unless Cocoa is in multithreading mode.
	Cocoa enters multithreading mode only after detaching its first
	NSThread object. To use Cocoa on secondary POSIX threads, your
	application must first detach at least one NSThread object,
	which can immediately exit. You can test whether Cocoa is
	in multithreading mode with the NSThread class method isMultiThreaded.

I'm guessing we need to take this advice, either:

	1) Use NSThread instead of pthreads()

	- OR -

	2) Do what the above docs advise, and just start a quick
	   NSThread() during the first use of Add_FD() so that our
	   use of posix threads will work properly, given the above warning.

I'm pretty sure that's the issue.

Peeter: as a quick workaround, can I advise that at the top of your main()
function, before doing anything else, create a simple thread using NSThread()
that does nothing (simply returns).

I think by doing this, it will do as the above recommends, triggering
whatever internal bookkeeping OSX wants to prevent the leak.

Doing this should be safe to do, even when we eventually fix the
problem.

Please open the STR with just your initial post, and I'll follow up
with the above details, and me and Manolo will chime in when we have
a fix to the code. I want you to open the STR so that you'll receive
emails as the fixes progress.


On 05/08/12 04:36, Peeter Vois wrote:
> I have application that does have strange memory leak in Mac OSX 10.6.8 and 10.7.3
> but not leaking in Mac OSX 10.5.8. I've used valgrind to figure out where the
> leak happens and it points to DataReady::DataReadyThread(void*) report below
> the message. XXXX.... is name of my application.
> 
> I've been searching for the dependencies and one of the pieces in the puzzle
> is that there is much more leaks when to use Fl::wait(0.01) and less leaks
> when to use Fl::wait(0.1) resulting almost no leaks but valgrind still identifies leaks.
> 
> 
> ==297== 222,260 bytes in 11,113 blocks are definitely lost in loss record 4,244 of 4,245
> ==297==    at 0x13CF47: calloc (vg_replace_malloc.c:569)
> ==297==    by 0x5CFC7E: _class_createInstanceFromZone (in /usr/lib/libobjc.A.dylib)
> ==297==    by 0x5CFCC4: _class_createInstance (in /usr/lib/libobjc.A.dylib)
> ==297==    by 0x5C62C7: _objc_rootAllocWithZone (in /usr/lib/libobjc.A.dylib)
> ==297==    by 0x25AD70: +[NSObject allocWithZone:] (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
> ==297==    by 0x6BE88D: +[NSAutoreleasePool allocWithZone:] (in /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation)
> ==297==    by 0x5C61BB: _objc_rootAlloc (in /usr/lib/libobjc.A.dylib)
> ==297==    by 0x73361: DataReady::DataReadyThread(void*) (in XXXXXXXXX)
> ==297==    by 0x1BB3ED8: _pthread_start (in /usr/lib/system/libsystem_c.dylib)
> ==297==    by 0x1BB76DD: thread_start (in /usr/lib/system/libsystem_c.dylib)
> ==297==
> ==297== LEAK SUMMARY:
> ==297==    definitely lost: 235,225 bytes in 11,357 blocks
> ==297==    indirectly lost: 6,440 bytes in 17 blocks
> ==297==      possibly lost: 3,883 bytes in 39 blocks
> ==297==    still reachable: 1,403,803 bytes in 10,153 blocks
> ==297==         suppressed: 0 bytes in 0 blocks
> ==297== Reachable blocks (those to which a pointer was found) are not shown.
> ==297== To see them, rerun with: --leak-check=full --show-reachable=yes
> ==297==
> ==297== For counts of detected and suppressed errors, rerun with: -v
> ==297== Use --track-origins=yes to see where uninitialised values come from
> ==297== ERROR SUMMARY: 28937 errors from 55 contexts (suppressed: 722 from 39)
> 
Direct Link to Message ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.