Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asserts are hit in production build causing crashes

I have several assert(condition, "message") statements in my project.

They are used to check invariant conditions during development. I thought they would be ignored in production/release build (as stated in this answer). They are not. Instead they cause crashes during TestFlight testing. When I comment asserts the app does not crash. Something usually gets wrong a bit but it does not crash.

Can it be something with my build settings?

All my archive schemes use release configuration:

enter image description here

The asserts are in Cocoa Touch Framework project, that is used from custom keyboard extension.

All the targets in all projects (Cocoa Touch Framework, and the main project with keyboard extension target) have these Build Settings:

Enable Foundation Assertions
    Debug    YES
    Release  NO

Disable Safety Checks  NO

What's wrong?


EDIT:

Sulthan's answer shows how to disable asserts globally for both debug and relase builds. That is not what I need. I want it to work as expected - asserts should be enabled in debug but disabled in release builds.

By default it works that way - and it also works that way in my main project. But it does not work for asserts located in Framework project that is linked from that main project (details in this question). Why? How to fix it?

like image 399
Rasto Avatar asked Apr 02 '16 13:04

Rasto


People also ask

Does assert crash the program?

Assert is a tool. The purpose of this tool is to halt your program in DEBUG and indicate that a condition you have stated should never be false is, indeed, false. This allows you to debug your code before you hand it to your professor.

Should you use assert in production code?

In the Java guideline, it is said that "assertions are only intended for debugging and bug hunting, but should be removed in production code".

What does assert do in swift?

As you can see assert() takes two parameters: something to check, and a message to print out of the check fails. If the check evaluates to false, your app will be forced to crash because you know it's not in a safe state, and you'll see the error message in the debug console.

Does assertionFailure crash the app?

One step up from assert() is assertionFailure() , which no longer has a condition: it will always crash your app when the function is called, printing any message you provide. As with assert() this will only ever be used in debug builds, so you don't have to worry about this in release mode.


1 Answers

The options you have tried:

Enable Foundation Assertions is in the preprocessing section (Macros). Swift is not preprocessed and does not use macros. This option disables NSAssert, NSParameterAssert and similar macros commonly used in Objective-C.

Disable Safety Checks is a performance option:

By default, the standard library guarantees memory safety. Many functions and methods document the requirements that must be satisfied by the caller, such as an array index being valid; memory safety is guaranteed even if a requirement is violated. However, violating a requirement can trigger a runtime error. APIs that include the word “unsafe” in their name let you explicitly disable safety checks in places where you need the additional performance. It’s your responsibility to verify the memory safety of code that uses unsafe APIs. Memory safety is also not guaranteed if there is a race condition in multithreaded code.

(Swift Library Reference)

You should probably try my answer here (use -assert-config Release in Other Swift Flags).

Or just keep the asserts in production builds. Every failing assert is a bug and in general it's better to know about a bug as soon as possible.

like image 81
Sulthan Avatar answered Oct 01 '22 04:10

Sulthan