Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4388732
Votes 22
Synopsis System.exit(n) where n != 0 doesn't work on RH 7 + JDK 1.3
Category java:runtime
Reported Against 1.3 , 2.0fcs , ladybird-beta , kest-linux-fcs
Release Fixed
State 11-Closed, Will Not Fix, bug
Priority: 3-Medium
Related Bugs 4385520 , 4405143 , 4454544
Submit Date 13-NOV-2000
Description
The bug is actually is the libpthread-0.9 that comes with glibc-2.2
The new libpthread attachs the exit handler with cxa_atexit() instead
of on_exit() (the cxa_handler is supposed to be called also when the
shared library is unloaded). But the cxa exit handler flavor is not called
with the exit code during exit(). The cxa handler takes only one argument
specified when cxa_atexit() is called. The new libpthread sets this 
argument to NULL and by side effect this argument becomes the exit code of 
the process. Note that this is only a problem if the thread that does exit() is not the main thread. RedHat fixed this and lot of other libc bugs in RedHat 7.1.
Please upgrade 7.0 to 7.1 to avoid this problem.

RedHat bug Id:  23758
location: http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=23758





java version "1.3.0rc1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0rc1-b17)
Java HotSpot(TM) Client VM (build 1.3.0rc1-b17, mixed mode)

When System.exit(int) is invoked under Red Hat 7.0, the program never exits with
a non-zero value. Note that this is the same bug as 4383241, but the test
engineers never bothered to test that one under the current version of Red Hat.

fmh $ cat z.java
class z
{
    public static void main(String[] argv) {
        int exitval = Integer.parseInt(argv[0]);
        System.out.println("Exiting with exit value " + exitval);
        System.exit(exitval);
    }
}
fmh $ javac z.java
fmh $ java z 0; echo $?
Exiting with exit value 0
0
fmh $ java z 1; echo $?
Exiting with exit value 1
0
fmh $ java z 127; echo $?
Exiting with exit value 127
0
(Review ID: 111862) 
======================================================================
Work Around
N/A
Evaluation
The problem is caused by a bug in /lib/libc.so library.
RedHat6.2 uses version 2.1.2 of the library
RedHat7.0 uses  version 2.2 of the library.

libc's function exit() was changed dramatically. I don't have the library sources but I studied disassembly of the both libraries. It looks like exit()
in 2.2 does not save exit status code, when invokes handlers registered with atexit() call. See for yourself. 

