GHCI/FFI/GMP/Me madness

Remi Turk rturk at science.uva.nl
Thu Aug 5 09:17:45 EDT 2004


Hi all,

I recently tried to create a ffi-binding to gmp in ghc, and
failed miserably. After a few days of debugging, simplifying the
code and tearing my hear out, I'm slightly completely stumped,
and crying for help ;)

In short: calling gmp-functions from GHCI *with a prompt between*
them seems to do Really Bad Things. (read: memory corruption)


The long story:
---------------

mpz_t p;

str_test()
{
	gmp_printf("%Zd\n", p);
}

void mpz_new()
{
	mpz_init_set_si(p, 1);
}

foreign import ccall mpz_new    :: IO ()
foreign import ccall str_test   :: IO ()


Prelude Main> mpz_new
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
1
Prelude Main> str_test
142833060
Prelude Main> str_test
142833060


Using other flags, importing extra modules, using CVS 6.3 (a few
weeks old) or not compiling it before loading it in GHCI slightly
changes the symptoms (other wrong numbers or make it happen
later/earlier) but copypasting the code from main some 10 to 20
times seems to be a sure way to reproduce it.

Simply running main doesn't seem to expose the problem.
Now of course, GHCI uses Integer-ops during it's REPL, which I
suspect is exactly what causes/exposes the problem.

Am I doing (Un)Officially Forbidden Things? Is it time for a
bug-report? Do I finally have to learn drinking coffee? ;)
I'd be delighted to know.

The full code is attached.

TIA,
Remi

-- 
Nobody can be exactly like me. Even I have trouble doing it.
-------------- next part --------------
.PHONY: clean ghci

CC=gcc
CFLAGS=-Wall -g
GHCFLAGS=util.o -\#include util.h

main_src=PrimMpz.hs

ghci: util.o
	ghci $(GHCFLAGS) $(main_src)

exe: util.o
	ghc --make $(GHCFLAGS) $(main_src)

util.o: util.c
	$(CC) $(CFLAGS) -c $<

clean:
	rm -f a.out *.o *.hi
-------------- next part --------------
{-# OPTIONS -fffi #-}
module Main where

foreign import ccall mpz_new    :: IO ()
foreign import ccall str_test   :: IO ()

main= do
    mpz_new
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
    str_test
-------------- next part --------------
#include <stdio.h>

#include "util.h"

mpz_t p;

void str_test()
{
	gmp_printf("%Zd\n", p);
}

void mpz_new()
{
	mpz_init_set_si(p, 1);
}
-------------- next part --------------
#ifndef _UTIL_H
#define _UTIL_H

#include <gmp.h>

void str_test();
void mpz_new();

#endif /* _UTIL_H */


More information about the Glasgow-haskell-users mailing list