inkyblackness / imgui-go

Go wrapper library for "Dear ImGui" (https://github.com/ocornut/imgui)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exception 0xc0000005 - unknown pc

kylhuk opened this issue · comments

Hey there,

I seem to have an issue with imgui-go and I can't really figure it out where it is. Trying to run the following code:

Main.go //added this function to your Main.go

func Main() {
	Begin("Hello World")
	if BeginMenuBar() {
		if BeginMenu("Menu") {
			EndMenu()
		}
		if BeginMenu("Examples") {
			EndMenu()
		}
		if BeginMenu("Tools") {
			EndMenu()
		}

		EndMenuBar()
	}

	Text(fmt.Sprintf("dear imgui says hello. (%s)", Version()))
}

Main_test.go

func TestVersion(t *testing.T) {
	imgui.Main()
	assert.Equal(t, true, true)
}

I get this following exception:

=== RUN   TestVersion
Exception 0xc0000005 0x0 0x1a14 0xaa8427
PC=0xaa8427

runtime: unknown pc 0xaa8427
stack: frame={sp:0xf9ffbff3d0, fp:0x0} stack=[0x0,0xf9ffbff710)

000000f9ffbff2d0:  00000048ece34201  00000000009a7f9e <testing.tRunner+30> 
000000f9ffbff2e0:  00000265ed1a0000  00000265ed1a7f58 
000000f9ffbff2f0:  0000000000000001  ffffffffffbff4a8 
000000f9ffbff300:  00000000009a7d00 <testing.(*common).runCleanup+224>  0000000000000005 
000000f9ffbff310:  000000c00000ac00  00000265ed1a7f60 
000000f9ffbff320:  0000000000000000  0000000000000001 
000000f9ffbff330:  00000265ed1a7f50  0000000000af3780 
000000f9ffbff340:  0000000000000000  00000000009a7fc7 <testing.tRunner+71> 
000000f9ffbff350:  00000265ed1a0150  0000000000c5a401 
000000f9ffbff360:  0000000000000005  0000000000000080 
000000f9ffbff370:  00000265ed1a7f50  000000f9ffbff488 
000000f9ffbff380:  0000000000000005  00000000009218a1 <runtime.goexit+1> 
000000f9ffbff390:  0000000000af3780  000000f9ffbff668 
000000f9ffbff3a0:  0000000000910b2f <runtime.gentraceback+3791>  0000000000000002 
000000f9ffbff3b0:  00000265ed1a1360  0000000000000005 
000000f9ffbff3c0:  0000000000000000  00000265ed1a0150 
000000f9ffbff3d0: <00000000ffffffff  0000000000000007 
000000f9ffbff3e0:  0000000000000000  0000000000000001 
000000f9ffbff3f0:  00000000009a7fc6 <testing.tRunner+70>  0000000000000005 
000000f9ffbff400:  00000000009a7fc7 <testing.tRunner+71>  0000000000000000 
000000f9ffbff410:  0000d251fff946d6  0000000000000000 
000000f9ffbff420:  0000000000000000  000000c000073fc8 
000000f9ffbff430:  000000c00000acf0  0000000000000020 
000000f9ffbff440:  0000000000000000  0000000000000000 
000000f9ffbff450:  000002652e00002e  00000265ed1a2914 
000000f9ffbff460:  0000000000000000  00007ffeb50001b4 
000000f9ffbff470:  0000000000030000  0000000007000007 
000000f9ffbff480:  00000265ece14e50  00000000009a7fc7 <testing.tRunner+71> 
000000f9ffbff490:  000000480008fb38  000000002e00002e 
000000f9ffbff4a0:  0000000000000000  00000000b50001b4 
000000f9ffbff4b0:  0000000000000000  000000002e00002e 
000000f9ffbff4c0:  000001180008fa23  0000000000000000 
runtime: unknown pc 0xaa8427
stack: frame={sp:0xf9ffbff3d0, fp:0x0} stack=[0x0,0xf9ffbff710)

000000f9ffbff2d0:  00000048ece34201  00000000009a7f9e <testing.tRunner+30> 
000000f9ffbff2e0:  00000265ed1a0000  00000265ed1a7f58 
000000f9ffbff2f0:  0000000000000001  ffffffffffbff4a8 
000000f9ffbff300:  00000000009a7d00 <testing.(*common).runCleanup+224>  0000000000000005 
000000f9ffbff310:  000000c00000ac00  00000265ed1a7f60 
000000f9ffbff320:  0000000000000000  0000000000000001 
000000f9ffbff330:  00000265ed1a7f50  0000000000af3780 
000000f9ffbff340:  0000000000000000  00000000009a7fc7 <testing.tRunner+71> 
000000f9ffbff350:  00000265ed1a0150  0000000000c5a401 
000000f9ffbff360:  0000000000000005  0000000000000080 
000000f9ffbff370:  00000265ed1a7f50  000000f9ffbff488 
000000f9ffbff380:  0000000000000005  00000000009218a1 <runtime.goexit+1> 
000000f9ffbff390:  0000000000af3780  000000f9ffbff668 
000000f9ffbff3a0:  0000000000910b2f <runtime.gentraceback+3791>  0000000000000002 
000000f9ffbff3b0:  00000265ed1a1360  0000000000000005 
000000f9ffbff3c0:  0000000000000000  00000265ed1a0150 
000000f9ffbff3d0: <00000000ffffffff  0000000000000007 
000000f9ffbff3e0:  0000000000000000  0000000000000001 
000000f9ffbff3f0:  00000000009a7fc6 <testing.tRunner+70>  0000000000000005 
000000f9ffbff400:  00000000009a7fc7 <testing.tRunner+71>  0000000000000000 
000000f9ffbff410:  0000d251fff946d6  0000000000000000 
000000f9ffbff420:  0000000000000000  000000c000073fc8 
000000f9ffbff430:  000000c00000acf0  0000000000000020 
000000f9ffbff440:  0000000000000000  0000000000000000 
000000f9ffbff450:  000002652e00002e  00000265ed1a2914 
000000f9ffbff460:  0000000000000000  00007ffeb50001b4 
000000f9ffbff470:  0000000000030000  0000000007000007 
000000f9ffbff480:  00000265ece14e50  00000000009a7fc7 <testing.tRunner+71> 
000000f9ffbff490:  000000480008fb38  000000002e00002e 
000000f9ffbff4a0:  0000000000000000  00000000b50001b4 
000000f9ffbff4b0:  0000000000000000  000000002e00002e 
000000f9ffbff4c0:  000001180008fa23  0000000000000000 

goroutine 6 [syscall]:
github.com/inkyblackness/imgui-go/v2._Cfunc_iggBegin(0x265ed1a7f60, 0x0, 0x0, 0xc000000000)
	_cgo_gotypes.go:386 +0x54
github.com/inkyblackness/imgui-go/v2.BeginV(0xb806e6, 0xb, 0x0, 0x0, 0x0)
	C:/Users/wenga/go/src/awesomeProject6/Window.go:92 +0xa9
github.com/inkyblackness/imgui-go/v2.Begin(...)
	C:/Users/wenga/go/src/awesomeProject6/Window.go:97
github.com/inkyblackness/imgui-go/v2.Main()
	C:/Users/wenga/go/src/awesomeProject6/Main.go:36 +0x49
github.com/inkyblackness/imgui-go/v2_test.TestVersion(0xc00005f380)
	C:/Users/wenga/go/src/awesomeProject6/Main_test.go:12 +0x29
testing.tRunner(0xc00005f380, 0xb92ed0)
	C:/Program Files/Go/src/testing/testing.go:1123 +0xef
created by testing.(*T).Run
	C:/Program Files/Go/src/testing/testing.go:1168 +0x2b3

goroutine 1 [chan receive]:
testing.(*T).Run(0xc00005f380, 0xb807d8, 0xb, 0xb92ed0, 0x947401)
	C:/Program Files/Go/src/testing/testing.go:1169 +0x2da
testing.runTests.func1(0xc00005f200)
	C:/Program Files/Go/src/testing/testing.go:1439 +0x7f
testing.tRunner(0xc00005f200, 0xc000123de0)
	C:/Program Files/Go/src/testing/testing.go:1123 +0xef
testing.runTests(0xc000004700, 0xb1da00, 0x15, 0x15, 0x0, 0x0, 0x0, 0x8bf630)
	C:/Program Files/Go/src/testing/testing.go:1437 +0x310
testing.(*M).Run(0xc00016e000, 0x0)
	C:/Program Files/Go/src/testing/testing.go:1345 +0x1f5
main.main()
	_testmain.go:85 +0x145
rax     0xc000074000
rbx     0xc000073e78
rcx     0x265ed1a7f60
rdi     0xc000074000
rsi     0x0
rbp     0xc000073e38
rsp     0xf9ffbff3d0
r8      0x0
r9      0x0
r10     0x2
r11     0xc00006aeb0
r12     0xb50d40
r13     0xbb8659
r14     0x0
r15     0x200
rip     0xaa8427
rflags  0x10206
cs      0x33
fs      0x53
gs      0x2b


Process finished with exit code 1

Clearly there is something happening with C.iggBegin(idArg, openArg, C.int(flags)) != 0. I can reproduce this issue on two different PCs. Imgui was running perfectly last December (hence the v2.6.0). The C++ Dear Imgui is working fine without issues.

If you need anything else, let me know.

OS: Windows 10 20H2
GPU: Nvidia
imgui-go version: v2.6.0 (same issue with v3.0.0)

First try it with go version 1.14 and see if there's still any problem. If problem disappears then it could be the same problem I had a few months ago, which was introduced when I changed to go version 1.15. Here's how I solved it (not much info about this on the internet):

  • Changed C++ compiler from tdm64-gcc to MinGW-64

  • When compiling started to use this flag: -ldflags="-extldflags=-static"

@the-goodies thanks for your suggestion and lucky you for solving this issue on your end!

  • Switched from tdm-gcc to mingw-64 earlier this day because I also thought it could be a gcc bug. Current gcc: gcc (x86_64-win32-seh-rev0, Built by MinGW-W64 project) 8.1.0
  • Now tried building it with go build -ldflags '-extldflags="-static"' -o main.exe
  • Tried that with go1.15.8 and go1.14.15

Unfortunately, it still does not work.

Edit:
finally got gdb to debug my binary. That's what gdb says:

Thread 1 received signal SIGSEGV, Segmentation fault.
ImGui::Begin (name=0x2d92990 "Hello WOrld", p_open=0x0, flags=0)
    at C:/Users/wenga/go/pkg/mod/github.com/inkyblackness/imgui-go/v3@v3.0.0/imgui/imgui.cpp:5478
5478        IM_ASSERT(g.WithinFrameScope);                  // Forgot to call ImGui::NewFrame()

Ignore the imgui-go version - switched back up as soon as I saw that it was not an issue of v3.0.0

Okay, got it to run. It was a mix of several problems. All in all was it some missing code on my end, and some missing error handling on the library end.

Here is the file I made. Tidy? no. Working? yea: https://gist.github.com/kylhuk/cdf928b6f523665f47a25119237ec394

Maybe a dev/contributer could take a look at how to catch such an error. Basically all failed IM_ASSERT should raise a proper error.

Hello there!
Great that you could solve this meanwhile.
Yes, the library does need some setup and maintenance during the game loop. I guess this is what you figured out by following the imgui-go-examples repository to put together your final code.

As such, the assertions are all from the wrapped library. They are set up in a way to tell that something basic is missing - because once it runs, there are no further issues. The assertions from the library are set up to cause a panic in the go wrapper as they are expected to interrupt the program flow.

All the best for your project!

@dertseha Thanks for reaching out. One thing about the assertions is, that they are not visible outside the CGO world - this was my main issue. CGO crashes, without telling why. A newbie like me didn't know that there are proper build flags (like GOTRACEBACK=crash) or even the possibility to ignore the SIGABRT signal from C++, by adding signal.Ignore(syscall.SIGABRT) to the code. Both would have helped in debugging.

Would it make sense to add signal.Ignore(...) in general when using CGO?

For this generic question I'd go for the generic answer: No, avoid ignoring signals. Because they are there for a reason to, well, signal an issue.
If there's a null-pointer dereference (or similar critical problem) in the "raw" native world, there's nothing that can be done in the Go world, other than "using it correctly". Because such an error simply tears down the process.
Apart from the "completely wrong" usage, there are still some assertion checks in the native library. Although these still expect that the process is terminated, yet at least there's a callback (into the Go wrapper) that allows for a panic() that possibly gives more insight into the problem, such as a call-stack and a message.
However I don't know to which degree the Go test environment furthermore wraps/covers panics.

My understanding of the implementation of Dear ImGui is that it's a special-purpose library without much "handholding". It either works, according to intended usage, or it does a hard fail. This wrapper here follows that intent and does no further state-keeping checks - it is as thin as reasonably possible.
Although there are entire applications built using this UI system (such as I did), the original intent of the original library is to provide a "quick and dirty debugging interface".