libc-2.1.2::exit()
--------------------
00020970 <exit>:
   20970:   55                      pushl  %ebp
   20971:   89 e5                   movl   %esp,%ebp
   20973:   57                      pushl  %edi
   20974:   56                      pushl  %esi
   20975:   53                      pushl  %ebx
   20976:   e8 00 00 00 00          call   2097b <exit+0xb>
   2097b:   5b                      popl   %ebx
   2097c:   81 c3 11 db 0c 00       addl   $0xcdb11,%ebx
   20982:   8b 8b b8 07 00 00       movl   0x7b8(%ebx),%ecx
   20988:   83 39 00                cmpl   $0x0,(%ecx)
   2098b:   0f 84 7d 00 00 00       je     20a0e <exit+0x9e>
   20991:   8b 01                   movl   (%ecx),%eax
   20993:   8b 50 04                movl   0x4(%eax),%edx
   20996:   8d 7a ff                leal   0xffffffff(%edx),%edi
   20999:   89 78 04                movl   %edi,0x4(%eax)
   2099c:   8d 54 52 fd             leal   0xfffffffd(%edx,%edx,2),%edx
   209a0:   8b 01                   movl   (%ecx),%eax
   209a2:   8d 54 90 08             leal   0x8(%eax,%edx,4),%edx
   209a6:   8b 02                   movl   (%edx),%eax
   209a8:   83 f8 03                cmpl   $0x3,%eax
   209ab:   77 39                   ja     209e6 <exit+0x76>
   209ad:   89 df                   movl   %ebx,%edi
   209af:   2b bc 83 34 25 f3 ff    subl   0xfff32534(%ebx,%eax,4),%edi
   209b6:   ff e7                   jmp    *%edi
   209b8:   90                      nop
   209b9:   8d b4 26 00 00 00 00    leal   0x0(%esi,1),%esi
   209c0:   a6                      cmpsb  %ds:(%esi),%es:(%edi)
   209c1:   da 0c 00                fimull (%eax,%eax,1)
   209c4:   a6                      cmpsb  %ds:(%esi),%es:(%edi)
   209c5:   da 0c 00                fimull (%eax,%eax,1)
   209c8:   bc da 0c 00 ab          movl   $0xab000cda,%esp
   209cd:   da 0c 00                fimull (%eax,%eax,1)
   209d0:   ff 72 08                pushl  0x8(%edx)
   209d3:   8b 7d 08                movl   0x8(%ebp),%edi
   209d6:   57                      pushl  %edi
   209d7:   8b 42 04                movl   0x4(%edx),%eax
   209da:   ff d0                   call   *%eax
   209dc:   83 c4 08                addl   $0x8,%esp
   209df:   eb 05                   jmp    209e6 <exit+0x76>
   209e1:   8b 42 04                movl   0x4(%edx),%eax
   209e4:   ff d0                   call   *%eax
   209e6:   8b 8b b8 07 00 00       movl   0x7b8(%ebx),%ecx
   209ec:   8b 11                   movl   (%ecx),%edx
   209ee:   83 7a 04 00             cmpl   $0x0,0x4(%edx)
   209f2:   75 9d                   jne    20991 <exit+0x21>
   209f4:   8b 02                   movl   (%edx),%eax
   209f6:   89 01                   movl   %eax,(%ecx)
   209f8:   52                      pushl  %edx
   209f9:   e8 4e 74 ff ff          call   17e4c <GLIBC_2.0+0x17e4c>
   209fe:   83 c4 04                addl   $0x4,%esp
   20a01:   8b 83 b8 07 00 00       movl   0x7b8(%ebx),%eax
   20a07:   89 c1                   movl   %eax,%ecx
   20a09:   83 39 00                cmpl   $0x0,(%ecx)
   20a0c:   75 83                   jne    20991 <exit+0x21>
   20a0e:   8b b3 bc 07 00 00       movl   0x7bc(%ebx),%esi
   20a14:   3b b3 c0 07 00 00       cmpl   0x7c0(%ebx),%esi
   20a1a:   73 13                   jae    20a2f <exit+0xbf>
   20a1c:   8d 74 26 00             leal   0x0(%esi,1),%esi
   20a20:   8b 06                   movl   (%esi),%eax
   20a22:   ff d0                   call   *%eax
   20a24:   83 c6 04                addl   $0x4,%esi
   20a27:   3b b3 c0 07 00 00       cmpl   0x7c0(%ebx),%esi
   20a2d:   72 f1                   jb     20a20 <exit+0xb0>
   20a2f:   8b 7d 08                movl   0x8(%ebp),%edi
   20a32:   57                      pushl  %edi
   20a33:   e8 64 71 ff ff          call   17b9c <GLIBC_2.0+0x17b9c>
   20a38:   90                      nop
   20a39:   90                      nop

