Track call sites of QMacAutoReleasePools for debugging pool usage
Printing pools by calling [NSAutoreleasePool showPools] will now give a more detailed view of where the various pools in the stack were created, eg: AUTORELEASE POOLS for thread 0x1000be5c0 17 releases pending. [0x107802000] ................ PAGE (hot) (cold) [0x107802038] ################ POOL 0x107802038 [0x107802040] 0x107791c70 ^-- allocated in function: main [0x107802048] ################ POOL 0x107802048 [0x107802050] 0x1073b2e80 ^-- allocated in function: QCocoaWindow::initialize() [0x107802058] 0x107111ed0 NSCompositeAppearance [0x107802060] 0x107111ed0 NSCompositeAppearance [0x107802068] 0x107111ed0 NSCompositeAppearance [0x107802070] 0x1073bbe10 __NSCFString [0x107802078] 0x1073bbde0 _NSViewBackingLayer [0x107802080] 0x1073bc100 NSWeakObjectValue [0x107802088] 0x1073bbe40 QNSView [0x107802090] 0x1073bbe40 QNSView [0x107802098] 0x107111ed0 NSCompositeAppearance [0x1078020a0] 0x107111ed0 NSCompositeAppearance [0x1078020a8] 0x1073bbe40 QNSView [0x1078020b0] ################ POOL 0x1078020b0 [0x1078020b8] 0x1073bbe30 ^-- allocated in function: QCocoaWindow::recreateWindowIfNeeded() Change-Id: I97faf30db5835fea2f05320435b1b8c334a478d1 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
d6c474b49b
commit
6c18f86af7
@ -48,6 +48,11 @@
|
|||||||
#include <UIKit/UIKit.h>
|
#include <UIKit/UIKit.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <cxxabi.h>
|
||||||
|
#include <objc/runtime.h>
|
||||||
|
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -127,22 +132,54 @@ QT_USE_NAMESPACE
|
|||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker);
|
QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker);
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Manages a scoped auto-release pool.
|
|
||||||
|
|
||||||
To track autoreleases without any pools in place, such as in main()
|
|
||||||
before the runloop has started, export OBJC_DEBUG_MISSING_POOLS=YES
|
|
||||||
and break in objc_autoreleaseNoPool, e.g.:
|
|
||||||
|
|
||||||
br set -n objc_autoreleaseNoPool -c "[((NSObject*)$r14) class] == [QNSWindow class]"
|
|
||||||
*/
|
|
||||||
QMacAutoReleasePool::QMacAutoReleasePool()
|
QMacAutoReleasePool::QMacAutoReleasePool()
|
||||||
: pool([[NSAutoreleasePool alloc] init])
|
: pool([[NSAutoreleasePool alloc] init])
|
||||||
{
|
{
|
||||||
[[[QMacAutoReleasePoolTracker alloc] initWithPool:
|
Class trackerClass = [QMacAutoReleasePoolTracker class];
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
void *poolFrame = nullptr;
|
||||||
|
if (__builtin_available(macOS 10.14, iOS 12.0, tvOS 12.0, watchOS 5.0, *)) {
|
||||||
|
void *frame;
|
||||||
|
if (backtrace_from_fp(__builtin_frame_address(0), &frame, 1))
|
||||||
|
poolFrame = frame;
|
||||||
|
} else {
|
||||||
|
static const int maxFrames = 3;
|
||||||
|
void *callstack[maxFrames];
|
||||||
|
if (backtrace(callstack, maxFrames) == maxFrames)
|
||||||
|
poolFrame = callstack[maxFrames - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (poolFrame) {
|
||||||
|
Dl_info info;
|
||||||
|
if (dladdr(poolFrame, &info) && info.dli_sname) {
|
||||||
|
const char *symbolName = info.dli_sname;
|
||||||
|
if (symbolName[0] == '_') {
|
||||||
|
int status;
|
||||||
|
if (char *demangled = abi::__cxa_demangle(info.dli_sname, nullptr, 0, &status))
|
||||||
|
symbolName = demangled;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *className = nullptr;
|
||||||
|
asprintf(&className, " ^-- allocated in function: %s", symbolName);
|
||||||
|
|
||||||
|
if (Class existingClass = objc_getClass(className))
|
||||||
|
trackerClass = existingClass;
|
||||||
|
else
|
||||||
|
trackerClass = objc_duplicateClass(trackerClass, className, 0);
|
||||||
|
|
||||||
|
free(className);
|
||||||
|
|
||||||
|
if (symbolName != info.dli_sname)
|
||||||
|
free((char*)symbolName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[[[trackerClass alloc] initWithPool:
|
||||||
reinterpret_cast<NSAutoreleasePool **>(&pool)] autorelease];
|
reinterpret_cast<NSAutoreleasePool **>(&pool)] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user