Skip to content

panics within a Begin()->End() clause are partially suppressed #24

Open

Description

@Omustardo

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

  1. Omustardo commented on Sep 4, 2024

    @Omustardo
    Author

    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.

    	opts := &ebiten.RunGameOptions{
    		SingleThread: true,
    	}
    	if err := ebiten.RunGameWithOptions(game.NewGame(settings, state), opts); err != nil {
    		glog.Infof("%v", err)
    	}
    

    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=code


    The only call to recover() in cimgui-go also doesn't obviously seem related because I don't think it's called from Begin().
    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.Begin doesn't really make sense, because panics should propagate up the call stack, and a parent having a deferred call to recover() shouldn't change depending on calling imgui.Begin(). Also if this were the case I'd expect to have found the call to recover().

    Maybe there's something special about cgo and it just interacts oddly with panics?

  2. Omustardo commented on Sep 5, 2024

    @Omustardo
    Author

    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#L123

    I dug through the ebiten-imgui code a bit but it doesn't call CreateBackend either, 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-go or gabstv/ebiten-imgui.

  3. Omustardo commented on Sep 5, 2024

    @Omustardo
    Author

    To continue narrowing down the cause, I wanted to know if the issue existed in AllenDang/cimgui-go in 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:

    $ go get -u github.com/AllenDang/cimgui-go@be475901c1522924a8acaa52a847a3c259f8b119
    go: downloading github.com/AllenDang/cimgui-go v0.0.0-20231121075724-be475901c152
    go: downgraded github.com/AllenDang/cimgui-go v0.0.0-20240806122035-9ebf619d1d03 => v0.0.0-20231121075724-be475901c152
    

    I had to slightly modify the demo code because imgui.CreateBackend didn't return an error: https://gist.github.com/Omustardo/e87dbdd0182b3ca9ec7b05821582f793

    Running the demo again didn't reproduce the suppressed messages, so at this point I'm pretty sure the issue is in either gabstv/cimgui-go or gabstv/ebiten-imgui.

  4. gucio321 commented on Sep 6, 2024

    @gucio321
  5. gucio321 commented on Sep 6, 2024

    @gucio321

    Oh I see

    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-go or gabstv/ebiten-imgui.

    I think that this repos upstream cimgui-go is outdated a bit

  6. Omustardo commented on Sep 6, 2024

    @Omustardo
    Author

    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.

  7. gucio321 commented on Sep 7, 2024

    @gucio321

    Btw im going to make this one of cimgui-go backends https://github.com/gucio321/cimgui-go/tree/ebiten-cimgui

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions