Repository navigation
panics within a Begin()->End() clause are partially suppressed #24
Description
Issue
When running imgui code, anything that would cause a panic (e.g. indexing too high in a slice) will correctly cause the program to crash, but the real error message gets suppressed in favor of one from imgui.
A normal message after a panic looks like:
$ go run .
panic: runtime error: index out of range [1] with length 0
goroutine 44 [running]:
main.(*G).Update(0xc000079d30?)
/home/omustardo/go/src/github.com/omustardo/idle/experimentation/crash_demo/main.go:49 +0xa8
github.com/hajimehoshi/ebiten/v2.(*gameForUI).Update(0xc0000c22a0)
/home/omustardo/go/pkg/mod/github.com/hajimehoshi/ebiten/v2@v2.7.8/gameforui.go:142 +0x23
github.com/hajimehoshi/ebiten/v2/internal/ui.(*context).updateFrameImpl(0xc000216b00, {0xd586d8, 0xc0001c1200}, 0x1, 0x407f400000000000, 0x407f400000000000, 0x3ff0000000000000, 0xc0003c3348, 0x0)
/home/omustardo/go/pkg/mod/github.com/hajimehoshi/ebiten/v2@v2.7.8/internal/ui/context.go:148 +0x2be
github.com/hajimehoshi/ebiten/v2/internal/ui.(*context).updateFrame(0xc000216b00, {0xd586d8, 0xc0001c1200}, 0x407f400000000000, 0x407f400000000000, 0x3ff0000000000000, 0xc0003c3348)
/home/omustardo/go/pkg/mod/github.com/hajimehoshi/ebiten/v2@v2.7.8/internal/ui/context.go:73 +0x76
github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).updateGame(0xc0003c3348)
/home/omustardo/go/pkg/mod/github.com/hajimehoshi/ebiten/v2@v2.7.8/internal/ui/ui_glfw.go:1452 +0x1a5
github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).loopGame(0xc0003c3348)
/home/omustardo/go/pkg/mod/github.com/hajimehoshi/ebiten/v2@v2.7.8/internal/ui/ui_glfw.go:1409 +0x97
github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).runMultiThread.func2()
/home/omustardo/go/pkg/mod/github.com/hajimehoshi/ebiten/v2@v2.7.8/internal/ui/run.go:67 +0x37
golang.org/x/sync/errgroup.(*Group).Go.func1()
/home/omustardo/go/pkg/mod/golang.org/x/sync@v0.7.0/errgroup/errgroup.go:78 +0x56
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 1
/home/omustardo/go/pkg/mod/golang.org/x/sync@v0.7.0/errgroup/errgroup.go:75 +0x96
exit status 2
Using the example code below, this is what results if the panic is in the scope of certain imgui calls:
$ go run .
File: /home/runner/work/cimgui-go/cimgui-go/cimgui/imgui/imgui.cpp, Line: 9932
exit status 1
If you go to the suggested line, the error message is: "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?", which is misleading at best.
Demo
This is easily reproducible with: https://gist.github.com/Omustardo/6f7446d958e9005357b631eaba995305
I didn't test too thoroughly, but it definitely occurs when there's a panic between a call to imgui.Begin() and imgui.End(). Ideally imgui wouldn't affect panics in code outside of its scope.
Relevant bits:
func (g *G) Update() error {
ebimgui.Update(1.0 / 60.0)
ebimgui.BeginFrame()
defer ebimgui.EndFrame()
// _ = []int{}[1] // uncommenting causes a panic in a goroutine
imgui.BeginV("Window", nil, 0)
//_ = []int{}[1] // uncommenting causes a crash in imgui.cpp, Line: 9932
imgui.Text("Hello World!")
//_ = []int{}[1] // uncommenting causes a crash in imgui.cpp, Line: 9932
imgui.End()
// _ = []int{}[1] // uncommenting causes a panic in a goroutine
return nil
Activity
Omustardo commentedon Sep 4, 2024
I noticed that my example goroutine stack included
github.com/hajimehoshi/ebiten/v2/internal/ui.(*UserInterface).runMultiThread.func2(). I suspected this multi-threading option (implemented here) could be the cause.I adjusted my example code to be single threaded using ebiten.RunGameOptions, but it didn't have any noticeable effect.
I looked through Ebiten for calls to
recover()but only found one within Mobile UI rendering, so it's probably not related since this reproduces on my linux desktop. https://github.com/search?q=repo%3Ahajimehoshi%2Febiten+recover%28%29&type=codeThe only call to
recover()in cimgui-go also doesn't obviously seem related because I don't think it's called fromBegin().https://github.com/search?q=repo%3Agabstv%2Fcimgui-go%20recover()&type=code
Now I'm wondering if I'm mis-interpreting the error somehow. It being recovered only within the span of calls to
imgui.Begindoesn't really make sense, because panics should propagate up the call stack, and a parent having a deferred call torecover()shouldn't change depending on callingimgui.Begin(). Also if this were the case I'd expect to have found the call torecover().Maybe there's something special about cgo and it just interacts oddly with panics?
Omustardo commentedon Sep 5, 2024
I tested a bit more. I wanted to try reproducing this in the underlying cimgui library. This could narrow down where the issue is occurring. The example in the prior comment uses https://github.com/gabstv/ebiten-imgui/
gabstv/cimgui-go
http://github.com/gabstv/cimgui-go is used by http://github.com/gabstv/ebiten-imgui/. It's the first step down the dependency tree.
I wasn't able to get a demo working. The example code doesn't compile, and it's not clear how to get parameters for
imgui.CreateBackend. https://github.com/gabstv/cimgui-go/blob/68bd718f94cc1a3811bd4c364a5d90b60b674d07/examples/main.go#L123I dug through the
ebiten-imguicode a bit but it doesn't callCreateBackendeither, so my guess is the demo is just very out of date.AllenDang/cimgui-go
http://github.com/gabstv/cimgui-go is a fork of https://github.com/AllenDang/cimgui-go. The AllenDang repo is not a dependency of
ebiten-imgui, but reproducing the issue there would still be helpful to figure out what's going on.I was able to get a demo running easily: https://gist.github.com/Omustardo/cfcaf9c7f87c0f456a21f80188ab6bb7
but it didn't reproduce the suppressed panic messages.
Summary
The issue not reproducing in AllenDang's repo means that it has either already been fixed there, or it's an issue that's new to either
gabstv/cimgui-goorgabstv/ebiten-imgui.Omustardo commentedon Sep 5, 2024
To continue narrowing down the cause, I wanted to know if the issue existed in
AllenDang/cimgui-goin the past.I compared the two repos and selected the first commit from AllenDang that isn't in gabstv's repo.
gabstv/cimgui-go@main...AllenDang:cimgui-go:main
I then downgraded my local instance of that code with:
I had to slightly modify the demo code because
imgui.CreateBackenddidn't return an error: https://gist.github.com/Omustardo/e87dbdd0182b3ca9ec7b05821582f793Running the demo again didn't reproduce the suppressed messages, so at this point I'm pretty sure the issue is in either
gabstv/cimgui-goorgabstv/ebiten-imgui.gucio321 commentedon Sep 6, 2024
gucio321 commentedon Sep 6, 2024
Oh I see
I think that this repos upstream cimgui-go is outdated a bit
Omustardo commentedon Sep 6, 2024
Thanks, that makes sense and thank you for your work on imgui.
I don't think it's worth pulling in the upstream changes just to resolve this minor (but annoying) issue. Hopefully it'll happen someday.
In the meantime I'll use https://github.com/AllenDang/cimgui-go as I don't actually need all of the features that come with Ebiten.
gucio321 commentedon Sep 7, 2024
Btw im going to make this one of cimgui-go backends https://github.com/gucio321/cimgui-go/tree/ebiten-cimgui