c - Why is the stack size different in different runs of the same program? -


consider following program. takes argument command line , unrolls recursive function limit.

#include <stdio.h> #include <stdlib.h>  int rec(int x, int limit) {   if (x == limit) {     return limit;   }   int r = rec(x + 1, limit);   return r - 1; }  int main(int arc, char* argv[]) {   int result, limit;   limit = atoi(argv[1]);   printf("stack: %p\n", &result);   result = rec(0, limit);   printf("%d\n", result); } 

if compile expect run out of stack fixed input argument limit. else happens.

dejan@raven:~/test/stack$ gcc stack.c dejan@raven:~/test/stack$ ./a.out 174580 stack: 0x7fff42fd58f0 segmentation fault (core dumped) dejan@raven:~/test/stack$ ./a.out 174580 stack: 0x7ffdd2dd8b20 0 

in 2 different runs, stack size seems different. doesn't seem compiler issue same thing happens clang, , disassembly doesn't involve strange.

why stack sizes on different runs different?

i have added /proc/self/maps parser program (same approach @andrewhenle advises, on start of program, , not invoke pmap):

char* get_stack_bounds() {     file* maps = fopen("/proc/self/maps", "r");     static char line[256];      while(!feof(maps)) {         fgets(line, 255, maps);         if(strstr(line, "[stack]")) {             char* space = strchr(line, ' ');             *space = '\0';             fclose(maps);             return line;         }     }      fclose(maps);     return null; }  unsigned long get_stack_right() {     char* bounds = get_stack_bounds();     bounds = strchr(bounds, '-') + 1;     return strtol(bounds, null, 16); } 

and dump information in beginning of main():

printf("&result: %p delta: %ld\n", &result,       get_stack_right() - ((unsigned long) &result)); 

here results:

> ./a.out 104747 &result: 0x7fff3347c7f8 delta: 6152 0 > ./a.out 174580 &result: 0x7fffe43c9b38 delta: 5320 0 > ./a.out 174580 &result: 0x7fff26ad2b28 delta: 9432 segmentation fault (core dumped) > ./a.out 174580 &result: 0x7fff145aa5a8 delta: 6744 0 > ./a.out 174580 &result: 0x7fff74fff0b8 delta: 12104 segmentation fault (core dumped) 

i think correlation between delta (which difference between result address , base address of stack) , segmentation fault obvious.


you should note main() not first function runs in program, actual entry point _start() crt1.o (or whatever), initial stack size can differ.

actual problem address space layout randomization . here comment fs/binfmt_elf_fdpic.c regarding usage:

/* in cases (e.g. hyper-threading), want avoid l1 evictions  * processes running on same package. 1 thing can  * shuffle initial stack them, give architecture  * opportunity here.  */ sp = arch_align_stack(bprm->p); 

here implementation of arch_align_stack() on x86:

unsigned long arch_align_stack(unsigned long sp) {     if (!(current->personality & addr_no_randomize) && randomize_va_space)         sp -= get_random_int() % 8192;     return sp & ~0xf; } 

Popular posts from this blog