2017-12-10 6 views
4

Während mit Speicherzuweisung zu tun, valgrind und gdb, ich hatte ein einfaches C-Programm mit einer ungültigen frei schreiben:Mysterious Linux Backtrace und Speicherkarte

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

int main (void) 
{ 
    int* arr = (void*) malloc(100 * sizeof(int)); 
    arr[50] = 10; 
    free(arr + (20 * sizeof(int))); 
    printf("arr[50] = %d\n", arr[50]); 
    return 0; 
} 

, die einen Fehler erzeugt, wie gewünscht:

*** Error in `./allocWithFunnyFree': free(): invalid pointer: ... *** 
======= Backtrace: ========= 
... 
======= Memory map: ======== 
... 

Dann habe ich versucht, die Ausgabe durch Umleiten sdtout und stderr zu /dev/null zu entfernen, aber bemerkte, dass die Ausgabe immer noch gedruckt werden würde, die mich verblüfft ließ.

ich das Programm eine Anweisung vor dem free() Aufruf mit einem Debugger stoped, sah das /proc/PID/fd dir und wieder versucht, alle aufgeführten fd des zu /dev/null aber noch gleiche Ergebnis Umleiten ..

ich nach Antworten online recherchiert und fragte einige von meinen Kollegen, aber niemand konnte mir erklären, wie diese Ausgabe gedruckt wird und warum sie nicht umgeleitet werden kann.

Sicher gibt es immer noch viele Dinge, die ich nicht über Betriebssysteme/Linux weiß, aber ich hoffe, Sie können mir helfen zu verstehen, was hier vor sich geht.
Danke!

Antwort

4

Die Backtraces (in glibc) are printed to /dev/tty, die ein anderer Dateideskriptor sein wird (es wird 3 in Ihrem Programm sein) als 1 und 2 und Ihre Shell weiß es nicht.

Glibc bietet eine Umgebungsvariable LIBC_FATAL_STDERR_ mit der Sie es an anderer Stelle umleiten können. Zum Beispiel können Sie Backtraces umleiten mit nach stderr:

$ export LIBC_FATAL_STDERR_=2 
$ ./allocWithFunnyFre 2>free_backtrace 

Wenn Sie Ihr Programm unter strace laufen, können Sie es besser verstehen können (und wie die Backtraces geschrieben werden).