GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wert des Stapelzeigers ausgeben

Ein Trick, der nicht portabel ist oder gar nicht garantiert funktioniert, besteht darin, einfach die Adresse eines Einheimischen als Hinweis auszudrucken.

void print_stack_pointer() {
  void* p = NULL;
  printf("%p", (void*)&p);
}

Dadurch wird im Wesentlichen die Adresse von p ausgegeben das ist eine gute Annäherung an den aktuellen Stapelzeiger


Dafür gibt es keine tragbare Möglichkeit.

In GNU C kann dies für Ziel-ISAs funktionieren, die ein Register namens SP haben, einschließlich x86, wo gcc "SP" als Abkürzung für ESP oder RSP erkennt.

// broken with clang, but usually works with GCC
register void *sp asm ("sp");
printf("%p", sp);

Diese Verwendung lokaler Registervariablen wird jetzt von GCC abgelehnt:

Die einzige unterstützte Verwendung für diese Funktion ist die Angabe von Registern für Eingabe- und Ausgabeoperanden beim Aufruf von Extended asm

Durch die Definition einer Registervariablen wird das Register nicht reserviert. Außer beim Aufrufen des erweiterten asm wird der Inhalt des angegebenen Registers nicht garantiert. Aus diesem Grund werden die folgenden Verwendungen ausdrücklich nicht unterstützt. Wenn sie zu funktionieren scheinen, ist das nur Zufall , und funktioniert möglicherweise aufgrund von (scheinbar) nicht zusammenhängenden Änderungen im umgebenden Code oder sogar geringfügigen Änderungen in der Optimierung einer zukünftigen Version von gcc nicht mehr wie beabsichtigt. ...

Es wird auch in der Praxis mit clang gebrochen, wo sp wird wie jede andere nicht initialisierte Variable behandelt.


Zusätzlich zur Antwort von duedl0r mit speziell GCC Sie könnten __builtin_frame_address(0) verwenden was GCC-spezifisch ist (aber nicht x86 spezifisch).

Dies sollte auch auf Clang funktionieren (aber es gibt einige Fehler).

Es ist auch eine Lösung, die Adresse eines Einheimischen zu nehmen (wie JaredPar antwortete).

Beachten Sie, dass AFAIK der C-Standard theoretisch keinen Call-Stack benötigt.

Man könnte von einer anderen Technik träumen. Und Sie könnten Stapel geteilt haben (zumindest auf dem neuesten GCC), in diesem Fall hat der Begriff des Stapelzeigers viel weniger Sinn (weil der Stapel dann nicht zusammenhängend ist und aus vielen Segmenten mit jeweils wenigen Aufrufrahmen bestehen könnte). .


Linux
  1. Zeitüberschreitung in einem Shell-Skript?

  2. Linux – Wie finde ich die Intel-Architekturfamilie über die Befehlszeile heraus?

  3. Nach Hex-Wert sortieren?

  4. Linux – Wie kann man herausfinden, ob sich Dateien in einem Ordner befinden und entsprechend beenden (in Ksh)?

  5. Curl schreibt den Wert eines bestimmten Headers aus

Aufrufliste in C oder C++ drucken

Wie erhalte ich einen Stack-Trace für C++ mit gcc mit Zeilennummerinformationen?

Verhindern des C-Integer-Überlaufs

Das Ausführen von 'gcc' auf einer C++-Quelldatei unter Linux gibt cc1plus:out of memory allocating ... Fehlermeldung

Was setzt fs:[0x28] (Stack Canary)?

Können Sie jedes Programm in Linux dazu bringen, einen Stack-Trace zu drucken, wenn es einen Segfault hat?