libc-2.2::exit()
----------------
0002f744 <exit>:
   2f744:       55                      push   %ebp
   2f745:       89 e5                   mov    %esp,%ebp
   2f747:       57                      push   %edi
   2f748:       56                      push   %esi
   2f749:       53                      push   %ebx
   2f74a:       83 ec 0c                sub    $0xc,%esp
   2f74d:       e8 ee ff ff ff          call   2f740 <__secure_getenv+0x4c>
   2f752:       81 c3 76 61 0f 00       add    $0xf6176,%ebx
   2f758:       8b b3 dc 07 00 00       mov    0x7dc(%ebx),%esi
   2f75e:       8b 7d 08                mov    0x8(%ebp),%edi
   2f761:       8b 16                   mov    (%esi),%edx
   2f763:       85 d2                   test   %edx,%edx
   2f765:       0f 84 9b 00 00 00       je     2f806 <exit+0xc2>
   2f76b:       90                      nop
   2f76c:       8d 74 26 00             lea    0x0(%esi,1),%esi
   2f770:       8b 06                   mov    (%esi),%eax
   2f772:       89 f2                   mov    %esi,%edx
   2f774:       8b 40 04                mov    0x4(%eax),%eax
   2f777:       85 c0                   test   %eax,%eax
   2f779:       74 64                   je     2f7df <exit+0x9b>
   2f77b:       90                      nop
   2f77c:       8d 74 26 00             lea    0x0(%esi,1),%esi
   2f780:       8b 12                   mov    (%edx),%edx
   2f782:       8b 42 04                mov    0x4(%edx),%eax
   2f785:       48                      dec    %eax
   2f786:       89 42 04                mov    %eax,0x4(%edx)
   2f789:       c1 e0 04                shl    $0x4,%eax
   2f78c:       01 c2                   add    %eax,%edx
   2f78e:       8b 42 08                mov    0x8(%edx),%eax
   2f791:       8d 4a 08                lea    0x8(%edx),%ecx
   2f794:       83 f8 04                cmp    $0x4,%eax
   2f797:       77 35                   ja     2f7ce <exit+0x8a>
   2f799:       8b b4 83 e0 9e f0 ff    mov    0xfff09ee0(%ebx,%eax,4),%esi
   2f7a0:       89 da                   mov    %ebx,%edx
   2f7a2:       29 f2                   sub    %esi,%edx
   2f7a4:       89 d0                   mov    %edx,%eax
   2f7a6:       ff e0                   jmp    *%eax
   2f7a8:       fa                      cli
   2f7a9:       60                      pusha
   2f7aa:       0f 00                   (bad)
   2f7ac:       fa                      cli
   2f7ad:       60                      pusha
   2f7ae:       0f 00 08                str    (%eax)
   2f7b1:       61                      popa
   2f7b2:       0f 00 98 60 0f 00 93    ltr    0x93000f60(%eax)
   2f7b9:       60                      pusha
   2f7ba:       0f 00 8d 74 26 00 8b    str    0x8b002674(%ebp)
   2f7c1:       41                      inc    %ecx
   2f7c2:       08 83 ec 08 50 57       or     %al,0x575008ec(%ebx)
   2f7c8:       ff 51 04                call   *0x4(%ecx)
   2f7cb:       83 c4 10                add    $0x10,%esp
   2f7ce:       8b b3 dc 07 00 00       mov    0x7dc(%ebx),%esi
   2f7d4:       8b 06                   mov    (%esi),%eax
   2f7d6:       89 f2                   mov    %esi,%edx
   2f7d8:       8b 48 04                mov    0x4(%eax),%ecx
   2f7db:       85 c9                   test   %ecx,%ecx
   2f7dd:       75 a1                   jne    2f780 <exit+0x3c>
   2f7df:       8b 16                   mov    (%esi),%edx
   2f7e1:       8b 02                   mov    (%edx),%eax
   2f7e3:       85 c0                   test   %eax,%eax
   2f7e5:       89 06                   mov    %eax,(%esi)
   2f7e7:       74 0c                   je     2f7f5 <exit+0xb1>
   2f7e9:       83 ec 0c                sub    $0xc,%esp
   2f7ec:       52                      push   %edx
   2f7ed:       e8 56 c4 fe ff          call   1bc48 <GLIBC_2.0+0x1bc48>
   2f7f2:       83 c4 10                add    $0x10,%esp
   2f7f5:       8b 06                   mov    (%esi),%eax
   2f7f7:       85 c0                   test   %eax,%eax
   2f7f9:       74 0b                   je     2f806 <exit+0xc2>
   2f7fb:       8b b3 dc 07 00 00       mov    0x7dc(%ebx),%esi
   2f801:       e9 6a ff ff ff          jmp    2f770 <exit+0x2c>
   2f806:       8b b3 bc 08 00 00       mov    0x8bc(%ebx),%esi
   2f80c:       3b b3 3c 09 00 00       cmp    0x93c(%ebx),%esi
   2f812:       73 2c                   jae    2f840 <exit+0xfc>
   2f814:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
   2f81a:       8d bf 00 00 00 00       lea    0x0(%edi),%edi
   2f820:       ff 16                   call   *(%esi)
   2f822:       83 c6 04                add    $0x4,%esi
   2f825:       3b b3 3c 09 00 00       cmp    0x93c(%ebx),%esi
   2f82b:       72 f3                   jb     2f820 <exit+0xdc>
   2f82d:       eb 11                   jmp    2f840 <exit+0xfc>
   2f82f:       90                      nop
   2f830:       ff 51 04                call   *0x4(%ecx)
   2f833:       eb 99                   jmp    2f7ce <exit+0x8a>
   2f835:       8b 71 08                mov    0x8(%ecx),%esi
   2f838:       83 ec 0c                sub    $0xc,%esp
   2f83b:       56                      push   %esi
   2f83c:       eb 8a                   jmp    2f7c8 <exit+0x84>
   2f83e:       89 f6                   mov    %esi,%esi
   2f840:       83 ec 0c                sub    $0xc,%esp
   2f843:       57                      push   %edi
   2f844:       e8 5f c1 fe ff          call   1b9a8 <GLIBC_2.0+0x1b9a8>
   2f849:       90                      nop
   2f84a:       90                      nop
   2f84b:       90                      nop
   2f84c:       90                      nop
   2f84d:       90                      nop
   2f84e:       90                      nop
   2f84f:       90                      nop
   2f850:       8b 1c 24                mov    (%esp,1),%ebx
   2f853:       c3                      ret



 xxxxx@xxxxx  2000-12-20

