24

I'd like to use Haskell's quickcheck library test some C code. The easiest way seems to be doing a foreign import and write a property on top of the resulting haskell function. The problem with this is that if the C code causes a segfault or manages to corrupt memory, my tests either crash without output or do something totally unpredictable.

The second alternative is to make simple executable wrappers over the C-bits and execute them outside the testing process via System.Process. Needless to say, doing this requires a lot of scaffolding and serializing values, but on the other hand, it can handle segfaults.

Is there any way of making the foreign import strategy as safe as running an external process?

aleator
  • 4,436
  • 20
  • 31
  • 5
    I guess you could try to do the executable wrapper in your current process, using `System.Posix.Process.forkProcess` and program the communication using Haskell. – Joachim Breitner Aug 08 '14 at 11:03
  • @JoachimBreitner Hmm.. That's a decent idea. Everything still needs to be serialized/deserialized, but at least I can do that in Haskell and without multiple compilation phases. – aleator Aug 12 '14 at 07:23
  • 5
    If you don't mind a hacky solution, there's libsigsegv[1] which can catch segfaults and return you to a safe(ish) point. Just set a status flag and do a `getcontext` before entering the real C function and on fault flip the flag and do a `setcontext` to return to where you `getcontext`ed. If the flag is still in its original state, everything went fine. Maybe combine with something like http://www.cs.rutgers.edu/~santosh.nagarakatte/softbound/ for non-crashy errors. [1]:libsigsegv is GPL, but you don't release your tests – or do you? ;-) If that's a problem I have simpler code I can release. – nobody Sep 19 '14 at 17:33
  • (Not posting this as an answer as this is almost certainly not _"as safe as running an external process"_.) – nobody Sep 19 '14 at 17:35
  • 1
    Would running it under Valgrind be an option? That won't help on the Haskell side of things, but it'll hopefully catch those memory bugs. – Lambda Fairy Oct 01 '14 at 09:41
  • @JoachimBreitner I think your comment would serve as an answer if you moved it down to resolve this officially unanswered question :-) – sclv Feb 20 '15 at 03:55

1 Answers1

1

You could implement the wrapper in your current process, but then use System.Posix.Process.forkProcess to run in safely in a process of its own, implementing the necessary communication using Haskell.

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139
  • 1
    thank you for the pointer; care to expand a little? I'd be interested in knowing how this works as well. Thank you – ocramz Apr 24 '15 at 00:42