TCB Initialization issues if compiled with Relibc Debug Profile
To reproduce:
touch relibc
REPO_DEBUG=1 make prefix cr.zsh p.zsh # make sure zsh is statically linked
It will create a page fault without even touching the C main function. This happens both with GDB attached or not attached.
ser:~$ zsh
Page fault: 00007FFFFFEFFFC8 WR | US
RFLAG: 0000000000000202
CS: 000000000000002b
RIP: 00000000005a00ec
RSP: 00007fffffefffd0
I don't understand what is going on, but I can give clues: It stopped within relibc_start_v1
, at:
// Initialize TLS, if necessary
ld_so::init(
sp,
#[cfg(target_os = "redox")]
thr_fd,
);
Then it calls static_init
, Tcb::new(vsize)
then Self::os_new
. Here's the values:
While it's return Ok (with tcb zero??), it doesn't hit the next step of the call, it just going straight into the end of this function:
/// Create a new TCB
///
/// `size` is the size of the TLS in bytes.
pub unsafe fn new(size: usize) -> Result<&'static mut Self, DlError> {
let page_size = Sys::getpagesize();
let (_abi_page, tls, tcb_page) = Self::os_new(size.next_multiple_of(page_size))?; <---- last called here
let tcb_ptr = tcb_page.as_mut_ptr() as *mut Self;
ptr::write(
tcb_ptr,
Self {
.....
},
);
Ok(&mut *tcb_ptr)
} // <------- next step going here
Then jumps at this panic function:
I knew that you cannot print anything before TCB is inited, it will create page fault. I don't know why the Error values is DlError
, but coincidentally, the enum value is zero, so something else trigger it.