Herausfinden, ob ein Zeiger auf den Stack, Heap oder Programmtext zeigt?

Lesezeit: 3 Minuten

Benutzer-Avatar
verblasste Biene

Gibt es eine Möglichkeit herauszufinden, ob ein Zeiger auf eine Stelle zeigt in:

  • der Stapel
  • der Haufen
  • oder das Programm (und wenn ja, welcher Abschnitt zB elf .text)?

Kann dies auch portabel durchgeführt werden (Linux 64/32 Bit, OSX und Windows 7+)?

nachverfolgen:

Ich versuche nicht herauszufinden, ob etwas mallociert wurde.

Ich möchte void*-Zeiger auf Funktionen im Programm effizient von void*-Zeigern auf Daten auf dem Stack oder Heap unterscheiden.

Dies ist für eine in C geschriebene Sprachlaufzeit, nicht für ein “normales” C-Programm.

Diese Antwort war bisher die nützlichste: Überprüfen, ob etwas Malloced war

  • Sehen Sie sich die Antworten auf diese Frage an.

    Benutzer529758

    3. Mai 2013 um 14:02 Uhr

  • Unter Windows können Sie WinDbg verwenden !address Erweiterung, um dies für Sie zu ermitteln. Ich weiß nichts über * nix-basierte Betriebssysteme.

    – Benutzer1354557

    3. Mai 2013 um 14:24 Uhr

Benutzer-Avatar
Diomidis Spinellis

Sie können auf portierbare Weise nicht tun, was Sie wollen, da der C-Sprachstandard den Stack, den Programmbereich und den Heap nicht als getrennte Bereiche spezifiziert. Ihre Position kann von der Prozessorarchitektur, dem Betriebssystem, dem Ladeprogramm, dem Linker und dem Compiler abhängen. Der Versuch zu erraten, wohin ein Zeiger zeigt, bricht die von C bereitgestellte Abstraktion, also sollten Sie das wahrscheinlich nicht tun.

Nichtsdestotrotz gibt es Möglichkeiten, Code zu schreiben, der für eine bestimmte Umgebung eine korrekte Vermutung anstellt. Dazu untersuchen Sie die Adressen vorhandener Objekte und suchen nach Mustern. Betrachten Sie das folgende Programm.

#include <stdlib.h>
#include <stdio.h>

void
function()
{
    int stack2;

    printf("stack2:  %15p\n", &stack2);
}

int
main(int argc, char *argv[])
{
    int stack;
    void *heap = malloc(1);
    void *heap2 = malloc(1);

    printf("program: %15p\n", main);
    printf("heap:    %15p\n", heap);
    printf("heap2:   %15p\n", heap2);
    printf("stack:   %15p\n", &stack);
    function();
    return 0;
}

Wenn Sie die Ausgabe untersuchen, können Sie ein Muster erkennen, wie z. B. das folgende unter x64-Linux.

program:        0x400504
heap:          0x1675010
heap2:         0x1675030
stack:    0x7fff282c783c
stack2:   0x7fff6ae37afc

Aus dem Obigen können Sie bestimmen, dass (wahrscheinlich) der Heap ab 0x1675010 aufwächst, alles darunter Programmcode (oder statische Daten, die Sie nicht erwähnt haben) und dass der Stack auf unvorhersehbare Weise wächst (wahrscheinlich aufgrund von Stack Randomisierung) um eine sehr große Adresse, wie 0x7fff282c783c.

Vergleichen Sie dies mit der Ausgabe unter 32-Bit-Intel-Linux:

program:       0x804842f
heap:          0x804b008
heap2:         0x804b018
stack:        0xbf84ad38
stack2:       0xbf84ad14

Microsoft Windows und der 32-Bit-Compiler von Microsoft C:

program:        01271020
heap:           002E3B00
heap2:          002E3B10
stack:          0024F978
stack2:         0024F964

gcc unter Windows Cygwin:

program:        0040130B
heap:           00A41728
heap2:          00A417A8
stack:          0028FF44
stack2:         0028FF14

gcc unter Intel 32-Bit FreeBSD:

program:       0x8048524
heap:          0x804b030
heap2:         0x804b040
stack:        0xbfbffb3c
stack2:       0xbfbffb1c

gcc unter Intel 64-Bit FreeBSD:

program:        0x400770
heap:        0x801006058
heap2:       0x801006060
stack:    0x7fffffffdaec
stack2:   0x7fffffffdabc

gcc unter SPARC-64 FreeBSD:

program:        0x100860
heap:         0x40c04098
heap2:        0x40c040a0
stack:     0x7fdffffe9ac
stack2:    0x7fdffffe8dc

PowerPC mit MacOS X:

program:          0x1ed4
heap:           0x100120
heap2:          0x100130
stack:        0xbffffba0
stack2:       0xbffffb38

PowerPC mit Linux:

program:      0x10000514
heap:         0x100c6008
heap2:        0x100c6018
stack:        0xbff45db0
stack2:       0xbff45d88

StrongARM mit NetBSD:

program:          0x1c5c
heap:             0x5030
heap2:            0x5040
stack:        0xefbfdcd0
stack2:       0xefbfdcb4

und ARMv6 unter Linux:

program:          0x842c
heap:           0xb63008
heap2:          0xb63018
stack:        0xbe83eac4
stack2:       0xbe83eaac

Wie Sie sehen, sind die Möglichkeiten endlos.

  • Unter Linux gibt mir /proc/self/maps alle Informationen, die ich brauche.

    – verblasste Biene

    7. Mai 2013 um 7:32 Uhr

  • Hast du irgendwie die Codezeile zum Erstellen vergessen heap2?

    – R Sahu

    19. Januar 2015 um 19:54 Uhr

Sie können die Position des Stapels und Haufens im Allgemeinen bestimmen, aber wie groß es ist, wird eine andere Geschichte sein …

void *heap_locations;
void *stack_location;

void determine_locations (int any_int) {
   free(heap_location = malloc(248));
   stack_location = &any_int;
}

int main(int argc, char *argv[]) {
  determine_locations(argc);
      .
      .
      .
  return 0;
}

Ein bisschen unhöflich und Sie werden die Expansionsrichtung oder -größe von beiden nicht mit absoluter Sicherheit kennen, es sei denn, Sie haben es mit bestimmten Plattformen zu tun.

1246190cookie-checkHerausfinden, ob ein Zeiger auf den Stack, Heap oder Programmtext zeigt?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy