Skip to content

Segfault with set_use_custom_draw #36

@tjkirch

Description

@tjkirch

That said, set_use_custom_draw does seem like the right approach for this. If you can reproduce the segfaults we should figure out why they occur.

Originally posted by @rtsuk in #35 (comment)


Here's a minimal reproduction:

#![no_std]
extern crate alloc;

use {
    alloc::boxed::Box,
    anyhow::Error,
    crankstart::{
        crankstart_game,
        graphics::Graphics,
        sprite::{Sprite, SpriteManager},
        Game, Playdate,
    },
    crankstart_sys::{LCDBitmapFlip, PDRect},
};

struct State {
    // If the sprite is not stored, the crash doesn't happen
    _sprite: Sprite,
}

impl State {
    pub fn new(_playdate: &Playdate) -> Result<Box<Self>, Error> {
        // Load an image, assign it to a custom-draw sprite, add the sprite.
        // Crash doesn't happen unless a bitmap is assigned to the sprite.
        let bitmap = Graphics::get().load_bitmap("graphics/wedge")?;
        let sprite_manager = SpriteManager::get_mut();
        let mut sprite = sprite_manager.new_sprite()?;
        // No crash unless it's custom-draw.
        sprite.set_use_custom_draw()?;
        sprite.set_image(bitmap, LCDBitmapFlip::kBitmapUnflipped)?;
        sprite_manager.add_sprite(&sprite)?;
        Ok(Box::new(Self { _sprite: sprite }))
    }
}

impl Game for State {
    fn update(&mut self, _playdate: &mut Playdate) -> Result<(), Error> {
        Ok(())
    }

    fn update_sprite(&mut self, _: &mut Sprite, _: &mut Playdate) -> Result<(), Error> {
        Ok(())
    }

    // Same crash happens with or without this definition:
    fn draw_sprite(&self, _: &Sprite, _: &PDRect, _: &PDRect, _: &Playdate) -> Result<(), Error> {
        Ok(())
    }
}

crankstart_game!(State);

The result:

Loading C API game: target/Golf Date.pdx/pdex.so
16:23:47: Loading: OK

Thread 1 "PlaydateSimulat" received signal SIGSEGV, Segmentation fault.
0x0000555555968c88 in _compositeRow ()
(gdb) bt
#0  0x0000555555968c88 in _compositeRow ()
#1  0x00005555559735da in LCDBitmap_drawBitmap ()
#2  0x0000555555980d70 in LCD_drawBitmap ()
#3  0x00005555559828b9 in LCDSprite_draw ()
#4  0x000055555597d71c in LCDDisplayList_drawScreenRect ()
Dwarf Error: Cannot find DIE at 0xccf referenced from DIE at 0x1349f [in module target/Golf Date.pdx/pdex.so]

The backtrace is the same whether I define draw_sprite or not. Is it not being hooked up properly? Or is draw_sprite required to take some action that the SDK depends upon having happened?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions