سؤال

Step to reproduce:

  1. Make a trivial modification to java.lang.String from JDK's src.zip such as adding

    private boolean dummy=false;

  2. Compile the change (Eclipse compiler)

  3. Update rt.jar with the new java/lang/String.class
  4. Replace rt.jar in jre/lib with the updated version.
  5. Run bin/java or any of the utils that use rt.jar

The VM will segfault every time on startup.

OS is Linux (Debian Wheezy) x86_64. Happens with both JDK 1.7.0_55 and 1.8.0_05

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000000000000, pid=13313, tid=140065468557056
#
# JRE version:  (7.0_55-b13) (build )
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.55-b03 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  0x0000000000000000
#
# Core dump written. Default location: /home/chris/workspace/JDK7/foo/core or core.13313
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#

---------------  T H R E A D  ---------------

Current thread (0x0000000000eb6000):  JavaThread "Unknown thread" [_thread_in_Java, id=13314, stack(0x00007f63886fa000,0x00007f63887fb000)]

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000000000000000

Loading the core dump in gdb gives:

chris@nb:~/workspace/JDK7/foo$ gdb /home/chris/java/bin/java core
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/chris/jdk1.7.0_55/bin/java...(no debugging symbols     found)...done.

warning: core file may not match specified executable file.
[New LWP 13314]
[New LWP 13315]
[New LWP 13313]
[New LWP 13316]
[New LWP 13317]

warning: Error reading shared library list entry at 0x302e6f732e646165

warning: Error reading shared library list entry at 0x5f006f732e696c6a
Core was generated by `jar cf rt.jar com java javax META-INF org sun sunw'.
Program terminated with signal 6, Aborted.
#0  0x00007f6387c6b475 in ?? ()
(gdb) bt
#0  0x00007f6387c6b475 in ?? ()
#1  0x00007f6387c6e6f0 in ?? ()
#2  0x0000000000000000 in ?? ()

I've modified other VM classes previously (earlier Java 7 versions) this way without problems. Is there something special about java.lang.String that means it can't be modified? (Checksumming etc.?)

This is for personal benchmarking experiments so no need to reply about license / distribution issues.

Thanks,

Chris

هل كانت مفيدة؟

المحلول

Prior to this changeset: https://bugs.openjdk.java.net/browse/JDK-6924259 Hotspot had hardcoded assumptions about the field offsets of the various fields in java.lang.String. This means if you add fields to the String class which cause the class layouting logic to move the existing fields around you will break the JVM. The changeset above moves the JVM to instead compute these offsets at runtime from the real String class layout. The associated bug shows what version this has been back ported to: https://bugs.openjdk.java.net/browse/JDK-6924259. I've not tested anything but I'm pretty sure that @shipilev's example would have worked in a JVM prior to this change anyway since the single boolean didn't shift any of the existing fields. Either way: use a recent JVM and all should be fine. Use an older JVM and mucho breakage can result.

نصائح أخرى

String is heavily optimised at runtime so you might find the JVM can't handle changes to the Java code. I would try adding to the end of the class as the best chance of working.

For example, you can add one method to Object but add two methods and the JVM can crash without even a dump.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top