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
tomingw-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".