Saturday, September 13, 2014

Unix Prog: Non-Local Jump(2)

1. Variable Values

When we use longjmp to transfer control to lower stack entry, we need to be extremely careful that some variables are rolled back to values when setting up setjmp, some variables are not! And it is implementation dependent.

proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<setjmp.h>  
   
 jmp_buf jmpbuffer;  
 int globval;  
   
 static void f2()  
 {  
  longjmp(jmpbuffer, 1);  
 }  
   
 static void f1(int i, int j, int k, int l)  
 {  
  printf("in f1: ()\n");  
  printf("globval: %d, autoval: %d, regival: %d, volval: %d, statval: %d\n",  
      globval, i, j, k, l);  
  f2();  
 }  
   
 int main(int argc, char* argv[])  
 {  
  int autoval;  
  register int regival;  
  volatile int volval;  
  static int statval;  
   
  globval = 1;  
  autoval = 2;  
  regival = 3;  
  volval = 4;  
  statval = 5;  
   
  if(setjmp(jmpbuffer)!=0) {  
   printf("after long jmp: \n");  
   printf("globval: %d, autoval: %d, regival: %d, volval: %d, statval: %d\n",  
       globval, autoval, regival, volval, statval);  
   exit(0);  
  }  
   
  globval = 101;  
  autoval = 102;  
  regival = 103;  
  volval = 104;  
  statval = 105;  
   
  f1(autoval, regival, volval, statval);  
  exit(0);  
 }  

shell:
1) If we compile and link without the optimization option(-O), everything will not be rolled back.
2) If we compile and link with the optimization option(-O), register variable will be saved inside the CPU register, and it will be rolled back to value when setjmp is called to pack up the environment information.
 ubuntu@ip-172-31-23-227:~$ gcc -g proc.c -o proc.out  
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 in f1: ()  
 globval: 101, autoval: 102, regival: 103, volval: 104, statval: 105  
 after long jmp:  
 globval: 101, autoval: 102, regival: 103, volval: 104, statval: 105  
 ubuntu@ip-172-31-23-227:~$ gcc -g -O proc.c -o proc.out  
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 in f1: ()  
 globval: 101, autoval: 102, regival: 103, volval: 104, statval: 105  
 after long jmp:  
 globval: 101, autoval: 2, regival: 3, volval: 104, statval: 105  

2. Automatic Variables Problems
When exiting one function, the stack entry, including all automatic variables, will be released, and that memory space will be for future stack entry to use.
We should be extremely careful about the automatic variable.

proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
   
 FILE* open_file(void)  
 {  
  FILE *fp;  
  char databuf[BUFSIZ];  
   
  if((fp = fopen("test.txt", "r")) == NULL)  
   return NULL;  
  if(setvbuf(fp, databuf, _IOLBF, BUFSIZ) != 0)  
   return NULL;  
   
  // This is error, we declared databuf in open_file function  
  // After function exit, databuf space is released for future  
  // use. But returning FILE pointer will still use that buffer  
  // space to read in data, which will cause chaos  
   
  return fp;  
 }  
   
 int main(int argc, char* argv[])  
 {  
  FILE *fp = open_file();  
   
  /*  
   * Use fp to read in file content  
   */  
   
  exit(0);  
 }  

No comments:

Post a Comment