Page 1 of 1

Passing a stack frame by value

Posted: Fri Sep 20, 2019 1:57 am
by unablegrid
I spent about three hours yesterday debugging an issue triggered by a gcc optimisation. I'm posting it in the hope that it may save someone some time. Basically, my ISR look like this:

Code: Select all

...
pusha
call handler
popa
...
iret
where handler is the following C function:

Code: Select all

void handler(isr_stack_frame_t stack)
{
   /* possibly do something to the stack */
}
Obviously (in retrospect), this is wrong, because the compiler is free to elide any modifications to stack that the function makes (and indeed it did so when compiling with -O2).

I wonder if there is a way to beat the compiler into submission by explaining that the stack is going to be valid after the call. For example, adding a call to an empty function (defined in another compilation unit!) that takes a pointer to the stack as argument does the trick, but I don't think it's guaranteed to. I guess the calling convention makes no guarantees about the validity of the arguments on the stack after the call, so I should probably give up and pass the stack frame by reference, shouldn't I?

Re: Passing a stack frame by value

Posted: Fri Sep 20, 2019 2:08 am
by Octocontrabass
You should.

Were you perhaps following a tutorial known to have this bug?

Re: Passing a stack frame by value

Posted: Fri Sep 20, 2019 2:11 am
by unablegrid
Were you perhaps following a tutorial known to have this bug?
Ahah, no, I take all the blame. :)

Re: Passing a stack frame by value

Posted: Fri Sep 20, 2019 2:44 am
by unablegrid
Note that the Little Book about OS Development makes the same mistake. Here's the github issue about it.