Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VSCode probe-rs debugger extension "gets lost" single-stepping embassy-rs wifi_blinky app #106

Open
U007D opened this issue Oct 23, 2024 · 1 comment

Comments

@U007D
Copy link

U007D commented Oct 23, 2024

Description

I am building and debugging (single-stepping) embassy's wifi_blinky example app.

I set two breakpoints: first is the first statement within main and the second is the first statement in the loop.

When using Step Over, everything appears to work correctly through the first loop iteration, but then the debugger appears to lose track of the remote processor starting with the second iteration of the loop. This only occurs when single-stepping (using Step Over). On the second iteration of the loop, the IDE starts by pointing to the second loop statement (control.gpio_set().await, skipping the info! statement). Single-stepping further gives more and more bizarre source code locations until the debugger simply displays "The editor could not be opened because the file was not found" and is unresponsive except for halt.

If I instead only use Continue, the debugger (and hardware) behave perfectly for as many iterations as I wish. Subsequently using Step Over shows the "lost control" behavior beginning with the subsequent iteration.

#[embassy_executor::main]
async fn main(spawner: Spawner) {
    let p = embassy_rp::init(Default::default()); // <-- breakpoint #1 here
    // let fw = include_bytes!("../../../../cyw43-firmware/43439A0.bin");
    // let clm = include_bytes!("../../../../cyw43-firmware/43439A0_clm.bin");

    // To make flashing faster for development, you may want to flash the firmwares independently
    // at hardcoded addresses, instead of baking them into the program with `include_bytes!`:
    //     probe-rs download ../../cyw43-firmware/43439A0.bin --binary-format bin --chip RP2040 --base-address 0x10100000
    //     probe-rs download ../../cyw43-firmware/43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x10140000
    let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) };
    let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) };

    let pwr = Output::new(p.PIN_23, Level::Low);
    let cs = Output::new(p.PIN_25, Level::High);
    let mut pio = Pio::new(p.PIO0, Irqs);
    let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);

    static STATE: StaticCell<cyw43::State> = StaticCell::new();
    let state = STATE.init(cyw43::State::new());
    let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
    unwrap!(spawner.spawn(cyw43_task(runner)));

    control.init(clm).await;
    control
        .set_power_management(cyw43::PowerManagementMode::PowerSave)
        .await;

    let delay = Duration::from_secs(1);
    loop {
        info!("led on!"); // <-- breakpoint #2 here
        control.gpio_set(0, true).await;
        Timer::after(delay).await;

        info!("led off!");
        control.gpio_set(0, false).await;
        Timer::after(delay).await;
    }
}

Repro Steps

git clone https://github.com/embassy-rs/embassy
git checkout f7d372f33f3 # currently `HEAD`
cd embassy/examples/rp
cargo build --bin wifi_blinky --locked
code .
In VSCode, set a breakpoint on `main()`'s first statement and another on the `loop`'s first statement
Run and Debug | Ensure "launch executable on remote target using `probe_rs`" is selected | Start Debugging
Single step (to see error beginning on second loop iteration)
Continue (to pause at breakpoint successfully each iteration)

Perhaps I have misconfigured something?

Details

System: Apple M3 Max
OS: macOS Sequoia 15.0.1
VSCode: Version: 1.94.2 Commit: 384ff7382de624fb94dbaf6da11977bba1ecd427 Date: 2024-10-09T16:08:44.566Z
VSCode probe-rs Debugger Extension: Debugger for probe-rs v0.24.2
probe-rs --version: v0.24.0 (git commit: crates.io)
rustc --version: rustc 1.82.0 (f6e511eec 2024-10-15)
Debugger hardware: RPi Debug Probe
Debugger firmware: v2.0.1
Target: RPi Pico W
embassy-rs: commit
rp2040.svd: pico-sdk v2.0.0

.vscode/launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "probe-rs-debug",
            "request": "launch",
            "name": "probe-rs (rp2040)",
            "cwd": "${workspaceFolder}",
            "connectUnderReset": true,
            "chip": "rp2040",
            "flashingConfig": {
                "flashingEnabled": true,
                "haltAfterReset": false
            },
            "coreConfigs": [
                {
                    "coreIndex": 0,
                    // Because `embassy` defiens multiple binaries in the `bin` folder, we can't just use the
                    // folder name as the executable name; hard-code the name of the bin we want to debug
                    //"programBinary": "./target/thumbv6m-none-eabi/debug/${workspaceFolderBasename}"
                    "programBinary": "./target/thumbv6m-none-eabi/debug/wifi_blinky"
                }
            ]
        },
        {
            "type": "probe-rs-debug",
            "request": "launch",
            "name": "launch executable on remote target using `probe_rs`",
            "cwd": "${workspaceFolder}",
            //!MODIFY (or remove)
            //"speed": 24000,
            //!MODIFY (or remove)
            // "probe": "VID:PID:<Serial>",
            "runtimeExecutable": "probe-rs",
            // "runtimeArgs": ["dap-server"],
            //!MODIFY
            "chip": "rp2040",
            "flashingConfig": {
                "flashingEnabled": true,
                "haltAfterReset": false,
                "formatOptions": {
                //!MODIFY (or remove). Valid values are: 'bin', 'hex', 'elf'(default), 'idf'
                // "binaryFormat": "elf"
                }
            },
            "coreConfigs": [
                {
                "coreIndex": 0,
                //!MODIFY
                "programBinary": "./target/thumbv6m-none-eabi/debug/wifi_blinky",
                //!MODIFY
                "svdFile": "./.vscode/rp2040.svd"
                }
            ],
            "env": {
                //!MODIFY (or remove)
                // If you set this variable, check the VSCode console log window for the location of the log file.
                "RUST_LOG": "info"
            },
                // Info, Debug
            "consoleLogLevel": "Console"
        }
    ]
}

Please let me know if there is any other information I can provide.

@Jack-NimbleTron
Copy link

Jack-NimbleTron commented Nov 25, 2024

I apologize for the slow response on this one. The current version of probe-rs has some known limitations with respect to stepping code, and this one falls squarely into that category.

The debug stepping functionality is actually very tricky to implement, because the debug info generated by Rust (and similarly by other languages) have some limitations. Lots of optimizations to the current 'semantic' implementation is possible, but the only way to really fix this would be to implement platform specific disassembly to interpret the branching instructions in the code (this is what tools like gdb does).

For clarity's sake, I should add that you can 'workaround' this limitation by one of two means, or even a combination of the two:

  • Switch to disassembly view, and now step - this steps the processor at instruction level, and will allow you to follow the execution at a more granular level.
  • If you know the location (or multiple probable locations) where you expect the code to branch to, add some breakpoints at those locations, and then run the binary until it hits one of those, instead of trying to step.

I hope this helps.

PR's are always welcome :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants