Akira's Tech Notes

Java/JVM | GNU/Linux | Emacs/Lisp | 知的好奇心駆動

header-icon
ネイティブでない日本語で思い付くことや気になることをダラダラ書く、体裁とかは気にしない。読みづらいと感じた時に随時更新する。

[tips][Java]OpenJDK8付属ツール実行時エラーの対策

本記事のOpenJDK障害は次の環境で確認しています。

$ java -version
openjdk version "1.8.0_60"
OpenJDK Runtime Environment (build 1.8.0_60-b24)
OpenJDK 64-Bit Server VM (build 25.60-b23, mixed mode)

$ uname -a
Linux mimi 4.1.6-1-ARCH #1 SMP PREEMPT Mon Aug 17 08:52:28 CEST 2015 x86_64 GNU/Linux

1 プロセスのアタッチ出来ない

$ /usr/lib/jvm/java-8-openjdk/bin/jinfo -sysprops 22286
Attaching to process ID 22286, please wait...
Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
	at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.execute(LinuxDebuggerLocal.java:163)
	at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach(LinuxDebuggerLocal.java:278)
	at sun.jvm.hotspot.HotSpotAgent.attachDebugger(HotSpotAgent.java:671)
	at sun.jvm.hotspot.HotSpotAgent.setupDebuggerLinux(HotSpotAgent.java:611)
	at sun.jvm.hotspot.HotSpotAgent.setupDebugger(HotSpotAgent.java:337)
	at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304)
	at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
	at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
	at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
	at sun.jvm.hotspot.tools.JInfo.main(JInfo.java:138)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at sun.tools.jinfo.JInfo.runTool(JInfo.java:108)
	at sun.tools.jinfo.JInfo.main(JInfo.java:76)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process
	at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach0(Native Method)
	at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.access$100(LinuxDebuggerLocal.java:62)
	at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$1AttachTask.doit(LinuxDebuggerLocal.java:269)
	at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal$LinuxDebuggerLocalWorkerThread.run(LinuxDebuggerLocal.java:138)

同じ障害に遭遇した方々

straceで見たら、 ptrace システムコールのPTRACE_ATTACHリクエストで実行中のJavaプロセス をアタッチしようとするところで Operation not permitted 理由に怒られた。

  |$ strace -ff /usr/lib/jvm/java-8-openjdk/bin/jinfo -sysprops 22286
  |(中略)
  |[pid 24277] close(7)                    = 0
**|[pid 24277] ptrace(PTRACE_ATTACH, 22286, 0, 0) = -1 EPERM (Operation not permitted)
  |[pid 24277] futex(0x7fef94008854, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fef94008850, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
  |[pid 24263] <... futex resumed> )       = 0
  |[pid 24277] futex(0x7fef9414b154, FUTEX_WAIT_PRIVATE, 3, NULL <unfinished ...>
  |[pid 24263] futex(0x7fef94008828, FUTEX_WAKE_PRIVATE, 1) = 0
  |[pid 24263] write(2, "Error attaching to process: ", 28Error attaching to process: ) = 28
  |[pid 24274] futex(0x7fef940bb654, FUTEX_WAIT_BITSET_PRIVATE, 57, {29187, 107955715}, ffffffff <unfinished ...>
**|[pid 24263] write(2, "sun.jvm.hotspot.debugger.Debugge"..., 71sun.jvm.hotspot.debugger.DebuggerException: Can't attach to the process) = 71
  |[pid 24263] write(2, "\n", 1

これはLinuxカーネルのセキュリティモジュール yama の制限に引掛かったのが原因です。 下記手順でこの制限を解除すれば、エラーが解消されます。

$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

yamaによるptrace制限に関して下記が分かやすいと思います。

https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace_Protection

もっと簡単な対応方法として、sudoでrootユーザで実行すれば良いでしょう。

2 Metadata does not appear to be polymorphic

$ /usr/lib/jvm/java-8-openjdk/bin/jinfo -sysprops 22286
Attaching to process ID 22286, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23
Exception in thread "main" java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at sun.tools.jinfo.JInfo.runTool(JInfo.java:108)
	at sun.tools.jinfo.JInfo.main(JInfo.java:76)
Caused by: java.lang.InternalError: Metadata does not appear to be polymorphic
	at sun.jvm.hotspot.types.basic.BasicTypeDataBase.findDynamicTypeForAddress(BasicTypeDataBase.java:278)
	at sun.jvm.hotspot.runtime.VirtualBaseConstructor.instantiateWrapperFor(VirtualBaseConstructor.java:102)
	at sun.jvm.hotspot.oops.Metadata.instantiateWrapperFor(Metadata.java:68)
	at sun.jvm.hotspot.memory.SystemDictionary.getSystemKlass(SystemDictionary.java:127)
	at sun.jvm.hotspot.runtime.VM.readSystemProperties(VM.java:879)
	at sun.jvm.hotspot.runtime.VM.getSystemProperties(VM.java:873)
	at sun.jvm.hotspot.tools.SysPropsDumper.run(SysPropsDumper.java:44)
	at sun.jvm.hotspot.tools.JInfo.run(JInfo.java:94)
	at sun.jvm.hotspot.tools.Tool.startInternal(Tool.java:260)
	at sun.jvm.hotspot.tools.Tool.start(Tool.java:223)
	at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
	at sun.jvm.hotspot.tools.JInfo.main(JInfo.java:138)
	... 6 more

原因はよくわからないのですが、twitter上で流れた情報 によるとJVMのdebuginfoを入れれば 問題が回避されるようです。実際に確認したところで確かに回避出来た、しかしdebuginfo禁止 の商用環境やdebuginfoが簡単に導入出来ないdistroには寂しいでしょう。

yumが使える環境は、次のように debuginfo-install で簡単にインストールが出来ます。

$ sudo debuginfo-install java-1.8.0-openjdk-devel

3 unknown CollectedHeap type

$ /usr/lib/jvm/java-8-openjdk/bin/jmap -heap 22286
Attaching to process ID 22286, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 0
   MaxHeapFreeRatio         = 100
   MaxHeapSize              = 1367343104 (1304.0MB)
   NewSize                  = 455606272 (434.5MB)
   MaxNewSize               = 455606272 (434.5MB)
   OldSize                  = 911736832 (869.5MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
Exception in thread "main" java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at sun.tools.jmap.JMap.runTool(JMap.java:201)
	at sun.tools.jmap.JMap.main(JMap.java:130)
Caused by: java.lang.RuntimeException: unknown CollectedHeap type : class sun.jvm.hotspot.gc_interface.CollectedHeap
	at sun.jvm.hotspot.tools.HeapSummary.run(HeapSummary.java:144)
	at sun.jvm.hotspot.tools.Tool.startInternal(Tool.java:260)
	at sun.jvm.hotspot.tools.Tool.start(Tool.java:223)
	at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
	at sun.jvm.hotspot.tools.HeapSummary.main(HeapSummary.java:49)
	... 6 more

このエラーもdebuginfoをインストールすれば、回避出来る。

↓OpenJDK7でバグ報告された記録、残念ながら WONTFIX 状態でした。

https://bugzilla.redhat.com/show_bug.cgi?id=1010786

Comments