macos haskell segmentation-fault cabal ffi

macos - OSX, ghci, dylib, ¿cuál es la forma correcta?



haskell segmentation-fault (1)

Preguntas iniciales

¿Debería esto funcionar con ghci? Si es así, ¿qué estoy haciendo mal o cómo puedo solucionar el bloqueo?

En OSX 10.6.7 (usando la plataforma Haskell / w GHC 7.0.2) podría cargar su biblioteca compartida compartida en ghci de la siguiente manera:

➜ GLFW-b git:(master) ✗ ghci dist/build/Graphics/UI/GLFW.hs -Lbuild/dynam ic -lglfw GHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Loading object (dynamic) glfw ... done final link ... done [1 of 1] Compiling Graphics.UI.GLFW ( dist/build/Graphics/UI/GLFW.hs, inte rpreted ) Ok, modules loaded: Graphics.UI.GLFW. *Graphics.UI.GLFW> initialize True

Nota: construí las libs de glfw usando el archivo Makefile proporcionado, y adicionalmente usé su archivo .cabal para procesar src/Graphics/UI/GLFW.hsc y compilación dist/build/Graphics/UI/GLFW.hs (es decir, que había ejecutado anteriormente cabal configure/build ).

¿Puedo seguir con la versión .a estática de la biblioteca con ghci?

Sí, el soporte para cargar libs estáticas se incluyó en GHC 7.0.2 ( Manual de GHC ). compiler/ghci/Linker.lhs es una gran lectura, y le dará un alto nivel de cómo ghci decide qué hacer con los argumentos de la línea de comando que se le pasan. Además, al navegar por varios problemas de soporte de la plataforma, encontré esta documentación extremadamente útil.

Vinculación de archivos estáticos con ghci.

Al momento de escribir, la línea 1113 del compiler/ghci/Linker.hs demuestra que ghci actualmente requiere que los archivos estáticos sean compiler/ghci/Linker.hs por el sistema del paquete (es decir, con el nombre HSlibname.a )

locateOneObj :: [FilePath] -> String -> IO LibrarySpec locateOneObj dirs lib | not ("HS" `isPrefixOf` lib) -- For non-Haskell libraries (e.g. gmp, iconv) we assume dynamic library = assumeDll | not isDynamicGhcLib -- When the GHC package was not compiled as dynamic library -- (=DYNAMIC not set), we search for .o libraries or, if they -- don''t exist, .a libraries. = findObject `orElse` findArchive `orElse` assumeDll

La investigación adicional de análisis de argumento de línea cmd indica que las bibliotecas especificadas se recopilan en la línea 402 en la función reallyInitDynLinker :

; classified_ld_inputs <- mapM classifyLdInput cmdline_ld_inputs

donde se define classifyLdInput over

classifyLdInput :: FilePath -> IO (Maybe LibrarySpec) classifyLdInput f | isObjectFilename f = return (Just (Object f)) | isDynLibFilename f = return (Just (DLLPath f)) | otherwise = do hPutStrLn stderr ("Warning: ignoring unrecognised input `" ++ f ++ "''") return Nothing

Esto significa que, al margen de una especificación de paquete, actualmente no existe una forma directa de vincular un archivo de almacenamiento en ghci (o dicho de otra manera, actualmente no existe un argumento de línea de cmd para hacerlo).

Reparar tu paquete cabal

En su .cabal paquete .cabal , está intentando compilar dos bibliotecas conflictivas:

  • A : enlace en una biblioteca preconstruida (construida según su especificación en Setup.hs y Makefile , y vinculada según las directivas extra-libraries y extra-lib-dirs )
  • B : crear una nueva biblioteca en línea (las directivas c-sources y frameworks ).

Una solución simple para el error anterior es simplemente eliminar todas las directivas que habiliten B al construir para Mac OSX, de la siguiente manera:

include-dirs: glfw/include glfw/lib - c-sources: - glfw/lib/enable.c - glfw/lib/fullscreen.c - glfw/lib/glext.c - glfw/lib/image.c - glfw/lib/init.c - glfw/lib/input.c - glfw/lib/joystick.c - glfw/lib/stream.c - glfw/lib/tga.c - glfw/lib/thread.c - glfw/lib/time.c - glfw/lib/window.c + + if !os(darwin) + c-sources: + glfw/lib/enable.c + glfw/lib/fullscreen.c + glfw/lib/glext.c + glfw/lib/image.c + glfw/lib/init.c + glfw/lib/input.c + glfw/lib/joystick.c + glfw/lib/stream.c + glfw/lib/tga.c + glfw/lib/thread.c + glfw/lib/time.c + glfw/lib/window.c

