objective c - Base64EncodedString memory leak -
i'm using nsdata+base64 opensrc library found on githubt project due in next month. started profiling, analyzing , optimizing, , found out leak comes code. have disabled nszombie , debugging methods & try-catches, have found leak memory. exact lines leak pin-pointed is:
- (nsstring *)base64encodedstring { return [self base64encodedstringwithwrapwidth:0]; } and disassembly:
+0x0 pushl %ebp +0x1 movl %esp, %ebp +0x3 subl $24, %esp +0x6 calll -[nsdata(base64) base64encodedstring]+0xb +0xb popl %eax +0xc movl +86389(%eax), %eax +0x12 movl %eax, +4(%esp) +0x16 movl +8(%ebp), %eax +0x19 movl %eax, (%esp) +0x1c movl $0, +8(%esp) +0x24 calll dyld-stub$$objc_msgsend // 100% leak +0x29 addl $24, %esp +0x2c popl %ebp +0x2d ret i have not contacted author, fear may fault not using library, or other part of code.
when use specific method (only use once), after encryption routine:
+ (nsstring *) encryptstring:(nsstring *)plaintext withkey:(nsstring *)key { // convert string-to-be-encrypted data nsdata *indata = [miscellaneous utf8string2data:plaintext]; // encrypt, encode, return return [[self encryptdata:indata withkey:key] base64encodedstring]; } however, feeling actual point memory leaking in method being called method
base64encodedstringwithwrapwidth
and exact lines are:
outputbytes = realloc(outputbytes, outputlength); nsstring *result = [[nsstring alloc] initwithbytesnocopy:outputbytes length:outputlength encoding:nsasciistringencoding freewhendone:yes]; so guess questions are: 1) has observed similar behavior using library 2) possibly me inducing leak using badly allocated strings 3) know how solve it, or of library can use replace ?
thanks!
edit: have changed above lines instruments pinpoints leaking code to:
outputbytes = realloc(outputbytes, outputlength); nsstring *result = [[nsstring alloc] initwithbytes:outputbytes length:outputlength encoding:nsasciistringencoding]; free(outputbytes); however, still leak line. there issue malloc/realloc/free in objective c ?
edit 2:
bytes used # leaks symbol name 512 bytes 5.2% 2 thread_start 512 bytes 5.2% 2 _pthread_start 512 bytes 5.2% 2 __nsthread__main__ 512 bytes 5.2% 2 -[nsthread main] 512 bytes 5.2% 2 -[sync get] 512 bytes 5.2% 2 -[request dorequest] 512 bytes 5.2% 2 -[request encryptmessage:] 512 bytes 5.2% 2 +[aes256 encryptstring:withkey:] 512 bytes 5.2% 2 -[nsdata(base64) base64encodedstring] 512 bytes 5.2% 2 -[nsdata(base64) base64encodedstringwithwrapwidth:] 512 bytes 5.2% 2 -[nsplaceholderstring initwithbytes:length:encoding:] 512 bytes 5.2% 2 cfstringcreatewithbytes 512 bytes 5.2% 2 __cfstringcreateimmutablefunnel3 512 bytes 5.2% 2 _cfruntimecreateinstance 512 bytes 5.2% 2 cfallocatorallocate 512 bytes 5.2% 2 __cfallocatorsystemallocate i don't know if identify whether false warning or not, not filtering anything, culprit appears cfallocatorsystemallocate:
+0x13 calll dyld-stub$$malloc_zone_malloc +0x18 addl $8, %esp so starting have reservations wether leak. debugging on both emulator & ipad has same results. arc used, , i'm trying copy objects instead of referencing them.
solution: have found leak, in method implemented improperly using wrong kind of cast ( silly me didn't see first time )
return (__bridge_transfer nsstring *)cfurlcreatestringbyaddingpercentescapes(null, (__bridge_retained cfstringref)string, null, (cfstringref)@"!*'\"();:@&=+$,/?%#[]% ", cfstringconvertnsstringencodingtoencoding(encoding)); bridge_retain here incremented arc one, , wasn't being released, , thats why getting warning. funnily last piece of code looked at, before realized wrong. thank help
you right in analysis leak comes place outputbytes reallocated. however, note "real" culprit leak outputbytes not freed in end. question why not freed.
if take @ next line, outputbytes fed nsstring directly without copying contents of string points to, guess intention of author nsstring takes ownership of outputbytes memory block on, , responsibility of nsstring free it. nsstring free block when reference counter becomes zero. next few lines in code show nsstring becomes auto-released:
#if !__has_feature(objc_arc) [result autorelease]; #endif if nsstring auto-released, should fine -- ownership of nsstring taken autorelease pool, , should not have release on own when use it. above code snippet says autorelease called if compiling code without arc (automatic reference counting). so, think code correct, therefore reason why outputbytes leaked because retaining returned nsstring somewhere , forget release it. in other words, leaked memory allocated within library using, reason why not freed lies outside library , library cannot made responsible leak.
your encryptstring method seems take encoded string , pass along caller, not changing reference count anywhere, have keep on looking @ places calling encryptstring see if there place accidentally retaining string , not releasing later.
Comments
Post a Comment