-
Notifications
You must be signed in to change notification settings - Fork 843
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
Fix potential bug in Stack failing to properly isolate pkg-db environment #4706
Comments
Thanks for raising this, @hvr.
I'm unfamiliar with this feature, myself — would this be the place to start? With that, I have some questions about the technical details of the problem you report. It would be helpful to have log information, from somebody able to reproduce this issue. Would you please invite the person who raised the issue to comment here, if possible? |
Hi! I'm the user that @hvr is talking about here. I originally made my comment on Reddit. You can find it here: https://np.reddit.com/r/haskell/comments/b9scx2/package_environment_files_run_counter_to/ek6u69t/ I did not open a bug report for this problem for two reasons: One, it wasn't clear to me which component was at fault, if any (Stack, Cabal, or GHC). Two, I didn't record or remember the exact actions that got me into and subsequently out of this situation. Since my hand has more or less been forced here, I'm working on reproducing this bug. |
I managed to reproduce this. For context, here is my system information: $ uname -a
Linux adele 4.18.0-17-generic #18-Ubuntu SMP Wed Mar 13 14:34:40 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ stack --version
Version 1.9.3, Git revision 40cf7b37526b86d1676da82167ea8758a854953b (6211 commits) x86_64 hpack-0.31.1
$ stack exec -- cabal --version
cabal-install version 2.4.1.0
compiled using version 2.4.1.0 of the Cabal library To get started, set up an empty Stack project somewhere. The location and the resolver don't matter. $ mkdir /tmp/example
$ cd /tmp/example
$ echo '{ "resolver": "lts-13.0" }' > stack.yaml Then create a minimal package file. The name and version don't matter. $ echo 'cabal-version: 2.4' > example.cabal
$ echo 'name: example' >> example.cabal
$ echo 'version: 0' >> example.cabal
$ echo 'library { default-language: Haskell2010 }' >> example.cabal Then prove that getting a REPL through Stack works: $ stack build
example-0: configure (lib)
Configuring example-0...
example-0: build (lib)
Preprocessing library for example-0..
Building library for example-0..
example-0: copy/register
Installing library in /tmp/example/.stack-work/install/x86_64-linux-tinfo6/lts-13.0/8.6.3/lib/x86_64-linux-ghc-8.6.3/example-0-AX5rovEqDIA8Qj0gJCELXw
Registering library for example-0..
$ echo ':quit' | stack exec ghci
GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/taylor/.ghci
>>> Leaving GHCi. Then build the project with Cabal: $ stack exec -- cabal v2-build
cabal: Use of GHC's environment variable GHC_PACKAGE_PATH is incompatible with
Cabal. Use the flag --package-db to specify a package database (it can be used
multiple times).
$ stack exec --no-ghc-package-path -- cabal v2-build
Resolving dependencies...
Build profile: -w ghc-8.6.3 -O1
In order, the following will be built (use -v for more details):
- example-0 (lib) (first run)
Configuring library for example-0..
Preprocessing library for example-0..
Building library for example-0.. Now see that you can not longer get a REPL through Stack: $ stack exec ghci
GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help
Loaded package environment from /tmp/example/.ghc.environment.x86_64-linux-8.6.3
<interactive>:1:6: error:
Not in scope: ‘System.IO.hSetBuffering’
No module named ‘System.IO’ is imported.
<interactive>:1:30: error:
Not in scope: ‘System.IO.stdin’
No module named ‘System.IO’ is imported.
<interactive>:1:46: error:
Not in scope: data constructor ‘System.IO.NoBuffering’
No module named ‘System.IO’ is imported.
<interactive>:1:70: error:
Not in scope: ‘System.IO.hSetBuffering’
No module named ‘System.IO’ is imported.
<interactive>:1:94: error:
Not in scope: ‘System.IO.stdout’
No module named ‘System.IO’ is imported.
<interactive>:1:111: error:
Not in scope: data constructor ‘System.IO.NoBuffering’
No module named ‘System.IO’ is imported.
<interactive>:1:135: error:
Not in scope: ‘System.IO.hSetBuffering’
No module named ‘System.IO’ is imported.
<interactive>:1:159: error:
Not in scope: ‘System.IO.stderr’
No module named ‘System.IO’ is imported.
<interactive>:1:176: error:
Not in scope: data constructor ‘System.IO.NoBuffering’
No module named ‘System.IO’ is imported. Finally, just to drive the point home, show that removing the GHC environment file allows you to get a REPL through Stack again: $ rm .ghc.environment.x86_64-linux-8.6.3
$ echo ':quit' | stack exec ghci
GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/taylor/.ghci
>>> Leaving GHCi. |
Thanks for the repro. Can you confirm that setting the |
Yup, that works. $ echo ':quit' | env GHC_ENVIRONMENT=- stack exec ghci
GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/taylor/.ghci
>>> Leaving GHCi. |
Cool, thanks. I played around with setting that environment variable before, but it seemed to break builds (ie calls into the Cabal library). We can probably treat this like the |
OK, one more bit of fun. Does it also fail for you when using GHC 8.2.2 and setting that environment variable? Afaict, there's no environment variable setting that will work across all versions of GHC out there today. |
I've opened an issue about this against the Cabal repo: haskell/cabal#5988 |
For that empty package, @tfausak said
I tried to I think setting
But there aren't any issues, neither any other clear descriptions what those are. |
You're completely wrong. If you think about it a bit more you might realize there'd be a way to set the env-var in a way that works across the GHC versions |
@hvr your tone is out of line, and will not be accepted on this repo. Speak with respect to others, or do not participate here. I will not tolerate this kind of tone any further. |
@phadej thanks for the feedback. I'm leaning towards doing nothing in Stack at all, possibly with some code to detect and warn about these files. However, given how much of a corner case this is, and that the feature is changing soon in cabal, I'm not such a fan of adding a bunch of system calls and I/O to Stack's initialization procedure. |
It seems there's still a worrying lack of understanding about what "the feature is changing soon in cabal" actually means. For one, once the reported issues that can be addressed on cabal and ghc's side have been resolved (and this doesn't mean that Stack refusing to become resilient in the context of a documented GHC feature will be considered a blocker to hold back enhancements in Cabal) the reasons that motivated the change of defaults become moot again; and even with 3.0's defaults you have to take into account users to turn it on globally themselves and not be confronted by Stack failing to handle one of GHC's features. What you also seem to fail to understand is environment files are generated by cabal in various situations (i.e. not only in the specific case whose default is being changed) which I expect to become relatively popular among non-Nix users (as those have a different Nix-idiomatic way at their disposal to achieve the same, so likely won't be using it), so if you want to support users that switch back and forth between |
@hvr so do you propose for stack rather set To illustrate, currently
These however work differently: cabal lists the packages, so I cannot load a module from
But with stack I can, as all packages are exposed:
EDIT: I accidenally left
I'd recommend setting |
This fixes #4706. Since GHC 8.0, GHC will now implicitly read in from a .ghc.environment.* file, which can cause commands like `stack exec ghci` to fail. Due to the use case of `stack exec`, it doesn't make sense to try to create our own environment file, but instead tell GHC to ignore it. Unfortunately, the ability to ignore environment files was only added in GHC 8.4.4. This patch: * Unsets any `GHC_ENVIRONMENT` variable already set outside of Stack * When using GHC 8.4.4 or later, sets the variable to `-` This will help work around situations where `cabal new-build` creates an environment file without the user's awareness. This may be somewhat superfluous in the future depending on changes to either GHC or cabal-install, but shouldn't present any harm for the foreseeable future (unless GHC changes its understanding of `GHC_ENVIRONMENT`).
Recently a Stack user complained about bugs in Stack in a public venue which as you'll surely agree isn't a suitable place to complain about bugs in Stack and even less so for getting said bugs resolved. Therefore I'm quoting their lament here in Stack's bug tracker where it actually belongs so we can quickly resolve this to everyone's benefit:
I don't use Stack myself nor do I remember having heard any such bug reports about Stack since this feature was added to GHC 8.0 three years ago. I also reached out to a Stack user who wasn't able to reproduce this. So even though the reported faulty Stack behaviour appears unlikely to me (given there's already four major GHC series out there with this new exciting feature and this is the first time I'm aware of a report of it suggesting a bug in Stack's implementation) I'd like to give the reported malfunction in Stack the benefit of the doubt and assume it being made in good faith, and consequently take it seriously enough to bring it to your attention.
Please let me know if you have any questions about the semantics/mechanics as well as current limitations of this powerful package environment file feature in GHC as there appears to be a lot of not-well-informed misconceptions being dispersed about it. I've been involved in supporting early adopters as well as improving its implementation in response to the technical feedback we received over time, so I most likely can answer most of the question you might have even if the documentation might be lacking and this should help to quickly address this potential bug in Stack in a most effective way.
The text was updated successfully, but these errors were encountered: