【问题标题】:Segmentation fault when running hs_init(0, 0) for ffi为 ffi 运行 hs_init(0, 0) 时出现分段错误
【发布时间】:2013-01-10 15:37:22
【问题描述】:

我正在尝试从 python 调用 Haskell 函数。 我有以下制作文件:

GHC=ghc
GHC_RUNTIME_LINKER_FLAG=-lHSrts-ghc7.4.1

libffi-example.so: Example.o wrapper.o
    $(GHC) -o $@ -shared -dynamic -fPIC $^ $(GHC_RUNTIME_LINKER_FLAG)

Example_stub.h Example.o: Example.hs
    $(GHC) -c -dynamic -fPIC Example.hs

wrapper.o: wrapper.c Example_stub.h
    $(GHC) -c -dynamic -fPIC wrapper.c

clean:
    rm -f *.hi *.o *_stub.[ch]

clean-all:
    rm -f *.hi *.o *_stub.[ch] *.so


# Runs the example Python program
example: libffi-example.so
    python program.py

wrapper.c 唯一的作用是通过调用hs_init(0,0);hs_init 创建包装器。包装器称为example_init

example_init 中运行make example 时出现分段错误(即调用hs_init(0,0) 时)。

谁能告诉我这是为什么和/或如何解决它?

谢谢!

【问题讨论】:

  • hs_init 获取指向 argv 和 argc 的指针。尝试传递正确的指针,例如hs_init(&argc, &argv); ?

标签: haskell ffi


【解决方案1】:

它应该可以工作:

“此外,对于 argc 和 argv,hs_init() 可能以 NULL 调用,表示缺少命令行参数。”

好像是ghc-7.2.1到ghc-7.4.1的bug:

RFib.hs:

{-# LANGUAGE ForeignFunctionInterface #-}
module RFib where

fib :: Int -> Int
fib n
    | n >= 0    = go 0 1 n
    | even n    = -go 0 1 (-n)
    | otherwise = go 0 1 (-n)
      where
        go a _ 0 = a
        go a b k = go b (a+b) (k-1)

foreign export ccall "rfib" fib :: Int -> Int

rfib.c:

#include <stdio.h>
#include <HsFFI.h>

int rfib(int);

int main(void) {
    hs_init(0,0);
    printf("%d\n", rfib(35));
    hs_exit();
    return 0;
}

编译运行:

$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.0.2 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.0.4 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.2.1 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
Speicherzugriffsfehler
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.2.2 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
Speicherzugriffsfehler
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.4.1 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
Speicherzugriffsfehler
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc-7.4.2 -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465
$ rm rfib.o RFib.hi RFib.o a.out
$ ghc -O2 -Wall -no-hs-main RFib.hs rfib.c && ./a.out
[1 of 1] Compiling RFib             ( RFib.hs, RFib.o )
Linking a.out ...
9227465

rfib.c中更改两行:

int main(int argc, char *argv[]) {
    hs_init(&argc,&argv);

它适用于所有版本(>= 我安装的 7.0)。

所以修复它

  • 通过&amp;argc&amp;argv
  • 升级 GHC

是最明显的两种方式。

【讨论】:

  • 非常感谢。使用 hs_init(NULL, NULL) 将 ghc 升级到 7.4.2。太棒了:)
猜你喜欢
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多