[slim-vim] "socket crash bug" im Vim+ECL fixed

Brad Beveridge brad.beveridge at gmail.com
Sat Jun 17 19:23:51 CDT 2006


On 17/06/06, Larry Clapp <larry at theclapp.org> wrote:
> [ Note: Cross-posted to both the Slim-Vim list and the ECL devel list. ]
>
> I fixed the "socket crash bug" in Vim+ECL, and I think I discovered
> what caused it (in that order!).
>
> The fix: Change vim:add-input-listener so that instead of evaling a
> list, it funcalls a closure.
>
> Changes:
>   if_ecl.lisp:
>      (defun add-input-listener (stream callback)
>        "Registers a callback to be invoked when data arrives to a stream"
>        (check-type stream stream)
>        (check-type callback function)
>        (setf (gethash stream callbacks) callback)
>   -    (add-input-listener-int stream `(safe-eval '(cl:funcall ,callback) nil))
>   +    (add-input-listener-int stream callback)
>        t)
>
>   if_ecl.c:
>    static void listener_callback(int fd, void *data)
>    {
>   -    safe_eval_form((cl_object)data, FALSE);
>   +    cl_funcall(1, (cl_object) data);
>
> I didn't make this change to fix the bug; I only made it because I
> didn't like that invoking the network callback went like this
>
>   vim
>   -> listener_callback
>   -> safe_eval_form
>   -> si_eval_with_env
>   -> SAFE-EVAL
>   -> SAFE-EVAL
>   -> the callback
>
> and I wanted it more like
>
>   vim
>   -> listener_callback
>   -> the callback
>
> So the patch changed the invocation sequence, which made the bug
> either go away, or made it a lot rarer.  I assumed that using
> SAFE-EVAL somehow caused problems, and I wanted to know why, so I
> added it back into the callback.  It didn't fail.  I added another.
> It still didn't fail.  Somewhere in there, I re-read Jim's recent post
> and studied what I changed, and what I changed it from, and gradually
> the light came on.
>
> Jim's post, in part:
>
>   > The GC ECL uses is the Boehm GC, which (thankfully) doesn't move
>   > things around. You do have to be careful of storing pointers to
>   > gc-allocated memory in non gc-allocated memory, e.g. storing an
>   > ECL closure pointer in malloc'd memory, such things arn't detected
>   > by the mark and sweep and can lead to premature collection and
>   > horrible problems. This is why the callbacks are stored in a CL
>   > hash-table as well to stop them from disappearing. Of course I may
>   > have got this wrong and messed up really really badly, maybe it is
>   > worth turning the gc off temporarily just to see what happens.
>
> Look closely at ADD-INPUT-LISTENER, above.  Notice that Jim puts the
> callback into a hash table (so some Lisp datastructure will have a
> reference to it, so the GC won't collect it), and then wraps a list
> around it and gives Vim a pointer to the list, which we later EVAL.
> (Now see there?  I've just about given it away!  :)  The *callback* is
> in the hashtable, but the *list around it isn't*!  And nothing else
> references it, either!  One GC later and it's game over.
>
> Anyway, the patch (all two lines of it :) is at theclapp.org[1].
> Happy hacking!
>
> -- Larry

Fantastic!!  Well done Larry, I am really glad that is sorted out, it
was seriously starting to bug me!
I've restarted work on slim-vim now :)
If anybody is interested is hacking on slim-vim, I'd appreciate an ECL
based indent function that generates the same indentation as Emacs.
This should be a nice little project to get started with, and Vim
users will no longer suffer as second class citizens in the
indentation wars :)

Cheers
Brad

PS, thanks again Larry!


More information about the slim-vim mailing list