4

Is there a direct method in which the values of the stack_start and stack_end symbols can be referenced in a 'C' function? I can do this using a bit of assembler to read each symbol and place it to a variable that has been given the 'used' attribute. For example.

static __attribute__((used)) UI_32 StkStart;

__asm__
(
    "LDR R0, =__stack_start__ \n"
    "LDR R1, =StkStart\n"
    "STMIA.W R1, {R0}\n"
);

Is there a way to avoid the use of assember here?

The reason that I need to do this is that my stack region is initialised to a particular pattern in the startup module and in order to determine how much of the stack has been used I can walk through the stack memory checking for changes to the original pattern.

phoxis
  • 60,131
  • 14
  • 81
  • 117
  • 1
    I hope this is not going into production code (why would you *ever* need the stack size unless exploiting a security vulnerability?) - so then you can experiment with UB an write stuff like `void *get_sp() { char a; return &a; }` –  May 23 '13 at 07:07
  • As already stated previously, to get an idea of stack usage! – user1704021 May 23 '13 at 09:09
  • if the assembler/linker can resolve the above by name, then it should work, from C, to simply say `extern UI_32* __stack_start__, __stack_end__`. They're defined via linker script, http://stackoverflow.com/questions/13831462/understanding-the-location-counter-of-gnu-linker-scripts – FrankH. May 23 '13 at 12:16
  • Beyond that ... the above are _only valid_ for singlethreaded processes / for the `main` thread in a multithreaded process. In general, glibc exposes the runtime stack limits via `pthread_getattr_getstack()`, see http://man7.org/linux/man-pages/man3/pthread_getattr_np.3.html for an example how to use it for this. – FrankH. May 23 '13 at 12:37

2 Answers2

1

There is no direct way in C to access stack_start and stack_end symbols. You have to use Assembly code to access the stack memory.

Deepu
  • 7,592
  • 4
  • 25
  • 47
1

It may be possible to get a rough idea of stack usage:

#include <stdio.h>

char *stack_top;

void f() {
  int stack;
  char tab[1 << 20];
  char stack_end;

  stack = stack_top - &stack_end;
  printf("%d.\n", stack);
}

void main() {
  char dummy;
  stack_top = &dummy;

  f();
  exit(0);
}

sample run:

$ gcc stack.c -o stack
$ ./stack
1048624.
xtof pernod
  • 862
  • 5
  • 7
  • 1
    This is wrong on so many levels. A ton of unstated assumptions about where stuff is in the address space? void main? – Jens Dec 03 '15 at 22:03