Page 1 of 1
[Solved] Newlib's ctype.h functions cause paging corruption
Posted: Fri Mar 24, 2017 11:32 am
by codyd51
Hi!
I'm encountering a strange bug and I'm wondering if anyone's ever ran into something similar.
If I use any function from newlib's ctype.h, following by a printf, followed by a fork, the fork fails as the kernel fails to create a new process, claiming we've run out of free frames. I've noticed that when this bug occurs, my clone_page_table function is called many times, which is not typical for a fork (most tables are just copied from kernel).
If I comment out the ctype call, or the printf call, the bug does not occur. But if both calls are there, the fork then fails. The ctype call doesn't even have to execute, it just has to be present in the binary.
I initially thought that some kernel-side syscall wasn't being implemented correctly, but I looked at the newlib source and it says no OS-side support is required for ctype functions; no great shock there.
Does anyone know what might be going on here?
Re: Newlib's ctype.h functions cause paging corruption
Posted: Fri Mar 24, 2017 1:58 pm
by dchapiesky
does your fork'd process get a different newlib REENT pointer from __getreent()?
Re: Newlib's ctype.h functions cause paging corruption
Posted: Fri Mar 24, 2017 7:50 pm
by codyd51
dchapiesky wrote:does your fork'd process get a different newlib REENT pointer from __getreent()?
No, the REENT pointers are both 0x8055040. Should they be different?
Re: Newlib's ctype.h functions cause paging corruption
Posted: Sat Mar 25, 2017 1:49 pm
by codyd51
I've noticed that, when the ctype and printf calls are both compiled, the ELF makes a very big sbrk request, which explains why fork() runs out of memory.
Without both calls (when everything works), I get an sbrk for 0x40419.
When I have both calls, I get an sbrk for 0x804adb8.
Re: Newlib's ctype.h functions cause paging corruption
Posted: Sun Mar 26, 2017 2:00 am
by bluemoon
even sbrk for 0x40419(a bit more than 256k) doesn't seems normal for a trivial program.
Just to make sure, do the program runs fine without fork()?
do the lib properly initialized (double check all bss cleared?)
Re: Newlib's ctype.h functions cause paging corruption
Posted: Sun Mar 26, 2017 8:17 am
by dchapiesky
ctype has a lot of static tables... I feel like something isn't being initialized correctly in your sections... I agree with bluemoon - check your sections and your elf loader....
does the code work under linux?
Re: Newlib's ctype.h functions cause paging corruption
Posted: Sun Mar 26, 2017 1:25 pm
by nielsd
I've ran into the same problem and have been unable to fix it. However, for me, it never happens if I compile the program with -O0.
The problem started appearing when I updated to the latest newlib.
Re: Newlib's ctype.h functions cause paging corruption
Posted: Sun Mar 26, 2017 5:20 pm
by codyd51
bluemoon wrote:even sbrk for 0x40419(a bit more than 256k) doesn't seems normal for a trivial program.
Just to make sure, do the program runs fine without fork()?
do the lib properly initialized (double check all bss cleared?)
I'm pretty positive I'm clearing out .bss. This is the function in the ELF loader that fills in .bss segment:
Code: Select all
//map pages for bss segment pointed to by shdr
//stores program break (end of .bss segment) in prog_break
//stored start of .bss segment in bss_loc
static void alloc_bss(elf_s_header* shdr, int* prog_break, int* bss_loc) {
printf("ELF .bss mapped @ %x - %x\n", shdr->addr, shdr->addr + shdr->size);
for (int i = 0; i <= shdr->size + 0x1000; i += 0x1000) {
extern page_directory_t* current_directory;
page_t* page = get_page(shdr->addr + i, 1, current_directory);
if (!alloc_frame(page, 1, 1)) {
printf_err(".bss %x wasn't alloc'd", shdr->addr + i);
}
}
//zero out .bss
memset((char*)shdr->addr, 0, shdr->size);
//set program break to .bss segment
*prog_break = shdr->addr + shdr->size;
*bss_loc = shdr->addr;
}
Re: Newlib's ctype.h functions cause paging corruption
Posted: Tue Mar 28, 2017 1:35 am
by codyd51
bluemoon wrote:even sbrk for 0x40419(a bit more than 256k) doesn't seems normal for a trivial program.
Just to make sure, do the program runs fine without fork()?
do the lib properly initialized (double check all bss cleared?)
dchapiesky wrote:ctype has a lot of static tables... I feel like something isn't being initialized correctly in your sections... I agree with bluemoon - check your sections and your elf loader....
does the code work under linux?
Thanks for pointing me in the right direction! I wasn't following the ELF spec. The issue was, when loading each ELF segment, I was memcpy'ing memsz bytes, instead of filesz bytes. Changing that to only copy filesz bytes, and memset memsz bytes, fixed the issue.