I inserted printouts in os::exit() and VM_Exit::doit() to make sure that exit status code is passed correctly to libc::exit(). results look as follows:

s/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:695
exit  _code=55 thread=80da240 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:697
exit  _code=55 thread=80d9628 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:695
exit  _code=55 thread=80d9628 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:697
exit  _code=55 thread=80d8a20 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:695
exit  _code=55 thread=80d8a20 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:697
exit  _code=55 thread=80d0e18 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:695
exit  _code=55 thread=80d0e18 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:697
exit  _code=55 thread=80cf7a0 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:695
exit  _code=55 thread=80cf7a0 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:697
exit  _code=55 thread=805f610 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:695
exit  _code=55 thread=805f610 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:697
exit  _code=55 thread=805f610 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:701
exit  _code=55 thread=805f610 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:703
exit  _code=55 thread=805f610 at/.automount/jano/root/export/disk07/runtime/users/wdavid/1.4_sa/build/linux/../../src/os/linux/vm/os_linux.cpp:708

No doubts the bug is in the library.
The bug only shows up when atexit handlers are invoked.

 
 xxxxx@xxxxx  2000-12-20

The bug is actually is the libpthread-0.9 that comes with glibc-2.2
The new libpthread attachs the exit handler with cxa_atexit() instead
of on_exit() (the cxa_handler is supposed to be called also when the
shared library is unloaded). But the cxa exit handler flavor is not called
with the exit code during exit(). The cxa handler takes only one argument
specified when cxa_atexit() is called. The new libpthread sets this 
argument to NULL and by side effect this argument becomes the exit code of 
the process.
Note that this is only a problem if the thread that does exit() is not the main
thread.
Potential workaround in the JVM: force the main thread to do the exit().

 xxxxx@xxxxx  2001-01-10

I had a meeting with Ludo and we dicussed the bug. It is not only Hotspot problem, any multythread application is affected. The bug in pthread library caused wrong exit code was filed with RedHat.  The bug and lot of  xxxxx  libc bugs are expected to be fixed in RedHat 7.1. So we propose upgrade to 7.1 as
a "workaround" for this bug.

RedHat bug Id:  23758
location: http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=23758

 xxxxx@xxxxx  2001-02-06
Comments
  
  Include a link with my name & email   

Submitted On 19-NOV-2000
KleemannR
Apparently, this also affects the return value of javac
which makes it impossible to build java projects with
makefiles.  A workaround until this bug is fixed is to use
IBM's java 1.3 sdk.


Submitted On 21-NOV-2000
cjs@cynic.net
The javac return value problem was how I found the bug in
the first place, in fact. I have a script that finds all of
the outdated files in my tree and runs a single javac to
build them all (this is much faster than invoking javac
individually for each out-of-date files). My workaround was
to add code to this script to check again after compilation
for out-of-date files and exit with an error value should
any still exist. You could do the same with your .java.class
rules in your Makefile.


