Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an automatic variable in this setjmp/longjmp context?

Tags:

c

unix

Advanced Programming in the UNIX Environment by W. Richard Stevens states:

"What are the the states of the automatic variables and register variables in the main function?"

with regard to what happens when you longjmp back to main (or another function) from somewhere lower down the stack.

It goes on to say:

"It depends. Most implementations do not try to roll back these automatic variables and register variables, but all that the standards say is that their values are indeterminate. If you have an automatic variable that you don't want rolled back, define it with the volatile attribute. Variables that are declared global or static are left alone when longjmp is executed.

It seems like he's saying that normal stack-variables will not have their values set back to what they were at the time of the setjmp - but then the rest of the function couldn't rely on its stack variables after the longjmp back to it which seems crazy, so I'm guessing I'm wrong.

Can someone define "automatic variables" for me and explain what specifically isn't set back to its original value and why that is?

like image 672
John Humphreys Avatar asked Feb 02 '23 14:02

John Humphreys


2 Answers

All it's saying is that if

  1. you have an automatic (function-local non-static) variable that's not declared volatile; and
  2. you change the value of the variable between setjmp and longjmp

then after the longjmp the value of that variable becomes indeterminate.

I believe this has to do with the possibility of such variables residing in CPU registers rather than in RAM, and the associated difficulty of preserving the values of such variable across the longjmp.

Here is a quote from the gcc manual:

If you use longjmp, beware of automatic variables. ISO C says that automatic variables that are not declared volatile have undefined values after a longjmp. And this is all GCC promises to do, because it is very difficult to restore register variables correctly, and one of GCC's features is that it can put variables in registers without your asking it to.

If the potential loss of variable values is a problem in your use case, declare the relevant variables as volatile.

like image 74
NPE Avatar answered Feb 08 '23 15:02

NPE


"Automatic variables" is an old term for ordinary (not declared with register or static) local variables, which goes back to terminology used in the C standard and the original meaning of the auto keyword. See sections 6.2.4 and 6.7.1 of the standard

As for this:

but then the rest of the function couldn't rely on its stack variables after the longjmp back to it which seems crazy

The idea is that you're not supposed to modify them in the first place if you're going to longjmp because then you can't know what's going to happen.

The reason is that longjmp may restore state such as processor registers, which automatic variables may have been mapped to (there is no guarantee that they will be on "the stack" or in memory at all. And even if they do exist in memory, some operations may not [unless it is declared volatile] directly access the memory but may access a processor register which the value has already been loaded into)

Your question is kind of odd because it implies you would want them to be restored [i.e. your modifications in intervening functions to be erased] - in general this caveat is warning that they may be restored by accident when it's not expected. "Not restored" doesn't mean "unusable" [though the standard DOES declare them unusable because it might restore a cached register but not the memory so you'll get inconsistent results], it means "has the value a later function wrote to it (because you passed the address intending for it to be written to)".

like image 41
Random832 Avatar answered Feb 08 '23 14:02

Random832