Description: When invoked IOHIDDeviceClass::setElementDictIntValue() leaks memory quite substantially, as does : IOHIDDeviceClass::createElement() and these are invoked multiple times. Steps to Reproduce: 1. Start XCode, then Instruments.app 2. Choose Memory Leak profile tool 3. Select LibreOffice.app in instdir as target process 4. Click on the record button, LODev is started by the profiling tool 5. Wait for the StartCenter to load - note the occurrences of memory leaks as they occur. 6. Open a new Writer document. 7. When the document has loaded, click on the dropdown font list. Scroll up and down the list with the Up/Down cursor arrows 8. Stop recording. 9. Analyse the profile trace. Actual Results: It leaks memory Expected Results: It shouldn't leak memory Reproducible: Always User Profile Reset: No Additional Info: The responsible code seems to be here : +0x09 pushq %rax +0x0a movq %rdx, %r14 +0x0d movq %rsi, %r15 +0x10 movl %ecx, -28(%rbp) +0x13 movq 37794(%rip), %rax +0x1a movq (%rax), %rdi +0x1d leaq -28(%rbp), %rdx +0x21 movl $9, %esi +0x26 callq "DYLD-STUB$$CFNumberCreate" +0x2b movq %rax, %rbx +0x2e testq %rbx, %rbx +0x31 je "IOHIDDeviceClass::setElementDictIntValue(__CFDictionary*, __CFString const*, unsigned int)+0x49" +0x33 movq %r15, %rdi +0x36 movq %r14, %rsi +0x39 movq %rbx, %rdx +0x3c callq "DYLD-STUB$$CFDictionarySetValue" +0x41 movq %rbx, %rdi +0x44 callq "DYLD-STUB$$CFRelease" +0x49 addq $8, %rsp +0x4d popq %rbx +0x4e popq %r14 +0x50 popq %r15 +0x52 popq %rbp +0x53 retq User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0
Created attachment 135350 [details] Screenshot of Instruments.app showing memory leaks A screenshot of the number of leaks occurring is enclosed
From what I understand, this relates to : https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDLib/IOHIDDeviceClass.cpp.auto.html which is Apple's code.
From https://github.com/st3fan/osx-10.9/blob/master/IOHIDFamily-503.1.13/IOHIDLib/IOHIDDeviceClass.cpp it appears to be this section of code: void IOHIDDeviceClass::setElementDictIntValue(CFMutableDictionaryRef element, CFStringRef key, uint32_t value) { CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value); if ( !number ) return; CFDictionarySetValue(element, key, number); CFRelease(number); }
and here : CFTypeRef IOHIDDeviceClass::createElement(CFDataRef data, IOHIDElementStruct * element, uint32_t index, CFTypeRef parentElement, CFMutableDictionaryRef elementCache, bool * isElementCached, IOOptionBits options) { CFTypeRef type = 0; CFNumberRef key = 0; uint32_t cookie = element->cookieMin + index; if ( elementCache ) { key = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &cookie); if ( key ) { type = CFDictionaryGetValue(elementCache, key); if ( type ) { if (isElementCached) *isElementCached = true; CFRetain(type); CFRelease(key); return type; } } }
@Julien : not sure if you can do anything about this one ?
I don't know what can be done here since it's Apple code. Moreover, I'm not sure there's a leak in this part of code. Perhaps it just shows that fonts are loaded in memory when scrolling and it's kept in cache. To test, you can scroll once the whole dropdown font list. Then you scroll again to see if consumed memory increases. BTW, would it be possible to have a bt of something similar to know where it's called in LO?
Perhaps this is linked to my input devices on this machine, I honestly don't know, as IOHIDDeviceClass is supposed to relate to USB and other connected hardware devices ? Whether this is due to a keyboard input (I use an Apple wireless keyboard on my test machine), or the USB mouse, or the display refresh ? No idea unfortunately.
(In reply to Julien Nabet from comment #6) > BTW, would it be possible to have a bt of something similar to know where > it's called in LO? I'll have a look.
Here's the code pointer: https://opengrok.libreoffice.org/xref/core/apple_remote/source/HIDRemoteControlDevice.m#423 success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements);
It seems that the problems are indeed linked to AppleRemote handling code : success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); line 423 of HIDRemoteCotnrolDevice.m
Created attachment 135642 [details] Leak cycle graph for CFArray management I am enclosing a leak cycle graph for the CFArray management code cycle
Trace of calls leading to leak : 9 libAppleRemotelo.dylib -[HIDRemoteControlDevice(IOKitMethods) initializeCookies] /Users/Shared/LO/core/apple_remote/source/HIDRemoteControlDevice.m:423 10 libAppleRemotelo.dylib -[HIDRemoteControlDevice startListening:] /Users/Shared/LO/core/apple_remote/source/HIDRemoteControlDevice.m:180 11 libAppleRemotelo.dylib -[RemoteControlContainer startListening:] /Users/Shared/LO/core/apple_remote/source/RemoteControlContainer.m:114 12 libvcllo.dylib -[VCL_NSApplication applicationWillBecomeActive:] /Users/Shared/LO/core/vcl/osx/vclnsapp.mm:504
See also lines 109-115 of RemoteControlContainer.m : - (void) startListening: (id) sender { #ifdef DEBUG NSLog(@"Apple Remote: start listening to events... "); #endif for(NSUInteger i=0; i < [remoteControls count]; i++) { [[remoteControls objectAtIndex: i] startListening: sender]; } where the line : [[remoteControls objectAtIndex: i] startListening: sender]; is identified as a leak point.
That points to : - (void) startListening: (id) sender { (void)sender; if ([self isListeningToRemote]) return; at lines 147-149 in HIDRemoteControlDevice.m
I'm noticing a different leak with the the given steps (with a USB device attached): [NSCFTimer initWithFireDate:interval:target:selector:userInfo:repeats:] Version: 6.0.0.0.alpha0+ Build ID: 2b78b9feab9521e614b9edae17709cb6e2001292 CPU threads: 4; OS: Mac OS X 10.12.6; UI render: default; TinderBox: MacOSX-x86_64@49-TDF, Branch:master, Time: 2017-08-25_05:47:15 Locale: nl-NL (nl_NL.UTF-8); Calc: group However, I think I have seen this one too ... some while ago. I will retest it with a USB device connected..
I gave a try locally with https://gerrit.libreoffice.org/#/c/43329/ I don't reproduce the leaks with it and have no crash. However, perhaps I missed something so first, I'll wait for MacOs Jenkins build.
Julien Nabet committed a patch related to this issue. It has been pushed to "master": http://cgit.freedesktop.org/libreoffice/core/commit/?id=47039a11dae0a614213cae136fe705d32f9efa1c tdf#111561: try to fix leak in HIDRemoteControlDevice (apple_remote) It will be available in 6.0.0. The patch should be included in the daily builds available at http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More information about daily builds can be found at: http://wiki.documentfoundation.org/Testing_Daily_Builds Affected users are encouraged to test the fix and report feedback.
Julien Nabet committed a patch related to this issue. It has been pushed to "master": http://cgit.freedesktop.org/libreoffice/core/commit/?id=b8a6998342fbbeb77bca354df306dd94d94d57e9 Following tdf#111561: no need to autorelease "elements" (apple_remote) It will be available in 6.0.0. The patch should be included in the daily builds available at http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More information about daily builds can be found at: http://wiki.documentfoundation.org/Testing_Daily_Builds Affected users are encouraged to test the fix and report feedback.
(In reply to Commit Notification from comment #17) > > Affected users are encouraged to test the fix and report feedback. Hmm, doesn't seem to change anything on my locally built master: Version: 6.0.0.0.alpha0+ Build ID: 643e9001bff137b6e5a8784d9e1f25a51e0d1644 CPU threads: 4; OS: Mac OS X 10.13; UI render: default; Locale: fr-FR (fr_FR.UTF-8); Calc: group
Thank you for your feedback Alex. No idea then :-(
So, what I'm currently seeing is : success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); at line 423 of HIDRemoteControlDevice.m
(In reply to Alex Thurgood from comment #21) > So, what I'm currently seeing is : > > success = (*handle)->copyMatchingElements(handle, NULL, > (CFArrayRef*)&elements); > > > > at line 423 of HIDRemoteControlDevice.m So the bit before the above line is : - (BOOL) initializeCookies { IOHIDDeviceInterface122** handle = (IOHIDDeviceInterface122**)hidDeviceInterface; IOHIDElementCookie cookie; long usage; long usagePage; id object; NSArray* elements = nil; NSDictionary* element; IOReturn success; if (!handle || !(*handle)) return NO; // Copy all elements, since we're grabbing most of the elements // for this device anyway, and thus, it's faster to iterate them // ourselves. When grabbing only one or two elements, a matching // dictionary should be passed in here instead of NULL. and according to Apple documentation : https://developer.apple.com/documentation/iokit/iohiddevicedeviceinterface/1395733-copymatchingelements?language=objc the example that Apple gives appears to be slightly different to that used in our code ?
Alex: I don't understand what you mean Apple: IOReturn (*copyMatchingElements)(void *self, CFDictionaryRef matchingDict, CFArrayRef *pElements, IOOptionBits options); LO code: success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements); from LO code "IOReturn success;" => OK handle corresponds to *self => OK NULL corresponds to matchingDict and there's none here comments in the code: "419 // Copy all elements, since we're grabbing most of the elements 420 // for this device anyway, and thus, it's faster to iterate them 421 // ourselves. When grabbing only one or two elements, a matching 422 // dictionary should be passed in here instead of NULL." => OK NSArray* elements = nil; but code shows "&elements" cast with (CFArrayRef*) => OK about "options", Apple website indicates: "Reserved for future use. Ignored in current implementation. Set to zero." => OK Did I miss something?
(In reply to Julien Nabet from comment #23) > Did I miss something? No you didn't miss anything and thanks for the explanation - my observation was due to my lack of understanding in C++
** Please read this message in its entirety before responding ** To make sure we're focusing on the bugs that affect our users today, LibreOffice QA is asking bug reporters and confirmers to retest open, confirmed bugs which have not been touched for over a year. There have been thousands of bug fixes and commits since anyone checked on this bug report. During that time, it's possible that the bug has been fixed, or the details of the problem have changed. We'd really appreciate your help in getting confirmation that the bug is still present. If you have time, please do the following: Test to see if the bug is still present with the latest version of LibreOffice from https://www.libreoffice.org/download/ If the bug is present, please leave a comment that includes the information from Help - About LibreOffice. If the bug is NOT present, please set the bug's Status field to RESOLVED-WORKSFORME and leave a comment that includes the information from Help - About LibreOffice. Please DO NOT Update the version field Reply via email (please reply directly on the bug tracker) Set the bug's Status field to RESOLVED - FIXED (this status has a particular meaning that is not appropriate in this case) If you want to do more to help you can test to see if your issue is a REGRESSION. To do so: 1. Download and install oldest version of LibreOffice (usually 3.3 unless your bug pertains to a feature added after 3.3) from http://downloadarchive.documentfoundation.org/libreoffice/old/ 2. Test your bug 3. Leave a comment with your results. 4a. If the bug was present with 3.3 - set version to 'inherited from OOo'; 4b. If the bug was not present in 3.3 - add 'regression' to keyword Feel free to come ask questions or to say hello in our QA chat: https://kiwiirc.com/nextclient/irc.freenode.net/#libreoffice-qa Thank you for helping us make LibreOffice even better for everyone! Warm Regards, QA Team MassPing-UntouchedBug
Seeing as I couldn't bring this any further, and it looks like it is Apple's own code that might be the root cause, let's close this as NOTOURBUG.