347 Stimmen

Was ist der einfachste Weg, ein C++-Programm zum Absturz zu bringen?

Ich versuche, ein Python-Programm zu erstellen, das eine Schnittstelle zu einem anderen Crashy-Prozess hat (das liegt nicht in meiner Hand). Leider stürzt das Programm, mit dem ich eine Schnittstelle bilden will, nicht einmal zuverlässig ab! Also möchte ich ein schnelles C++-Programm machen, das absichtlich abstürzt, aber ich weiß nicht wirklich den besten und kürzesten Weg, um das zu tun, weiß jemand, was ich zwischen meinen:

int main() {
    crashyCodeGoesHere();
}

um mein C++-Programm zuverlässig zum Absturz zu bringen

36voto

Macke Punkte 23640
 throw 42;

Genau die richtige Antwort... :)

17voto

Dan F Punkte 17354

assert(false); ist auch ziemlich gut.

Nach ISO/IEC 9899:1999 wird es garantiert zum Absturz kommen, wenn NDEBUG nicht definiert ist:

Wenn NDEBUG definiert ist [...], ist das Assert-Makro einfach definiert als

#define assert(ignore) ((void)0)

Das Assert-Makro wird entsprechend dem aktuellen Zustand von NDEBUG jedes Mal neu definiert, wenn es eingebunden wird.

[...]

Das assert-Makro fügt diagnostische Tests in Programme ein; [...] wenn der Ausdruck (der einen skalaren Typ haben muss) falsch ist [...]. Es ruft dann die Abbruchfunktion auf.

12voto

PlasmaHH Punkte 15095

Da ein Absturz ein Symptom für das Aufrufen von undefiniertem Verhalten ist, und da das Aufrufen von undefiniertem Verhalten zu allem führen kann, einschließlich eines Absturzes, glaube ich nicht, dass Sie Ihr Programm wirklich abstürzen lassen wollen, sondern es nur in einen Debugger fallen lassen wollen. Der portabelste Weg, dies zu tun, ist wahrscheinlich abort() .

Während raise(SIGABRT) hat die gleiche Wirkung, es ist sicherlich mehr zu schreiben. Beide Wege können jedoch abgefangen werden, indem man einen Signalhandler für SIGABRT . Je nach Ihrer Situation möchten/müssen Sie also vielleicht ein anderes Signal setzen. SIGFPE , SIGILL , SIGINT , SIGTERM ou SIGSEGV könnte der richtige Weg sein, aber sie können alle abgefangen werden.

Wenn Sie unbeweglich sind, haben Sie vielleicht sogar noch mehr Möglichkeiten, z. B. mit SIGBUS unter Linux.

10voto

Paul Biggar Punkte 25771

Die Antwort ist plattformspezifisch und hängt von Ihren Zielen ab. Aber hier ist die Mozilla-Javascript-Absturzfunktion, die meiner Meinung nach viele der Herausforderungen veranschaulicht, die es zu meistern gilt:

static JS_NEVER_INLINE void
CrashInJS()
{
    /*
     * We write 123 here so that the machine code for this function is
     * unique. Otherwise the linker, trying to be smart, might use the
     * same code for CrashInJS and for some other function. That
     * messes up the signature in minidumps.
     */

#if defined(WIN32)
    /*
     * We used to call DebugBreak() on Windows, but amazingly, it causes
     * the MSVS 2010 debugger not to be able to recover a call stack.
     */
    *((int *) NULL) = 123;
    exit(3);
#elif defined(__APPLE__)
    /*
     * On Mac OS X, Breakpad ignores signals. Only real Mach exceptions are
     * trapped.
     */
    *((int *) NULL) = 123;  /* To continue from here in GDB: "return" then "continue". */
    raise(SIGABRT);  /* In case above statement gets nixed by the optimizer. */
#else
    raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */
#endif
}

9voto

Abhinav Punkte 1506

Ich sehe, es gibt viele Antworten hier gepostet, die in Glücksfälle fallen, um den Job zu erledigen, aber keiner von ihnen sind 100% deterministisch zum Absturz. Einige werden auf einer bestimmten Hardware und einem bestimmten Betriebssystem abstürzen, andere nicht. Es gibt jedoch eine Standardmethode gemäß dem offiziellen C++-Standard, um es zum Absturz zu bringen.

Zitiert von C++ Standard ISO/IEC 14882 §15.1-7 :

Wenn der Mechanismus zur Behandlung von Ausnahmen nach Abschluss der Initialisierung des Ausnahmeobjekts, aber vor der Aktivierung eines Handlers für die Ausnahme, eine Funktion aufruft, die durch eine Ausnahme beendet, wird std::terminate aufgerufen (15.5.1).

struct C {
    C() { }
    C(const C&) {
        if (std::uncaught_exceptions()) {
            throw 0; // throw during copy to handler’s exception-declaration object (15.3)
        }
    }
};
int main() {
    try {
    throw C(); // calls std::terminate() if construction of the handler’s
    // exception-declaration object is not elided (12.8)
    } catch(C) { }
}

Ich habe einen kleinen Code geschrieben, um dies zu demonstrieren, und er kann gefunden und ausprobiert werden unter Ideone hier .

class MyClass{
    public:
    ~MyClass() throw(int) { throw 0;}
};

int main() {
  try {
    MyClass myobj; // its destructor will cause an exception

    // This is another exception along with exception due to destructor of myobj and will cause app to terminate
     throw 1;      // It could be some function call which can result in exception.
  }
  catch(...)
  {
    std::cout<<"Exception catched"<<endl;
  }
  return 0;
}

ISO/IEC 14882 §15.1/9 Erwähnungen werfen ohne Try-Block, was zu einem impliziten Aufruf zum Abbruch führt:

Wenn derzeit keine Ausnahme behandelt wird, wird e throw-Ausdrucks ohne Operand std::terminate() aufgerufen

Andere sind: Wurf aus dem Destruktor: ISO/IEC 14882 §15.2/3

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X