veandco / go-sdl2

SDL2 binding for Go
https://godoc.org/github.com/veandco/go-sdl2
BSD 3-Clause "New" or "Revised" License
2.21k stars 221 forks source link

Panic on surface.FillRect(nil,0) #418

Closed husio closed 3 years ago

husio commented 5 years ago

When running the below example, surface.FillRect(nil, 0) occasionally panics with

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x7f61ad1d544e]

runtime stack:
runtime.throw(0x4d1074, 0x2a)
        /usr/lib/go/src/runtime/panic.go:617 +0x72
runtime.sigpanic()
        /usr/lib/go/src/runtime/signal_unix.go:374 +0x4a9

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x492600, 0xc0000326d0, 0xc00008a050)
        /usr/lib/go/src/runtime/cgocall.go:128 +0x5b fp=0xc0000326a0 sp=0xc000032668 pc=0x415e1b
github.com/veandco/go-sdl2/sdl._Cfunc_SDL_FillRect(0x997fa0, 0x0, 0x0, 0x0)
        _cgo_gotypes.go:2863 +0x4d fp=0xc0000326d0 sp=0xc0000326a0 pc=0x489f5d
github.com/veandco/go-sdl2/sdl.(*Surface).FillRect.func1(0x997fa0, 0x0, 0x0, 0xc000032740)
        /home/piotr/go/src/github.com/veandco/go-sdl2/sdl/surface.go:411 +0x6a fp=0xc000032708 sp=0xc0000326d0 pc=0x48b9fa
github.com/veandco/go-sdl2/sdl.(*Surface).FillRect(0x997fa0, 0x0, 0x0, 0xb74640, 0x0)
        /home/piotr/go/src/github.com/veandco/go-sdl2/sdl/surface.go:411 +0x3d fp=0xc000032738 sp=0xc000032708 pc=0x48b56d
main.main()
        /tmp/example.go:32 +0x1b4 fp=0xc000032798 sp=0xc000032738 pc=0x48dce4
runtime.main()
        /usr/lib/go/src/runtime/proc.go:200 +0x20c fp=0xc0000327e0 sp=0xc000032798 pc=0x43d18c
runtime.goexit()
        /usr/lib/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000327e8 sp=0xc0000327e0 pc=0x464bd1
exit status 2

go1.12.7 linux/amd64 github.com/veandco/go-sdl2 v0.3.1-0.20190809154531-da65661eff7f gcc (GCC) 9.1.0 SDL source-revision: SDL2:d3df61d8af architecture: x86_64-musl

package main

import (
        "os"

        "github.com/veandco/go-sdl2/sdl"
)

func main() {
        if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
                panic(err)
        }
        defer sdl.Quit()

        window, err := sdl.CreateWindow(os.Args[0], sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 20, 20, sdl.WINDOW_SHOWN)
        if err != nil {
                panic(err)
        }
        defer window.Destroy()

        surface, err := window.GetSurface()
        if err != nil {
                panic(err)
        }

        renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
        if err != nil {
                panic(err)
        }
        defer renderer.Destroy()

        surface.FillRect(nil, 0) // Panic
        window.UpdateSurface()
}
veeableful commented 5 years ago

Hi @husio, while I don't know why it segfaults exactly, I believe the issue is related to the mixing of software and hardware rendering.

If you want to use SDL_Surface (software) for rendering, you can omit sdl.Renderer. If you want to use SDL_Renderer (hardware), you can set sdl.WINDOW_OPENGL in sdl.CreateWindow() and use renderer.FillRect() for rendering instead.

husio commented 5 years ago

I do not fully understand what was the issue with the code. What @veeableful wrote seem to help. Would it be helpful to add the information about not using sdl.Render with software rendering to the documentation?

kroppt commented 4 years ago

In the SDL2 documentation, window.GetSurface is documented here: https://wiki.libsdl.org/SDL_GetWindowSurface. It notes, "You may not combine this with 3D or the rendering API on this window." The bottom of that page indicates it is in the Video API category. So if we look at the API categories and select 2D Accelerated Rendering, we get the page https://wiki.libsdl.org/CategoryRender. This page contains the API for sdl.CreateRenderer here: https://wiki.libsdl.org/SDL_CreateRenderer. Thus, using SDL_GetWindowSurface and SDL_CreateRenderer together is prohibited, or at least causes undefined behavior.

If you want a surface with the current properties of your window, you can try https://wiki.libsdl.org/SDL_CreateRGBSurfaceWithFormat with https://wiki.libsdl.org/SDL_GetWindowPixelFormat as the format and https://wiki.libsdl.org/SDL_GetWindowSize as the size.

husio commented 3 years ago

I have reported this issue so long ago that I no longer remember any details. I think it can be closed, although I really cannot tell if the root cause was solved (or valid).

veeableful commented 3 years ago

Thanks, @husio. I will close it for now but feel free to comment here again if the same issue comes up!