rust-qt / ritual

Use C++ libraries from Rust
Apache License 2.0
1.24k stars 49 forks source link

Segmentation Fault when assigning a Slot to the "value_changed" socket of a QSpinBox #98

Closed notgull closed 4 years ago

notgull commented 4 years ago

The problem code:

x.value_changed().connect(&controller.x_changed);
y.value_changed().connect(&controller.y_changed);

x and y are QSpinBoxes, initialized via the following function:

        // macro for creating a spin box
        macro_rules! spinbox {
            ($name: expr) => (
                unsafe {
                    let mut container = QWidget::new_0a();
                    let mut container_layout = QHBoxLayout::new_1a(&mut container).into_ptr();

                    // label and spin box
                    let mut spin_label = QLabel::from_q_string(&QString::from_std_str($name));
                    let mut spin_box = QSpinBox::new_0a();
                    spin_box.set_minimum(-127);
                    spin_box.set_maximum(127);

                    container_layout.add_widget(&mut spin_box);
                    container_layout.add_widget(&mut spin_label);

                    layout.add_widget(&mut container);
                    spin_box.into_ptr()
                }
            )
        }

        let x = spinbox!("X");
        let y = spinbox!("Y");

x_changed and y_changed are initialized via the following macro:

        // macro for creating a slot that corresponds to a spinbox
        macro_rules! changed_handler {
            ($field_name: ident) => {
                unsafe {
                    Slot::new(move || {
                        (*input_reference.lock().unwrap()).$field_name = $field_name.value().try_into().unwrap();
                    })
                }
            }
        };

        let x_changed = changed_handler!(x);
        let y_changed = changed_handler!(y)

input_reference is an Arc<Mutex<a struct of my own creation>> that is passed into this function. For a more complete example, refer to my complete source code here.

The output: This is a Mupen64Plus plugin, so the complete output of that program loaded with this plugin is listed here:

$ mupen64plus --verbose --input target/debug/libtasinput2.so test_rom.n64
 __  __                         __   _  _   ____  _             
|  \/  |_   _ _ __   ___ _ __  / /_ | || | |  _ \| |_   _ ___ 
| |\/| | | | | '_ \ / _ \ '_ \| '_ \| || |_| |_) | | | | / __|  
| |  | | |_| | |_) |  __/ | | | (_) |__   _|  __/| | |_| \__ \  
|_|  |_|\__,_| .__/ \___|_| |_|\___/   |_| |_|   |_|\__,_|___/  
             |_|         http://code.google.com/p/mupen64plus/  
Mupen64Plus Console User-Interface Version 2.5.0

UI-Console: attached to core library 'Mupen64Plus Core' version 2.5.0
UI-Console:             Includes support for Dynamic Recompiler.
UI-Console:             Includes support for MIPS r4300 Debugger.
Core: Goodname: Super Mario 64 (U) [!]
Core: Name: SUPER MARIO 64      
Core: MD5: 20B854B239203BAF6C961B850A4A51A2
Core: CRC: 635A2BFF 8B022326
Core: Imagetype: .v64 (byteswapped)
Core: Rom size: 8388608 bytes (or 8 Mb or 64 Megabits)
Core: ClockRate = F
Core: Version: 1444
Core: Manufacturer: Nintendo
Core: Cartridge_ID: 4D53
Core: Country: USA
Core: PC = 80246000
Core: Save type: 0
UI-Console Status: Cheat codes disabled.
UI-Console: using Video plugin: 'Mupen64Plus OpenGL Video Plugin by Rice' v2.5.0
UI-Console: Video plugin library: /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-video-rice.so
UI-Console: using Audio plugin: 'Mupen64Plus SDL Audio Plugin' v2.5.0
UI-Console: Audio plugin library: /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-audio-sdl.so
Input Error: 
Input Error: Starting input plugin...
Input Error: 

UI-Console: using Input plugin: 'TAS Input Plugin 2 by not_a_seagull' v1.0.0
UI-Console: Input plugin library: target/debug/libtasinput2.so
UI-Console: using RSP plugin: 'Hacktarux/Azimer High-Level Emulation RSP Plugin' v2.5.0
UI-Console: RSP plugin library: /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-rsp-hle.so
Core: input plugin did not specify a render callback; there will be no on screen display by the input plugin.
Core: Memory initialized
Video: Reading .ini file: RiceVideoLinux.ini
Video: SSE processing enabled.
Video: Found ROM 'SUPER MARIO 64', CRC ff2b5a632623028b-45
Video: InitExternalTextures
Video: Initializing OpenGL Device Context.
Video: Initializing video subsystem...
Core: Setting 32-bit video mode: 320x240
Input Error: 
Input Error: Spin boxes
Input Error: 

[1]    6817 segmentation fault (core dumped)  mupen64plus --verbose --input target/debug/libtasinput2.so

The problem could be the ArcMutex dereferenced in the socket, but I'm relatively sure it isn't.

notgull commented 4 years ago

The real issue here was that I was not initializing the spin boxes properly.