2015-10-29 19 views
6

Ho un progetto C di grandi dimensioni che deve essere compilato con gcc. Così mi collego l'eseguibile principale con un file in questo modo:Errori di runtime di GHC RTS quando si utilizza hs_init con la creazione di profili della libreria di cabali condivisa

#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(); } 

che funziona come previsto - il sistema di runtime GHC viene inizializzato e io sono in grado di utilizzare la FFI per chiamare il codice Haskell da C.

Quindi tento di abilitare la profilazione (principalmente per le tracce di stack con Debug.Trace) e la copertura del codice (HPC) utilizzando i flag "+RTS", "-N", "-p", "-s", "-h", "-i0.1", "-RTS" sulla riga commentata in precedenza. Tuttavia vengono visualizzati messaggi di errore relativi filettatura e profilatura durante l'inizializzazione:

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 

ho configurato il pacchetto cabala con:

"--enable-library-profiling" 
"--enable-executable-profiling" 
"--enable-shared" 
"--enable-tests" 
"--enable-coverage" 

che ha correttamente dato me impilare tracce e la copertura del codice, quando i file eseguibili in esecuzione compilati come parte di il progetto della cabala.

Se provo ad usare hs_init_with_rtsopts come raccomandato dal messaggio di errore, ho un SIGSEGV durante l'RTS di inizializzazione GHC:

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() 

Così come posso abilitare runtime profiling da un programma compilato con gcc?

+0

Il codice C è stato copiato e incollato dal tuo programma reale? In particolare sei sicuro di aver incluso sia '&' che '_' attorno a' argv' in 'hs_init_with_rtsopts (& argc, & argv_)'? Sembra incompatibile con il tuo output gdb. –

+0

Per il threading e il profiling, è necessario eseguire il collegamento alla versione con thread e profilatura dell'RTS ('HSrts_thr_p'). –

+0

Stavo collegando con '-lHSrts-ghc7.10.2'. Proverò ad usare 'HSrts_thr_p' ora. – KarlC

risposta

1

Quindi il segfault era dovuto a un errore di battitura non incluso nella domanda. Subdolo!

Per abilitare la filettatura e la creazione di profili e così via, è necessario collegare il programma finale al gusto RTS appropriato. Questo è un effetto del flag -prof di GHC e l'unico effetto del flag -threaded e di altri flag come -debug.

I sapori RTS sono in librerie diverse con nomi del modulo

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) 
... 

Sulla sinistra sono librerie statiche; sulla destra ci sono le librerie dinamiche, i cui nomi di librerie includono la versione di GHC per rendere più facile per il caricatore dinamico di runtime trovare la versione corretta se sono installate più versioni di GHC. È possibile visualizzare l'elenco completo per l'installazione di GHC in "Modalità RTS" in ghc --info.

Non ci sono librerie di profiling dinamiche installate di default, ma penso che non ci sia alcun problema fondamentale per averle ed è possibile configurare il sistema di generazione di GHC per costruirle. (Non sono particolarmente utili ora perché ghci non supporta la profilazione, anche se si spera che cambino molto presto.)

+0

Sì, ho bisogno di creare ora ghc per ottenere il file '.so' giusto, ma l'uso di una delle versioni con thread ha eliminato il messaggio di threading in modo che dovrebbe funzionare una volta ottenuta la possibilità di compilare ghc. – KarlC