Frage

Ich habe ein Programm, das gezielt eine Division durch Null durchführt (und speichert das Ergebnis in einem flüchtigen Variable), um unter bestimmten Umständen zu stoppen. Ich würde jedoch gerne in der Lage sein, diesen Anhalt zu deaktivieren, ohne das Makro zu ändern, der die Division durch Null führt.

Gibt es eine Möglichkeit, es zu ignorieren?

Ich habe versucht mit

#include <signal.h>
...
int main(void) {
  signal(SIGFPE, SIG_IGN);
  ...
}

, aber es stirbt nach wie vor mit der Meldung "Floating-Point exception (core dumped)".

ich eigentlich nicht den Wert verwenden, so dass ich weiß nicht wirklich, was den Variablen zugewiesen ist; 0, gelegentlich, undefined ...

EDIT: Ich weiß, dass dies nicht die tragbar ist, aber es ist für ein eingebettetes Gerät vorgesehen, die auf vielen verschiedenen Betriebssystemen laufen. Die Standard halte Aktion durch Null zu dividieren; andere Plattformen erfordern unterschiedliche Tricks eine Watchdog-induzierte reboot (mit deaktivierten Interrupts wie eine Endlosschleife) zu erzwingen. Für einen PC (Linux) Testumgebung, wollte ich die halt auf eine Division durch Null, ohne sich auf Dinge wie assert deaktivieren.

War es hilfreich?

Lösung

Warum sollte man bewusst eine Division durch Null zu stoppen durchführen? exit(-1) oder einige gleichwertige Könnten Sie nicht?

Vor allem, wenn Sie das Ergebnis der Division durch 0 nicht brauchen, dies macht einfach keinen Sinn machen.

Andere Tipps

Okay, zunächst einmal, sollen Sie werden mit sigaction (2) anstelle der veralteten signal().

Zum anderen mit SIGFPE für die Zwecke der Beendigung des Programms ist absurd, wie Sie ein Signal wie SIGTERM oder SIGUSR1 statt Jury-Rigging ein anderes Signal für seine Nebenwirkung sollte das Anheben und seine semantischen Wert zu vernachlässigen. Und genauer gesagt, der Mann Seite für sigaction (2) hat ein NOTES Abschnitt mit einem kurzen Text über SIGFPE, die ein oder zwei Möglichkeiten, Ihre beabsichtigten Gebrauch davon zeigt gebrochen ist.

Was Sie tun sollten, ist erhöhen (3) ein Signal, wenn Sie beenden möchten. Verwenden Sie dann das sa_handler Feld in der sigaction Struktur zu ändern, ob (SIG_IGN) oder beenden (SIG_DFL) auf diesem Signal zu ignorieren.

int main(void) {
  struct sigaction my_action;

  my_action.sa_handler = SIG_IGN;
  my_action.sa_flags = SA_RESTART;
  sigaction(SIGUSR1, &my_action, NULL);

  raise(SIGUSR1);  /* Ignored */

  my_action.sa_handler = SIG_DFL;
  sigaction(SIGUSR1, &my_action, NULL);

  raise(SIGUSR1); /* Terminates */

  return 0;
}

Das heißt, ich kann nicht sehen, warum Sie Signale anstelle eines einfachen exit() verwenden würde.

Überprüfen Sie den Rückgabewert von

signal(SIGFPE, SIG_IGN);

Wenn Sie SIG_ERR erhalten, überprüfen Sie den Wert errno, um herauszufinden, was schief gelaufen ist. Das ist so viel wie Sie portably tun können.

Ich weiß, Sie wollen nicht auf die Division durch Null ändern, aber es ist nicht portierbar und eingängig. Sie wollen coredump wenn eine Bedingung auftritt, aber in der Lage, dieses Verhalten zu deaktivieren, ohne Code zu bearbeiten? Verwenden Sie assert und NDEBUG.

Das ist nicht tragbar, aber auf x86 Sie durch die Steuerung der FPU können:

Mit gcc unter Linux (ich bin sicher, dass andere Compiler haben ähnliche Einrichtungen):

#include <fpu_control.h>

_FPU_SETCW (_FPU_DEFAULT);

Da _FPU_DEFAULT Standardwerte gesetzt _FPU_MASK_ZM (ZM steht für Zero Divide-Maske).

void handler(int trapId)
{
   // Whatever
}

signal(SIGFPE, handler);

Könnten Sie bewirken, dass das Programm durch einen weniger gekünstelt Ausdruck verlassen? Zum Beispiel:

#include <signal.h>

#ifdef DEBUG
#define DIE_HERE raise(SIGFPE)
#else
#define DIE_HERE
#endif

Ich würde zögern, das Standardverhalten außer Kraft zu setzen, damit nicht einem anderen Teil des Programms Division durch Null unbeabsichtigt. Alternativ, wenn Sie es verlassen auf diese Weise um sind Erzwingen ein Core Dump zu erhalten, können Sie in einem Debugger in der Verwendung von Haltepunkten suchen. Oder, wenn Sie auf einem System mit den GDB-Debugger sind, dann kann das gcore Dienstprogramm nützlich sein.

Wenn Sie die Kontrolle über den Absturz-Code haben, dann würde ich empfehlen, auch den Code zu ändern, um eine andere Art und Weise zu sterben. Wenn Sie dies nicht tun, könnten Sie versuchen, ein leeren Signal-Handler zu installieren statt (dh Verwendung signal(SIGFPE, &EmptyFunction)), aber Sie sind immer noch auf undefiniertes Verhalten verlassen, so gibt es keine Garantie, es noch auf anderen Systemen arbeitet, oder andere Kernel oder C Bibliotheksversionen.

lnmiit l über das Krachen Code, dann würde ich empfehlen, auch den Code zu ändern, um eine andere Art und Weise zu sterben. Wenn Sie dies nicht tun, könnten Sie versuchen, eine Installation

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top