OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 5:29 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Page fault when accessing global c++ object method
PostPosted: Fri Jul 17, 2020 10:51 am 
Offline

Joined: Sun Apr 28, 2019 7:39 am
Posts: 22
Hi,

I have an issue with kernel space c++ objects that are global i.e. declared at the top of the file.
When I access a method inside the object, a call to another method causes a page fault.
The pagefault error code is 0 and CR2 is something that it shouldnt be which is definately not mapped, which is probably why the page fault happens.

The strange thing is that if the object is delacred inside a function (even as static) then it works great.
reating the object dynamically using new also works fine.

I followed the gudie here https://wiki.osdev.org/C%2B%2B#Introduction
The fact that its only global objects is some kind of hint but im not sure what exactly it could be

Can anyone point me in the right direction on what im missing?

Thanks


Top
 Profile  
 
 Post subject: Re: Page fault when accessing global c++ object method
PostPosted: Fri Jul 17, 2020 10:57 am 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 898
An object declared in a function will be stored on the stack. Thus its memory will most likely be mapped.

An object declared globally will be stored somewhere else (BSS or DATA section). Check where that object is in your binary image (make sure it exists) and see where it is loaded.

_________________
https://github.com/kiznit/rainbow-os


Last edited by kzinti on Fri Jul 17, 2020 11:02 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Page fault when accessing global c++ object method
PostPosted: Fri Jul 17, 2020 11:01 am 
Offline

Joined: Sun Apr 28, 2019 7:39 am
Posts: 22
I've identity mapped the entire kernel space according to the multiboot structure so it shouldnt't be a probme.
I also checked with qemu using tbl command and the page is mapped to the same address in physical memory

The problem is that one method calls another, which then causes the page fault.
The first method that is caused sits very close to the method that causes the page fault - they are in the same page.


Top
 Profile  
 
 Post subject: Re: Page fault when accessing global c++ object method
PostPosted: Fri Jul 17, 2020 11:04 am 
Offline
Member
Member

Joined: Mon Feb 02, 2015 7:11 pm
Posts: 898
Where/when/did you call the constructor for that global object? Perhaps you are crashing when trying to call a virtual function...

Using a C++ object that is not properly initialized is undefined behaviour.

_________________
https://github.com/kiznit/rainbow-os


Top
 Profile  
 
 Post subject: Re: Page fault when accessing global c++ object method
PostPosted: Fri Jul 17, 2020 11:20 am 
Offline

Joined: Sun Apr 28, 2019 7:39 am
Posts: 22
Ah how stupid of me the particular object that was causing the problem is declared as virtual.
Thanks for giving me a nudge in the right direction

The object is declared as a global so if I understand correctly the constructor should be called before my kernel main?

I can see that when its declared globally the constructor doesn't get called

I guess im missing something...


Top
 Profile  
 
 Post subject: Re: Page fault when accessing global c++ object method
PostPosted: Fri Jul 17, 2020 11:40 am 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1604
Normally, ELF constructors are run by the ELF loader (if you are using ELF, that is). However, in case of a kernel, that doesn't happen. The bootloader usually dumps your binary into memory, and then maybe clears BSS, and then that's your lot, then it jumps to your start symbol. If you do require constructors to run, you have to call them yourself. I'm going to continue guessing you use ELF, as I have no idea how exactly this works for PE. You can run all constructors just by running this code:

Code:
extern void (*__init_array_start[])(void) __attribute__((weak));
extern void (*__init_array_end[])(void) __attribute__((weak));
static void dummy(void) {}
extern void _init(void) __attribute((weak, alias("dummy")));

void run_constructors(void) {
  for (void (**it)(void) = __init_array_start; (uintptr_t)it < (uintptr_t)__init_array_end; it++)
    (*it)();
  _init();
}
Since I literally just came up with this code, you might want to check it for bugs. All these symbols should be declared by the linker. If you ever switch to a higher-half memory model, you can only run this code after the switching on paging. As for the constructors themselves, those are emitted by the compiler.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: Page fault when accessing global c++ object method
PostPosted: Fri Jul 17, 2020 11:55 am 
Offline

Joined: Sun Apr 28, 2019 7:39 am
Posts: 22
Thanks its now working...that was pretty painless. BTW...can I add the below code to the wiki? Is it editable by anyone?
I had to use nullplans answer with some stuff on the wiki. It explains a bit in https://wiki.osdev.org/index.php?title= ... ldid=14651 how to do it

Add this to your linker
Code:
.rodata ALIGN(0x1000) :
    {
        start_ctors = .;
        *(SORT(.ctors*))  /* Note the "SORT" */
        end_ctors = .;

        start_dtors = .;
        *(SORT(.dtors*))
        end_dtors = .;

        *(.rodata*)
        *(.gnu.linkonce.r*)
    }


Then somewhere in your main you can call

Code:

extern void (*start_ctors)(void) __attribute__((weak));
extern void (*end_ctors)(void) __attribute__((weak));

// Constructor list is defined in the linker script.
// The .ctors section is just an array of function pointers.
// iterate through, calling each in turn.
uintptr_t *iterator = reinterpret_cast<uintptr_t*>(&start_ctors);
while (iterator < reinterpret_cast<uintptr_t*>(&end_ctors))
{
    void (*fp)(void) = reinterpret_cast<void (*)(void)>(*iterator);
    fp();
    iterator++;
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: 8infy, Majestic-12 [Bot] and 225 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group