From 32ff6237dd53fbb37e3c268d253a19dac74fff76 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh Date: Mon, 15 Feb 2021 11:16:31 +0700 Subject: [PATCH] Possibility fixes #39: Unsafe.getInt() crashes # Problematic frame: # V [libjvm.dylib+0x982a60] Unsafe_GetInt(JNIEnv_*, _jobject*, _jobject*, long)+0x104 J 373 jdk.internal.misc.Unsafe.getInt(Ljava/lang/Object;J)I java.base@16 (0 bytes) @ 0x0000000d40e0f254 [0x0000000d40e0f1c0+0x0000000000000094] j sun.misc.Unsafe.getInt(Ljava/lang/Object;J)I+5 jdk.unsupported@16 j org.lwjgl.glfw.GLFWVidMode.nblueBits(J)I+10 j org.lwjgl.glfw.GLFWVidMode$Buffer.blueBits()I+4 j dey.(Lorg/lwjgl/glfw/GLFWVidMode$Buffer;)V+38 j der.a()V+47 j der.(J)V+17 j eau$$Lambda$2435+0x0000000300729bf8.createMonitor(J)Lder;+5 j dev.(Ldes;)V+72 j eau.(Ldjz;)V+19 j djz.(Ldsz;)V+666 j net.minecraft.client.main.Main.main([Ljava/lang/String;)V+1250 v ~StubRoutines::call_stub j jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Ljava/lang/reflec t/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;+0 java.base@16 j jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Ljava/lang/Object; [Ljava/lang/Object;)Ljava/lang/Object;+113 java.base@16 j jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Ljava/lang/Obj ect;[Ljava/lang/Object;)Ljava/lang/Object;+6 java.base@16 j java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)L java/lang/Object;+59 java.base@16 j net.kdt.pojavlaunch.Tools.lambda$launchMinecraft$0(Ljava/util/List;Lnet /kdt/pojavlaunch/JMinecraftVersionList$Version;[Ljava/lang/String;)V+71 j net.kdt.pojavlaunch.Tools$$Lambda$69+0x00000003001db880.run()V+12 j java.lang.Thread.run()V+11 java.base@16 v ~StubRoutines::call_stub siginfo: si_signo: 11 (SIGSEGV), si_code: 2 (SEGV_ACCERR), si_addr: 0x000000011fcf8000 --- .../src/main/java/org/lwjgl/glfw/GLFW.java | 7 + .../main/java/org/lwjgl/glfw/GLFWVidMode.java | 21 +- .../java/org/lwjgl/glfw/GLFWVidMode.java.real | 204 ++++++++++++++++++ 3 files changed, 218 insertions(+), 14 deletions(-) create mode 100644 JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java.real diff --git a/JavaApp/src/main/java/org/lwjgl/glfw/GLFW.java b/JavaApp/src/main/java/org/lwjgl/glfw/GLFW.java index 6683dcb6..32c50282 100644 --- a/JavaApp/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/JavaApp/src/main/java/org/lwjgl/glfw/GLFW.java @@ -516,12 +516,19 @@ public class GLFW mGLFWWindowMap = new ArrayMap<>(); mGLFWVideoMode = new GLFWVidMode(ByteBuffer.allocateDirect(GLFWVidMode.SIZEOF)); +/* memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.WIDTH, mGLFWWindowWidth); memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.HEIGHT, mGLFWWindowHeight); memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.REDBITS, 8); memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.GREENBITS, 8); memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.BLUEBITS, 8); memPutInt(mGLFWVideoMode.address() + mGLFWVideoMode.REFRESHRATE, 60); +*/ + + GLFWVidMode.WIDTH = mGLFWWindowWidth; + GLFWVidMode.HEIGHT = mGFLWWindowHeight; + GLFWVidMode.REDBITS = GFLWVidMode.GREENBITS = GLFWVidMode.BLUEBITS = 8; + GLFWVidMode.REFRESHRATE = 60; // A way to generate key code names Field[] thisFieldArr = GLFW.class.getFields(); diff --git a/JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java b/JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java index 5e06259d..9ed61258 100644 --- a/JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java +++ b/JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java @@ -49,7 +49,7 @@ public class GLFWVidMode extends Struct { public static final int ALIGNOF; /** The struct member offsets. */ - public static final int + public static /* final */ int WIDTH, HEIGHT, REDBITS, @@ -69,13 +69,6 @@ public class GLFWVidMode extends Struct { SIZEOF = layout.getSize(); ALIGNOF = layout.getAlignment(); - - WIDTH = layout.offsetof(0); - HEIGHT = layout.offsetof(1); - REDBITS = layout.offsetof(2); - GREENBITS = layout.offsetof(3); - BLUEBITS = layout.offsetof(4); - REFRESHRATE = layout.offsetof(5); } /** @@ -136,17 +129,17 @@ public class GLFWVidMode extends Struct { // ----------------------------------- /** Unsafe version of {@link #width}. */ - public static int nwidth(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.WIDTH); } + public static int nwidth(long struct) { return WIDTH; } /** Unsafe version of {@link #height}. */ - public static int nheight(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.HEIGHT); } + public static int nheight(long struct) { return HEIGHT; } /** Unsafe version of {@link #redBits}. */ - public static int nredBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.REDBITS); } + public static int nredBits(long struct) { return REDBITS; } /** Unsafe version of {@link #greenBits}. */ - public static int ngreenBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.GREENBITS); } + public static int ngreenBits(long struct) { return GREENBITS; } /** Unsafe version of {@link #blueBits}. */ - public static int nblueBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.BLUEBITS); } + public static int nblueBits(long struct) { return BLUEBITS; } /** Unsafe version of {@link #refreshRate}. */ - public static int nrefreshRate(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.REFRESHRATE); } + public static int nrefreshRate(long struct) { return REFRESHRATE; } // ----------------------------------- diff --git a/JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java.real b/JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java.real new file mode 100644 index 00000000..5e06259d --- /dev/null +++ b/JavaApp/src/main/java/org/lwjgl/glfw/GLFWVidMode.java.real @@ -0,0 +1,204 @@ +/* + * Copyright LWJGL. All rights reserved. + * License terms: https://www.lwjgl.org/license + * MACHINE GENERATED FILE, DO NOT EDIT + */ +package org.lwjgl.glfw; + +import javax.annotation.*; + +import java.nio.*; + +import org.lwjgl.system.*; + +import static org.lwjgl.system.MemoryUtil.*; + +/** + * Describes a single video mode. + * + *

