【问题标题】:OpenGL's glClear() causes Access Violation (0xc0000005) in Windows 64 [closed]OpenGL 的 glClear() 导致 Windows 64 中的访问冲突 (0xc0000005) [关闭]
【发布时间】:2012-05-10 17:44:45
【问题描述】:

看看这个用 Go 编写的超级简单的小测试用例 OpenGL 程序:

package main

import (
    "runtime"
    "./glfw"
    gl "github.com/chsc/gogl/gl21"
)

func onExit (err error) {
    glfw.Terminate()
    if err != nil { panic(err) }
}

func main () {
    runtime.LockOSThread()
    err := glfw.Init()
    if err != nil { panic(err) }
    err = glfw.OpenWindow(1280, 720, 0, 0, 0, 0, 0, 0, glfw.Windowed)
    if err != nil { onExit(err) }
    err = gl.Init()
    if err != nil || gl.GetError() != 0 { onExit(err) }
    for glfw.WindowParam(glfw.Opened) == 1 {
        gl.Viewport(0, 0, 1280, 720)
        gl.ClearColor(1, 0, 0, 1)
        gl.Clear(gl.COLOR_BUFFER_BIT) // THE CRASH
        gl.Begin(gl.TRIANGLES)
        gl.Color3f(1, 0, 0)
        gl.Vertex3f(-1, -1, 0)
        gl.Color3f(0, 1, 0)
        gl.Vertex3f(0, 1, 0)
        gl.Color3f(0, 0, 1)
        gl.Vertex3f(1, -1, 0)
        gl.End()
        glfw.SwapBuffers()
        if glfw.Key(glfw.KeyEsc) == 1 {
            glfw.CloseWindow()
        }
    }
    onExit(nil)
}

这在 Windows 7 64 位和 Go 1.0.1 64 位下构建良好。

它也工作正常(OpenGL 绘制一个彩虹色的 2D 三角形,直到窗口关闭)如果你取出(或注释掉)gl.Clear(gl.COLOR_BUFFER_BIT) 行。

一旦调用 gl.Clear(无论传递什么参数),它就会崩溃,Windows 通知我“glfw-win.exe 已停止工作...”并且 Windows 事件查看器出现以下错误为我登录:

Faulting application name: glfw-win.exe, version: 0.0.0.0, time stamp: 0x4f9f5ec5
Faulting module name: glfw-win.exe, version: 0.0.0.0, time stamp: 0x4f9f5ec5
Exception code: 0xc0000005
Fault offset: 0x0000000000012883
Faulting process id: 0xd4c
Faulting application start time: 0x01cd274e4c69a3d3
Faulting application path: C:\mytmp\glfw-win\glfw-win.exe
Faulting module path: C:\mytmp\glfw-win\glfw-win.exe
Report Id: 8a5bacc0-9341-11e1-911a-d067e544ad7f

现在,有几点值得注意...

  1. glfw 包只是一个自定义包,它公开与 github.com/jteeuwen/glfw 完全相同的 API,但在内部使用 LoadLibrary/GetProcAddress 来使用 glfw.dll 而不是编译时CGO/GCC/LD 链接——因为后者不能在 64 位 Windows 中工作,很遗憾,不确定是 mingw64 还是 gcc 或 cgo 是罪魁祸首。使用 LoadLibrary/GetProcAddress 调用我的 glfw.dll 的自定义 64 位版本运行良好。显然这里的问题是调用 gl 包,而不是 glfw。

  2. gl 包确实只是 this one,未经修改。我尝试了一些 LDFLAGS 修改,例如 -m64 -lmingw32 -Wl,/windows/opengl32.dll 等,但没有区别,只要不调用 gl.Clear(),原始工作与修改后的工作一样好,所以我恢复到原来的。当然,稍后我会继续使用 OpenGL 4.2。

  3. 使用 Process Explorer,我可以看到我的进程是 64 位的,并且所有加载的 DLL 也是 64 位图像(包括 opengl32.dll 和 glfw.dll)。

  4. “难道是gl21包无法为opengl32.dll导出的glClear()函数获取有效地址?” -- 不太可能:根据line 2926,如果是这种情况,我对 gl.Init() 的调用将失败。

  5. GPU 驱动程序问题?更不可能了。安装了最新的官方 nVidia Quadro 5010M 驱动程序 296.35。还尝试了“性能驱动程序”,但无论如何似乎是完全相同的驱动程序。根据 nVidia 控制面板,完全支持 OpenGL 4.2(尽管 opengl32.dll 的日期为 2009 年——无论如何,我目前的目标是 2.1)。此外,“Geeks3D GPU Caps Viewer”和“Shader Toy Mark”中的 OpenGL 着色器运行,正如 GLFW 示例程序particles.exe 一样——它们都使用 glClear()。

  6. 使用 gl42 而不是 gl21 时会出现完全相同的问题,所以这也不是原因。

请注意所有其他 gl.SomeExportedFunc() 调用在此示例中不会崩溃...

做什么,如何进行?

如果这种情况只发生在 gl.Clear() 而没有其他函数,我可以忍受——无论如何,我只是用自定义内容渲染全屏四边形——但我在测试 Win64 方面相当早这里(有很多 gl42 代码在 Linux64 下工作得很好,现在即将“移植”到 Win64),我担心以后进一步的调用会暴露同样的问题,所以我现在报告这个。我很快就会知道还有哪些其他电话会受此影响。

【问题讨论】:

    标签: opengl 64-bit go mingw-w64 cgo


    【解决方案1】:

    没有 CGO 生成的存根就不能调用 C 函数。

    【讨论】:

    • 感谢您的想法...但我认为这在这里并不适用:注意我可以调用 gl.Viewport()、gl.Begin() 等.pp...所以,当然,在 \Go\pkg\windows_amd64\github.com\chsc\gogl 下有一个适当的 gl21.a 库,完全通过“go build”构建,因此隐式 CGO,否则全部其他 gl 调用根本不可能。只有 gl.Clear() 给出了访问冲突(到目前为止),到目前为止我测试过的其他 gl21.a 函数没有。
    • 跨越 Go/C 边界需要在新线程中设置和非拆分堆栈。即使它在一些简单的情况下可能会意外工作,但并不能消除一般情况下的要求。
    • 不确定我明白了——等等……这是否意味着 GitHub 等上 95% 的现成互操作包(基于 CGO 构建)基本上没用? launchpad.net/mgo ... github.com/jteeuwen/glfw ... github.com/chsc/gogl ... 许多其他人,在过去 3 个月在 Linux 下对我来说都可以顺利运行,没有任何问题,并且对于无数人来说其他 Go 开发人员。如果支持,99% 的情况下也在 Win32 下,甚至在大部分情况下在 Win64 下 [除了 cough gl.Clear() ]。如果是这样,为什么没有在任何地方解释“设置和非拆分堆栈”?....
    • 为什么在新线程中?注意我没有使用 goroutines 和 runtime.LockOSThread() 强制所有 main() 始终停留在第一次调用 main() 的单个线程中。
    • 那些包使用 CGo,我说的是你的情况,它没有。而你正在使用 goroutine,甚至 main() 一个 goroutine。
    【解决方案2】:

    Go、GLFW 和 Mingw-w64 的最新版本不再是问题。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 2012-05-22
      • 1970-01-01
      • 2016-07-12
      • 2014-05-07
      • 1970-01-01
      • 2017-08-31
      • 2010-11-05
      • 1970-01-01
      相关资源
      最近更新 更多