Page fault generated when switching task

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
raywill

Page fault generated when switching task

Post by raywill »

I get 3 tasks running in my os,using round-robin.

At first these tasks can switch smoothly .
But after a little while (5 to 10 seconds ) there is a Page Fault.Incorrect memory was accessed.

What is the problem do you think?

P.S. my tasks just do infinate loop and print some text.

Code: Select all

void test_task1(void){

???int i=1,j=1;
???char buf[20];
???clrscr();
???print("Hello from task 1\n");
???while(j++<0xffffff)
??????print("Hello from task 1\n");
????while(1);
}

void test_task2(void){
???int i=2,j=1;
???char buf[20];
while(j++<0xfffffff)
???print("Hello from task 2\n");
while(1);
}
edit: the third one is alike
paulbarker

Re:Page fault generated when switching task

Post by paulbarker »

Wheres the 3rd task?

Can you tidy up that code, remove the unused stuff and run it through gcc with the "-Wall" option?

Doesn't itoa take 3 arguments? radix?

Does print() work properly, are you sure you're not running off the end of the screen memory?

Lastly, the problem is much more likely to be in your scheduler or task switching code rather than the tasks themselves.
raywill

Re:Page fault generated when switching task

Post by raywill »

Does print() work properly, are you sure you're not running off the end of the screen memory?
I am quite sure print() works fine.
paulbarker

Re:Page fault generated when switching task

Post by paulbarker »

I am quite sure print() works fine.
Is it thread safe?

I suggest you get the task switching code to dump all the task data when it switches, that showed a few problems in my code. Also try just 2 tasks, and depending on how your thread switching works, maybe try just 1 task (my code would still do a thread switch even if the thread to be switched to was the thread already running).
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Page fault generated when switching task

Post by Pype.Clicker »

if the problem can be reproduced in BOCHS, i suggest you let the test running with "trace-on". That should provide you a exhaustive list of executed instructions eventually ending with the faulty one.

I suspect either your print("xxx") isn't thread-safe (e.g. if you have general variables and no locking...) or that your switching process doesn't restore the stack as expected and results in a slowly growing (and eventually getting wrong) stack.

Of course, knowing eIP and CR3 for the fault will help you to figure out where things goes wrong ...
raywill

Re:Page fault generated when switching task

Post by raywill »

Pype.Clicker wrote: I suspect either your print("xxx") isn't thread-safe (e.g. if you have general variables and no locking...) or that your switching process doesn't restore the stack as expected and results in a slowly growing (and eventually getting wrong) stack.
Maybe my print("**") isn't thread-safe.....
here is my print():

Code: Select all

#define TAB_SIZE 8
#define thisline(vp) ((vp -VIDMEM)%80)
#define thisrow(vp)   ((vp -VIDMEM)/80)

unsigned short* const VIDMEM = ((unsigned short*) 0xB8000);
unsigned long* const XVIDMEM = ((unsigned long*) (0xB8000+0xC0000000));
static void clear( void );

unsigned short * vp;
void print( const char* str )
{
    if( vp>=VIDMEM+80*25 )
       {
          clear();
          vp=VIDMEM   ;
       }
    while (*str != '\0')
    {
        if(*str=='\n')
              {
              vp=vp + 80 - (vp -VIDMEM) % 80;
              str++;
              continue;
           }
        if(*str=='\t')
           {
              vp=vp+TAB_SIZE-thisline(vp)%TAB_SIZE;
              str++;
              continue;   
           }
        *vp++ = (0x0600 | ((unsigned short) *str++));
    }

}
Can you give me any instruction on how to write a thread-safe print();?
Thanks .
Senaus

Re:Page fault generated when switching task

Post by Senaus »

raywill wrote: Can you give me any instruction on how to write a thread-safe print();?
The easiest way would be to disable interrupts for the duration of the print();

For example:

Code: Select all

void print( const char* str )
{
    __asm volatile("cli" ::);

    ...

    __asm volatile("sti" ::);
}
However, you will also need spinlocks if you want to be SMP safe.

Cheers
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Page fault generated when switching task

Post by Pype.Clicker »

it is indeed not thread safe in the sense that accesses to global pointer "vp" are not protected in any way, yet all updates of vp should be "atomic" and thus there shouldn't be possible (assuming decent compiler) to trash that pointer...
The worse you will get with that code is "missing" characters (as some of them might be "replaced" by characters printed by another thread)

So probably your problem is more with stack. I suggest you print your "esp" address in the loops (or track its value somehow). If everything works fine, the loop should always keep the same ESP for the sme thread.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:Page fault generated when switching task

Post by Colonel Kernel »

Pype.Clicker wrote: yet all updates of vp should be "atomic" and thus there shouldn't be possible (assuming decent compiler) to trash that pointer...
This doesn't look atomic to me:

Code: Select all

vp=vp + 80 - (vp -VIDMEM) % 80;
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
raywill

Re:Page fault generated when switching task

Post by raywill »

Colonel Kernel wrote:
Pype.Clicker wrote: yet all updates of vp should be "atomic" and thus there shouldn't be possible (assuming decent compiler) to trash that pointer...
This doesn't look atomic to me:

Code: Select all

vp=vp + 80 - (vp -VIDMEM) % 80;
Thanks,everyone.
It IS because of the unprotected vp pointer.
After I added sti and cli in print(),everything works fine now.

I am now considering to give each task a virtual console :)
Post Reply