Ahbee / ofxCoreImageDetector

an openframeworks wrapper for apple's CoreImage Detector
16 stars 2 forks source link

threading malloc #2

Open antimodular opened 9 years ago

antimodular commented 9 years ago

Hey Ahbee.

Me again :)

I am running 4 threads each having their own ofxCoreImageDetector. After running for a while successfully get this malloc error:

coreImageDetector_17Debug(6460,0x10d7a8000) malloc: *** error for object 0x610000241890: Invalid pointer dequeued from free list
*** set a breakpoint in malloc_error_break to debug

I have put in checks with try and catch, made sure the image is allocated etc. see 2nd screen shot.

any ideas? thanks.

screen shot 2015-10-05 at 10 35 52 am screen shot 2015-10-05 at 10 36 30 am
antimodular commented 9 years ago

i have found people with similar problems, where after a while CIDetector crashes. http://stackoverflow.com/questions/24109232/exception-when-reusing-cidetector

I see you already have a [_detector retain] call. So why do you think the detector gets freed randomly?

antimodular commented 9 years ago

in an effort to work around this problem i thought of releasing the detector every now and then. but i guess i don't know to do this correctly, because the memory use starts increasing to a point that the system crashes,

       if(ofGetElapsedTimef() - faceFoundTimer > 10){
                            ofLog()<<"----------------------------------reset detector "<<threadID;
                            faceFoundTimer = ofGetElapsedTimef();
                            detector.~ofxCIDetector();
                            bIsDetectorSetup = false;
       }

what's the correct way to "delete" the current detector and then re-initalize it. thanks

Ahbee commented 9 years ago

It need to see the whole project, can you make a simple example that replicates the problem? How long did it run before the crash happens? Is the time consistent or is it random? To delete and create the detector again you would just run these three lines again. [_detector release];

  _detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:@{CIDetectorAccuracy: accuracyString,
                                                                                        CIDetectorTracking:[NSNumber numberWithBool:tracking],
                                                                                        CIDetectorMinFeatureSize:[NSNumber numberWithFloat:minFeatureSize]}];

[_detector retain];

but you really should not have to do that. I think the problem is something else. .

antimodular commented 9 years ago

hey. thanks for taking the time. here is the project: https://www.dropbox.com/s/z1pax8mpkdq04yh/coreImageDetector_17.zip?dl=0 here are addons used:https://www.dropbox.com/s/ma96wi6gt4oa3pt/test_addons.zip?dl=0 it's for of_v0.9.0RC1_osx_release

usually this works with 4 separate cameras but i just changed it to run of one and make 4 copies of the one video stream. I have not duration tested this 1 camera test app. Usually the crash happens after a few hours :( it always points to

NSArray *features = [_detector featuresInImage:myImage options:options];
antimodular commented 9 years ago

i just tried your release and retain code above but the memory increases overtime it gets called.

i made this new function and call it when ever no face was detected for x-seconds.

void ofxCIDetector::reinit(OFX_DETECTOR_ACCURACY accuracy, bool tracking, float minFeatureSize){
   [_detector release];

    if (minFeatureSize <=0 || minFeatureSize >=1) {
        ofLogError("ofxCIDetector") << "minFeatureSize must be between 0-1.0 exclusive";
        return;
    }

    NSString *accuracyString;
    if (accuracy == OFX_ACCURACY_LOW) {
        accuracyString = CIDetectorAccuracyLow;
    }else{
        accuracyString = CIDetectorAccuracyHigh;
    }
    _detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:@{CIDetectorAccuracy: accuracyString,
                                                                                    CIDetectorTracking:[NSNumber numberWithBool:tracking],
                                                                                    CIDetectorMinFeatureSize:[NSNumber numberWithFloat:minFeatureSize]}];
    //   _detector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:@{CIDetectorAccuracy: accuracyString, CIDetectorMinFeatureSize:[NSNumber numberWithFloat:minFeatureSize]}];

    [_detector retain];

}
antimodular commented 9 years ago

seems like the code i posted via dropbox has not yet produce a crash, in the last 2 hours. this code only uses one camera. the version that crashes uses 4 different cameras.

Ahbee commented 9 years ago

just tried your release and retain code above but the memory increases overtime it gets called.

i made this new function and call it when ever no face was detected for x-seconds.

that must mean something else is retaining the detector. In objective-c things only get released when then retain count goes to zero. you can check the retain count with

[_detector retainCount]

if the retain count it higher then 1 right before you release. then memory will go up

Ahbee commented 9 years ago

Can you put a autorelease pool around the setup like

 if (!bIsDetectorSetup) {
                bIsDetectorSetup = true;
                @autoreleasepool{
                    detector.setup(OFX_ACCURACY_HIGH, true, .01); //,true);
                }
 }

and tell me if it still leaks. any time you have objective-c code it needs to have an autorelease pool. The main loop I think glfw sets one up so you dont have to have one there. But on separate threads you need one. Also If you could , can you simply the example project to the bare minimum for a crash just so its easier for me to debug thanks. I'll look at it tomorrow.

