How to determine if a given address is on the heap or on the stack

I have a requirement to determine if a given address is on the heap or on the stack. Is there a reliable way to do this on Linux?

I thought of the next approach, assuming the stack would grow down and the heap would grow to stack. How reliable is this solution? We do not use gcc split-stack .

 is_stack (void *addr) { int a; if( &a < addr) return stack; else return heap } 

[edit - I saw a similar question, but more theoretical in nature]

+7
c gcc linux unix
source share
2 answers

Firstly, you may have several stacks in a process , in particular if it is multi-threaded (and some libraries may run threads without asking you to). And your virtual address space process can have more segments than just a heap and a stack.

You can parse the pseudo file /proc/self/maps . See proc (5) . Note that since this is a pseudo file that is generated by the kernel, there is no physical I / O, and reading and parsing this /proc/self/maps file should be really fast.

The address map of your process can change by calling mmap (2) , munmap , execve , mprotect and some other system calls (see syscalls (2) for a list of them); use strace (1) to understand which system calls are made. Any call to malloc (internally called by many functions, including fopen ...) or free (before dlopen , etc. etc.) could (but not always) use them, so caching the result of parsing /proc/self/maps not a reliable option.

First try the cat /proc/$$/maps command in the terminal (showing you a description of the virtual address space of your shell).

As many have noted, because of ASLR, you have no idea of ​​the relative position of the stack and heap, even if there is one single stack. A possible trick would be to start your main with something putting the address of some local variable (or even from main argc first argument or from argv[0] ) in some global void*stackbottom; and then to compare the address like you, this is an if( &a < addr && &a > stackbottom) test if( &a < addr && &a > stackbottom) . Please note that the Boehm garbage collector does similar things.

But the most reliable way is to read and parse /proc/self/maps , and this should be pretty fast and, of course, be a software solution (the kernel dynamically provides information about the state and state of the process through /proc/ , and the physical IO is involved in reading it).

And yet, being on the stack or on the heap is a poorly defined property of pointers (in other words, a stack or a heap is a much more complicated concept than what you imagine). You need to be more precise about what you really want to do.

Redefine your own malloc , free , etc. and save the malloc memory card.

+4
source share

There is no concept of heap or stack in the C standard, so the language itself cannot tell you.

But you mentioned Linux, so everything is not lost - you can achieve this with honest work.

If you define a heap as the memory allocated by malloc , you might consider creating your own memory allocation system. Many C compilers allow you to use a different malloc at a time for all the libraries associated with your program, so this approach is entirely possible. (See LD_PRELOAD). Of course, the main guts of your malloc replacement will simply cause a standard function. But the other part will support the allocated memory table. You can use this information in a test function that you need to write.

You will need to do the same for calloc , free , & c.

+2
source share

All Articles