Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmake: Delete -DNDEBUG from all available config-specific flags #1606

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

hebasto
Copy link
Member

@hebasto hebasto commented Sep 16, 2024

During the integration of libsecp256k1's build system into Bitcoin Core's build system, it was decided to always build the most tested "RelWithDebInfo" configuration, regardless of the Bitcoin Core's actual build configuration.

To achieve this goal for muli-config generators, we assign to each CMAKE_C_FLAGS_<CONFIG> variable the default value of the CMAKE_C_FLAGS_RELWITHDEBINFO variable before processing libsecp256k1's CMakeLists.txt file.

The problem with this approach is that, at this point, the CMAKE_C_FLAGS_RELWITHDEBINFO variable has not yet been stripped of the -DNDEBUG flag, which leaks into other CMAKE_C_FLAGS_<CONFIG> variables.

This PR fixes this issue.

@real-or-random
Copy link
Contributor

Is it correct that the first commit is the actual fix and the second commit is just a refactor?

@hebasto
Copy link
Member Author

hebasto commented Sep 17, 2024

Is it correct that the first commit is the actual fix and the second commit is just a refactor?

The second commit is the fix, as the current implementation skips the CMAKE_C_FLAGS_DEBUG variable, falsely assuming it doesn't contain -DNDEBUG.

The first commit is a prerequisite since the new code processes the CMAKE_BUILD_TYPE variable, which must be set beforehand.

@real-or-random
Copy link
Contributor

Oh ok, I missed CMAKE_C_FLAGS_DEBUG...

I'd Concept ACK this in principle, but I think there's a simpler solution:

Background

The reason why we remove this entire -DNDEBUG thing is only because we use assert() (from the standard library's <assert.h>) in the examples. Assertions can be made no-ops by passing -DNDEBUG, which CMake's defaults always set, even in debug builds. See also the comment in the CMake file "# We leave assertions on because they are only used in the examples, and we want them always on there."

Alternative suggestion

So this added complexity in the build system is only there because of the examples. We could just replace assert(expr) in the examples by if (!expr) exit(1), or even if (!expr) exit(EXIT_FAILURE). This gets us rid of the fiddling with CMAKE_C_FLAGS_* variables entirely.

We also have some cases of return 1 in main(), which is equivalent to exit(1). But also these are a bit bad for examples because they change their semantics if people copy-n-paste them out of our main() in different functions.

Rationale

I assume we thought it's a "good" and idiomatic example to use a standard library function, but it may be bad practice after all:

  • I think assert() is more for debugging (that's why it can be turned off by defining NDEBUG). But in the case of real failures occurring in production, it's more conservative to halt the program. And we want to be conservative in cryptographic code.
  • Another thing which is wrong with the ability to disable assertion is this entire story of unintentionally disabled side effects.
  • And if CMake disables assertions by default, it's apparently an easy mistake to make, even without knowing about it.
  • assert() itself calls abort() but exit() is probably better practice, at least according to https://wiki.sei.cmu.edu/confluence/display/c/ERR04-C.+Choose+an+appropriate+termination+strategy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants