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

Build error with -fsanitize=address,undefined -O0 #868

Closed
guidovranken opened this issue Jan 17, 2021 · 5 comments
Closed

Build error with -fsanitize=address,undefined -O0 #868

guidovranken opened this issue Jan 17, 2021 · 5 comments

Comments

@guidovranken
Copy link

Set env:

export CC=clang-11
export CFLAGS="-fsanitize=address,undefined -O0"

(This is a valid combination of compile flags that works with any other project)

Then ./configure and build:

  CC       src/libsecp256k1_la-secp256k1.lo
In file included from src/secp256k1.c:13:
In file included from ./src/field_impl.h:18:
In file included from ./src/field_5x52_impl.h:18:
./src/field_5x52_asm_impl.h:29:5: error: inline assembly requires more registers than available
    "movq 0(%%rsi),%%r10\n"
    ^
./src/field_5x52_asm_impl.h:29:5: error: inline assembly requires more registers than available
./src/field_5x52_asm_impl.h:29:5: error: inline assembly requires more registers than available
./src/field_5x52_asm_impl.h:299:5: error: inline assembly requires more registers than available
    "movq 0(%%rsi),%%r10\n"
    ^
./src/field_5x52_asm_impl.h:299:5: error: inline assembly requires more registers than available
./src/field_5x52_asm_impl.h:299:5: error: inline assembly requires more registers than available
In file included from src/secp256k1.c:14:
In file included from ./src/scalar_impl.h:24:
./src/scalar_4x64_impl.h:279:5: error: inline assembly requires more registers than available
    "movq 32(%%rsi), %%r11\n"
    ^
./src/scalar_4x64_impl.h:279:5: error: inline assembly requires more registers than available
./src/scalar_4x64_impl.h:279:5: error: inline assembly requires more registers than available
9 errors generated.
Makefile:1054: recipe for target 'src/libsecp256k1_la-secp256k1.lo' failed

Tested with Clang 11 and latest repository checkout on Linux 64 bit.

@gmaxwell
Copy link
Contributor

Looks like a clang bug to me. If it needs more registers for its own usage, its free to save something onto the stack to get enough for the assembly. Looks like there a number of unresolved reports of similar in their bug tracker: https://bugs.llvm.org/buglist.cgi?quicksearch=%22inline%20assembly%20requires%20more%20registers%20than%20available%22%20

You can disable assembly in this library or presumably use different compiler flags to avoid the issue.

@guidovranken
Copy link
Author

Got it, thanks.

@sipa
Copy link
Contributor

sipa commented Jan 17, 2021

I remember when writing this code originally it was hard to not run out of registers, and initially it needed -fomit-frame-pointer. That's no longer needed, but we're probably still very close to the limit. If enabling these sanitizers reserves more registers from something else, it's not unreasonable that it causes failure.

@real-or-random
Copy link
Contributor

real-or-random commented Jan 18, 2021

Fwiw, you see essentially the same error with ./configure CFLAGS="-fsanitize=address -O0" CC=gcc But in the case of gcc, -fomit-frame-pointer is enough (which is in -O1). For clang, you apparently need some other flags in -O1. Just passing -O1 already works.

Can I ask why you compile with -O0? Is there some evidence that this provides "better" results for the sanitizers?

see #846 (comment) where I ran into the same issue.

@guidovranken
Copy link
Author

-O0 can certainly bring to light bugs which do not manifest in high(er) optimization levels. A simple example is the statement

(void)strlen(s);

There's a good chance that will be optimized away with -O3 because it's essentially a no-op (the result of strlen isn't used, nor does strlen alter s, so removing it results in an equivalent program). But there's an OOB read there if s is an invalid pointer (or a string that is not NULL-terminated). Hence you can find this bug with -O0 but not -O3.

Similarly other code may be elided too when using optimization (according to any logic the compiler deems appropriate) so I occasionally run things with -O0 to get the most "verbatim" binary representation of the source code to potentially find new bugs.

Aggressive optimizations like -O3 can sometimes be useful to find undefined behavior (that's not detected by UBSAN, which only detects a small subset of all undefined behavior in C). If you start running into logic bugs or crashes that are not logical in relation to what the source code prescribes with -O3 that's often a manifestation of UB.

OSS-Fuzz strikes a balance by compiling everything with -O1 by default.

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

No branches or pull requests

4 participants