openj9 icon indicating copy to clipboard operation
openj9 copied to clipboard

BufferOverflowException in !snapformat DDR command

Open kgibm opened this issue 3 years ago • 0 comments

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.

kgibm avatar Sep 14 '22 20:09 kgibm