work around ldd crash on arm64 autobuilder
authorJoey Hess <joeyh@joeyh.name>
Sat, 28 Jan 2023 17:50:33 +0000 (13:50 -0400)
committerJoey Hess <joeyh@joeyh.name>
Sat, 28 Jan 2023 18:26:01 +0000 (14:26 -0400)
This does mean it has to run ldd once per executable, which is actually
quite a number of times, so will be a bit slower.

Sponsored-by: Luke Shumaker on Patreon
Build/LinuxMkLibs.hs
Utility/LinuxMkLibs.hs

index 7beab60125c518960283175fd21d4ca90e3ab1fd..33357909e685d540ecfd18809a90dbed5bcc85af 100644 (file)
@@ -31,7 +31,7 @@ mklibs :: FilePath -> a -> IO Bool
 mklibs top _installedbins = do
        fs <- dirContentsRecursive top
        exes <- filterM checkExe fs
-       libs <- parseLdd <$> readProcess "ldd" exes
+       libs <- runLdd exes
        
        glibclibs <- glibcLibs
        let libs' = nub $ libs ++ glibclibs
index 81109d96a0494c5d5d5b778573fc773fd713ed4a..55f6998e5e307cfd7a46bc558c87538e97c5e03e 100644 (file)
@@ -1,13 +1,16 @@
 {- Linux library copier and binary shimmer
  -
- - Copyright 2013-2020 Joey Hess <id@joeyh.name>
+ - Copyright 2013-2023 Joey Hess <id@joeyh.name>
  -
  - License: BSD-2-clause
  -}
 
+{-# Language LambdaCase #-}
+
 module Utility.LinuxMkLibs (
        installLib,
        parseLdd,
+       runLdd,
        glibcLibs,
        gconvLibs,
        inTop,
@@ -21,6 +24,8 @@ import Utility.Path
 import Utility.Path.AbsRel
 import Utility.Split
 import Utility.FileSystemEncoding
+import Utility.Env
+import Utility.Exception
 
 import Data.Maybe
 import System.FilePath
@@ -63,6 +68,19 @@ parseLdd :: String -> [FilePath]
 parseLdd = mapMaybe (getlib . dropWhile isSpace) . lines
   where
        getlib l = headMaybe . words =<< lastMaybe (split " => " l)
+       
+runLdd :: [String] -> IO [FilePath]
+runLdd exes = concat <$> mapM go exes
+  where
+       go exe = tryNonAsync (readProcess "ldd" [exe]) >>= \case
+               Right o -> return (parseLdd o)
+               -- ldd for some reason segfaults when run in an arm64
+               -- chroot on an amd64 host, on a binary produced by ghc.
+               -- But asking ldd to trace loaded objects works.
+               Left _e -> do
+                       environ <- getEnvironment
+                       let environ' =("LD_TRACE_LOADED_OBJECTS","1"):environ
+                       parseLdd <$> readProcessEnv exe [] (Just environ')
 
 {- Get all glibc libs, and also libgcc_s
  -