Page 1 of 1

Function calls inside tasks doesn't work

Posted: Mon Feb 26, 2007 5:04 am
by sampath
I am doing the software multitasking,but inside the tasks if I have any function calls,the system is restarting.

Pseudo:
Task1()
{

fun1();

}


fun1()
{

fun2();

}


Task2()
{

fun3();

}


fun3)
{

fun4();

}


TimerISR( )
{

SAVE_ALL
Swtich_to()
}

Switich_to()
{
RESTORE_ALL
Jmp CS:eip ;task2
}

Can any one help me in this..?? Plz ask me if u need more details ;-)

Cheers!
Sampath S

Posted: Mon Feb 26, 2007 5:11 am
by AJ
Hi,
A few thoughts:

Can you run this in an emulator such as Bochs? If so:

* Is your Stack valid for each task? If not, as soon as you do anything that pushes or pops (such as a function call...), you will get a triple fault. This is the most likely cause.

* Are you mixing ring0 and ring3 code? If so, ALL code called by your ring 3 tasks needs to be in ring 3 segments and 'user' pages.

* Are you using separate memory spaces? If so, how is your tasks page directory looking?

* Are CS, DS, ES, FS, GS and SS all valid (delete as applicable if not used!) ?

I would at least start by running this in Bochs and checking that ESP is where you expect it to be (and SS).

Cheers,
Adam

Posted: Fri Mar 02, 2007 12:12 am
by pcmattman
I have the same problem! Whenever my tasks call another function they first throw an Invalid Opcode, then a GPF, then a Debug, then the system restarts and I'm left with nothing :(. Any ideas?

Edit: I'm sure it's a problem with the tasks because I can do everything properly when I've disabled multitasking (ie. procedural, not concurrent)

Edit 2: Problem solved, turns out the only things stopping it are the text input routine (ie. gets)

Posted: Fri Mar 02, 2007 3:58 am
by AJ
Hi,

Im *sure* this must be stack trashing. Your c functions are, of course, setting EBP and ESP in every function call. If the stack is not right before your first function call, fine.

If, however, you then want to call and return from subsequent functions, this would be a problem. If your stack is trashed and you want to return from the *original* function, forget it :) !

Adam

Posted: Fri Mar 02, 2007 4:29 am
by XCHG
Normally, a sane compiler, when calling a procedure inside whatever context, should push the current procedure's offset onto the stack and then decrement the stack pointer by the number of bytes pushed and finally call the destination procedure. If the procedure in which another procedure is called, has local variables and/or parameters, then the *sane* compiler again must build the stack frame in this way:

Code: Select all

PUSH    EBP
MOV     EBP , ESP
SUB     ESP , NUMBER OF BYTES TO ALLOCATE

  ; CALL OTHER PROCEDURES, ETC
  
ADD     ESP , NUMBER OF BYTES TO DEALLOCATE
POP     EBP
RET     NUMBER OF BYTES TO SWEEP OFF OF THE STACK

Posted: Fri Mar 02, 2007 5:39 pm
by pcmattman
I don't think you caught the drift of what I was trying to say...

In any function with code like this (for instance, this is from my gets procedure)

Code: Select all

while( !kbhit() )
{
    // wait for keyboard...
}
to do something like wait for keyboard input, I get a triple fault... However, if I put an instruction inside (like kputs( "A" )), no problems at all!

I just need to know what I'm doing wrong - why don't these sort of loops work?

Edit: forgot to mention, functions without this type of loop work without a hitch... also, this happens on any loop without any code execution, not just while( true ) loops.

Posted: Sun Mar 04, 2007 3:49 pm
by Combuster
By the looks of it, your scheduler is messing up something that causes your program to fail. A potential reason this only occurs in loops is that they keep the processor busy in a state which is different from the one the scheduler returns from.

I suggest you run bochs and make cpu dumps before and after each task switch, and compare them.