Page 1 of 1

Page fault generated when switching task

Posted: Fri Apr 07, 2006 10:17 am
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

Re:Page fault generated when switching task

Posted: Fri Apr 07, 2006 10:50 am
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.

Re:Page fault generated when switching task

Posted: Fri Apr 07, 2006 11:18 am
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.

Re:Page fault generated when switching task

Posted: Fri Apr 07, 2006 12:00 pm
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).

Re:Page fault generated when switching task

Posted: Mon Apr 10, 2006 4:05 am
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 ...

Re:Page fault generated when switching task

Posted: Mon Apr 10, 2006 9:05 am
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 .

Re:Page fault generated when switching task

Posted: Mon Apr 10, 2006 9:19 am
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

Re:Page fault generated when switching task

Posted: Mon Apr 10, 2006 9:21 am
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.

Re:Page fault generated when switching task

Posted: Mon Apr 10, 2006 9:42 am
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;

Re:Page fault generated when switching task

Posted: Mon Apr 10, 2006 10:59 pm
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 :)