2017-09-20 9 views
7

Chociaż nie ma oficjalnie obsługiwanego sposobu, aby to zrobić. Czy istnieje sposób (w nowoczesnych systemach), aby wykryć, czy wskaźnik jest ze stosu (na przykład stos rozmówcy).Jak wykryć, czy pamięć jest ze stosu? (nie sterty lub zmienna statyczna)

Nawet jeśli to nie będzie działać jako część rzeczywistego logiki kodu, to może pomóc uniknąć błędów w konfiguracji, które mogą wykryć, np

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 ... */ 
} 
+4

Jeśli znasz początkowy wskaźnik stosu i znasz rozmiar stosu, możesz łatwo obliczyć, czy bieżąca zmienna znajduje się w zasięgu. Prostym przykładem byłoby zrobienie 'int main (void) {int firstVar; char * ptrToFirstVar = (char *) i firstVar;/* Teraz masz krótki początek stosu */char * endOfStack = ptrToFirstVar - yourSTACKSIZE; 'Następnie sprawdź, czy zmienna znajduje się pomiędzy początkiem stosu a rozmiarem stosu. – tilz0R

+0

@ tilz0R lub większość platform udostępnia interfejsy API do wysyłania zapytań o te informacje. –

+0

@AjayBrahmakshatriya skupić się na * na większości * części komentarza. – tilz0R

Odpowiedz

5

Ponieważ stos i układ pamięci nie jest standard C, nie ma oczywiście przenośnego sposobu określania pozycji stosu. Jeśli jednak kompilujesz system zarządzany przez system operacyjny, istnieje duża szansa, że ​​system operacyjny udostępni kwerendę API związaną przez stos.

W systemie Windows można to zrobić tak -

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


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

Ale należy pamiętać, że to da granice stos bieżącego wątku, zmienna może być położony na stosie innego wątku. W takim przypadku będziesz musiał powtórzyć przechodzenie przez uchwyty gwintów i porównać je z każdym związanym stosem. Możesz użyć do tego ThreadFirst i ThreadNext.

W systemie Linux można przeczytać plik /proc/<pid>/maps i wyszukać wpis [stack].

Powiązane problemy