[bug] SIGSEGV: Segment Violation with Progress Bar
What happend?
This code worked in v0.7. Updating to v0.8.1 causes a segment violation at runtime.
SIGSEGV: segmentation violation
PC=0x7fdd72531b29 m=13 sigcode=1 addr=0x998
signal arrived during cgo execution
goroutine 5 gp=0xc000007c00 m=13 mp=0xc000501808 [syscall]:
runtime.cgocall(0x74a7e0, 0xc000070590)
runtime/cgocall.go:157 +0x4b fp=0xc000070568 sp=0xc000070530 pc=0x40ed0b
github.com/AllenDang/cimgui-go._Cfunc_igDeleteTexture(0x25)
_cgo_gotypes.go:23190 +0x3f fp=0xc000070590 sp=0xc000070568 pc=0x6eb8ff
github.com/AllenDang/cimgui-go.(*GLFWBackend).DeleteTexture.func1({0x7fdd71a9c548?})
github.com/AllenDang/[email protected]/glfw_backend.go:376 +0x34 fp=0xc0000705c8 sp=0xc000070590 pc=0x6f2bf4
github.com/AllenDang/cimgui-go.(*GLFWBackend).DeleteTexture(0x10?, {0xc000501808?})
github.com/AllenDang/[email protected]/glfw_backend.go:376 +0x16 fp=0xc0000705e0 sp=0xc0000705c8 pc=0x6f2b96
github.com/AllenDang/cimgui-go.(*Texture).release(0x0?)
github.com/AllenDang/[email protected]/texture.go:36 +0x28 fp=0xc000070600 sp=0xc0000705e0 pc=0x6eac28
runtime.call16(0x0, 0xe17808, 0xc000124010, 0x10, 0x10, 0x10, 0xc000070690)
runtime/asm_amd64.s:770 +0x43 fp=0xc000070620 sp=0xc000070600 pc=0x4755a3
runtime.runfinq()
runtime/mfinal.go:256 +0x3f1 fp=0xc0000707e0 sp=0xc000070620 pc=0x424331
runtime.goexit({})
runtime/asm_amd64.s:1695 +0x1 fp=0xc0000707e8 sp=0xc0000707e0 pc=0x477061
created by runtime.createfing in goroutine 1
runtime/mfinal.go:164 +0x3d
goroutine 1 gp=0xc0000061c0 m=nil [select, locked to thread]:
runtime.gopark(0xc000551e50?, 0x2?, 0xb8?, 0x9?, 0xc000551e44?)
runtime/proc.go:402 +0xce fp=0xc000551cf0 sp=0xc000551cd0 pc=0x4450ce
runtime.selectgo(0xc000551e50, 0xc000551e40, 0x18?, 0x0, 0xc000384030?, 0x1)
runtime/select.go:327 +0x725 fp=0xc000551e10 sp=0xc000551cf0 pc=0x456705
github.com/faiface/mainthread.Run(0xc000384030)
github.com/faiface/[email protected]/mainthread.go:42 +0x10d fp=0xc000551e88 sp=0xc000551e10 pc=0x6ff5ad
github.com/AllenDang/giu.mainthreadCallPlatform(...)
github.com/AllenDang/[email protected]/mainthread_all.go:9
github.com/AllenDang/giu.(*MasterWindow).Run(...)
github.com/AllenDang/[email protected]/MasterWindow.go:236
github.com/alpine-client/pinnacle/ui.Render()
github.com/alpine-client/pinnacle/ui/ui.go:112 +0x67 fp=0xc000551eb0 sp=0xc000551e88 pc=0x707d67
main.Run()
github.com/alpine-client/pinnacle/main.go:50 +0xf0 fp=0xc000551f10 sp=0xc000551eb0 pc=0x7120b0
main.main()
github.com/alpine-client/pinnacle/main.go:28 +0xb2 fp=0xc000551f50 sp=0xc000551f10 pc=0x711f92
runtime.main()
runtime/proc.go:271 +0x29d fp=0xc000551fe0 sp=0xc000551f50 pc=0x444c9d
runtime.goexit({})
runtime/asm_amd64.s:1695 +0x1 fp=0xc000551fe8 sp=0xc000551fe0 pc=0x477061
goroutine 2 gp=0xc000006c40 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
runtime/proc.go:402 +0xce fp=0xc000070fa8 sp=0xc000070f88 pc=0x4450ce
runtime.goparkunlock(...)
runtime/proc.go:408
runtime.forcegchelper()
runtime/proc.go:326 +0xb3 fp=0xc000070fe0 sp=0xc000070fa8 pc=0x444f53
runtime.goexit({})
runtime/asm_amd64.s:1695 +0x1 fp=0xc000070fe8 sp=0xc000070fe0 pc=0x477061
created by runtime.init.6 in goroutine 1
runtime/proc.go:314 +0x1a
goroutine 3 gp=0xc000007180 m=nil [runnable]:
runtime.goschedIfBusy()
runtime/proc.go:365 +0x28 fp=0xc000071780 sp=0xc000071768 pc=0x444fe8
runtime.bgsweep(0xc00009a000)
runtime/mgcsweep.go:302 +0x14f fp=0xc0000717c8 sp=0xc000071780 pc=0x43076f
runtime.gcenable.gowrap1()
runtime/mgc.go:203 +0x25 fp=0xc0000717e0 sp=0xc0000717c8 pc=0x425005
runtime.goexit({})
runtime/asm_amd64.s:1695 +0x1 fp=0xc0000717e8 sp=0xc0000717e0 pc=0x477061
created by runtime.gcenable in goroutine 1
runtime/mgc.go:203 +0x66
Code example
main.go
//go:embed assets/*
var assets embed.FS
var (
logo *image.RGBA
window *giu.MasterWindow
)
func main(){
window = giu.NewMasterWindow(
"Updater",
377, 144,
giu.MasterWindowFlagsFrameless|giu.MasterWindowFlagsNotResizable|giu.MasterWindowFlagsTransparent,
)
logo, _ = loadImage(assets, "assets/logo.png")
window.Run(defaultUI)
}
func defaultUI() {
giu.SingleWindow().Layout(
giu.Align(giu.AlignCenter).To(
giu.Dummy(0, scaleDivider(6)),
giu.ImageWithRgba(logo).Size(80, 80),
giu.Dummy(0, scaleDivider(6)),
giu.ProgressBar(ReadProgress()).Size(scaleValueX(377)*0.75, scaleValueY(5)),
),
)
}
func scaleDivider(value float32) float32 {
_, yScale := giu.Context.Backend().ContentScale()
if yScale > 1.0 {
value *= 2
}
return value * yScale
}
func scaleValueY(value int) float32 {
_, yScale := giu.Context.Backend().ContentScale()
return float32(value) * yScale
}
func scaleValueX(value int) float32 {
xScale, _ := giu.Context.Backend().ContentScale()
return float32(value) * xScale
}
func loadImage(assets embed.FS, path string) (*image.RGBA, error) {
data, err := assets.ReadFile(path)
if err != nil {
return nil, err
}
img, err := png.Decode(bytes.NewReader(data))
if err != nil {
return nil, err
}
return giu.ImageToRgba(img), nil
}
You can also find the actual code I'm using this for here: https://github.com/alpine-client/pinnacle/blob/084fde184a816b2241c36bd4f37a9fced3f21dbf/ui/ui.go#L83
To Reproduce
- Run my demo
- will see the crash...
Version
(latest)
OS
Fedora 40
@xEricL, I can't reproduce
Here is the code I'm using
package main
import (
"bytes"
"embed"
"image"
"image/png"
"github.com/AllenDang/giu"
)
//go:embed assets/*
var assets embed.FS
var (
logo *image.RGBA
window *giu.MasterWindow
)
func main() {
window = giu.NewMasterWindow(
"Updater",
377, 144,
giu.MasterWindowFlagsFrameless|giu.MasterWindowFlagsNotResizable|giu.MasterWindowFlagsTransparent,
)
logo, _ = loadImage(assets, "assets/logo.png")
window.Run(defaultUI)
}
func defaultUI() {
giu.SingleWindow().Layout(
giu.Align(giu.AlignCenter).To(
giu.Dummy(0, scaleDivider(6)),
giu.ImageWithRgba(logo).Size(80, 80),
giu.Dummy(0, scaleDivider(6)),
giu.ProgressBar(ReadProgress()).Size(scaleValueX(377)*0.75, scaleValueY(5)),
),
)
}
func ReadProgress() float32 {
return 0.5
}
func scaleDivider(value float32) float32 {
_, yScale := giu.Context.Backend().ContentScale()
if yScale > 1.0 {
value *= 2
}
return value * yScale
}
func scaleValueY(value int) float32 {
_, yScale := giu.Context.Backend().ContentScale()
return float32(value) * yScale
}
func scaleValueX(value int) float32 {
xScale, _ := giu.Context.Backend().ContentScale()
return float32(value) * xScale
}
func loadImage(assets embed.FS, path string) (*image.RGBA, error) {
data, err := assets.ReadFile(path)
if err != nil {
return nil, err
}
img, err := png.Decode(bytes.NewReader(data))
if err != nil {
return nil, err
}
return giu.ImageToRgba(img), nil
}
It works fine (assets/logo.png for me is examples/loadimage/gopher.png)
I've a suggestion for your project: make sure your style.go does not use AllenDang/imgui-go - you need AllenDang/cimgui-go
I've a suggestion for your project: make sure your
style.godoes not use AllenDang/imgui-go - you need AllenDang/cimgui-go
@gucio321 I've made sure to update my style.go. I've pushed the updated code to a new branch https://github.com/alpine-client/pinnacle/tree/giu-v0.8
I didn't think styling was the issue because it still happens even if I removed SetupStyle and PopStyle from the defaultUI() function.
After further testing, I've discovered 2 cases where the SIGSEV does not happen (which should narrow down the issue):
- Removing
giu.ImageWithRgba(logo)fromdefaultUI(). Specifically, this line: https://github.com/alpine-client/pinnacle/blob/92462557244d9d37c35cae535529d894a9e5b21d/ui/ui.go#L88 - Do 1 successful run (case 1), but then add back the
giu.ImageWithRgba(logo)line and run the code again (skips most of the progress bar)
Let me further explain our program. It basically downloads and unzips Java 17, downloads a launcher.jar from our website, and then uses the Java binary to run launcher.jar. This only needs to happen once, so if the program detects that the Java runtime package and launcher.jar already exist on the system, it doesn't do it again. This means the progress bar goes much faster after 1 successful run. As a result, if you get the program to run successfully, you need to delete ~/.alpineclient/ before running it again or else SIGSEV won't happen again (I know, it's very strange).
Since you're unable to recreate it, please clone this branch, run make run, and the SIGSEV should happen. Once again, the program only interacts with ~/.alpineclient/, so remember to delete that after a successful run (and at the end when you're finished testing). I've also commented out the code that runs launcher.jar (so no other code will be executed on your system).
Please let me know if you're still unable to recreate it under these conditions. The issue is most likely related to giu.ImageWithRgba (case 1). Although I don't know why the SIGSEV doesn't happen after 1 successful run (case 2).
Even if I comment out the progress bar and only load the image by itself, the SIGSEV occurs. It is almost certainly caused by giu.ImageWithRgba.
Replacing giu.ImageWithRgba with giu.ImageWithURL fixes the issue. Not an ideal solution but will have to do in the meantime. This is probably a lower-level issue with cimgui-go.
Image with url is almost the same as image with rgba iirc So this night be a giu issue, let me investigate it
@xEricL I'm sorry but I'm still unable to reproduce:
https://github.com/user-attachments/assets/c7559080-d283-4381-9916-cd4ebad18022
That is very interesting. I just tested it in a Debian 11 Virtual Machine and it compiled and ran no problem. Perhaps it's just an issue with Fedora 40 or maybe even just a problem with my system.
Thank you for the video and for taking the time to look into this.
@xEricL I'm on fedora 39. I can check on f40 laptop later.
You use wayland or xorg? And what gpu?
You use wayland or xorg? And what gpu?
I'm on xorg. GPU is NVIDIA 2060S.
@xEricL I managed to reproduce on fedora 40 laptop with nvidia gpu. I have no idea is it hardware or os thing yet. Will try to debug this.
fedora 40 PC with no gpu - still works for me. This must be something about gpu (but why?) Generally ImageWithRGBa has something to do with texture loading and this is deffinitly gpu thing.
It likely has something to do with NVIDIA drivers for Fedora 40.
Very weird that giu.ImageWithURL and giu.ImageWithFile work just fine. I decided to just go with giu.ImageWithFile. Perhaps it will resolve on it's own with a NVIDIA driver update in the future. Thank you again for taking the time to look into this for me.
Same issue here. Fixed by switching from ImageWithRgbaWidget to ImageWithFileWidget. Apple M1 Pro.
SIGSEGV: segmentation violation
PC=0x1d73748f8 m=9 sigcode=2 addr=0x30
signal arrived during cgo execution
goroutine 3 gp=0x14000003880 m=9 mp=0x1400007e808 [syscall]:
runtime.cgocall(0x104f7affc, 0x140000504e8)
/usr/local/go/src/runtime/cgocall.go:167 +0x44 fp=0x140000504b0 sp=0x14000050470 pc=0x104bddf24
github.com/AllenDang/cimgui-go._Cfunc_igDeleteTexture(0x6)
_cgo_gotypes.go:23020 +0x30 fp=0x140000504e0 sp=0x140000504b0 pc=0x104d24050
github.com/AllenDang/cimgui-go.(*GLFWBackend).DeleteTexture.func1({0x14000050548?})
@terranvigil what gpu?
@terranvigil what gpu?
It's the integrated Apple GPU, 16 core
I had a chat on discord with someone who has similar issue. Turns out it happens independently to ProgressBar.
If you just use ImageWithRgba to display an image and wait about 30 seconds it will crash with no reason.
code
package main
import (
"fmt"
"image"
g "github.com/AllenDang/giu"
)
var (
rgba *image.RGBA
)
func loop() {
g.SingleWindow().Layout(
g.Label("Display image from rgba"),
g.ImageWithRgba(rgba).OnClick(func() {
fmt.Println("rgba image was clicked")
}).Size(200, 100),
)
}
func main() {
rgba, _ = g.LoadImage("./fallback.png")
wnd := g.NewMasterWindow("Load Image", 600, 500, 0)
wnd.Run(loop)
}
@terranvigil could you confirm?
I proposed a simple solution to the imageWithRgba issue there, that work flawlessy for me. Gone from 2gb gpu vram (or crash) down to 60Mb
https://github.com/AllenDang/giu/issues/854#issue-2541415933