You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Original bug ID: 3680 Reporter: administrator Status: closed Resolution: fixed Priority: normal Severity: minor Category: ~DO NOT USE (was: OCaml general)
I confirm this bug (but couldn't find a way to directly post a comment
on it), we also hit it here with version 3.08.3 and 2.6 kernel with
NPTL, this is a backtrace:
#0 0xb7d02436 in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0 #1 0xb7cff893 in _L_mutex_lock_26 () from /lib/tls/libpthread.so.0 #2 0x00000000 in ?? () #3 0x00000000 in ?? () #4 0x00000000 in ?? () #5 0x00000000 in ?? () #6 0x0807d958 in JCR_LIST () #7 0x00000000 in ?? () #8 0xb2d7b54c in ?? () #9 0x08061647 in caml_thread_leave_blocking_section () #10 0x08061647 in caml_thread_leave_blocking_section () #11 0x08066bb0 in caml_leave_blocking_section () #12 0x08066afb in handle_signal () #13 #14 0xb7d02436 in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0 #15 0xb7cff893 in _L_mutex_lock_26 () from /lib/tls/libpthread.so.0 #16 0x00000004 in ?? () #17 0x00000000 in ?? () #18 0xb2d7b8a8 in ?? () #19 0x08065970 in caml_add_to_heap () #20 0x080615ff in caml_thread_enter_blocking_section () #21 0x08066b99 in caml_enter_blocking_section () #22 0x0805bfcc in ocaml_samba_open (furl=134869200, flags=134867664, mode=841) at smbclient_stubs.c:211 #23 0x08074005 in caml_interprete () #24 0x080703c7 in caml_callbackN_exn () #25 0x0807040e in caml_callback_exn () #26 0x08061c1c in caml_thread_start ()
Approximately the same problem: the handle_signal() signal handler calls thread_leave_blocking_section() before thread_enter_blocking_section() finishes...
As proposed by Gerd, masking signals should work indeed, there would then even be no need to check caml_pending_signal again.
A lighter solution would be this:
void caml_enter_blocking_section(void)
{
int sig;
while (1){
Assert (!caml_async_signal_mode);
/* If a signal arrives between the next two instructions,
it will be lost. /
while (sig = caml_pending_signal) {
caml_pending_signal = 0;
caml_young_limit = caml_young_start;
caml_execute_signal(sig, 0);
}
if (caml_enter_blocking_section_hook != NULL){
caml_enter_blocking_section_hook();
}
caml_async_signal_mode = 1;
if (!caml_pending_signal) break;
/ got signal while entering blocking section, redo from start */
caml_async_signal_mode = 0;
if (caml_leave_blocking_section_hook != NULL){
caml_leave_blocking_section_hook();
}
}
}
Before calling the enter_blocking_section hook, it flushes signals (some may arrive during signal handlers), then it tries to enter blocking section. If a signal arrives while calling the hook, just redo from start. Signals are hence handled just the same as previously: on enter_blocking_section() return, there is no pending signal in caml_pending_signal.
Gerd told about not calling pthread_* functions in the signal handler. But I'm actually wondering about functions in general. The list of functions that can be called from handlers is restricted. Since this is not enforced for caml handlers, the documentation should warn people about that.
The text was updated successfully, but these errors were encountered:
Just to let you now that the proposed patch (with the obvious move
of Assert(caml_async_signal_mode) up too) does work fine (and Gerd's
program doesn't hang any more).
Original bug ID: 3680
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)
Bug description
Bug: 3659
Hi,
http://pauillac.inria.fr/bin/caml-bugs/incoming?id=3659;user=guest;selectid=3659
I confirm this bug (but couldn't find a way to directly post a comment
on it), we also hit it here with version 3.08.3 and 2.6 kernel with
NPTL, this is a backtrace:
#0 0xb7d02436 in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0
#1 0xb7cff893 in _L_mutex_lock_26 () from /lib/tls/libpthread.so.0
#2 0x00000000 in ?? ()
#3 0x00000000 in ?? ()
#4 0x00000000 in ?? ()
#5 0x00000000 in ?? ()
#6 0x0807d958 in JCR_LIST ()
#7 0x00000000 in ?? ()
#8 0xb2d7b54c in ?? ()
#9 0x08061647 in caml_thread_leave_blocking_section ()
#10 0x08061647 in caml_thread_leave_blocking_section ()
#11 0x08066bb0 in caml_leave_blocking_section ()
#12 0x08066afb in handle_signal ()
#13
#14 0xb7d02436 in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0
#15 0xb7cff893 in _L_mutex_lock_26 () from /lib/tls/libpthread.so.0
#16 0x00000004 in ?? ()
#17 0x00000000 in ?? ()
#18 0xb2d7b8a8 in ?? ()
#19 0x08065970 in caml_add_to_heap ()
#20 0x080615ff in caml_thread_enter_blocking_section ()
#21 0x08066b99 in caml_enter_blocking_section ()
#22 0x0805bfcc in ocaml_samba_open (furl=134869200, flags=134867664, mode=841) at smbclient_stubs.c:211
#23 0x08074005 in caml_interprete ()
#24 0x080703c7 in caml_callbackN_exn ()
#25 0x0807040e in caml_callback_exn ()
#26 0x08061c1c in caml_thread_start ()
Approximately the same problem: the handle_signal() signal handler calls thread_leave_blocking_section() before thread_enter_blocking_section() finishes...
As proposed by Gerd, masking signals should work indeed, there would then even be no need to check caml_pending_signal again.
A lighter solution would be this:
void caml_enter_blocking_section(void)
{
int sig;
while (1){
Assert (!caml_async_signal_mode);
/* If a signal arrives between the next two instructions,
it will be lost. /
while (sig = caml_pending_signal) {
caml_pending_signal = 0;
caml_young_limit = caml_young_start;
caml_execute_signal(sig, 0);
}
if (caml_enter_blocking_section_hook != NULL){
caml_enter_blocking_section_hook();
}
caml_async_signal_mode = 1;
if (!caml_pending_signal) break;
/ got signal while entering blocking section, redo from start */
caml_async_signal_mode = 0;
if (caml_leave_blocking_section_hook != NULL){
caml_leave_blocking_section_hook();
}
}
}
void caml_leave_blocking_section(void)
{
caml_async_signal_mode = 0;
if (caml_leave_blocking_section_hook != NULL){
caml_leave_blocking_section_hook();
}
Assert(caml_async_signal_mode);
}
Before calling the enter_blocking_section hook, it flushes signals (some may arrive during signal handlers), then it tries to enter blocking section. If a signal arrives while calling the hook, just redo from start. Signals are hence handled just the same as previously: on enter_blocking_section() return, there is no pending signal in caml_pending_signal.
Gerd told about not calling pthread_* functions in the signal handler. But I'm actually wondering about functions in general. The list of functions that can be called from handlers is restricted. Since this is not enforced for caml handlers, the documentation should warn people about that.
The text was updated successfully, but these errors were encountered: