Java signal chaining
Asked Answered
D

2

20

I've got a program with a specialized Process-type class which handles executing the processes natively on Linux.

It does not use Java's Process class at all, because it needs to do some special handling of the process. Because of this, it also installs its own signal handler for SIGCHLD, so that it knows when a process exits.

However, I just added a Runtime.exec() call in my code, which apparently installs its own signal handler for SIGCHLD, which means that I never get a SIGCHLD again, which is bad. I've followed the signal-chaining instructions from oracle, but the same problem happens, I never get a SIGCHLD.

So, the basic question is this: is it possible to chain SIGCHLD in Java?

Dedicated answered 20/9, 2013 at 16:34 Comment(4)
Which of the two described methods did you try?Springhalt
Using LD_PRELOAD; I haven't tried making an application which embeds the JVM.Dedicated
I will also award a BOUNTY of 100 to successful answer. (I cannot now as there can only be a single bounty to the question at a time)Renitarenitent
Have you tried the -Xrs option to java ?Mckie
B
7

libjsig does not help, because SIGCHLD handler is installed by libjava, not by JVM itself.

sigaction(SIGCHLD, ...) with sa_handler = SIG_DFL is called only once by Java Class Library in the static initializer of java.lang.UNIXProcess.

Now you have the following options to work-around this.

  1. The easiest one. Just install your signal handler after initialization of java.lang.UNIXProcess.

  2. Create your own LD_PRELOAD hook that will intercept sigaction and ignore it when called with SIGCHLD and SIG_DFL arguments:

E.g.

#define _GNU_SOURCE
#include <signal.h>
#include <dlfcn.h>
#include <stddef.h>

int sigaction(int signum, const struct sigaction* act, struct sigaction* oldact) {
    static int (*real_sa)(int, const struct sigaction*, struct sigaction*) = NULL;

    if (signum == SIGCHLD && act->sa_handler == SIG_DFL) {
        return 0;
    }

    if (real_sa == NULL) {
        real_sa = dlsym(RTLD_NEXT, "sigaction");
    }
    return real_sa(signum, act, oldact);
}
Banal answered 12/8, 2014 at 22:55 Comment(0)
A
-2

How about using sockets to communicate with your child process in stead of SIGCHLD? I assume you create the child process code yourself.

Arabeila answered 11/8, 2014 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.