[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: the state of the concurrency branch

From: Barry OReilly
Subject: Re: the state of the concurrency branch
Date: Wed, 16 Oct 2013 14:24:43 -0400

> Here's a recipe for reproducing this:
>  emacs -Q
> Insert this:
>    (defvar threads-test-binding nil)
>    (defun threads-test-thread2 ()
>      (let ((threads-test-binding 23))
>        (thread-yield))
>      (setq threads-test-global 23))
>    (progn
>      (setq threads-test-global nil)
>      (make-thread #'threads-test-thread2)
>      (while (not threads-test-global)
>        (thread-yield))
>      (and (not threads-test-binding)
>           threads-test-global))
> Mark the defvar and the defun, type "M-x eval-region RET".  Go to the
> last closing parent of progn, type "C-x C-e", get the expected result
> 23.  All's well till now.
> Go to the right paren of the defvar, type "C-x C-e" there.  Now go
> again to the rightmost paren of progn, type "C-x C-e", and get the
> wrong-type-argument error.

If you evaluate the progn enough, it's possible to induce a core dump.

In unbind_for_thread_switch:

  unbind_for_thread_switch (struct thread_state *thr)
    union specbinding *bind;
    for (bind = thr->m_specpdl_ptr; bind != thr->m_specpdl; --bind)
        if (bind->kind >= SPECPDL_LET)
           bind->let.saved_value = find_symbol_value (specpdl_symbol (bind));
           do_one_unbind (bind, 0);

I find that bind->kind has values like 22 and 105, which are out of
bounds for the enum. Garbage values are one possibility.

When I looked at how other parts of the code iterate over the specpdl,
I find that the iterator decrements from specpdl_ptr first.
Furthermore, the documentation for specpdl_ptr says:

  /* Pointer to first unused element in specpdl.  */

  union specbinding *specpdl_ptr;

So is the solution to decrement bind once before iterating?

reply via email to

[Prev in Thread] Current Thread [Next in Thread]