openj9
openj9 copied to clipboard
BufferOverflowException in !snapformat DDR command
Java -version output
java -version
openjdk version "1.8.0_352-internal"
OpenJDK Runtime Environment (build 1.8.0_352-internal-_2022_09_14_18_38-b00)
Eclipse OpenJ9 VM (build master-430e01e, JRE 1.8.0 Linux amd64-64-Bit Compressed References 20220914_000000 (JIT enabled, AOT enabled)
OpenJ9 - 430e01e
OMR - 38e2433
JCL - 8e8d4d3 based on jdk8u352-b05)
Summary of problem
This issue has some strange background: I'm running DDR commands in the context of another Java program so I'm using code something like this (simplified into a standalone program for purposes of demonstration):
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import com.ibm.jvm.dtfjview.Session;
public class DTFJTest {
public static void main(String[] args) throws Throwable {
String file = args[0];
String command = args[1];
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos, true, StandardCharsets.UTF_8.name())) {
Session session = (Session) Session.getInstance(new String[] { "-core", file });
session.findAndSetContextWithJVM();
session.execute(command, ps);
}
System.out.println(baos.toString(StandardCharsets.UTF_8.name()));
}
}
If I use this to run the !snapformat command on a particular customer dump, I get a BufferOverflowException:
$ j2sdk-image/bin/java -cp /users/k/g/kgrigore/j2sdk-image/jre/lib/ddr/j9ddr.jar:. DTFJTest /ecurep/sf/TS010/241/TS010241652/2022-09-02/hostcontext.hostcontext.oomdump-DUP0001.tar.gz_unpack/hostcontext.hostcontext.system.dmp '!snapformat'
[...]
Problem running command:
java.nio.BufferOverflowException
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:194)
at java.nio.ByteBuffer.put(ByteBuffer.java:867)
at com.ibm.j9ddr.tools.ddrinteractive.commands.TraceFileHeaderWriter.writeStartupSection(TraceFileHeaderWriter.java:331)
at com.ibm.j9ddr.tools.ddrinteractive.commands.TraceFileHeaderWriter.writeTraceFileHeader(TraceFileHeaderWriter.java:203)
at com.ibm.j9ddr.tools.ddrinteractive.commands.TraceFileHeaderWriter.createAndWriteTraceFileHeader(TraceFileHeaderWriter.java:164)
at com.ibm.j9ddr.tools.ddrinteractive.commands.SnapBaseCommand.createAndWriteTraceFileHeader(SnapBaseCommand.java:177)
at com.ibm.j9ddr.tools.ddrinteractive.commands.SnapBaseCommand.extractTraceData(SnapBaseCommand.java:88)
at com.ibm.j9ddr.tools.ddrinteractive.commands.SnapFormatCommand.run(SnapFormatCommand.java:458)
at com.ibm.j9ddr.tools.ddrinteractive.commands.SnapFormatWrapperCommand.run(SnapFormatWrapperCommand.java:70)
at com.ibm.j9ddr.tools.ddrinteractive.Context.tryCommand(Context.java:229)
at com.ibm.j9ddr.tools.ddrinteractive.Context.execute(Context.java:202)
at com.ibm.j9ddr.tools.ddrinteractive.DDRInteractive.execute(DDRInteractive.java:356)
at com.ibm.j9ddr.command.CommandReader.processLine(CommandReader.java:78)
at com.ibm.j9ddr.tools.ddrinteractive.DDRInteractive.processLine(DDRInteractive.java:331)
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:498)
at com.ibm.jvm.dtfjview.CombinedContext.executeDDRInteractiveCommand(CombinedContext.java:258)
at com.ibm.jvm.dtfjview.CombinedContext.execute(CombinedContext.java:169)
at com.ibm.jvm.dtfjview.Session.execute(Session.java:813)
at com.ibm.jvm.dtfjview.Session.execute(Session.java:767)
at DTFJTest.main(DTFJTest.java:15)
However, running the same command with the same JVM within jdmpview works fine:
$ j2sdk-image/bin/jdmpview -core /ecurep/sf/TS010/241/TS010241652/2022-09-02/hostcontext.hostcontext.oomdump-DUP0001.tar.gz_unpack/hostcontext.hostcontext.system.dmp
[...]
> !snapformat
Formatting trace using format dat files J9TraceFormat.dat, OMRTraceFormat.dat from /gpfs/sharedfs/users/k/g/kgrigore/j2sdk-image/jre/lib
Buffer size = 8192
firstBuffer: !uttracebuffer 0x7fb0a0000ee0
[...]
I don't understand how this behaves differently as I presume both executions will use the same com.ibm.j9ddr.tools.ddrinteractive.commands.TraceFileHeaderWriter class.
Nevertheless, without putting too much effort into investigating that, it seems like a reasonable solution would be to simply increase the size of the ByteBuffer from 16KB as it's a pretty narrow use case of printing the header to a byte[] so I don't really see any downsides; but, opening an issue to discuss if there are.
I haven't done a comprehensive search for the right value of the ByteBuffer (since it's quite a pain to get a build of a JDK up to ECuRep), but, experimentally, increasing to 160KB works and that seems reasonable to me.