go-gl / gl

Go bindings for OpenGL (generated via glow)
MIT License
1.08k stars 74 forks source link

v4.1-core/gl: LinkProgram crashes on Linux #123

Closed gmlewis closed 3 years ago

gmlewis commented 4 years ago

I have a valid fragment shader that is causing LinkProgram to crash on Linux. I narrowed it down to the smallest test program I could:

Go program causing crash

```go package main import ( "fmt" "log" "runtime" "strings" "github.com/go-gl/gl/v4.1-core/gl" "github.com/go-gl/glfw/v3.3/glfw" ) func init() { // GLFW event handling must run on the main OS thread runtime.LockOSThread() } func main() { err := glfw.Init() if err != nil { log.Fatalln(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(600, 400, "IRMF Slicer", nil, nil) if err != nil { log.Fatalln(err) } window.MakeContextCurrent() err = gl.Init() if err != nil { log.Fatalln(err) } version := gl.GoStr(gl.GetString(gl.VERSION)) fmt.Println("OpenGL version", version) vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { log.Fatalln(err) } fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { log.Fatalln(err) } program := gl.CreateProgram() gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) // OpenGL crashes on the following line: gl.LinkProgram(program) select {} // wait forever } func compileShader(source string, shaderType uint32) (uint32, error) { shader := gl.CreateShader(shaderType) csources, free := gl.Strs(source) gl.ShaderSource(shader, 1, csources, nil) free() gl.CompileShader(shader) var status int32 gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log)) return 0, fmt.Errorf("failed to compile %v: %v", source, log) } return shader, nil } const vertexShaderSource = ` #version 330 uniform mat4 projection; uniform mat4 camera; uniform mat4 model; in vec3 vert; out vec3 fragVert; void main() { gl_Position = projection * camera * model * vec4(vert, 1); fragVert = vert; } ` + "\x00" const fragmentShaderSource = ` #version 330 precision highp float; precision highp int; in vec3 fragVert; out vec4 outputColor; uniform float u_slice; uniform int u_materialNum; vec2 superquad2(in float slices, in float e1, in float e2, in float a4, in vec3 xyz) { xyz.xyz *= 2.5; vec2 result = (mod(abs(xyz.z) * 6.0, 1.0) <= 0.5) ? vec2(1, 0) : vec2(0, 1); float angle = -1.3; float c = cos(angle); float s = sin(angle); xyz.yz = mat2(c, - s, s, c) * xyz.yz; xyz = abs(xyz); // Due to GLSL 'pow' definition. float f = pow(pow(pow(xyz.x, 2.0 / e2) + pow(xyz.y, 2.0 / e2), e2 / 2.0) - a4, 2.0 / e1) + pow(xyz.z, 2.0 / e1); return f <= 1.0 ? result : vec2(0); } void mainModel4(out vec4 materials, in vec3 xyz) { materials.xy = vec2(0); vec4 e = vec4(0.1, 0.3, 1.0, 3.0); vec4 o = vec4(-3.4, - 1.2, 1.2, 3.4); // Removing the two for loops avoids the SIGSEGV. for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { // Alternatively, replacing superquad2(...) with vec2(0) also avoids the SIGSEGV. materials.xy += superquad2(6.0, e[i], e[j], 1.5, xyz - vec3(o[j], 0, o[3 - i])); } } } void main() { vec4 m; mainModel4(m, vec3(fragVert.xy,u_slice)); outputColor = vec4(m.x); } ` + "\x00" ```

Stack trace of crash

``` go run main.go OpenGL version 4.1.0 NVIDIA 390.116 fatal error: unexpected signal during runtime execution [signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x7f5c3557ea32] runtime stack: runtime.throw(0x5716da, 0x2a) /usr/local/go/src/runtime/panic.go:1114 +0x72 runtime.sigpanic() /usr/local/go/src/runtime/signal_unix.go:679 +0x46a goroutine 1 [syscall, locked to thread]: runtime.cgocall(0x4ed230, 0xc000045ee0, 0xc000000000) /usr/local/go/src/runtime/cgocall.go:133 +0x5b fp=0xc000045eb0 sp=0xc000045e78 pc=0x42757b github.com/go-gl/gl/v4.1-core/gl._Cfunc_glowLinkProgram(0x7f5c766ff5e0, 0x200000003) _cgo_gotypes.go:12370 +0x41 fp=0xc000045ee0 sp=0xc000045eb0 pc=0x4c3191 github.com/go-gl/gl/v4.1-core/gl.LinkProgram(...) /home/glenn/go/src/github.com/go-gl/gl/v4.1-core/gl/package.go:10777 main.main() /home/glenn/src/glfw-bug/main.go:59 +0x3fc fp=0xc000045f88 sp=0xc000045ee0 pc=0x4e89ec runtime.main() /usr/local/go/src/runtime/proc.go:203 +0x212 fp=0xc000045fe0 sp=0xc000045f88 pc=0x4566c2 runtime.goexit() /usr/local/go/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc000045fe8 sp=0xc000045fe0 pc=0x480df1 exit status 2 ```