Ahbee commented 9 years ago

Also anywhere you call reinit make sure it has an autorelease pool around it.

antimodular commented 9 years ago

adding the extra autoreleasepool did stop the leaks. i still have to check with it prevents the crashes.

in the meantime here is a more simple code with 4 streams. i have it run here now and so far this simple version has not crashed. https://www.dropbox.com/s/1nmggqph4zlrjaa/coreImageDetector_17_simple.zip?dl=0

i also tried the code that usually crashes with just one camera. it also did not crash.

i know this all suggest that something else is causing the crash. but the crash error always is this line:

NSArray *features = [_detector featuresInImage:myImage options:options];
Ahbee commented 9 years ago

hmm, Yeah definitely keep the autoreleasepool pool around the setup, maybe make other autorelease pools more tight? Like just put an autorelease pool around

@autoreleasepool {
          detectedFaces = detector.detectFaceFeatures(cam_image, false, false);
 }

cause it could be that something else in your code is draining the current pool when its not supposed to. But I doubt it , putting all your code inside one autorelease pool should work.

Also make sure if you have other obj-C code that is not mine on your thread (like from an addon) , that they also need an autorelease pool pool around it.

You can also try the multi context branch- https://github.com/Ahbee/ofxCoreImageDetector/tree/multiContext. You need to set the last setup param to true when initializing on a separate thread.

If the simple code version works, then the only way to debug is to build you project step by step again and at each step see if the crash happens. Then you know what code caused the crash.

antimodular commented 9 years ago

ok will give that a try.

what is different in the multiContext tree ?

Ahbee commented 9 years ago

ok will give that a try.

what is different in the multiContext tree ?

For each thread I explicitly created a CIContext for the detector. Apple might already be doing that if you pass nil for the context. The documentation does not say. I dont know but it might be worth a try.

antimodular commented 8 years ago

Hey Ahbee.

I am back at it with the face tracker. I tried your multi context branch. Looks like you new code has both option included multi context (setup set to true) and the regular version by setting it to false. Right?

detector.setup(OFX_ACCURACY_HIGH, true, .05,false);

I had to add the following to ofxCIDetector.h for it to compile and not throw semantic issue like 'NSOpenGlContext' etc

 #import <Cocoa/Cocoa.h>

The main problem i am having is, once i get it to compile with multi context set to true my ofApp crashes right away due to texture and OpenGL issues.

What did you do to make it work?

thanks, stephan

screen shot 2016-01-26 at 1 55 10 pm
antimodular commented 8 years ago

for completion reason i am posted here the back trace to the malloc error i have been getting for the last months with the none multiContext version.

zoom_pavilion_faceTracker(71297,0x10eddd000) malloc: *** error for object 0x60800002b680: Invalid pointer dequeued from free list
*** set a breakpoint in malloc_error_break to debug
(lldb) bt
* thread #15: tid = 0x5c45b, 0x00007fff8a39f286 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
  * frame #0: 0x00007fff8a39f286 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff8f4ee9f9 libsystem_pthread.dylib`pthread_kill + 90
    frame #2: 0x00007fff88bcc9b3 libsystem_c.dylib`abort + 129
    frame #3: 0x00007fff874f6f4f libsystem_malloc.dylib`nanozone_error + 524
    frame #4: 0x00007fff874ecce3 libsystem_malloc.dylib`_nano_malloc_check_clear + 370
    frame #5: 0x00007fff874ecb53 libsystem_malloc.dylib`nano_malloc + 35
    frame #6: 0x00007fff874e4667 libsystem_malloc.dylib`malloc_zone_malloc + 71
    frame #7: 0x00007fff87914e0e CoreFoundation`_CFRuntimeCreateInstance + 350
    frame #8: 0x00007fff8e914b81 IOSurface`IOSurfaceLookupFromMachPort + 85
    frame #9: 0x000000010d23b97e VDC`___lldb_unnamed_function518$$VDC + 1756
    frame #10: 0x00007fff87992dad CoreFoundation`__CFMachPortPerform + 285
    frame #11: 0x00007fff87992c79 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
    frame #12: 0x00007fff87992beb CoreFoundation`__CFRunLoopDoSource1 + 475
    frame #13: 0x00007fff87984767 CoreFoundation`__CFRunLoopRun + 2375
    frame #14: 0x00007fff87983bd8 CoreFoundation`CFRunLoopRunSpecific + 296
    frame #15: 0x00007fff87a3b671 CoreFoundation`CFRunLoopRun + 97
    frame #16: 0x000000010d22a0dd VDC`___lldb_unnamed_function85$$VDC + 113
    frame #17: 0x00007fff8f4ed05a libsystem_pthread.dylib`_pthread_body + 131
    frame #18: 0x00007fff8f4ecfd7 libsystem_pthread.dylib`_pthread_start + 176
    frame #19: 0x00007fff8f4ea3ed libsystem_pthread.dylib`thread_start + 13
(lldb)