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

GCC has unwanted flags #18995

Closed
andrewrk opened this issue Sep 27, 2016 · 65 comments · Fixed by #28029
Closed

GCC has unwanted flags #18995

andrewrk opened this issue Sep 27, 2016 · 65 comments · Fixed by #28029
Assignees
Labels
0.kind: bug 0.kind: regression Something that worked before working no longer 1.severity: blocker
Milestone

Comments

@andrewrk
Copy link
Member

andy@xps:~/tmp$ NIX_DEBUG=true gcc
(some good flags for dealing with /nix/store/* and then...)
  -O2
  -D_FORTIFY_SOURCE=2
  -fstack-protector-strong
  --param
  ssp-buffer-size=4
  -fPIC
  -fno-strict-overflow
  -Wformat
  -Wformat-security
  -Werror=format-security

These flags should be enabled when compiling nix packages, but they should not be always on for general compiler use.

This has caused a broken debugging experience for me on the project I was working on.

Most projects have a "debug build" that has optimizations off, and this prevents that from working correctly.

NixOS version 16.09pre90254.6b20d5b (Flounder)

@andrewrk
Copy link
Member Author

I believe this was caused by #12895

@andrewrk
Copy link
Member Author

Not only that, but these flags are in the extraAfter section, which means I can't even override the flags, for example with -Og in a Makefile or build script.

@andrewrk
Copy link
Member Author

One workaround is putting

    hardeningDisable = [ "fortify" ];

in a nix-shell. Since I was already using a nix-shell for my environment, this is an acceptable workaround. Still, seems weird to assert -O2 by default and have to disable it to get previously expected behavior.

@abbradar
Copy link
Member

abbradar commented Sep 27, 2016

I think this can be fixed by adding a special flag, NIX_ENFORCE_HARDENING, that is only set in stdenvs. This way the flags won't be enforced in regular gcc invocations and could be disabled in shells by setting this flag to 0.

BTW having -O2 always added is not nice because some applications might want -O3 or -Ofast (which would be overridden). We may want to make this conditional somehow...

@rasendubi
Copy link
Member

/cc @globin @fpletz

@fpletz
Copy link
Member

fpletz commented Sep 27, 2016

You can use

hardeningDisable = [ "all" ];

to disable all hardening flags. This should also work if set as an environment variable.

We will work on a solution after 16.09 using gcc spec files that can detect for example if libraries are built or debugging is enabled. This was just our first iteration and we agree that it is not perfect. Changes to the cc-wrapper always require a full rebuild, which is very painful. More feedback on #12895 would've been helpful.

We didn't anticipate and test that those flags would be propagated to regular gcc invocations outside of nix builds. Not entirely sure how to fix it yet but @abbradar's proposal sounds reasonable. I will look into it after 16.09.

-O2 is required for -D_FORTIFY_SOURCE=2. Not sure though if higher optimizations also work.

@abbradar
Copy link
Member

FWIW I found that level 1 fortifying requires inlining:

As I said in that post, the special fortified functions (those that are available in the form of __$func_chk in the libc.so file and provide warnings at build time, and proper stack traces at runtime) only get enabled if inline functions are enabled, so are totally ignored at -O0 (simply disabling inlines, by using -fno-inline won’t stop them from being used, though).

I haven't been able to find anything except of anecdotal evidence that -O2 is required for level 2 (I'm not questioning your choice, rather I was trying to find a list of optimizations that are required so that we can enable them individually).

@fpletz
Copy link
Member

fpletz commented Sep 27, 2016

(I'm not questioning your choice, rather I was trying to find a list of optimizations that are required so that we can enable them individually).

I'm always open for suggestions. Thanks! 😃 We'll have to try that.

@abbradar
Copy link
Member

Unfortunately it may need peeking into rat nest GCC/glibc's codebases to determine this. Meanwhile I think it's okay to leave -O2.

@copumpkin
Copy link
Member

Just as a quick reminder when you talk about gcc: there's also clang to consider on Darwin (and in some cases on Linux too)

@jxy
Copy link

jxy commented Sep 29, 2016

So this is why recently gdb suddenly tells me different things in my code and gcc no longer does a good job optimizing my code. I almost thought gcc 5.4 had optimization regressions.

How do I get back a reasonable working gcc? Which nixpkgs version should I revert to?

Does this mean I should put hardeningDisable = [ "all" ]; in all of my custom nix files for my HPC production code, eg, mpich3?

I'm using nixpkgs on a ubuntu without root privilege.

It is NOT okay to leave -Oanything in extraAfter!

@andrewrk
Copy link
Member Author

We're all in agreement here @jxy and going to fix it soon. This is why it's called unstable!

The workaround you mentioned is working for me and is probably the reasonable thing to do until this is fixed.

@jxy
Copy link

jxy commented Sep 29, 2016

Right, thanks for the workaround. It wasn't easy to find this thread. I guess I'll need some performance regression tests after changing my system.

@jxy
Copy link

jxy commented Oct 3, 2016

Does NixOS 16.09 release version have this issue? If so, I'll put off upgrading until this is fixed.

@joachifm joachifm mentioned this issue Oct 7, 2016
17 tasks
@fpletz fpletz added this to the 16.09 milestone Oct 10, 2016
@fpletz fpletz self-assigned this Oct 10, 2016
@vcunat
Copy link
Member

vcunat commented Oct 11, 2016

Yes, both 16.09 and unstable/master.

@fpletz
Copy link
Member

fpletz commented Oct 11, 2016

I'm currently working on a fix.

@andrewrk
Copy link
Member Author

even though I knew about this, I temporarily forgot and it caused me to file a bogus issue report on another project: thejoshwolfe/legend-of-swarkland#36

@mboisson
Copy link

mboisson commented Feb 3, 2017

I'm running into this issue when compiling older versions of GCC.

gcc 4.8 compiles fine, but at run time, it tries to use stack-protector-strong, which is not supported.

I've wasted about 8 hours so far trying to fix this broken thing....
[mboisson@build-node easybuild-easyconfigs]$ gcc --version
gcc: erreur: unrecognized command line option ‘-fstack-protector-strong’
gcc (GCC) 4.8.5

Our fork of nixpkgs is based on 16.09 and is here:
github.com/computecanada/nixpkgs

is there any commit I could pull to fix this ?

@globin
Copy link
Member

globin commented Feb 3, 2017

There is no optimal fix yet, workaround is still to export hardeningDisable=all in your shell while developing.

@mboisson
Copy link

mboisson commented Feb 3, 2017

Thanks.

@cstrahan
Copy link
Contributor

/ping

@edolstra I hate to bug you personally/directly, but would you be able to specify your desired approach to fixing this bug - or if you can't spare the cycles for that, could you name an individual or two that you'd feel comfortable deferring to?

There's enough subtlety to the problem that I doubt everyone here will come to anything approaching a consensus. Nonetheless, the problem needs fixing, and I'd like to do the work to fix it - if someone with authority can state what an acceptable solution is.

Just as a reminder, I have this PR open: #28029

There's some feedback regarding cross compilation from @Ericson2314 that I can address, but I'm first waiting to know if we're going to accept that general approach, a variant of it, or something else entirely.

@edolstra
Copy link
Member

@cstrahan The PR looks good to me, thanks. It might be nice to issue an error/warning if there is a conflict between a hardening flag and a user-supplied -O flag, but that's not super important.

@cstrahan
Copy link
Contributor

@edolstra Awesome - thanks! I'll address @Ericson2314's points and try to get it ready for merging soon as I can - probably before the weekend is up.

@andrewrk
Copy link
Member Author

Even though I originally filed the bug, and it bit me again after that, I still forgot about it again and got bit by this issue again, wasting the musl-lib developers' time.

@Ericson2314
Copy link
Member

Hopefully @cstrahan's PR will be done soon. My bad recently for reviewing it slowly when he took it up again.

@fpletz fpletz modified the milestones: 18.03, 18.09 Mar 27, 2018
Ericson2314 pushed a commit to obsidiansystems/nixpkgs that referenced this issue Apr 10, 2018
Ericson2314 added a commit that referenced this issue Apr 10, 2018
@glaebhoerl
Copy link
Contributor

I ran into this as well, even though I'm on 18.09. After writing out most of a comment here to ask why, I realized I needed to re-instantiate my default.nix in order to actually pull in the new stuff. After doing that, I promptly got:

/nix/store/akak0rxhbi4n87z3nx78ipv76frvj841-glibc-2.27-dev/include/features.h:381:4: error: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Werror=cpp]
 #  warning _FORTIFY_SOURCE requires compiling with optimization (-O)

whenever I tried to build my project (which uses -Werror, yes), with no indication of what to do about it. Is this the expected behavior?

Since I've been reading this thread, I knew to try hardeningDisable = [ "fortify" ];, which thankfully fixed it, but Google was of no help at all. Now that I've written this comment, hopefully that might at least change. :)

(Yes I could've disabled -Werror, and if I only have to do that when also using -O0 I guess it's not such a huge deal, but it's surprising and perplexing nonetheless.)

@nh2
Copy link
Contributor

nh2 commented May 4, 2019

We continue to be plagued by this; I've opened a new issue on #60919.

Copying the descrpition here, so that people subscribed here can see what it's about and subscribe there if interested (I think the discussion should probably continue there):


This is in some way a continuation of #18995 GCC has unwanted flags.

Even though that one is marked as solved, I have over the last 2 years encountered many situations where silently -O2 -D_FORTIFY_SOURCE=2 is added to builds where I have explicitly requested that a debug build be done (which should result in -O0 / no -O flag being passed).

For example, right now on meson-based builds (on Darwin, but I believe on Linux too), if I set

mesonBuildType = "debug";

it does not have the desired effect unless I also add

hardeningDisable = [ "fortify" ];

because the fortify hardening adds -O2 -D_FORTIFY_SOURCE=2 no matter what.

The same happend to me in various C++ builds, and it's always a big drag in development time when you just can't get your -O0 debug builds working.


Reading the PR description of #28029, it says

user supplied -O flags should take precedence over the hardening flags

so I suspect that this isn't good enough, because most development builds don't add -O0 explicitly -- instead they add no -O flag at all, so even with the PR -O2 is still added.

I think we must do something about it because it's a total pain.

vs49688 added a commit to UQ-RCC/nimrodg-agent that referenced this issue Oct 14, 2020
komuw added a commit to komuw/hardstone that referenced this issue Jul 15, 2021
set/unset `NIX_HARDENING_ENABLE` env var; https://stackoverflow.com/a/27719330/2768067
We need to unset this because `delve` debugger is failing to debug with some error.
    ```
    runtime/cgo
    warning _FORTIFY_SOURCE requires compiling with optimization (-O)
        |    ^~~~~~~
    cc1: all warnings being treated as errors
    exit status 2
    ```
see issue: NixOS/nixpkgs#18995
also see PR: https://github.com/NixOS/nixpkgs/pull/28029/files on how it is set
@burdiyan
Copy link

Got hit by that too in 2022. So apparently it's not fixed. Been using gcc in a Nix shell, and couldn't perform debug on tests in Go because of the fortify flag.

@chloekek
Copy link

chloekek commented Jan 18, 2023

It's important to note that fortification isn't the only issue here. Having any behavioral flags passed to the compiler implicitly is unexpected to people who use Nix to obtain a development environment for C and C++ (and even Rust, where bindgen also uses cc-wrapper).

For the use case of C and C++ development, as opposed to the use case of writing Nix packages for inclusion in Nixpkgs, the only wrapping that should really be done is passing directories to the compiler, so that it can find crt1, libc, compiler-rt, etc.

I think the cleanest and most flexible solution would be to have a Nix function that takes a toolchain configuration and returns a set of toolchain derivations that generate appropriate wrappers. For the use case of writing Nix packages for inclusion in Nixpkgs, this function would be applied to the list of flags that are currently supplied by cc-wrapper. But if a C or C++ programmer wants different flags, they can easily do so.

@zot
Copy link

zot commented Mar 27, 2023

I was able to get go testing / delve working in VS Code by launching it as NIX_HARDENING_ENABLE="" code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug 0.kind: regression Something that worked before working no longer 1.severity: blocker
Projects
None yet
Development

Successfully merging a pull request may close this issue.