()
| 1438 | #[tokio::test] |
| 1439 | #[cfg_attr(miri, ignore)] |
| 1440 | async fn breakpoint_slips_to_first_opcode() -> wasmtime::Result<()> { |
| 1441 | let _ = env_logger::try_init(); |
| 1442 | |
| 1443 | // Breakpoints set at the function body start (which includes the |
| 1444 | // local declarations and precedes the first opcode) should be |
| 1445 | // "slipped" forward to the first opcode. This matches how LLDB |
| 1446 | // sets breakpoints using DWARF `DW_AT_low_pc`. |
| 1447 | // |
| 1448 | // For the WAT below, `wasm-objdump -d` shows: |
| 1449 | // |
| 1450 | // ``` |
| 1451 | // 000023 func[0] <main>: |
| 1452 | // 000024: 20 00 | local.get 0 |
| 1453 | // 000026: 20 01 | local.get 1 |
| 1454 | // 000028: 6a | i32.add |
| 1455 | // 000029: 0b | end |
| 1456 | // ``` |
| 1457 | // |
| 1458 | // 0x23 is the function body start (locals count byte), while 0x24 |
| 1459 | // is the first opcode. Setting a breakpoint at 0x23 should slip |
| 1460 | // to 0x24. |
| 1461 | let (module, mut store) = get_module_and_store( |
| 1462 | |_config| {}, |
| 1463 | r#" |
| 1464 | (module |
| 1465 | (func (export "main") (param i32 i32) (result i32) |
| 1466 | local.get 0 |
| 1467 | local.get 1 |
| 1468 | i32.add)) |
| 1469 | "#, |
| 1470 | )?; |
| 1471 | |
| 1472 | debug_event_checker!( |
| 1473 | D, store, |
| 1474 | { 0 ; |
| 1475 | wasmtime::DebugEvent::Breakpoint => { |
| 1476 | let stack = store.debug_exit_frames().next().unwrap(); |
| 1477 | let (func, pc) = stack.wasm_function_index_and_pc(&mut store).unwrap().unwrap(); |
| 1478 | assert_eq!(func.as_u32(), 0); |
| 1479 | // The breakpoint should fire at the first opcode |
| 1480 | // (0x24), not at the function body start (0x23). |
| 1481 | assert_eq!(pc.raw(), 0x24); |
| 1482 | } |
| 1483 | } |
| 1484 | ); |
| 1485 | |
| 1486 | let (handler, counter) = D::new_and_counter(); |
| 1487 | store.set_debug_handler(handler); |
| 1488 | |
| 1489 | store |
| 1490 | .edit_breakpoints() |
| 1491 | .unwrap() |
| 1492 | .add_breakpoint(&module, ModulePC::new(0x23))?; |
| 1493 | |
| 1494 | let instance = Instance::new_async(&mut store, &module, &[]).await?; |
| 1495 | let func = instance.get_func(&mut store, "main").unwrap(); |
| 1496 | let mut results = [Val::I32(0)]; |
| 1497 | func.call_async(&mut store, &[Val::I32(1), Val::I32(2)], &mut results) |
nothing calls this directly
no test coverage detected