使用hs_init进行共享cabal库分析时的GHC RTS运行时错误

cro*_*urg 6 haskell ffi ghc

我有一个大型的C项目,必须用gcc编译.所以我将主可执行文件链接到这样的文件:

#include <HsFFI.h>

static void my_enter(void) __attribute__((constructor));
static void my_enter(void) {
  static char *argv[] = { "Pointer.exe", 0 };
  //static char *argv[] = { "Pointer.exe", "+RTS", "-N", "-p", "-s", "-h", "-i0.1", "-RTS", 0 };
  static char **argv_ = argv;
  static int argc = 1; // 8 for profiling
  hs_init(&argc, &argv_);
  //hs_init_with_rtsopts(&argc, &argv_);
}

static void my_exit(void) __attribute__((destructor));
static void my_exit(void) { hs_exit(); }
Run Code Online (Sandbox Code Playgroud)

它按预期工作 - GHC运行时系统初始化,我能够使用FFI从C调用Haskell代码.

然后,我尝试Debug.Trace使用"+RTS", "-N", "-p", "-s", "-h", "-i0.1", "-RTS"上面注释掉的行上的标志启用分析(主要用于堆栈跟踪)和代码覆盖(HPC).但是我在初始化期间收到有关线程和分析的错误消息:

Pointer.exe: the flag -N requires the program to be built with -threaded
Pointer.exe: the flag -p requires the program to be built with -prof
Pointer.exe: Most RTS options are disabled. Use hs_init_with_rtsopts() to enable them.
Pointer.exe: newBoundTask: RTS is not initialised; call hs_init() first
Run Code Online (Sandbox Code Playgroud)

我配置了cabal包:

"--enable-library-profiling"
"--enable-executable-profiling"
"--enable-shared"
"--enable-tests"
"--enable-coverage"
Run Code Online (Sandbox Code Playgroud)

在运行作为cabal项目的一部分编译的可执行文件时,它正确地给了我堆栈跟踪和代码覆盖.

如果我尝试hs_init_with_rtsopts按照错误消息的建议使用,我在GHC rts初始化期间得到一个SIGSEGV:

Using host libthread_db library "/usr/lib/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6a2d0ca in strlen () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff6a2d0ca in strlen () from /usr/lib/libc.so.6
#1  0x00007ffff798c5f6 in copyArg (
    arg=0x657372615062696c <error: Cannot access memory at address 0x657372615062696c>) at rts/RtsFlags.c:1684
#2  0x00007ffff798c679 in copyArgv (argc=8, argv=0x555555554cee) at rts/RtsFlags.c:1696
#3  0x00007ffff798dbe2 in setFullProgArgv (argc=<optimized out>, argv=<optimized out>) at rts/RtsFlags.c:1780
#4  0x00007ffff798e773 in hs_init_ghc (argc=0x555555756090 <argc>, argv=0x5555557560a0 <argv>, rts_config=...)
    at rts/RtsStartup.c:162
#5  0x00007ffff798e7cc in hs_init_with_rtsopts (argc=<optimized out>, argv=<optimized out>)
    at rts/RtsStartup.c:121
#6  0x0000555555554c7d in __libc_csu_init ()
#7  0x00007ffff69cc59f in __libc_start_main () from /usr/lib/libc.so.6
#8  0x0000555555554b29 in _start ()
Run Code Online (Sandbox Code Playgroud)

那么如何从使用gcc编译的程序中启用运行时分析?

Rei*_*ton 1

因此,段错误是由于问题中未包含的拼写错误造成的。鬼鬼祟祟的!

要启用线程和分析等功能,您必须将最终程序与适当的 RTS 风格链接起来。这是 GHC 标志的效果之一-prof,也是其-threaded标志以及各种其他标志(例如-debug.

RTS 风格位于不同的库中,其名称形式为

libHSrts.a           libHSrts-ghc7.8.4.so        (vanilla)
libHSrts_debug.a     libHSrts_debug-ghc7.8.4.so  (debug)
libHSrts_thr.a       libHSrts_thr-ghc7.8.4.so    (threaded)
libHSrts_p.a         -                           (profiling)
libHSrts_thr_p.a     -                           (threaded+profiling)
libHSrts_l.a         libHSrts_l-ghc7.8.4.so      (eventlog)
...
Run Code Online (Sandbox Code Playgroud)

左边是静态库;右侧是动态库,其库名称包含 GHC 版本,以便运行时动态加载器在安装了多个版本的 GHC 时更容易找到正确的版本。您可以在 中的“RTS 方式”下查看 GHC 安装的完整列表ghc --info

默认情况下没有安装动态分析库,但我认为拥有它们没有根本问题,您可以配置 GHC 构建系统来构建它们。(它们现在不是特别有用,因为 ghci 不支持分析,但希望很快就会改变。)