Frage

Ich teste Code, der ausgelegt ist, zu erkennen, wenn ein Kind Prozess segfaulted hat. Stellen Sie sich meine überrascht, wenn dieser Code nicht immer segfault:

#include <stdio.h>

int main() {
  char *p = (char *)(unsigned long)0;
  putchar(*p);
  return 0;
}

Ich laufe unter Debian Linux 2.6.26-Kernel; meine Schale ist die AT & T ksh93 vom Debian ksh Paket, Version M 93s + 2008-01-31. Manchmal dieses Programm segfault aber ansonsten einfach es endet leise mit einem von Null verschiedenen Exit-Status, aber keine Nachricht. Mein signaldetektierenden Programm meldet die folgende:

segfault terminated by signal 11: Segmentation fault
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 11: Segmentation fault
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19
segfault terminated by signal 53: Real-time signal 19

Beim Laufen unter reinem ksh zeigt, dass die segfault ist auch selten:

Running... 
Running... 
Running... 
Running... 
Running... 
Running... Memory fault
Running... 

Interessanterweise bash richtig erkennt die segfault jedes Mal, .

Ich habe zwei Fragen:

  1. Kann jemand dieses Verhalten erklären?

  2. Kann jemand empfehlen, ein einfaches C-Programm, das zuverlässig bei jeder Ausführung segfault wird? Ich habe auch triedkill(getpid(), SIGSEGV), aber ich habe ähnliche Ergebnisse.


EDIT: jbcreix hat die Antwort : mein segfault Detektor defekt war. Ich wurde getäuscht, weil ksh hat das gleiche Problem. Ich habe versucht, mit bash und bash macht es richtig jedes Mal.

Mein Fehler war, dass ich WNOHANG zu waitpid() vorging, wo ich Null vorbei sein sollte. Ich weiß nicht, was ich habe gedacht könnte! Man fragt sich, was mit ksh ist, aber das ist eine andere Frage.

War es hilfreich?

Lösung

Schreiben zu NULL zuverlässig segfault oder Bus-Fehler.

Manchmal wird ein O eine Nur-Lese-Seite auf die Null-Adresse zuordnen. So können Sie manchmal von NULL lesen.

Auch wenn C die NULL Adresse als Sonder definiert, die ‚Umsetzung‘ dieser besonderen Status wird durch das Betriebssystem des virtuellen Speichers tatsächlich behandelt (VM) Subsystem.

WEIN und dosemu Notwendigkeit, eine Seite auf NULL für Windows-Kompatibilität kartieren. Siehe mmap_min_addr im Linux-Kernel einen Kernel neu zu erstellen, die dies nicht tun.

mmap_min_addr ist derzeit ein heißes Thema aufgrund eines im Zusammenhang auszunutzen und eine öffentliche Flamme auf Linus (von Linux Ruhm, natürlich) von Theo de Raadt, des OpenBSD Aufwand.

Wenn Sie das Kind auf diese Weise bereit, um Code sind, können Sie jederzeit anrufen: raise(SIGSEGV);

Sie können aber auch einen Zeiger garantiert zu segfault erhalten von: int *ptr_segv = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS, -1, 0);

Wo PROT_NONE ist der Schlüssel Speicher zu reservieren, die nicht zugegriffen werden kann. Für 32-Bit-Intel-Linux, PAGE_SIZE 4096.

Andere Tipps

Ich bin nicht sicher, warum es nicht ein konsistentes Verhalten hat. Ich würde denken, dass es mit dem Lesen nicht als nit-wählerisch ist. Oder so ähnlich, obwohl ich würde wahrscheinlich völlig falsch sein.

Versuchen Sie, bei NULL schreiben. Dies scheint für mich, konsequent zu sein. Ich habe keine Ahnung, warum Sie wollen würde dies aber verwenden. :)

int main()
{
    *(int *)0 = 0xFFFFFFFF;
    return -1;
}

Die Antwort auf Frage Nummer zwei von Wikipedia :

 int main(void)
 {
     char *s = "hello world";
     *s = 'H';
 }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top