Stig E Sandoe writes:
Quoting Atrix Wolfe (atrix2 at cox.net):
| It could be that you rprogram has some memory corruption going on. This
| seems especialy likely since MANY other people have made threaded programs
| before of all kinds and not had a problem. Blaming sdl is somewhat like
| blaming the compiler when your program crashes, chances are, its your own
| fault, not SDL’s.
Of course, it might be my program, but in this case I think it’s a
bug even if my program has other flaws. If I have specified
no-parachutes which is handled as it should in SDL_Init(), why
should not SDL_Quit() respect that and start messing with the
signal-handlers? I think SDL_Quit() should check what flags
were passed to SDL_Init() and if no-parachutes was a flagt to
SDL_Init() it should not mess with the signal-handlers as if the
parachutes were installed. Is my understanding of how this
should work wrong?
Of course, if my understanding is wrong I’ll accept that.
(And yes, the signal-handlers are used in my app for other tasks,
which is exactly why I pass the no-parachute argument)
Forgive me for intruding at this point – I spent a little time this
afternoon diagnosing this problem (I’m responsible for another of
Stig’s libraries), so let me just say what I found:
The reason the problem is being exhibited here is that the signal
handlers in Stig’s application are SA_SIGINFO Posix signal handlers.
These handlers have the signature
void (*sa_sigaction)(int, siginfo_t *, void *)
and are installed by calls of the form
sigaction sa;
sa.handler = sigsegv_handler;
sa.flags |= SA_SIGINFO;
sigaction(SIGSEGV, &sa, NULL);
The kernel is the responsible to pass the siginfo and ucontext
structures to the signal handler. (man sigaction(2) for more gory
details).
In SDL_UninstallParachute, however, all of the signal handlers are
installed and restored using signal(2), which does not preserve the
three-argument nature of the signal handler. Thus, though the
sigsegv_handler of the above fragment would be restored as the signal
handler for SEGV after SDL_UninstallParachute, it would only receive
one argument from the kernel, and this is what causes the problem –
the fact that UninstallParachute doesn’t restore the signal handler
state properly if it finds that SDL was not responsible for a given
signal.
This problem can be remedied by performing much the same action as
with signal in SDL_UninstallParachute, e.g. (untested code):
sigaction sa;
sigaction(SDL_fatal_signals[i], SIG_DFL, sa);
if(sa.handler != SDL_Parachute)
sigaction(SDL_fatal_signals[i], sa, NULL);
or by respecting the NO_PARACHUTE flag on Quit() as well as on
Init().
I hope that helps,
Cheers,
Christophe–
http://www-jcsu.jesus.cam.ac.uk/~csr21/ +44 1223 510 299/+44 7729 383 757
(set-pprint-dispatch 'number (lambda (s o) (declare (special b)) (format s b)))
(defvar b “~&Just another Lisp hacker~%”) (pprint #36rJesusCollegeCambridge)