复现问题
1 2 3 4 5 6 7
| (qemu) xp 0x09000010 PL011State::read: Bad offset 09000010: 0x00000000 (qemu) $ grep "Bad offset" rust/hw/char/pl011/src/device.rs log_mask_ln!(Log::GuestError, "PL011State::read: Bad offset {offset}"); "PL011State::write: Bad offset {offset} value {value}" $
|


找到Rust FFI键绑定

1 2
| $ grep -rn "rust_fwrite" --include="*.c" util/log.c:589:ssize_t rust_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|

这里出现了一个明显的错误,fwrite的返回值没有被使用。
修复:
1
| return ret < 0 ? -errno : (ssize_t)(ret * size);
|
验证修复
1 2 3 4
| (qemu) xp 0x09000010 PL011State::read: Bad offset 16 09000010: 0x00000000 (qemu)
|
附录
启动gdb对rust_fwrite进行调试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| [*#0] 0x5555568e209c <rust_fwrite+0x2f> [...] ------------------------------------------------------------------------------- gef> p ret $1 = 0x0 gef> p size $2 = 0x1 gef> p nmemb $3 = 0x1d gef> p stream $4 = (FILE *) 0x7ffff7e1b6a0 <_IO_2_1_stderr_> gef> list 590 { 591 /* 592 * Same as fwrite, but return -errno because Rust libc does not provide 593 * portable access to errno. :( 594 */ 595 int ret = fwrite(ptr, size, nmemb, stream); 596 printf("ret=%d, size=%zu, returning=%ld\n", ret, size, ret * size); 597 598 return ret < 0 ? -errno : (ssize_t)(ret * size); 599 } gef>
|