Member documentation

+ * + *
    + *
  • {@code width} – the width, in screen coordinates, of the video mode
  • + *
  • {@code height} – the height, in screen coordinates, of the video mode
  • + *
  • {@code redBits} – the bit depth of the red channel of the video mode
  • + *
  • {@code greenBits} – the bit depth of the green channel of the video mode
  • + *
  • {@code blueBits} – the bit depth of the blue channel of the video mode
  • + *
  • {@code refreshRate} – the refresh rate, in Hz, of the video mode
  • + *
+ * + *

Layout

+ * + *

+ * struct GLFWvidmode {
+ *     int width;
+ *     int height;
+ *     int redBits;
+ *     int greenBits;
+ *     int blueBits;
+ *     int refreshRate;
+ * }
+ */ +@NativeType("struct GLFWvidmode") +public class GLFWVidMode extends Struct { + + /** The struct size in bytes. */ + public static final int SIZEOF; + + /** The struct alignment in bytes. */ + public static final int ALIGNOF; + + /** The struct member offsets. */ + public static final int + WIDTH, + HEIGHT, + REDBITS, + GREENBITS, + BLUEBITS, + REFRESHRATE; + + static { + Layout layout = __struct( + __member(4), + __member(4), + __member(4), + __member(4), + __member(4), + __member(4) + ); + + SIZEOF = layout.getSize(); + ALIGNOF = layout.getAlignment(); + + WIDTH = layout.offsetof(0); + HEIGHT = layout.offsetof(1); + REDBITS = layout.offsetof(2); + GREENBITS = layout.offsetof(3); + BLUEBITS = layout.offsetof(4); + REFRESHRATE = layout.offsetof(5); + } + + /** + * Creates a {@code GLFWVidMode} instance at the current position of the specified {@link ByteBuffer} container. Changes to the buffer's content will be + * visible to the struct instance and vice versa. + * + *

The created instance holds a strong reference to the container object.

+ */ + public GLFWVidMode(ByteBuffer container) { + super(memAddress(container), __checkContainer(container, SIZEOF)); + } + + @Override + public int sizeof() { return SIZEOF; } + + /** Returns the value of the {@code width} field. */ + public int width() { return nwidth(address()); } + /** Returns the value of the {@code height} field. */ + public int height() { return nheight(address()); } + /** Returns the value of the {@code redBits} field. */ + public int redBits() { return nredBits(address()); } + /** Returns the value of the {@code greenBits} field. */ + public int greenBits() { return ngreenBits(address()); } + /** Returns the value of the {@code blueBits} field. */ + public int blueBits() { return nblueBits(address()); } + /** Returns the value of the {@code refreshRate} field. */ + public int refreshRate() { return nrefreshRate(address()); } + + // ----------------------------------- + + /** Returns a new {@code GLFWVidMode} instance for the specified memory address. */ + public static GLFWVidMode create(long address) { + return wrap(GLFWVidMode.class, address); + } + + /** Like {@link #create(long) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWVidMode createSafe(long address) { + return address == NULL ? null : wrap(GLFWVidMode.class, address); + } + + /** + * Create a {@link GLFWVidMode.Buffer} instance at the specified memory. + * + * @param address the memory address + * @param capacity the buffer capacity + */ + public static GLFWVidMode.Buffer create(long address, int capacity) { + return wrap(Buffer.class, address, capacity); + } + + /** Like {@link #create(long, int) create}, but returns {@code null} if {@code address} is {@code NULL}. */ + @Nullable + public static GLFWVidMode.Buffer createSafe(long address, int capacity) { + return address == NULL ? null : wrap(Buffer.class, address, capacity); + } + + // ----------------------------------- + + /** Unsafe version of {@link #width}. */ + public static int nwidth(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.WIDTH); } + /** Unsafe version of {@link #height}. */ + public static int nheight(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.HEIGHT); } + /** Unsafe version of {@link #redBits}. */ + public static int nredBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.REDBITS); } + /** Unsafe version of {@link #greenBits}. */ + public static int ngreenBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.GREENBITS); } + /** Unsafe version of {@link #blueBits}. */ + public static int nblueBits(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.BLUEBITS); } + /** Unsafe version of {@link #refreshRate}. */ + public static int nrefreshRate(long struct) { return UNSAFE.getInt(null, struct + GLFWVidMode.REFRESHRATE); } + + // ----------------------------------- + + /** An array of {@link GLFWVidMode} structs. */ + public static class Buffer extends StructBuffer { + + private static final GLFWVidMode ELEMENT_FACTORY = GLFWVidMode.create(-1L); + + /** + * Creates a new {@code GLFWVidMode.Buffer} instance backed by the specified container. + * + * Changes to the container's content will be visible to the struct buffer instance and vice versa. The two buffers' position, limit, and mark values + * will be independent. The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer divided + * by {@link GLFWVidMode#SIZEOF}, and its mark will be undefined. + * + *

The created buffer instance holds a strong reference to the container object.

+ */ + public Buffer(ByteBuffer container) { + super(container, container.remaining() / SIZEOF); + } + + public Buffer(long address, int cap) { + super(address, null, -1, 0, cap, cap); + } + + Buffer(long address, @Nullable ByteBuffer container, int mark, int pos, int lim, int cap) { + super(address, container, mark, pos, lim, cap); + } + + @Override + protected Buffer self() { + return this; + } + + @Override + protected GLFWVidMode getElementFactory() { + return ELEMENT_FACTORY; + } + + /** Returns the value of the {@code width} field. */ + public int width() { return GLFWVidMode.nwidth(address()); } + /** Returns the value of the {@code height} field. */ + public int height() { return GLFWVidMode.nheight(address()); } + /** Returns the value of the {@code redBits} field. */ + public int redBits() { return GLFWVidMode.nredBits(address()); } + /** Returns the value of the {@code greenBits} field. */ + public int greenBits() { return GLFWVidMode.ngreenBits(address()); } + /** Returns the value of the {@code blueBits} field. */ + public int blueBits() { return GLFWVidMode.nblueBits(address()); } + /** Returns the value of the {@code refreshRate} field. */ + public int refreshRate() { return GLFWVidMode.nrefreshRate(address()); } + + } + +} \ No newline at end of file