Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,844
    • Issues 4,844
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 453
    • Merge requests 453
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
    • Value stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #18418

Closed
Open
Created Jul 03, 2020 by Andreas Herrmann@trac-andreash

withArgs and withProgName permanently modify argv[0]

Summary

The functions withArgs and withProgName are meant to temporarily modify the program arguments, either argv[1] and upwards or argv[0]. However, they both have the side-effect to permanently modify argv[0].

Steps to reproduce

Consider the following example program (full project attached ghc_arg0.tgz ):

module Main where

import Arg0 (getArg0)
import System.Environment (withArgs, withProgName)

main :: IO ()
main = do
  before <- getArg0
  during <- withProgName "manual" getArg0
  -- during <- withArgs [] getArg0
  after <- getArg0
  putStrLn $ "before " ++ before ++ "\nduring " ++ during ++ "\nafter " ++ after

Observe the following behavior

$ cabal run
before /home/user/ghc_arg0/dist-newstyle/build/x86_64-linux/ghc-8.10.1/ghc-arg0-0.1.0.0/x/ghc-arg0/build/ghc-arg0/ghc-arg0
during manual
after ghc-arg0

I.e. the result of getArg0 is different before and after withProgName (same with withArgs).

Expected behavior

withProgName and withArgs should fully restore argv[0]. I.e. the output above should be

before /home/user/ghc_arg0/dist-newstyle/build/x86_64-linux/ghc-8.10.1/ghc-arg0-0.1.0.0/x/ghc-arg0/build/ghc-arg0/ghc-arg0
during manual
after /home/user/ghc_arg0/dist-newstyle/build/x86_64-linux/ghc-8.10.1/ghc-arg0-0.1.0.0/x/ghc-arg0/build/ghc-arg0/ghc-arg0

Environment

  • GHC version used: 8.10.1

Optional:

  • Operating System: Ubuntu 19.10
  • System Architecture: x86_64

Additional context

As pointed out in #3199 (closed) there is no easy access to argv[0] in GHC. The attached example uses a slight variation of getProgName that doesn't invoke basename on the result. Alternatively, there is https://hackage.haskell.org/package/system-argv0-0.1.1.

The motivating use-case is to determine the path by which the program was invoked, see https://github.com/tweag/rules_haskell/pull/1387 for details. Note, this is not necessarily the same as the result of getExecutablePath as that one uses /proc/self/exe and resolves symbolic links. The issue was caused by a program calling getProgName around an optparse-applicative parser to control the program name in error messages generated by optparse-applicative.

Edited Jul 03, 2020 by Andreas Herrmann
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking