So I have absolutely no idea what's going on here. I recently updated my qemu version to qemu 6.2.0. I also changed the compile target for my kernel (Rust recently added an "x86_64-uknown-none" target for bear metal targets like OSes) and now whenever I run my kernel in qemu it receives signal SIGQUIT when its trying to initialize its internal logger. I've no idea why this is happening; the target specification I switched to is no different from the one I was using other than the fact that I no longer have to rely on a JSON file to tell Rustc how to build my kernel. My interrupt handlers aren't even initialized so I have no idea if this is a triple fault or what (it might be, though I've no idea why that'd happen since I'm not to my knowledge doing anything that would cause that -- my kernel has pretty much just executed its first couple instructions, which don't do anything that would generate exceptions). Specifically, the line it runs that causes this to happen is:
Stepping instruction-by-instruction tells me that the system only executes four instructions before it dies. Specifically, those instructions, I believe, are:
Code: Select all
0x0000000000019a16 <+22>: lea -0xaf2d(%rip),%r14 # 0xeaf0
0x0000000000019a1d <+29>: lea 0x59f54(%rip),%rsi # 0x73978
0x0000000000019a24 <+36>: mov %r14,%rdi
=> 0x0000000000019a27 <+39>: call *0x63ee3(%rip) # 0x7d910
The problem is that I can't confirm that the set_logger function is the problem because it dies as soon as the call instruction is executed. (I don't even know if the instructions I'm getting are correct, though they just might be.) Is this a bug in Qemu or my code? I'm curious because in the past when a triple fault occurs it didn't do a SIGQUIT so...
Edit: so it definitely appears to be a triple fault. Specifically, a page fault. However, I have no idea why its being caused -- none of my code writes to raw memory, and the code for set_logger/set_logger_racy is simple:
Code: Select all
#[cfg(atomic_cas)]
pub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> {
set_logger_inner(|| logger)
}
All set_logger_inner does is atomically set the logger to use.