Re: Handling of siginfo, Java compatibility with IBM jdk

Corey Minyard <[email protected]> Wed, 15 May 2002 12:43:35 -0500
Newsgroups gmane.linux.ngpt.user
Message-ID <[email protected]>
Ok on the JDK stuff, but I hadn't seen an email on the JDK compliance. 
 Could some of the guys at IBM talk to the Java people at IBM?

I actually can't make this happen, because I can't get anything but the 
main thread to handle a signal to the process.  If I block the signal in 
the main thread, another thread doesn't seem to pick up the signal.  I 
found another bug in sleep.  I've attached a test case, it simply runs 
forever.  It runs forever in LinuxThreads (but that's expected since the 
main thread has the signal blocked).

If you run the program "test_siginfo 1", NGPT (version 1.2.2, btw) 
sleeps forever on a "sleep(1)" call.

If you run the program "test_siginfo 0", NGPT will not handle the signal 
that a forked process sends.  The main thread blocks the signal, another 
thread unblocks the signal and should handle it.

Under my thread package, it prints out:
   killing pid does not match signal sender
which is what I expect will happen when the other problems in NGPT are 
fixed.

BTW, it seems a lot simpler to handle this in the kernel.  Why not let 
the kernel signal handling look at the thread leader's signals and all 
the sub-handlers and deliver them that way?  It would not be hard to do 
and would simplify the signal handling in the threads package.

-Corey

Howell, David P wrote:

>Cory,
>>From the beginning of our work with NGPT it has been clear that the JVMs
>did utilize internal behavior of the Linuxthreads implementation in very 
>unportable ways, and being NGPT compliant with that was considered wrong.
>Sounds like you are saying we mishandle POSIX siginfo, and so in POSIX 
>compliant mode the JVMs are still failing with NGPT. 
>
>If this is so we need to fix it for POSIX compliance. Could we possibly 
>glean a test case from what you have done? You've given us most of the 
>detail we need below.
>
>Dave Howell
>
>-----Original Message-----
>From: Corey Minyard [mailto:[email protected]]
>Sent: Tuesday, May 14, 2002 10:44 PM
>To: [email protected]
>Subject: [pthreads-users] Handling of siginfo, Java compatability with
>IBM jdk
>
>
>I thought I would ask a question and answer a question...
>
>How does NGPT handle siginfo?  It seems (from looking at the code, so I 
>could have missed something) that currently the information in the 
>siginfo structure is wrong because the signal is resent from another 
>process.  I would thing that tkill() should take a siginfo structure and 
>be allowed to set the data.
>
>This is actually related to the answer below.  I have a threads package 
>I have been working on designed for reliability.  It runs in 
>LinuxThreads compatability mode (which handles signals just like 
>LinuxThreads) and in POSIX compliant mode (which handles signals like 
>POSIX says to).  I have some Java implementations running in 
>LinuxThreads compatability mode, but none work in POSIX compliant mode. 
> I suspect that it has something to do with the siginfo not being 
>correct, or perhaps that the Java implementation is directly calling 
>kill().  But either way, I would like the siginfo stuff to be right, and 
>I think a change to tkill is necessary to do it.
>
>The answer to the question below is that it was VERY hard to get my 1:1 
>threads package to work under Java, even in LinuxThreads compliant mode. 
> The JVMs do bizzare things, and they rely on undocumented behaviour 
>inside LinuxThreads, and I believe they rely on a 1:1 threads mapping. 
> (Why can't they just trust the threads package to do the right thing? 
> Why do they have to do their own things with the stack?)  This is both 
>Blackdown's and IBM's JDK.  It is going to be VERY VERY hard to get NGPT 
>to run the existing JDKs.  It may not even be doable.  When someone gets 
>there, I can look through my logs and see the problems I ran into and 
>advise, if necessary.  But IMHO, someone needs to fix the JDKs.
>
>-Corey
>
>bryan hunt wrote:
>
>  
>
>>Hi there,
>>I was reading a couple of posts on your list in July 2001 and there was 
>>discussion about compatablility with java. I am interested in moving out
>>company webservers from windows to linux but have run into a lot of
>>problems with the old linuxthreads. Is there any java implimentation that
>>works with ngpt ? I notice that 
>>cut=
>>ldd /opt/java/jre/bin/exe/java
>>       libpthread.so.0 => /lib/i686/libpthread.so.0 (0x4002f000)
>>       libnsl.so.1 => /lib/libnsl.so.1 (0x40044000)
>>       libdl.so.2 => /lib/libdl.so.2 (0x4005a000)
>>       libc.so.6 => /lib/i686/libc.so.6 (0x4005e000)
>>       /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
>>=cut
>>
>>There was some mention of efforts to make your library binary compatable
>>    
>>
>with 
>  
>
>>linuxthreads. Is this the case yet ?
>>
>>Thanks in advance
>>Bryan
>>_______________________________________________
>>pthreads-users mailing list
>>[email protected]
>>http://www-124.ibm.com/developerworks/oss/mailman/listinfo/pthreads-users
>> 
>>
>>    
>>
>
>
>
>_______________________________________________
>pthreads-users mailing list
>[email protected]
>http://www-124.ibm.com/developerworks/oss/mailman/listinfo/pthreads-users
>  
>
test_siginfo.c (text/plain, 2.3 KB)
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

