Niklas Hambüchen | 9 May 03:54 2013

ghci: Difference in garbage collection etc. between REPL and function

I have an annoying bug in a C binding that can be triggered like this:

    handle <- open ...

    prep <- makePreparedStatement handle "INSERT ..."

    performGC

    runStatement prep

    close handle

If I run these steps one by one in ghci, garbage ends up in my handle as
expected.

However, if I "let main = do ..." this whole block in order to pack it
in a test case, it does not happen, neither in ghci nor ghc.

What might be the special magic in ghci's REPL that allows me to trigger
my bug so easily there?

Thanks
Niklas
Jason Dagit | 9 May 05:12 2013
Picon

Re: ghci: Difference in garbage collection etc. between REPL and function

On Wed, May 8, 2013 at 6:54 PM, Niklas Hambüchen <mail <at> nh2.me> wrote:
> I have an annoying bug in a C binding that can be triggered like this:
>
>
>     handle <- open ...
>
>     prep <- makePreparedStatement handle "INSERT ..."
>
>     performGC
>
>     runStatement prep
>
>     close handle
>
> If I run these steps one by one in ghci, garbage ends up in my handle as
> expected.
>
> However, if I "let main = do ..." this whole block in order to pack it
> in a test case, it does not happen, neither in ghci nor ghc.
>
> What might be the special magic in ghci's REPL that allows me to trigger
> my bug so easily there?

One thing to investigate: Thread Local Storage

By default ghci puts each action you run into a thread and executes
it. If the underlying C code stores something (or accesses it) from
thread local storage, then you will run into issues like this.

Try starting ghci with -fno-ghci-sandbox. If the bad behavior goes
(Continue reading)

Jason Dagit | 9 May 05:21 2013
Picon

Re: ghci: Difference in garbage collection etc. between REPL and function

On Wed, May 8, 2013 at 8:12 PM, Jason Dagit <dagitj <at> gmail.com> wrote:
> On Wed, May 8, 2013 at 6:54 PM, Niklas Hambüchen <mail <at> nh2.me> wrote:
>> I have an annoying bug in a C binding that can be triggered like this:
>>
>>
>>     handle <- open ...
>>
>>     prep <- makePreparedStatement handle "INSERT ..."
>>
>>     performGC
>>
>>     runStatement prep
>>
>>     close handle
>>
>> If I run these steps one by one in ghci, garbage ends up in my handle as
>> expected.
>>
>> However, if I "let main = do ..." this whole block in order to pack it
>> in a test case, it does not happen, neither in ghci nor ghc.
>>
>> What might be the special magic in ghci's REPL that allows me to trigger
>> my bug so easily there?
>
> One thing to investigate: Thread Local Storage
>
> By default ghci puts each action you run into a thread and executes
> it. If the underlying C code stores something (or accesses it) from
> thread local storage, then you will run into issues like this.

(Continue reading)

Brandon Allbery | 9 May 14:50 2013
Picon

Re: ghci: Difference in garbage collection etc. between REPL and function

On Wed, May 8, 2013 at 9:54 PM, Niklas Hambüchen <mail <at> nh2.me> wrote:
If I run these steps one by one in ghci, garbage ends up in my handle as
expected.

However, if I "let main = do ..." this whole block in order to pack it
in a test case, it does not happen, neither in ghci nor ghc.

ghci is in many ways like an endless (or at least until ":l"/":r") do-block. In particular, the handle remains in scope after you run your commands at the prompt, so it is not garbage collected.  If you enclose it into its own do block, this introduces local scope and the handle goes out of scope and is garbage collected at the end.

--
brandon s allbery kf8nh                               sine nomine associates
allbery.b <at> gmail.com                                  ballbery <at> sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Niklas Hambüchen | 9 May 16:19 2013

Re: ghci: Difference in garbage collection etc. between REPL and function

On 09/05/13 20:50, Brandon Allbery wrote:
> ghci is in many ways like an endless (or at least until ":l"/":r")
> do-block. In particular, the handle remains in scope after you run your
> commands at the prompt, so it is not garbage collected.  If you enclose
> it into its own do block, this introduces local scope and the handle
> goes out of scope and is garbage collected at the end.

I am not sure how the handle is relevant - I do not expect it to garbage
collected before the close or rely on that, and my problem happens
earlier already.
Brandon Allbery | 9 May 16:26 2013
Picon

Re: ghci: Difference in garbage collection etc. between REPL and function

On Thu, May 9, 2013 at 10:19 AM, Niklas Hambüchen <mail <at> nh2.me> wrote:
On 09/05/13 20:50, Brandon Allbery wrote:
> ghci is in many ways like an endless (or at least until ":l"/":r")
> do-block. In particular, the handle remains in scope after you run your
> commands at the prompt, so it is not garbage collected.  If you enclose
> it into its own do block, this introduces local scope and the handle
> goes out of scope and is garbage collected at the end.

I am not sure how the handle is relevant - I do not expect it to garbage
collected before the close or rely on that, and my problem happens
earlier already.

You said 'garbage in the handle'... but in any case it applies to all the bindings, not just to that one. Generalize.

--
brandon s allbery kf8nh                               sine nomine associates
allbery.b <at> gmail.com                                  ballbery <at> sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane