当前位置: 首页 > 知识库问答 >
问题:

使用stbi_load时EXCEPTION_ACCESS_VIOLATION错误

有翰海
2023-03-14

我尝试使用<code>stbi_load</code>将图像加载到字节缓冲区。但是,控制台中会出现以下错误

Java运行时环境检测到致命错误:EXCEPTION_ACCESS_VIOLATION(0xc0000005)at pc=0x00007ffb5bb63b8c, pid=5424, tid=0x0000000000001364 JRE版本:OpenJDK运行时环境(8.0_312-b07)(build 1.8.0_312-b07)JavaVM:OpenJDK 64-Bit Server VM(25.312-b07混合模式windows-amd64压缩oops)问题框架:C[lwjgl_stb.dll0x3b8c]无法写入核心转储。Windows的客户端版本默认未启用Minidumps包含更多信息的错误报告文件保存为:C:\User\nottn\eclipse-workspace\Bon Sea\hs_err_pid5424.log如果您想提交错误报告,请访问:https://bugzilla.redhat.com/enter_bug.cgi崩溃发生在Java虚拟机之外的本机代码中。有关报告错误的位置,请参阅问题框架。

下面是产生此错误的代码(请记住,我在th之前使用的是LWJGL 3)

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.stb.STBImage.*;

import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.awt.image.BufferedImage;

public class Texture {
    private int id;
    private IntBuffer width, height, n;
    
    public Texture(String filename) 
    {
        BufferedImage bi;
        
        try 
        {
            bi = ImageIO.read(new File("./sprites/" + filename));
            
            width = IntBuffer.allocate(bi.getWidth());
            width.put(bi.getWidth());
            
            height = IntBuffer.allocate(bi.getHeight());
            height.put(bi.getHeight());
            
            n = IntBuffer.allocate(GL_RGBA);
            n.put(GL_RGBA);
            
            ByteBuffer data = stbi_load("/Users/nottn/eclipse-workspace/Bon Sea/sprites/test.png", width, height, n, STBI_rgb_alpha);
            
            id = glGenTextures();
            glBindTexture(GL_TEXTURE_2D, id);
            
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width.array()[0], height.array()[0], 0, GL_RGBA, GL_BYTE, data);
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
    
    public void Bind() {
        glBindTexture(GL_TEXTURE_2D, id);
    }
}

这是生成Pastebin.log的日志文件

对于为什么会出现这种错误的任何答案都非常感谢。

共有2个答案

江渊
2023-03-14

如果这是你问题的解决者,那就不行了,但是当我不小心移动类似的代码来执行之前行“GL.createCapabilities();”时,我遇到了这个错误。

慕俊语
2023-03-14

崩溃的原因是您使用的是由Java数组支持的非直接NIO缓冲区,即IntBuffer.allocate(...)而不是ByteBuffer.allocateDirect(...)。asIntBuffer(),由堆外(本机)虚拟内存支持。

LWJGL基本上只是将stbi_load(…)调用转发/引导到本机库。为了使本机库能够将内存放在提供的内存区域中,该区域必须是进程虚拟内存的实际“堆外”(如:它在Java垃圾收集堆之外)内存区域。

当您调用任何LWJGL提供的使用NIO缓冲区的方法(如<code>stbi_load(…)</code>)时,LWJML将做的是读取(隐藏的)<code>缓冲区的值。地址字段,仅当所述缓冲区是直接(或“堆外”)缓冲区时才填充。

对于由Java原语数组支持的非直接或(堆上)缓冲区,该字段为< code>0,因此本机库将访问零地址,这最终会导致崩溃。

为了解决这个问题,您应该只创建直接NIO缓冲区。

有关非直接与直接NIO缓冲区的解释,请参阅ByteBuffer类的JavaDocs。

我还强烈推荐阅读这篇LWJGL 3博客文章,它提供了关于LWJGL3中本机内存管理的更多见解和策略。

 类似资料:
  • 我使用lwjgl的<code>stb_image 我的纹理的位置: 我当然是这样尝试的: 同样的结果是,它没有加载。我做错了什么?

  • 我在用Java 8和LWJGL,用GLFW和OpenGL做一个游戏引擎。我有一个通用的IndexedVAO类,里面有我所有的VAO代码,以简化事情。以下是相关部分: 构造函数 上传功能 绘图功能 该代码在linux上运行良好,但今天我在windows机器上尝试了它,结果出现了EXCEPTION_ACCESS_VIOLATION jvm崩溃。当我检查JVM崩溃时生成的hs_err_pid####文件

  • 问题内容: 今天在工作中,我的日食开始反复崩溃。只需打开它并开始编辑文件,几分钟后即可崩溃。我重新安装了所有内容:Eclipse,Workspace,Java,但没有任何帮助。由于我目前无法工作,请尝试确定问题的根源。 (…) 问题答案: 这是C2编译器中的一个已知JVM错误:JDK-8154831。 尝试添加以下JVM参数:

  • 今天在工作中,我的eclipse开始反复崩溃。打开它并开始编辑文件几分钟后就会崩溃。我重新安装了所有东西:Eclipse、WorkspaceJava但没有任何帮助。请尝试确定我的问题的根源,因为我目前无法工作。 (…)

  • 我有问题。这是我使用ldap进行身份验证的代码 在Spring,但它有一个错误,告诉我AcceptSecurityContext。 javax.naming.身份验证异常:[LDAP:错误代码49 - 80090308:LdapErr:DSD-0C090400,注释:AcceptSecurityContext错误,数据52e,v1db1] 请帮帮我

  • 问题内容: 当Java VM因EXCEPTION_ACCESS_VIOLATION崩溃并生成hs_err_pidXXX.log文件时,这表明什么?错误本身基本上是空指针异常。它是否总是由JVM中的错误引起,还是有其他原因(如硬件故障或软件冲突)? 编辑:有一个本机组件,这是win32上的SWT应用程序。 问题答案: 在大多数情况下,这是VM中的错误。但这可能是由任何本机代码(例如JNI调用)引起的