pid_t killing_pid;
pid_t my_pid;

volatile pid_t signal_sender = 0;

int bug_to_test = 0;

void
sighandler(int sig, siginfo_t *info, void *context)
{
    printf("In signal handler\n");
    signal_sender = info->si_pid;
}

void sigchld_handler(int sig)
{
    int status;

    waitpid(-1, &status, WNOHANG);
}

void *
dummy_handler(void *data)
{
    sigset_t         mask;

    sigemptyset(&mask);
    sigaddset(&mask, SIGUSR1);
    sigprocmask(SIG_UNBLOCK, &mask, NULL);

    while (signal_sender == 0) {
	struct timeval tv = { 0, 100000 };
	
	select(0, NULL, NULL, NULL, &tv);
    }

    return NULL;
}

int
main(int argc, char *argv[])
{
    pthread_t        other_thread;
    struct sigaction act;
    int              err;
    sigset_t         mask;


    if (argc > 1)
	bug_to_test = atoi(argv[1]);

 
    /* Spawn another thread to receive the signal. */
    err = pthread_create(&other_thread, NULL, dummy_handler, NULL);
    if (err) {
	fprintf(stderr, "pthread_create: %s\n", strerror(err));
	exit(1);
    }

    act.sa_flags = SA_SIGINFO;
    sigemptyset(&act.sa_mask);
    act.sa_sigaction = sighandler;
    if (sigaction(SIGUSR1, &act, NULL) == -1) {
	perror("sigaction");
	exit(1);
    }

    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    act.sa_handler = sigchld_handler;
    if (sigaction(SIGCHLD, &act, NULL) == -1) {
	perror("sigaction");
	exit(1);
    }

    sigemptyset(&mask);
    sigaddset(&mask, SIGUSR1);
    sigprocmask(SIG_BLOCK, &mask, NULL);

    my_pid = getpid();

    /* If we sleep here, it sleeps forever. */
    if (bug_to_test == 1)
	sleep(1);

    killing_pid = fork();
    if (killing_pid == 0) {
	/* We are the fork, so sleep a little and do the kill. */
	sleep(1);
	if (kill(my_pid, SIGUSR1) == -1) {
	    perror("kill");
	    exit(1);
	}
	exit(0);
    } else {
	printf("pid %d will signal %d (me)\n", killing_pid, my_pid);
    }

    /* The main thread, wait for the signal. */
    while (signal_sender == 0) {
	struct timeval tv = { 0, 100000 };
	
printf("E\n");
	select(0, NULL, NULL, NULL, &tv);
    }

    if (signal_sender != killing_pid) {
	fprintf(stderr, "killing pid does not match signal sender\n");
	exit(1);
    }

printf("A\n");

    exit(0);
}