Submitted On 11-DEC-2000
gregholt
Please note that my above workaround does nothing for Java
programs that call System.exit. This only really helps when
compiling projects using Makefiles. It also has the side
effect of always returning exit code 1 if any data is output
to stderr.

Greg Holt


Submitted On 11-DEC-2000
gregholt
I had posted this on bug 4383241, which was closed without
full and proper testing...


This is very reproducible on RedHat Linux 7.0, with or
without all known updates from updates.redhat.com.

[greg@opal greg]$ cat z.java
class z {
  final int foo;
}
[greg@opal greg]$ javac z.java; echo exit value: $?
z.java:1: variable foo might not have been initialized
class z {
^
1 error
exit value: 0
[greg@opal greg]$ uname -a
Linux opal.inner.brim.net 2.2.16-22 #1 Tue Aug 22 16:49:06
EDT 2000 i686 unknown
[greg@opal greg]$ java -version
java version &quot;1.3.0&quot;
Java(TM) 2 Runtime Environment, Standard Edition (build
1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)


If you edit /usr/java/jdk1.3/bin/.java_wrapper and change
the line:

exec $DEBUG_PROG &quot;$prog&quot; &quot;$@&quot;

to:

$DEBUG_PROG &quot;$prog&quot; &quot;$@&quot;; echo .java_wrapper exit code: $?

and run the same test, you get:

[greg@opal greg]$ javac z.java                     
z.java:1: variable foo might not have been initialized
class z {
^
1 error
.java_wrapper exit code: 0

Which indicates that it is *not* a problem with
.java_wrapper itself, but the executable being called. In my
case this is
&quot;/usr/java/jdk1.3/bin/i386/native_threads/javac&quot;.


Workaround (very kludgy!):

Modify /usr/java/jdk1.3/bin/.java_wrapper:

Change the line that reads:

exec $DEBUG_PROG &quot;$prog&quot; &quot;$@&quot;

to:
    
tmpfile=&quot;/tmp/java_${UID}_${PPID}_${SECONDS}_${RANDOM}.tmp&quot;
$DEBUG_PROG &quot;$prog&quot; &quot;$@&quot; 2&gt; $tmpfile
if [ -s $tmpfile ]; then
  cat $tmpfile
  rm $tmpfile
  exit 1
fi
rm $tmpfile


Then, the test performs correctly:

[greg@opal greg]$ javac z.java; echo exit value: $?
z.java:1: variable foo might not have been initialized
class z {
^
1 error
exit value: 1


HOWEVER: This has the side-effect of buffering all stderr
output and only dumping it at the end, which may affect how
valid programs run with &quot;java&quot; work that use System.err.*.

It does keep my Makefiles informed of compilation errors
though and saves me a ton of headscratching when a program I
*thought* built fine didn't.

Greg Holt



Submitted On 13-DEC-2000
egoine
Please fix this! It's breaking so much stuff!


Submitted On 15-DEC-2000
cjs@cynic.net
Is someone from Sun actually dealing with this? It's a
pretty major problem that one would think would not be
rocket science to fix, and it's been over a month now.


Submitted On 21-DEC-2000
gregholt
Has this been reported to Red Hat? Does this mean we should
just use IBM's JDK until &quot;someone&quot; fixes this?


Submitted On 10-JAN-2001
Bill_CCHKK
A quick note.  It was reported that this fails on RedHat 7
but works on RedHat 6.2.  RedHat 7 uses glibc version
2.1.92, and was updated to 2.1.94 and then to 2.2.  I'm
running with the 2.1.94 version, and it is broke there as
well.

However, if I run the 1.2.2 JDK from blackdown (based on the
Sun code) on Red Hat 7, the behavior is correct, the return
code is correct.


Submitted On 12-JAN-2001
Bill_CCHKK
FYI, everyone, it looks like someone (presumably xxxxx@xxxxx
abover :-) ) reported this bug to Redhat.  Take a look at
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=23758
for the details.



PLEASE NOTE: JDK6 is formerly known as Project Mustang