【问题标题】:ghci gives ghc panic when using foreign c callsghci 在使用外部 c 调用时会导致 ghc 恐慌
【发布时间】:2023-03-03 06:50:20
【问题描述】:

我正在尝试在一个项目中使用 ghci / stack repl,其中一个模块具有链接到 C 库 tdsodbc 的外部调用,但我不断收到

ghc: panic! (the 'impossible' happened)
  (GHC version 7.10.3 for x86_64-unknown-linux):
    Loading temp shared object failed: /tmp/ghc4628_0/libghc_71.so: undefined symbol: SQLPrepareW

(其中 SQLPrepareW 在该 C 库中定义)。使用堆栈构建工作正常。即使在其他模块碰巧导入了外部调用模块,即使没有实际调用外部函数,也会发生这种情况。它不会在加载时发生,但是一旦我尝试完全评估 repl 中的任何函数。

如何告诉 ghci 某些函数是在 ghc 之外的库中定义的?

我尝试了-l 选项(例如stack exec ghci -- -ltdsodbc),但唯一的区别是错误消息中包含来自同一个库的不同函数:

ghc: panic! (the 'impossible' happened)
  (GHC version 7.10.3 for x86_64-unknown-linux):
        Loading temp shared object failed: /tmp/ghc24107_0/libghc_25.so: undefined symbol: SQLDriverConnectW

请注意,当使用-l 时,它显然是在检查库,因为如果我拼错了它,它会说它找不到它:

$ stack exec ghci -- -L/usr/lib/x86_64-linux-gnu/odbc  -ltdsodbctypo
Warning (added by new or init): Specified resolver could not satisfy all dependencies. Some external packages have been added as dependencies.
You can suppress this message by removing it from stack.yaml

GHCi, version 7.10.3: http://www.haskell.org/ghc/  :? for help
<command line>: user specified .o/.so/.DLL could not be loaded (libtdsodbctypo.so: cannot open shared object file: No such file or directory)
Whilst trying to load:  (dynamic) tdsodbctypo
Additional directories searched:   /usr/lib/x86_64-linux-gnu/odbc

这是与

$ stack --version
Version 1.4.0, Git revision e714f1dd3fade19496d91bd6a017e435a96a6bcd (4640 commits) x86_64 hpack-0.17.0

我也尝试过stack ghci --ghci-options '-ltdsodbc -fobject-code',但它也与undefined symbol: SQLPrepareW 发生了恐慌。

【问题讨论】:

  • 啊,看起来很有希望,我之前确实在other-modules 中缺少了一些模块,但即使在添加并执行stack clean &amp;&amp; stack build &amp;&amp; stack ghci 之后它仍然像以前一样恐慌:(
  • nm libtdsodbc.so | grep SQLDriverConnectW 显示什么?
  • $ nm libtdsodbc.so␍ nm: libtdsodbc.so: no symbols$ strings libtdsodbc.so|grep SQLDriverConnectW␍ SQLDriverConnectW(它可以在 ghc 中正常编译和运行,只是在 ghci 中不行)
  • strings 没意思,使用nm -D

标签: haskell linker read-eval-print-loop ffi ghci


【解决方案1】:

freenode 上#haskell 的好人说也许我应该尝试将-fobject-code 传递给ghci。那没有用。我尝试了:set:seti 来查看它是否已经设置,但是ghci 没有显示任何关于目标代码的信息。 (做:unset -fobject-code刚刚给了Some flags have not been recognized: -fno-object-code。)

然后今天我碰巧看到了我的~/.ghci,因为其他原因,确实:set -fobject-code,尽管:set/:seti 没有显示。从我的~/.ghci 中删除:set -fobject-code 消除了恐慌,我现在可以使用模块中的函数来导入定义外部函数的模块:)

实际上从 ghci 调用任何外部函数都会导致段错误(有兴趣的可以catchsegv log),但至少我现在可以测试纯的东西了……

【讨论】:

    猜你喜欢
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2022-01-25
    相关资源
    最近更新 更多