From 5243f74c094f5919642c3bde160689a9f77e7ae7 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 13 Jan 2016 23:47:34 +0100 Subject: Add more debug info for "Attempted to connect a connection that is not disconnected" crash (#2353) --- .../SPMySQLFramework/Source/SPMySQLConnection.h | 2 ++ .../SPMySQLFramework/Source/SPMySQLConnection.m | 27 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'Frameworks') diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h index 6a3a1013..15b809f1 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h @@ -128,6 +128,8 @@ BOOL retryQueriesOnConnectionFailure; SPMySQLClientFlags clientFlags; + + NSString *_debugLastConnectedEvent; } #pragma mark - diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m index f82a4241..365f8649 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m @@ -199,6 +199,8 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS // while running them retryQueriesOnConnectionFailure = YES; + _debugLastConnectedEvent = nil; + // Start the ping keepalive timer keepAliveTimer = [[SPMySQLKeepAliveTimer alloc] initWithInterval:10 target:self selector:@selector(_keepAlive)]; @@ -253,6 +255,8 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS if (querySqlstate) [querySqlstate release], querySqlstate = nil; [delegateDecisionLock release]; + [_debugLastConnectedEvent release]; + [NSObject cancelPreviousPerformRequestsWithTarget:self]; [super dealloc]; @@ -428,6 +432,14 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS const char *__crashreporter_info__ = NULL; asm(".desc ___crashreporter_info__, 0x10"); +static uint64_t _elapsedMicroSecondsSinceAbsoluteTime(uint64_t comparisonTime) +{ + uint64_t elapsedTime_t = mach_absolute_time() - comparisonTime; + Nanoseconds elapsedTime = AbsoluteToNanoseconds(*(AbsoluteTime *)&(elapsedTime_t)); + + return (UnsignedWideToUInt64(elapsedTime) / 1000ULL); +} + @implementation SPMySQLConnection (PrivateAPI) /** @@ -438,8 +450,11 @@ asm(".desc ___crashreporter_info__, 0x10"); // If a connection is already active in some form, throw an exception if (state != SPMySQLDisconnected && state != SPMySQLConnectionLostInBackground) { - asprintf(&__crashreporter_info__, "Attempted to connect a connection that is not disconnected (SPMySQLConnectionState=%d).", state); - __builtin_trap(); + @synchronized (self) { + uint64_t diff = _elapsedMicroSecondsSinceAbsoluteTime(initialConnectTime); + asprintf(&__crashreporter_info__, "Attempted to connect a connection that is not disconnected (SPMySQLConnectionState=%d).\nIf state==2: Previous connection made %lluµs ago from: %s", state, diff, [_debugLastConnectedEvent cStringUsingEncoding:NSUTF8StringEncoding]); + __builtin_trap(); + } [NSException raise:NSInternalInconsistencyException format:@"Attempted to connect a connection that is not disconnected (SPMySQLConnectionState=%d).", state]; return NO; } @@ -472,7 +487,13 @@ asm(".desc ___crashreporter_info__, 0x10"); // Successfully connected - record connected state and reset tracking variables state = SPMySQLConnected; - initialConnectTime = mach_absolute_time(); + + @synchronized (self) { + initialConnectTime = mach_absolute_time(); + [_debugLastConnectedEvent release]; + _debugLastConnectedEvent = [[NSString alloc] initWithFormat:@"thread=%@ stack=%@",[NSThread currentThread],[NSThread callStackSymbols]]; + } + mysqlConnectionThreadId = mySQLConnection->thread_id; lastConnectionUsedTime = initialConnectTime; -- cgit v1.2.3