From 1fa57bde927c4b67254abd05577b0b3e90d45e99 Mon Sep 17 00:00:00 2001 From: larpon <768942+larpon@users.noreply.github.com> Date: Sat, 15 Jun 2024 12:20:38 +0200 Subject: [PATCH] docs: add notice about known problems with SDL2 and V's garbage collector (#745) --- README.md | 16 +++++++++++ tests/crash_with_gc.vv | 61 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 tests/crash_with_gc.vv diff --git a/README.md b/README.md index 7529c082..7f4e6e02 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/tests/crash_with_gc.vv b/tests/crash_with_gc.vv new file mode 100644 index 00000000..92b1f00f --- /dev/null +++ b/tests/crash_with_gc.vv @@ -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() +}