rust3ds / citro3d-rs

Rust bindings and safe wrappers for citro3d
https://rust3ds.github.io/citro3d-rs
14 stars 11 forks source link

Deadlock in render::Target::drop #48

Open ian-h-chamberlain opened 4 months ago

ian-h-chamberlain commented 4 months ago

Reproducing code is https://github.com/CenTdemeern1/witness-rs/tree/main/frontend-3ds

Deadlock stack trace seems to be this:

#0  svcArbitrateAddressNoTimeout () at /Users/davem/projects/devkitpro/pacman-packages/libctru/src/libctru-2.3.1/libctru/source/svc.s:253
#1  0x00107bd8 in syncArbitrateAddress (addr=<optimized out>, type=<optimized out>, value=<optimized out>) at /Users/davem/projects/devkitpro/pacman-packages/libctru/src/libctru-2.3.1/libctru/source/synchronization.c:22
#2  0x0010683c in gspWaitForAnyEvent () at /Users/davem/projects/devkitpro/pacman-packages/libctru/src/libctru-2.3.1/libctru/source/services/gspgpu.c:311
#3  0x00136d3c in gxCmdQueueWait (queue=<optimized out>, timeout=<optimized out>) at /Users/davem/projects/devkitpro/pacman-packages/libctru/src/libctru-2.3.1/libctru/source/gpu/gxqueue.c:116
#4  0x00133be0 in C3Di_WaitAndClearQueue (timeout=<optimized out>) at /Users/davem/projects/devkitpro/pacman-packages/citro3d/src/citro3d-1.7.1/source/renderqueue.c:95
#5  0x001342f4 in C3D_RenderTargetSetOutput (target=target@entry=0x0, screen=GFX_TOP, side=GFX_LEFT, transferFlags=transferFlags@entry=0) at /Users/davem/projects/devkitpro/pacman-packages/citro3d/src/citro3d-1.7.1/source/renderqueue.c:381
#6  0x00134318 in C3D_RenderTargetDetachOutput (target=target@entry=0x82048a8) at /Users/davem/projects/devkitpro/pacman-packages/citro3d/src/citro3d-1.7.1/include/c3d/renderqueue.h:69
#7  0x00134348 in C3D_RenderTargetDelete (target=0x82048a8) at /Users/davem/projects/devkitpro/pacman-packages/citro3d/src/citro3d-1.7.1/source/renderqueue.c:366
#8  0x00112bd0 in citro3d::render::{impl#0}::drop (self=0x81ffb6c) at src/render.rs:33
#9  0x001010d8 in core::ptr::drop_in_place<citro3d::render::Target> () at /Users/ianchamberlain/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:514
#10 0x001034e4 in witness_3ds::main () at frontend-3ds/src/main.rs:105

Originally posted by @CenTdemeern1 in https://github.com/rust3ds/ctru-rs/discussions/179

ian-h-chamberlain commented 4 months ago

Hmm, possibly related to https://github.com/devkitPro/citro3d/issues/35 or https://github.com/devkitPro/citro3d/issues/42 ? Some of the situations described there seem similar, and the reproducing code doesn't use Target::clear... but adding a clear call doesn't seem like it fixes the lockup, in this case. There might be some other clues there, and with any luck we can change the Rust API to prevent this kind of "misuse" or behavior from happening.

CenTdemeern1 commented 4 months ago

but adding a clear call doesn't seem like it fixes the lockup

Yeah, I tried adding clear calls and other citro3d-sys calls before I made the repo public and it didn't seem to fix it. (I undid those changes before pushing)