Skip site navigation (1)Skip section navigation (2)
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>