xcode 9.3 fmdb?

Hello: I found a problem with the xcode 9.3 system. I use xcode9.3 to run my app with no problem. However, after using xcode to generate the ad hoc installation package, the app will crash. The location of the problem is a tripartite library fmdb. Then the same code, I use xcode9.2 to generate ad hoc installation package, everything is normal after installation, without any crash. I do not know where xcode 9.3 has been modified, resulting in the use of xcode 9.3 unison to run normally does not crash, but the installation package installation will crash. Is the use of fmdb wrong or that this is a problem with xcode9.3. Trouble give me an answer.

a part of log

Date/Time: 2018-04-03 17:29:38.8424 +0800

Launch Time: 2018-04-03 17:29:27.9140 +0800

OS Version: iPhone OS 11.3 (15E216)

Baseband Version: 4.56.00

Report Version: 104

Exception Type: EXC_BREAKPOINT (SIGTRAP)

Exception Codes: 0x0000000000000001, 0x00000001812655a0

Termination Signal: Trace/BPT trap: 5

Termination Reason: Namespace SIGNAL, Code 0x5

Terminating Process: exc handler [0]

Triggered by Thread: 0

Application Specific Information:

BUG IN CLIENT OF LIBDISPATCH: Release of a locked queue

Abort Cause 27021597764223744

Filtered syslog:

None found

Thread 0 Crashed:

0 libdispatch.dylib 0x00000001812655a0 _dispatch_queue_destroy$VARIANT$mp + 340

1 libdispatch.dylib 0x0000000181262874 _dispatch_dispose$VARIANT$mp + 80

2 libdispatch.dylib 0x0000000181262874 _dispatch_dispose$VARIANT$mp + 80

3 libdispatch.dylib 0x000000018128ebe0 -[OS_dispatch_queue _xref_dispose] + 52

4 myapp 0x00000001008657fc -[FMDatabaseQueue dealloc] + 1202172 (FMDatabaseQueue.m:143)

5 myapp 0x000000010090dec0 -[ECDataBase insertDataWithSQL:argumentsArray:tableName:operateStateBlock:] + 1892032 (ECDataBase.m:72)

Replies

Consider this from your crash report:

BUG IN CLIENT OF LIBDISPATCH: Release of a locked queue

Dispatch (that is, GCD) has crashed the app because you’ve violated one of its preconditions. The message means that:

  1. You’ve released the last reference to a queue

  2. While the queue is locked, typically because code is running on that queue

You can trigger this problem yourself with a small snippet of code:

static dispatch_queue_t q;

static void test(void) {
    q = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(q, ^{
        dispatch_release(q);
    });
}

Note This is Objective-C code in manual retain/release mode. Reliably triggering the crash from Swift, or even Objective-C in ARC mode, is a bit trickier (-:

It’s not clear why your app is causing this problem but, given that this is deep in FMDB code, I think you’ll need to focus your efforts there.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you for your response

Why I use xcode9.3 debugging to run without crashing, ipa running using xcode9.2 does not crash, only runs after xcode9.3 generates ipa crash

It’s not uncommon for changes in the compiler to uncover latent memory management problems. Earlier I posted an Objective-C manual retain/release snippet because that guarantees the order in which memory management operations are done, which guarantees to reproduce the problem. Consider some roughly equivalent Swift code:

var q: DispatchQueue?

func test() {  
    q = DispatchQueue("test")
    q.sync {  
        q = nil
    }
}

This may or may not reproduce the problem based on the level of compiler optimisations. For example:

  • In a debug build you might find that

    test
    retains
    q
    across the call to
    sync(…)
    and thus the problem always occurs (because the implicit release of
    q
    on line 6 isn’t the final release because
    test
    has a reference).
  • On the other hand, in an optimised build you might find that the code crashes because

    test
    releases its reference to
    q
    as soon as possible.

The exact memory management pattern changes from release to release of the compiler, and if you have a bug that’s caused by one specific memory management pattern then it’s not uncommon for this to come and go with different versions of the compiler.

Fixing this will require you to understand the problematic pattern and apply a change to guarantee that it never occurs. This can be quite tricky. On the plus side, you can reproduce the crash. A lot of crashes like this only show up in the field.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi Eskimo,


I've run into a very similar issue, where I am getting a crash from an object being released too soon.

Some investigation by my team has revealed the specific code that is crashing, and that it does not crash with Xcode 9.2


Having read this thread, it became apparent that there was a memory management issue, and that the compiler updates have caused this code to no longer be acceptable.

We fixed it, but before we are happy to continue using Xcode 9.3, we would like to be able to go through the rest of our codebase and resolve any other issues that are revealed because of these changes.


We checked the release notes, and were slightly dismayed that there is no mention of any change that directly influences memory management in Objective-C code.

How can we identify potential risk areas with the new compiler short of running Instruments and going over each of the app targets (approximately 25 targets, I should mention!) and performing full regression tests while doing so?


Much obliged for your assistance!

There’s three general categories of bugs like this:

  • Interior pointers (A)

  • Retain loops (B)

  • Shut down on last release (C)

A classic example of case A is

-[NSData bytes]
. The memory returned by that property points to the data buffer within the
NSData
object, so if you release the object then that memory goes away [1].

Most system APIs that work like this are now flagged with

NS_RETURNS_INNER_POINTER
, which tells the compiler about this problem. You can learn more about this in the Clang ARC documentation (search for
objc_returns_inner_pointer
, which is what
NS_RETURNS_INNER_POINTER
expands to).

However, if you have your own APIs like this then you could fall foul of the same problem.

Some subsystems avoid this problem by creating a retain loop (case B). For example,

NSTimer
forms a retain loop between the timer, the run loop, and the target of the timer. You have to explicitly call
-invalidate
to break that retain loop.

In my experience case C manifests in three ways:

  • Some subsystems detect this problem at runtime and crashed. The dispatch crash discussed above above is a classic example of this.

  • Some subsystems use weak references, in which case things just mysteriously stop working when the reference gets reset to

    nil
    .
  • Some subsystems do a clean cancel on the last release. Again, this manifests as the async operation just mysteriously stops.

It’s hard to find any of these problems via static analysis. The only good option I can think of is to apply the standard memory debugging tools to your contiguous integration system.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] You can also run into problems with

NSMutableData
if you modify the object in a way that causes it to reallocate its buffer.