Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signals on SGI #2416

Closed
vicuna opened this issue Apr 10, 2000 · 6 comments
Closed

Signals on SGI #2416

vicuna opened this issue Apr 10, 2000 · 6 comments
Labels

Comments

@vicuna
Copy link

vicuna commented Apr 10, 2000

Original bug ID: 78
Reporter: administrator
Status: closed
Resolution: not a bug
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Hello,

a while ago I stumbled upon an internal compiler problem
that occured with heavy inlining, and which you (Damien Doligez) answered:

The problem seems to be at line 572 in asmcomp/selectgen.ml:
Istore(_, addr) when r.(0).typ = Float -> Istore(Double, addr)
but r can be the empty array.

I'm fixing it by replacing line 572 with these two lines:
| Istore(_, addr) when Array.length r > 0 && r.(0).typ = Float
-> Istore(Double, addr)

At the time I did not try it out,
but the current cvs version works perfectly --- many thanks!

Now I am using signals for a certain kind of inter-process communication ---
with signal handlers from the standard library module Sys in one direction,
and with

Unix.sigprocmask mode:Unix.SIG_BLOCK,
Unix.sigpending (), and
Unix.sigprocmask mode:Unix.SIG_UNBLOCK

in the other direction. This works very well on Sparc/Solaris and on Pentium/Linux
but not on SGIs, where I need to get it to work now.

Anyway, even on the other two architectures I do not understand
why it works as it does:
I am using signal 18 on both, which seems to be SIGCONT on Linux,
which is plausible, but should be SIGCHLD on Sparc instead of SIGCONT,
which should be 25 and does not work for my application on Sparc.

No value I tried works on SGI ---
I just did not get any result from Unix.sigpending () there.
(The signal handler direction works with all signals I tried.)

In this context I tried the built-in signal constants in Sys --- with
spectacular failures, so that I inspected their values manually,
and I do not understand these, either:

====================================================================
% uname -a
IRIX64 picasso 6.5 01200532 IP27
% ocaml
Objective Caml version 2.99+15 (2000-04-05)

Sys.sigcont;;

  • : int = -15

Sys.sigchld;;

  • : int = -14

Sys.sigint;;

  • : int = -6

Sys.sigkill;;

  • : int = -7

Sys.sigterm;;

  • : int = -11

====================================================================

uname -a
Linux dionysos 2.2.13 #1 Mon Nov 8 15:51:29 CET 1999 i686 unknown
ocaml
Objective Caml version 2.99+15 (2000-04-05)

Sys.sigcont;;

  • : int = -15

Sys.sigchld;;

  • : int = -14

Sys.sigint;;

  • : int = -6

Sys.sigkill;;

  • : int = -7

Sys.sigterm;;

  • : int = -11
    ====================================================================

~~ uname -a
SunOS elektra 5.7 Generic sun4u sparc SUNW,Ultra-250
~~ ocaml
Objective Caml version 2.99+15 (2000-04-05)

Sys.sigcont;;

  • : int = -15

Sys.sigchld;;

  • : int = -14

Sys.sigint;;

  • : int = -6

Sys.sigkill;;

  • : int = -7

Sys.sigterm;;

  • : int = -11

====================================================================

Any help would be most welcome!

If you need me to experiment on SGIs, I would be most willing to do so.
(The effect is the same on 32bit SGIs, to which I have access, too:

uname -a
IRIX p3ws09 6.5 07151433 IP32
)

If necessary, I could also try to produce a smaller program that
exposes the differences in behaviour, but I am afraid that this would have
to wait until next week.

Best regards,

Wolfram

@vicuna
Copy link
Author

vicuna commented Apr 10, 2000

Comment author: administrator

Now I am using signals for a certain kind of inter-process communication ---
with signal handlers from the standard library module Sys in one direction,
and with

Unix.sigprocmask mode:Unix.SIG_BLOCK,
Unix.sigpending (), and
Unix.sigprocmask mode:Unix.SIG_UNBLOCK