Note that I found two workarounds for avoiding the crash (which I commented in the code):

I tried using the dlv debugger but couldn't figure out how to debug into the C code.

I also tried using gdb but the results were not much better:

gdb session

``` $ gdb gl-bug GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Registered pretty printers for UE4 classes Reading symbols from gl-bug...done. warning: File "/usr/local/go1.14.1/src/runtime/runtime-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". To enable execution of this file add add-auto-load-safe-path /usr/local/go1.14.1/src/runtime/runtime-gdb.py line to your configuration file "/home/glenn/.gdbinit". To completely disable this security protection add set auto-load safe-path / line to your configuration file "/home/glenn/.gdbinit". For more information about this security protection see the "Auto-loading safe path" section in the GDB manual. E.g., run from the shell: info "(gdb)Auto-loading safe path" (gdb) run Starting program: /home/glenn/src/gl-bug/gl-bug [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7fffcf217700 (LWP 30999)] [New Thread 0x7fffcea16700 (LWP 31000)] [New Thread 0x7fffce215700 (LWP 31001)] [New Thread 0x7fffcda14700 (LWP 31002)] [New Thread 0x7fffcd213700 (LWP 31003)] [New Thread 0x7fffcca12700 (LWP 31004)] OpenGL version 4.1.0 NVIDIA 390.116 Thread 1 "gl-bug" received signal SIGSEGV, Segmentation fault. 0x00007fffb4d4ba32 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 (gdb) where #0 0x00007fffb4d4ba32 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #1 0x00007fffb4d4babd in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #2 0x00007fffb4d4d073 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #3 0x00007fffb4d4df22 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #4 0x00007fffb4d538a4 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #5 0x00007fffb4d54110 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #6 0x00007fffb5885750 in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #7 0x00007fffb589788b in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #8 0x00007fffb589a46a in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #9 0x00007fffb586260c in ?? () from /usr/lib/x86_64-linux-gnu/libnvidia-glcore.so.390.116 #10 0x0000000000480530 in runtime.asmcgocall () at /usr/local/go/src/runtime/asm_amd64.s:655 #11 0x00000000008b0488 in runtime.memstats () #12 0x00007ffff7e2fb10 in ?? () #13 0x0000000000000001 in ?? () #14 0x000000c00002a000 in ?? () #15 0x000000c000000180 in ?? () #16 0x0000000000000190 in ?? () #17 0x000000c000000180 in ?? () #18 0x000000000047ed56 in runtime.systemstack () at /usr/local/go/src/runtime/asm_amd64.s:370 #19 0x0000000000458e50 in ?? () at :1 #20 0x000000000047ebe4 in runtime.rt0_go () at /usr/local/go/src/runtime/asm_amd64.s:220 #21 0x00000000005087f0 in crosscall_amd64 () #22 0x000000000047ebeb in runtime.rt0_go () at /usr/local/go/src/runtime/asm_amd64.s:225 #23 0x0000000000000001 in ?? () #24 0x00007fffffffda08 in ?? () #25 0x0000000000000001 in ?? () #26 0x00007fffffffda08 in ?? () #27 0x0000000000000000 in ?? () (gdb) q A debugging session is active. Inferior 1 [process 30995] will be killed. Quit anyway? (y or n) y ```

From this, it actually looks like the problem might be in the NVIDIA driver library... in which case, feel free to close this bug.

dertseha commented 3 years ago

Hello @gmlewis - were you able to cross test this with a different driver or version of the libraries?

gmlewis commented 3 years ago

Thanks for the reminder, @dertseha .

I just tried it again using an updated driver, and it works fine:

$ go run main.go
OpenGL version 4.1.0 NVIDIA 450.119.03

Closing as obsolete.