Date: Wed, 12 Feb 2003 16:50:06 -0800 From: Milo Hyson <milo@cyberlifelabs.com> To: FreeBSD Emulation List <freebsd-emulation@freebsd.org> Subject: Working on IBM JDK fix Message-ID: <3E4AEBBE.8070601@cyberlifelabs.com>
next in thread | raw e-mail | index | archive | help
I apologize in advance if this issue has already been dealt with, but I searched the list archives and didn't find anything. I also apologize if my conclusions below are totally whacked, as I've never looked at the FreeBSD or Linux kernel sources before. I'm working on fixing the broken IBM JDK port and my research has led me to believe the problem actually lies in the Linux emulation layer. It seems when a Java program exits without explicitly calling System.exit(), the JVM goes into an endless-loop while /var/log/messages fills up with kernel trap 26 (segment not present exception) messages. Comparing the outputs of ktrace on FreeBSD and strace on Linux, I found a SIGSEGV signal (in the FreeBSD implementation) that immediately follows a call to modify_ldt(), which appears to be returning an odd value. Here are excerpts from the traces showing where things start to differ: NOTE: FreeBSD = 4.7-RELEASE, Linux = Mandrake 9.0 *** FreeBSD ktrace *** ... 3600 java CALL write(0x1,0x2849ad78,0xc) 3600 java GIO fd 1 wrote 12 bytes "Hello, world" 3600 java RET write 12/0xc 3600 java CALL #175(0x2,0xbfbff28c,0,0x8) 3600 java RET #175 0 3600 java CALL #175(0x1,0xbfbff2c0,0xbfbff398,0x8) 3600 java RET #175 0 3600 java CALL write(0x1,0x2849ad78,0x1) 3600 java GIO fd 1 wrote 1 byte " " 3600 java RET write 1 3600 java CALL #175(0x2,0xbfbff2c0,0,0x8) 3600 java RET #175 0 3600 java CALL fchown(0x11,0xbfbff878,0x10) 3600 java RET fchown 8190/0x1ffe 3600 java PSIG SIGSEGV caught handler=0x28071670 mask=0xa0000000 code=0x0 ... *** Linux strace *** write(1, "Hello, world", 12) = 12 rt_sigprocmask(SIG_SETMASK, [USR1 RTMIN], NULL, 8) = 0 rt_sigprocmask(SIG_UNBLOCK, [USR1], [USR1 RTMIN], 8) = 0 write(1, "\n", 1) = 1 rt_sigprocmask(SIG_SETMASK, [USR1 RTMIN], NULL, 8) = 0 modify_ldt(17, {entry_number:8190, base_addr:00000000, limit:0, seg_32bit:0, contents:0, read_exec_only:1, limit_in_pages:0, seg_not_present:1, useable:0}, 16) = 0 sigaltstack({ss_sp=0, ss_flags=SS_DISABLE, ss_size=0}, NULL) = 0 The call to modify_ldt() appears to be trying to zero out entry number 8190. On Linux it works, as the call returns a zero. On FreeBSD however, it seems to be returning the entry number, a value that the spec for modify_ldt() says is not valid. One can only assume that the FreeBSD version is doing something wrong. However, looking through the source for that call reveals no way that value could be returned. Now this particular call to modify_ldt() occurrs many times over the course of the traces. However, this is the only time in which a segfault is logged. Since the call is returning prior to the logging of the fault, I'm inclined to think that modify_ldt() isn't triggering the exception itself, but may somehow be settings things up to fail later on down the line. Is there any way to obtain a detailed register/memory dump of the kernel trap? That would shed some light on what's going on. -- Milo Hyson CyberLife Labs To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-emulation" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3E4AEBBE.8070601>