[Solved] Newlib's ctype.h functions cause paging corruption

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

[Solved] Newlib's ctype.h functions cause paging corruption

Post 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?
Last edited by codyd51 on Tue Mar 28, 2017 1:35 am, edited 1 time in total.
User avatar
dchapiesky
Member
Member
Posts: 204
Joined: Sun Dec 25, 2016 1:54 am
Libera.chat IRC: dchapiesky

Re: Newlib's ctype.h functions cause paging corruption

Post by dchapiesky »

does your fork'd process get a different newlib REENT pointer from __getreent()?
Plagiarize. Plagiarize. Let not one line escape thine eyes...
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Newlib's ctype.h functions cause paging corruption

Post 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?
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Newlib's ctype.h functions cause paging corruption

Post 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.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Newlib's ctype.h functions cause paging corruption

Post 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?)
User avatar
dchapiesky
Member
Member
Posts: 204
Joined: Sun Dec 25, 2016 1:54 am
Libera.chat IRC: dchapiesky

Re: Newlib's ctype.h functions cause paging corruption

Post 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?
Plagiarize. Plagiarize. Let not one line escape thine eyes...
User avatar
nielsd
Member
Member
Posts: 31
Joined: Sun Apr 05, 2015 3:15 pm

Re: Newlib's ctype.h functions cause paging corruption

Post 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.
osdev project, goal is to run wasm as userspace: https://github.com/kwast-os/kwast
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Newlib's ctype.h functions cause paging corruption

Post 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;
}
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Newlib's ctype.h functions cause paging corruption

Post 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.
Post Reply