Skip to content

Commit

Permalink
docs: add notice about known problems with SDL2 and V's garbage colle…
Browse files Browse the repository at this point in the history
…ctor (vlang#745)
  • Loading branch information
larpon committed Jun 15, 2024
1 parent a892acd commit ff36c0a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,22 @@ against newer versions of the SDL2 library.

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

## Notes on garbage collection and memory issues

Currently, with some setups, SDL2 is known to trigger crashes when used in conjunction
with V's default garbage collector. In these cases running apps importing `sdl` with
`v run` you may experience runtime crashes and output similar to this:

```
main__main: RUNTIME ERROR: invalid memory access
```

We are tracking the issue here: https://github.com/vlang/sdl/issues/744

The crashes can be avoided by passing `-d sdl_memory_no_gc` when compiling V applications
that contains `import sdl` and managing SDL2's memory manually with calls to the various
`destroy` and `sdl.free/1` functions.

## Support

`sdl` is currently supported on:
Expand Down
61 changes: 61 additions & 0 deletions tests/crash_with_gc.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// This file serves as a MRE (minimal reproducible example) of a runtime crash triggered by compiling and running
// this file with just `v run ~/.vmodules/sdl/tests/crash_with_gc.vv`. On some setups, the problem seems to be
// memory corruption happening between actions in SDL2's memory allocations and V's default garbage collector.
// Especially when a lot of heap allocations occur.
//
// The example does not crash if compiled with `-d sdl_memory_no_gc`.
// See also: https://github.com/vlang/sdl/issues/744
module main

import sdl

struct Data1 {
mut:
a int
}

fn main() {
mut data1 := []&Data1{cap: 200}
for i in 0 .. 200 {
data1 << &Data1{
a: i
}
}

sdl.init(sdl.init_video)
window := sdl.create_window('Hello SDL2'.str, 300, 300, 500, 300, 0)
renderer := sdl.create_renderer(window, -1, u32(sdl.RendererFlags.accelerated) | u32(sdl.RendererFlags.presentvsync))

mut should_close := false
mut ticks := 0
for {
ticks++
evt := sdl.Event{}
for 0 < sdl.poll_event(&evt) {
match evt.@type {
.quit { should_close = true }
else {}
}
}

data1[0].a = ticks
data1.delete(10)
data1 << &Data1{
a: ticks
}

println('ticks: ${ticks}')
if should_close || ticks == 1000 {
break
}

sdl.set_render_draw_color(renderer, 255, 55, 55, 255)
sdl.render_clear(renderer)
sdl.render_present(renderer)
}
println('Exiting. If this was compiled without `-d sdl_memory_no_gc`, an invalid memory access error should occur')

sdl.destroy_renderer(renderer)
sdl.destroy_window(window)
sdl.quit()
}

0 comments on commit ff36c0a

Please sign in to comment.