2014-05-05 38 views
2

步驟重現:瑣碎修改爲java.lang.String在rt.jar中引起VM段錯誤

  1. 從JDK的src.zip 製作一個簡單的變形例爲java.lang.String如添加

    private boolean dummy = false;

  2. 編譯變化(Eclipse的編譯器)

  3. 更新的rt.jar與新的Java /郎/ String.class
  4. 替換的jre/lib下的rt.jar的更新版本。
  5. 運行斌/ Java或任何使用rt.jar中

VM將段錯誤在啓動時每次utils軟件包。

操作系統是Linux(Debian Wheezy)x86_64。既JDK 1.7.0_55和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 

裝入核心轉儲在gdb偏偏給:

[email protected]:~/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 ??() 

我以前(早期的Java 7版本),這種方式不修改其他VM類問題。有沒有什麼特別的java.lang.String,這意味着它不能被修改? (Checksumming等?)

這是個人基準測試實驗,所以不需要回復關於許可/分配問題。

感謝,

克里斯

+0

如果包括String.class在罐子的應用是什麼? afaik它應該替換rt.jar一個。 – JIV

+0

爲我工作:https://gist.github.com/shipilev/e43a27851a4ce985ac48。嘗試切換到Oracle/OpenJDK javac編譯器,甚至從源代碼構建完整的JDK。 –

回答

4

在此變更集之前:https://bugs.openjdk.java.net/browse/JDK-6924259熱點有關於java.lang.String中各個字段的字段偏移量的硬編碼假設。這意味着如果您將字段添加到String類,這會導致類佈局邏輯移動您周圍的現有字段將會破壞JVM。上面的變更集將JVM移動到運行時從真實的String類佈局中計算這些偏移量。相關的錯誤顯示了這個版本已被移植到的版本:https://bugs.openjdk.java.net/browse/JDK-6924259。我沒有測試任何東西,但我敢肯定,@ shipilev的例子已經在JVM這一變化之前,無論如何努力,因爲單一的布爾沒有轉移任何現有的字段。無論哪種方式:使用最近的JVM,一切都應該沒問題。使用較舊的JVM會導致mucho破損。

+0

嗨克里斯,問題發生在7u55和8u05,但我使用Eclipse編譯器重新編譯字符串。將嘗試使用Oracle javac重現。 – ChrisWhoCodes

+0

我試圖在本地重現這一點,並且不能......然後我意識到可能會出現什麼問題。我不知道爲什麼會觸發破壞,但如果你修改String.java,然後在rt中替換String.class。沒有也取代CaseInsensitiveComparator內部類的jar,然後我看到像你這樣的失敗。我已經通過核心轉儲挖掘了這一點,並且在嘗試在JVM創建時初始化String類時跳躍了起來。儘管如此,仍然在深入挖掘正在發生的事情。 –

+0

好吧 - 如此深埋在這個內部的NoSuchMethodError在嘗試查找內部比較器類的構造函數時(被引入我的未經訓練的眼睛)時被拋出,當嘗試拋出異常時看起來事情變得非常棘手(因爲VM尚未完全存在),因此我們只看到一個SIGSEGV。我猜NoSuchMethodError是由於常量池已經在String類中被修改的事實 - 儘管這看起來有點奇怪。無論如何,我已經決定在這一點上停止挖掘,因爲我認爲我已經足夠深入兔子洞了。 –

2

String在運行時高度優化的,所以你可能會發現JVM不能處理更改Java代碼。我會嘗試添加到班級的最後作爲工作的最佳機會。

例如,您可以將一種方法添加到Object,但添加了兩種方法,JVM甚至可能會崩潰而無需轉儲。