in the other direction. This works very well on Sparc/Solaris and on
Pentium/Linux but not on SGIs, where I need to get it to work now.

I'd be interested in a program that reproduces the problem. (I have
access to SGI machines running IRIX 6.5.)

Anyway, even on the other two architectures I do not understand
why it works as it does:
I am using signal 18 on both, which seems to be SIGCONT on Linux,
which is plausible, but should be SIGCHLD on Sparc instead of SIGCONT,
which should be 25 and does not work for my application on Sparc.

No value I tried works on SGI ---
I just did not get any result from Unix.sigpending () there.
(The signal handler direction works with all signals I tried.)

In this context I tried the built-in signal constants in Sys --- with
spectacular failures, so that I inspected their values manually,
and I do not understand these, either:

The idea behind those constants is to provide system-independent
values to denote standard POSIX signals. The idea is that all
functions that deal with signals translate those (negative) constants
to the corresponding signal number for the system.

It is true that Unix.sigpending and Unix.sigprocmask do not perform
the reverse translation on output, thus never return one of the Sys.sig*
constants. I realize this is questionable behavior...

Does this explain what you've observed?

Best regards,

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Apr 10, 2000

Comment author: administrator

Dear Xavier,

now I just put together a small demo:

===============================
kahl@dionysos:/var/tmp/kahl/hops > ./signaltest
block:
process 15293 waiting for signal 18
idling...
polling...
idling...
polling...
idling...
polling...
idling...
polling...
idling...
polling...
idling...
polling...
idling...
polling...
myblocked: 18
unblock: 18
Dealt with signal 18
block:
idling...
polling...

===============================

where the reaction Dealt with ...'' has been achieved by kill -18 15293''
from a different window.

This reaction does not happen on the SGIs --- not even without inlining.

Many thanks for looking into this!

Best regards,

Wolfram

============== signaltest.ml =========================================
(*
ocamlopt -modern -inline 25 -o signaltest unix.cmxa signaltest.ml -cclib -lunix
*)

(* library extensions begin *)

let string_of_intlist ?(sep:sep = " ") is =
String.concat sep:sep (List.map f:string_of_int is);;

let list_filter f:f =
List.fold_right f:(fun x xs -> if f x then x :: xs else xs) init:[];;

(* library extensions end *)

let mySignal = ref 18;;

let block _ =
let blocked = Unix.sigprocmask mode:Unix.SIG_BLOCK [!mySignal] in
prerr_endline ("block: " ^ string_of_intlist blocked);
()

let unblock _ =
let blocked = Unix.sigprocmask mode:Unix.SIG_UNBLOCK [!mySignal] in
prerr_endline ("unblock: " ^ string_of_intlist blocked);
()

let init _ = block ();;

let signals = [18;19;20;21;22;23;24;25;26;27;33;34];;

let poll _ =
let blocked = Unix.sigpending () in
let myblocked = list_filter f:(fun s -> List.mem s signals) blocked in
(match myblocked with [] -> ()
| _ -> prerr_endline ("poll: myblocked: " ^ string_of_intlist myblocked)
);
if List.mem !mySignal blocked
then (unblock ();
prerr_endline ("Dealt with signal " ^ string_of_int !mySignal);
block ()
)
else ();;

let rec loop x =
prerr_endline "idling...";
Unix.sleep 1;
prerr_endline "polling...";
poll ();
Unix.sleep 1;
loop x;;

let _ =
init ();
Arg.parse keywords:[] others:(fun s -> mySignal := int_of_string s)
errmsg:"usage: signaltest ";
let pid = Unix.getpid () in
prerr_endline ("process " ^ string_of_int pid ^
" waiting for signal " ^ string_of_int !mySignal);
loop ();;

@vicuna
Copy link
Author

vicuna commented Apr 10, 2000

Comment author: administrator

Dear Xavier,

sorry, I forgot to reply to the other part of your message:

The idea behind those constants is to provide system-independent
values to denote standard POSIX signals. The idea is that all
functions that deal with signals translate those (negative) constants
to the corresponding signal number for the system.

