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

Bad address when using relative cwd and setting env #219

Closed
pbrisbin opened this issue Oct 13, 2021 · 7 comments · Fixed by #229
Closed

Bad address when using relative cwd and setting env #219

pbrisbin opened this issue Oct 13, 2021 · 7 comments · Fixed by #229
Assignees

Comments

@pbrisbin
Copy link

I started getting a Bad address error when executing processes after updating from lts-18.5 to lts-18.10, which brings process from v1.6.9.0 to v1.6.13.2. It seems to be related to setting cwd and env in the CreateProcess.

Everything works fine if you don't change env. You can touch env, if you don't change cwd too. You can change env and change cwd, but depending on what you are changing cwd to and how that affects the command. For example, cwd = /bin and a command of ./true works fine even when changing env. Unfortunately, I have not been able to narrow down the pattern in that last variability. Note that setting cwd to . (or the full path to .) does not count as "change" for this issue, but setting env to the result of getEnvironment does. Straight-forward, right?

So, there are a lot of different combinations that trigger it, but here is one minimal repro:

% tree
.
├── Main.hs
└── sub
    └── exe

1 directory, 2 files
% cat sub/exe
#!/bin/sh    
true
-- Main.hs
{-# LANGUAGE TypeApplications #-}

module Main where

import Prelude

import Control.Exception (SomeException, try)
import System.Environment (getEnvironment)
import System.Process

main :: IO ()
main = do
    currentEnv <- getEnvironment
    let cp = (proc "./exe" []) { cwd = Just "./sub", env = Just currentEnv }
    x <- try @SomeException $ withCreateProcess cp $ \_ _ _ -> waitForProcess
    print x

Works in 18.5, not in 18.10:

% stack --resolver lts-18.5 runhaskell Main.hs
Right ExitSuccess
% stack --resolver lts-18.10 runhaskell Main.hs
Left ./exe: createProcess: exec: failed (Bad address)

Note that it is indeed isolated to process: I can use 18.10 with an extra-dep of process-1.6.9.0 and the bug goes away. I'm just not showing it that way because it requires more setup to repro.

I experienced this in typed-process (using setWorkingDir and setEnv), but eventually found the bug to be here.

@snoyberg
Copy link
Collaborator

@bgamari you think this could be related to #208?

@pbrisbin would you be able to narrow this down to a specific process version that introduces the breakage?

@pbrisbin
Copy link
Author

Good call. Let me do a little manual bisect with extra-deps of the versions between.

@pbrisbin
Copy link
Author

I can confirm process-1.6.12.0 does not reproduce the issue, and process-1.6.13.1 does.

I cannot test process-1.6.13.0 because I get a different error,

process> [5 of 5] Compiling System.Cmd
process>    
process> /tmp/stack-a87ce9ad085ca6e6/process-1.6.13.0/cbits/posix/find_executable.c:12:10: error:
process>      fatal error: common.h: No such file or directory
process>        12 | #include "common.h"
process>           |          ^~~~~~~~~~
process>    |
process> 12 | #include "common.h"
process>    |          ^
process> compilation terminated.
process> `gcc' failed in phase `C Compiler'. (Exit code: 1)

@snoyberg
Copy link
Collaborator

Thanks @pbrisbin. That makes it look pretty likely that #208 is at play here.

@pbrisbin
Copy link
Author

This is a complete rewrite...

😬 😱

@bgamari
Copy link
Contributor

bgamari commented Jan 11, 2022

Apologies for missing this earlier, @snoyberg! I'll investigate.

@bgamari
Copy link
Contributor

bgamari commented Jan 11, 2022

Yes, I see the problem here. find_executable fails to account for the change in working directory when searching for the target executable.

bgamari added a commit to bgamari/process that referenced this issue Jan 11, 2022
When `execvpe` is not available we use `find_executable` to search for
the executable prior to `fork`ing (fixing GHC #19994). However,
previously we failed to account for the fact that `exec` will be called
from a different working directory than that of the spawning process if
the user has set `cwd`.

Fix this by teaching `find_executable` to search relative to the
requested working directory.

Fixes haskell#219.
@bgamari bgamari mentioned this issue Jan 11, 2022
bgamari added a commit to bgamari/process that referenced this issue Jan 24, 2022
When `execvpe` is not available we use `find_executable` to search for
the executable prior to `fork`ing (fixing GHC #19994). However,
previously we failed to account for the fact that `exec` will be called
from a different working directory than that of the spawning process if
the user has set `cwd`.

Fix this by teaching `find_executable` to search relative to the
requested working directory.

Fixes haskell#219.
bgamari added a commit that referenced this issue Jan 24, 2022
When `execvpe` is not available we use `find_executable` to search for
the executable prior to `fork`ing (fixing GHC #19994). However,
previously we failed to account for the fact that `exec` will be called
from a different working directory than that of the spawning process if
the user has set `cwd`.

Fix this by teaching `find_executable` to search relative to the
requested working directory.

Fixes #219.
snoyberg added a commit that referenced this issue Jan 24, 2022
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

Successfully merging a pull request may close this issue.

3 participants