Page 1 of 1

Couple Of Questions

Posted: Sat Jan 31, 2009 8:47 am
by Creature
For quite some time, I've been working on a problem of mine which raised some questions. Not so long ago I was having a very strange problem; as soon as I added a certain line of code (it was a push_back call for a vector), the kernel page-faulted. You could say "Check your push_back or dynamic memory allocation code", but the strange thing is, the code wasn't even being called! Just putting the line there page-faulted the kernel. So I wondered "What could cause this?" and at the moment the only thing I could come up with is something being loaded incorrectly or something wrong with the linker. So my first question is, would someone take a look at my linker script and see if there's anything horribly wrong with it?

Code: Select all

ENTRY(BootEntry)
OUTPUT_FORMAT("elf32-i386")

SECTIONS
{
	.text 0x100000 :
	{
		code = .;
		*(.text)
		*(.rodata)				/* Assuming ELF cross-compiler. */
		. = ALIGN(4096);
	}

	.data :
	{
		/* Constructor and destructor variables are only used in ASM, so C-linkage is not necessary. */		
		ConstrStart = .;
		*(.ctor*)
		ConstrEnd = .;
		
		DestrStart = .;
		*(.dtor*)
		DestrEnd = .;
	
		data = .;
		*(.data)
		*(.rodata)				/* Assuming ELF cross-compiler, does this even need to be put here? */
		. = ALIGN(4096);
	}

	.bss :
	{
		bss = .;
		*(.bss)
		. = ALIGN(4096);
	}

	end = .;
}

INPUT
(	
	Entry.obj
	AsmImp.obj
	DescriptorTables.obj
	ISR.obj
	IRQ.obj
	
	GRUB.o
	Kernel.o
	Keyboard.o
	Event.o
	
	CppInit.o
	cstring.o
	CCRead.o
	CCWrite.o
	
	Heap.o
	Memory.o
	Multitasking.o
	OrderedList.o
	Paging.o
	
	Floppy.o
	
	NuclixFont.o
	
	FireDit.o
	
	CmdHandlers.o
	FireShell.o

	Main.o
)

OUTPUT(Kernel.nsf)
Secondly, as I was browsing around about linker scripts, I noticed our wiki says something about the (*.rodata*) section for the ELF format and (*.rdata*) for the PE/COFF format. I'm wondering if I'm supposed to use this (I'm using ELF with a GCC Cross-Compiler):

Code: Select all

(*.rodata)
or this:

Code: Select all

(*.rodata*)
In tutorials and other OS' I usually see the first, but our wiki for some reason suggests the second. Finally, I would like to know where to put this section. Again, the wiki says in the text section, but I've noticed some people also put it in the data section of the script.

Thanks for your time,
Creature

EDIT: Just recently I found something new; I was testing my vector implementation with a custom class foo I quickly made to test some functions. I got a page-fault, then I started using the 'Print-Something-In-The-Bochs-Console' way to find out exactly where it page-faulted, and when I put this in front of the function:

Code: Select all

BX_DebugStr("");  //Will output nothing as DebugStr will stop if the null-terminator is found.


The page-fault disappeared. I have no idea what is going on here and am amazed to see this fixed a page-fault, but the function doesn't do anything, and even if it did, it just writes to 2 or 3 ports that Bochs reads to print something in the background console!

Re: Couple Of Questions

Posted: Sat Jan 31, 2009 12:02 pm
by Brendan
Hi,
Creature wrote:

Code: Select all

BX_DebugStr("");  //Will output nothing as DebugStr will stop if the null-terminator is found.


The page-fault disappeared. I have no idea what is going on here and am amazed to see this fixed a page-fault, but the function doesn't do anything, and even if it did, it just writes to 2 or 3 ports that Bochs reads to print something in the background console!
Even though this seems like it should do nothing, it probably causes the compiler to shift temporary values from registers onto the stack (or into other memory locations), pushes the address of a NULL string onto the stack, calls the "BX_Debug()" function, cleans up the stack ("add esp,4") and then reloads temporary values into registers again; and it'd make your code slightly bigger (I don't know - maybe there's an important piece of data somewhere that you accidentally trash, and making the code a little bigger causes something that doesn't matter to be trashed instead). It might also cause the CPU to fetch new TLBs entries (and flush older TLB entries to make space for new ones); and it would effect the precise timing of everything (in case you've got race conditions).

The best thing to do in a situation like this is to make sure you can still make it crash - you don't want to do something innocent and lose your ability to find out if the problem is fixed (or just hidden).


Cheers,

Brendan

Re: Couple Of Questions

Posted: Fri Feb 06, 2009 11:13 am
by Creature
It turned out I had messed up some of the C++-dependent initialization functions. After reading and reworking most of the C++ part of my OS, the page-faults disappeared as magically as they came ;).