petegoodliffe / PGMidi

PGMidi iOS MIDI library and example code
297 stars 83 forks source link

Memory leak in example app (or PGMidi library?) #2

Open falsetto opened 12 years ago

falsetto commented 12 years ago

Overview

There appears to be a memory leak in the example app code or the PGMidi library. I'm trying to port the example code to RubyMotion and the app is crashing when running on the device with 'EXC_CRASH (SIGABRT)' shown as the reason in the device log. According to SO, that crash code indicates a memory leak?

I'm brand new to iOS app development and unfortunately have no idea how to fix the issue. But I'm nervous to keep banging my head against the wall trying to get the example app ported to RubyMotion knowing that there's a possible bug. I'm not sure how severe the issue is or if it could be causing the EXC_CRASH crashes. Since I can't fix the issue, I've tried to do as much of the debugging footwork as possible for you.

Thanks so much for taking a look and for releasing PGMidi. I sure appreciate it!

Debug Panel Output

I was able to hook up a wireless MIDI device to the simulator so I could reproduce the bug in a better debugging environment. Here is the output in the debugging panel when choosing 'Product -> Run':

objc[57951]: Object 0x8a94b30 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[57951]: Object 0x8a94e50 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[57951]: Object 0x688a390 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[57951]: Object 0x688c440 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

Instruments Leak Backtrace

I also was able to get a backtrace on the leak by running the app with Instruments. Here is the leak backtrace:

#   Address Category    Event Type  RefCt   Timestamp   Size    Responsible Library Responsible Caller
0   0x6874150   CFString (immutable)    Malloc  1   00:19.148.096   32  Foundation  -[NSPlaceholderString initWithFormat:locale:arguments:]
1   0x6874150   CFString (immutable)    Autorelease <null>  00:19.148.101   0   Foundation  +[NSString stringWithFormat:]
2   0x6874150   CFString (immutable)    CFRetain    2   00:19.148.131   0   MidiMonitor -[MidiMonitorViewController midiSource:midiReceived:]
3   0x6874150   CFString (immutable)    CFRetain    3   00:19.148.135   0   Foundation  -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:]
4   0x6874150   CFString (immutable)    CFRelease   2   00:19.148.147   0   MidiMonitor -[MidiMonitorViewController midiSource:midiReceived:]
5   0x6874150   CFString (immutable)    CFRetain    3   00:19.149.480   0   MidiMonitor -[MidiMonitorViewController addString:]
6   0x6874150   CFString (immutable)    CFRetain    4   00:19.149.513   0   Foundation  -[NSPlaceholderString initWithFormat:locale:arguments:]
7   0x6874150   CFString (immutable)    CFRelease   3   00:19.149.515   0   Foundation  -[NSPlaceholderString initWithFormat:locale:arguments:]
8   0x6874150   CFString (immutable)    CFRelease   2   00:19.150.312   0   MidiMonitor -[MidiMonitorViewController addString:]
9   0x6874150   CFString (immutable)    CFRelease   1   00:19.150.315   0   GraphicsServices    GSEventRunModal

Steps to reproduce

minihui commented 12 years ago

I'm having the same issue here... I'm making a MIDI remote controller so the MIDI data is traveling at a very high rate. The memory is leaking at about 0.3MB/min, and the App would crash after certain amount of time (1 hour maybe, on the 1st gen iPad, if running heavily). I googled a little and someone claims that CoreMIDI API is leaking memory. Would you please confirm that?

Thanks again for releasing PGMidi, it rocks anyway!!

minihui commented 12 years ago

Update, if PGMidi is compiled with no ARC (-fno-objc-arc), it will be fine.

nziebart commented 11 years ago

I changed the midiRead: function in PGMidi.mm to this:

(void) midiRead:(const MIDIPacketList )pktlist { NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init]; [delegate midiSource:self midiReceived:pktlist]; [pool drain]; }

and disabled ARC (-fno-objc-arc) for PGMidi.mm, and now it works.