It is true that Unix.sigpending and Unix.sigprocmask do not perform
the reverse translation on output, thus never return one of the Sys.sig*
constants. I realize this is questionable behavior...

Does this explain what you've observed?

It at least explains the negative values and their platform-independence ---
this, together with the lack of conversion in Unix
would be an indication for an abstract type in Sys for me.

It does not explain why 18 works on Sparcs, too, but maybe I misunderstand the
signal value listings I collect from the different places.

However, now I am even slightly more puzzled why
``Sys.signal 18 (Sys.Signal_handle handler)'' works in my application...

Many thanks!

Best regards,

Wolfram

@vicuna
Copy link
Author

vicuna commented Apr 11, 2000

Comment author: administrator

Thanks for the demo program. I had no problems running it under Linux
and IRIX and see the difference in behavior.

A few remarks on the program. First, I moved the call to init() after
the parsing of command-line arguments, so that if a signal number is
specified on the command-line, that signal gets blocked instead of the
default signal 18.

Second, when you unblock the signal in poll(), the action associated
with the signal is taken. (That's the normal Unix semantics.) For 18
(SIGCHLD), the signal is ignored because that's the default behavior
for SIGCHLD. For other signals whose default behavior is to terminate
the program, the program is terminated. If that's not what you want,
you should install a signal handler that does nothing for the signal
in question.

As for the different Linux/IRIX behaviors on SIGCHLD, this is normal
as far as the Unix98 spec is concerned. It says:

If the action associated with a blocked signal is
to ignore the signal and if that signal is generated for the
process, it is unspecified whether the signal is
discarded immediately upon generation or remains pending.

Linux chooses to add the ignored signal to the pending set, and IRIX
chooses to discard it. Again, to get consistent behavior, you should
install a signal handler for the signal.

It at least explains the negative values and their platform-independence ---
this, together with the lack of conversion in Unix
would be an indication for an abstract type in Sys for me.

The idea is that you may still want to use hard-wired signal numbers,
e.g. to access signals that are not specified in POSIX.

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Apr 11, 2000

Comment author: administrator

The behaviors observed are correct according to the Unix98 spec.

@vicuna vicuna closed this as completed Apr 11, 2000
@vicuna
Copy link
Author

vicuna commented Apr 11, 2000

Comment author: administrator

Linux chooses to add the ignored signal to the pending set, and IRIX
chooses to discard it. Again, to get consistent behavior, you should
install a signal handler for the signal.

That saved me! Thank you very much!
All it needed was a two-line change, and
five minutes before the lecture the compilation was finished,
and during the lecture it worked!
Thank you for your thorough explanation!

First, I moved the call to init() after
the parsing of command-line arguments, so that if a signal number is
specified on the command-line, that signal gets blocked instead of the
default signal 18.

Sorry --- that slipped into the demo,
where I left the init() in its initial position out of habit.
In my application the signal is fixed at compile-time.

Second, when you unblock the signal in poll(), the action associated
with the signal is taken. (That's the normal Unix semantics.)

That is why I first used SIGCONT and then continued with ignored signals.
I had never thought of mixing the Sys.signal and the Unix.block approach
in one communication setup.

The idea is that you may still want to use hard-wired signal numbers,
e.g. to access signals that are not specified in POSIX.

This makes sense. Perhaps it would be helpful to document this
and the platform-independent negative values of Sys.sig* in the manual.

Another unrelated feature that I thought might deserve mention in the manual
is the fact that Unix.create_process needs $0 in its argument array.
(I knew this might be the case when I first tried,
but I still started without.)

I admit that it probably makes sense that the level of low-level UNIX knowledge
should be a decisive factor of how far one gets with the Unix library,
and I got away for quite a long time without using such low-level features
(particularly Pervasives.open_process is a blessing!).
But when one arrives at the point where one needs more,
one is already spoiled by the good quality and comprehensiveness of the
rest of the OCaml documentation! ;-)

Thanks a lot for this wonderful system and the prompt and effective help!

Best regards,

Wolfram

@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant