Какой самый простой способ вызвать сбой программы на C ++? - PullRequest
306 голосов
/ 13 декабря 2011

Я пытаюсь создать программу на Python, которая взаимодействует с другим аварийным процессом (это не в моих руках). К сожалению, программа, с которой я взаимодействую, даже не дает сбоя! Поэтому я хочу сделать быструю программу на C ++, которая намеренно зависает, но я не знаю, какой самый лучший и кратчайший способ сделать это, кто-нибудь знает, что можно поставить между моими:

int main() {
    crashyCodeGoesHere();
}

для надежного сбоя моей программы на C ++

Ответы [ 28 ]

251 голосов
/ 13 декабря 2011

Функция abort(), вероятно, является вашей лучшей ставкой. Она является частью стандартной библиотеки C и определяется как «вызывающая ненормальное завершение программы» (например, фатальная ошибка или сбой).

110 голосов
/ 13 декабря 2011

Попробуйте:

raise(SIGSEGV);  // simulates a standard crash when access invalid memory
                 // ie anything that can go wrong with pointers.

Найдено в:

#include <signal.h>
73 голосов
/ 14 декабря 2011

При делении на ноль произойдет сбой приложения:

int main()
{
    return 1 / 0;
}
63 голосов
/ 13 декабря 2011
*((unsigned int*)0) = 0xDEAD;
51 голосов
/ 13 декабря 2011

Хорошо, мы находимся в стеке переполнении или нет?

for (long long int i = 0; ++i; (&i)[i] = i);

(Не гарантируется сбой по каким-либо стандартам, но ни один изпредлагаемые ответы, в том числе и принятые, поскольку SIGABRT можно было бы поймать в любом случае. На практике это будет происходить везде.)

34 голосов
/ 17 декабря 2011
 throw 42;

Просто ответ ...:)

15 голосов
/ 13 декабря 2011

assert(false); тоже довольно хорошо.

В соответствии с ISO / IEC 9899: 1999 гарантированно произойдет сбой, когда NDEBUG не определен:

Если определен NDEBUG [...] макрос assert определяется просто как

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

макрос assert переопределяется в соответствии с текущим состоянием NDEBUG при каждом включении.

[...]

Макрос assert помещает диагностические тесты в программы;[...] если выражение (которое должно иметь скалярный тип) является ложным [...].Затем он вызывает функцию прерывания.

11 голосов
/ 13 декабря 2011

Поскольку сбой является признаком вызова неопределенного поведения, и поскольку вызов неопределенного поведения может привести к чему угодно, включая сбой, я не думаю, что вы действительно хотите вывести свою программу из строя, но просто поместите ее в отладчик. Наиболее переносимый способ сделать это, вероятно, abort().

Хотя raise(SIGABRT) имеет тот же эффект, это, безусловно, больше писать. Однако оба способа могут быть перехвачены путем установки обработчика сигнала для SIGABRT. Поэтому, в зависимости от вашей ситуации, вы можете / должны поднять другой сигнал. SIGFPE, SIGILL, SIGINT, SIGTERM или SIGSEGV могут быть подходящим способом, но все они могут быть перехвачены.

Когда вы можете быть непереносимыми, ваш выбор может быть еще шире, например, использование SIGBUS в Linux.

9 голосов
/ 13 декабря 2011

Ответ зависит от платформы и зависит от ваших целей.Но вот функция сбоя Mozilla Javascript, которая, я думаю, иллюстрирует множество проблем, которые могут возникнуть при выполнении этой работы:

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
}
9 голосов
/ 13 декабря 2011

Единственная вспышка, которая у меня была, это функция прерывания () :

Прерывает процесс с ненормальным завершением программы. Генерирует сигнал SIGABRT , который по умолчанию вызывает завершение программы, возвращая код ошибки при неудачном завершении в среду хоста. Программа завершается без выполнения деструкторов для объектов автоматической или статической длительности хранения и без вызова any atexit (которая вызывается методом exit () до завершения программы). Он никогда не возвращается к своему абоненту.

...