y

if os(darwin) - include-dirs: - glfw/lib/cocoa - frameworks: - AGL - Cocoa - OpenGL extra-libraries: glfw - extra-lib-dirs: build/static build/dynamic + extra-lib-dirs: build/dynamic

No he probado nada más allá de verificar que lo siguiente ahora funciona correctamente:

➜ GLFW-b git:(master) ✗ ghci GHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude> :m + Graphics.UI.GLFW Prelude Graphics.UI.GLFW> initialize Loading package GLFW-b-0.0.2.6 ... linking ... done. True Prelude Graphics.UI.GLFW>

Necesito construir algún código C y luego hacer referencia a ese código C a través del FFI. Me gustaría utilizar mi enlace desde dentro de ghci on osx. Una de mis limitaciones es que no puedo entregar las fuentes C a ghc en el archivo .cabal. Esto se debe a una limitación con ghc / cabal que puede corregirse en la próxima versión de ghc (pero quiero que mi código funcione ahora y en versiones anteriores). Mira este error para más detalles .

La esencia de ese error es que el código C necesita ser compilado con algunos módulos de Objective-C y ghc malinterpreta esos como scripts del enlazador. He intentado muchas cosas y crear los archivos yo mismo con un archivo MAKE es lo único que funcionó. Realmente, esto no debería ser un problema, porque debería ser igual que si decidiera usar una biblioteca de C externa que no construí yo mismo. Por el bien de este problema, imaginemos que es una biblioteca de C separada que puedo reconstruir fácilmente con diferentes opciones.

Si construyo la biblioteca C como .a, entonces ghci se queja de que no puede abrir .dylib. Mi primera pregunta es: ¿Por qué ghci necesita un .dylib y realmente lo usa?

Cuando construyo un dylib obtengo un segfault al cargar el código en ghci .

Tenga en cuenta que este enlace ya funciona en otras plataformas, tanto Linux como Windows, y el enlace funciona bien en osx cuando estoy compilando en lugar de usar ghci. Este problema específico para el combo osx / ghci.

En ese rastro anterior, estoy usando gdb pero se bloquea independientemente de si uso gdb. Lo rastreé hasta las líneas que causan el bloqueo:

void _glfwClearWindowHints( void ) { memset( &_glfwLibrary.hints, 0, sizeof( _glfwLibrary.hints ) ); }

El creador de problemas es esa línea memset, bueno, en realidad el problema es que cuando se ejecuta dentro de la escritura de ghci en la estructura indirecta de _glfwLibrary hay una violación de acceso a la memoria. La estructura de consejos es simplemente un montón de enteros. Es muy plano y simple, y por lo tanto, creo que el problema es un problema, ya sea con la forma en que estoy vinculando las cosas o con la forma en que ghci está cargando el código.

Aquí están los bits de mi archivo MAKE que utilizo para construir el dylib y el .a:

GCCFLAGS := $(shell ghc --info | ghc -e "fmap read getContents >>= / putStrLn . unwords . read . Data.Maybe.fromJust . lookup / /"Gcc Linker flags/"") FRAMEWORK := -framework Cocoa -framework OpenGL GLFW_FLAG := $(GCCFLAGS) -O2 -fno-common -Iglfw/include -Iglfw/lib / -Iglfw/lib/cocoa $(CFLAGS) all: $(BUILD_DIR)/static/libglfw.a $(BUILD_DIR)/dynamic/libglfw.dylib $(BUILD_DIR)/dynamic/libglfw.dylib: $(OBJS) $(CC) -dynamiclib -Wl,-single_module -compatibility_version 1 / -current_version 1 / $(GLFW_FLAG) -o $@ $(OBJS) $(GLFW_SRC) $(FRAMEWORK) $(BUILD_DIR)/static/libglfw.a: $(OBJS) ar -rcs $@ $(OBJS)

La mayoría de las banderas se toman directamente del archivo MFLFW así que creo que deberían ser correctas para esa biblioteca.

La primera línea parece un poco extraña, pero es la solución que usé para este problema .

Detalles de la plataforma:

  • OSX 10.6.6
  • x86_64
  • 4 núcleos
  • GHC versión 7.0.3 instalado mediante el instalador de la plataforma Haskell
  • Repositorio de origen: https://github.com/dagit/GLFW-b

Editar: Aquí están mis preguntas:

  • ¿Debería esto funcionar con ghci?
  • Si es así, ¿qué estoy haciendo mal o cómo puedo solucionar el bloqueo?
  • ¿Puedo seguir con la versión .a estática de la biblioteca con ghci?