How to detect if memory is from the stack? (not heap or a static variable)
Asked Answered
B

1

7

While there is no officially supported way to do this. Is there a way (on modern systems), to detect if a pointer is from the stack (stack of the caller for example).

Even if this is not going to work as part of actual code logic, it could help avoid errors in for the configurations that can detect it, eg:

void my_function(void *arg) {
    /* Only some configurations can do this (depending on compiler & arch). */
#if THE_MOONS_ALIGN
    assert(not_stack_memory(arg));
#endif

   /* ... actual logic ... */
}
Burroughs answered 20/9, 2017 at 6:27 Comment(10)
If you know your initial stack pointer and you know the stack size, then you can easily calculate if current variable is in range. Simple example would be to do int main(void) {int firstVar; char* ptrToFirstVar = (char *)&firstVar; /* Now you have brief beginning of stack */ char *endOfStack = ptrToFirstVar - yourSTACKSIZE; Then check if your variable is between start of stack and stack size.Mallard
@tilz0R or most platforms provide APIs to query this information.Skivvy
@AjayBrahmakshatriya focus to on most part of your comment.Mallard
@tilz0R focus to on modern systems in OPs question.Skivvy
@AjayBrahmakshatriya Embedded systems are for sure modern.Mallard
If you are windows you can look at - NtCurrentTeb()Skivvy
@tilz0R also, the approach of trying to determine stack bounds might not be enough since the variable could be on the stack of another thread.Skivvy
@AjayBrahmakshatriya There was nothing mentioned about OS, but in this case sure, OS is the one who should check this. I'm done here.Mallard
I would abandon this idea. Considering threads, address space layout randomization, signal stacks, etc. People do crazy things all the time. What is the actual problem you're solving? When I ran into a problem with certain things being unsafe when on the stack (buffers for DMA, while waiting for the DMA to finish the stack could be swapped out), debugging it became such a hassle that it was just easier and safer to make the code safe when called with stack data.Unclear
@art it's a reasonable position to take, OTOH, just because this doesn't work in all cases. Doesn't mean there aren't times it could be useful, even in a limited situation (as shown in the current answer). The actual problem I rather leave out of this general question. I can always ask another question with the specifics.Burroughs
S
6

Since stack and memory layout is not in the C standard, there is obviously no portable way to determine stack positions. However if you are compiling for a system managed by an operating system, there is good chance that the OS provides an API query the stack bounds.

On Windows it can be done as -

#include <windows.h>
struct _TEB {
        NT_TIB NtTib;
};


void *getStackBase(){
        return NtCurrentTeb()->NtTib.StackBase;
}
void *getStackLimit(){
        return NtCurrentTeb()->NtTib.StackLimit;
}

But be aware that this will give the stack bounds of the current thread, the variable could be situated on another thread's stack. In that case you will have to iterate over the thread handles and compare with each stack bound. You can use ThreadFirst and ThreadNext for that.

On Linux you can read the /proc/<pid>/maps file and look for the [stack] entry.

Skivvy answered 20/9, 2017 at 6:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.