Skip to content

Commit 56f9fd6

Browse files
authored
docs: add notice about known problems with SDL2 and V's garbage collector (#745) (#754)
1 parent 40c5bf8 commit 56f9fd6

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ against newer versions of the SDL2 library.
5656

5757
Also note that SDL2 **is not** compatible with SDL `v1.x`.
5858

59+
## Notes on garbage collection and memory issues
60+
61+
Currently, with some setups, SDL2 is known to trigger crashes when used in conjunction
62+
with V's default garbage collector. In these cases running apps importing `sdl` with
63+
`v run` you may experience runtime crashes and output similar to this:
64+
65+
```
66+
main__main: RUNTIME ERROR: invalid memory access
67+
```
68+
69+
We are tracking the issue here: https://github.com/vlang/sdl/issues/744
70+
71+
The crashes can be avoided by passing `-d sdl_memory_no_gc` when compiling V applications
72+
that contains `import sdl` and managing SDL2's memory manually with calls to the various
73+
`destroy` and `sdl.free/1` functions.
74+
5975
## Support
6076

6177
`sdl` is currently supported on:

tests/crash_with_gc.vv

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// This file serves as a MRE (minimal reproducible example) of a runtime crash triggered by compiling and running
2+
// this file with just `v run ~/.vmodules/sdl/tests/crash_with_gc.vv`. On some setups, the problem seems to be
3+
// memory corruption happening between actions in SDL2's memory allocations and V's default garbage collector.
4+
// Especially when a lot of heap allocations occur.
5+
//
6+
// The example does not crash if compiled with `-d sdl_memory_no_gc`.
7+
// See also: https://github.com/vlang/sdl/issues/744
8+
module main
9+
10+
import sdl
11+
12+
struct Data1 {
13+
mut:
14+
a int
15+
}
16+
17+
fn main() {
18+
mut data1 := []&Data1{cap: 200}
19+
for i in 0 .. 200 {
20+
data1 << &Data1{
21+
a: i
22+
}
23+
}
24+
25+
sdl.init(sdl.init_video)
26+
window := sdl.create_window('Hello SDL2'.str, 300, 300, 500, 300, 0)
27+
renderer := sdl.create_renderer(window, -1, u32(sdl.RendererFlags.accelerated) | u32(sdl.RendererFlags.presentvsync))
28+
29+
mut should_close := false
30+
mut ticks := 0
31+
for {
32+
ticks++
33+
evt := sdl.Event{}
34+
for 0 < sdl.poll_event(&evt) {
35+
match evt.@type {
36+
.quit { should_close = true }
37+
else {}
38+
}
39+
}
40+
41+
data1[0].a = ticks
42+
data1.delete(10)
43+
data1 << &Data1{
44+
a: ticks
45+
}
46+
47+
println('ticks: ${ticks}')
48+
if should_close || ticks == 1000 {
49+
break
50+
}
51+
52+
sdl.set_render_draw_color(renderer, 255, 55, 55, 255)
53+
sdl.render_clear(renderer)
54+
sdl.render_present(renderer)
55+
}
56+
println('Exiting. If this was compiled without `-d sdl_memory_no_gc`, an invalid memory access error should occur')
57+
58+
sdl.destroy_renderer(renderer)
59+
sdl.destroy_window(window)
60+
sdl.quit()
61+
}

0 commit comments

Comments
 (0)