Каков самый простой способ сделать сбой программы на С++?

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

int main() {
    crashyCodeGoesHere();
}

чтобы сделать мою программу на С++ надежной

Ответ 1

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

Ответ 2

Try:

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

Найдено в:

#include <signal.h>

Ответ 3

Деление на ноль приведет к сбою приложения:

int main()
{
    return 1 / 0;
}

Ответ 4

*((unsigned int*)0) = 0xDEAD;

Ответ 5

Ну, мы в стеке переполнения, или нет?

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

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

Ответ 6

 throw 42;

Только ответ...:)

Ответ 7

assert(false); тоже неплохо.

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

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

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

Макрос утверждения переопределяется в соответствии с текущим состоянием NDEBUG каждый раз, когда он включен.

[...]

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

Ответ 8

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

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

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

Ответ 9

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

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

Ответ 10

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

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
}

Ответ 11

Я вижу, что здесь опубликовано много ответов, которые выпадут в удачных случаях, чтобы выполнить работу, но ни один из них не является на 100% детерминированным к краху. Некоторые будут зависать на одном оборудовании и ОС, другие - нет. Тем не менее, существует официальный способ, согласно официальному стандарту C++, сделать его аварийным.

Цитирование из стандарта C++ ISO/IEC 14882 §15.1-7:

Если механизм обработки исключений после завершения инициализации объекта исключения, но до активации обработчика исключения, вызывает функцию, которая завершается через исключение, вызывается std :: terminate (15.5.1).

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

Я написал небольшой код, чтобы продемонстрировать это, и его можно найти и попробовать на Ideone здесь.

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;
}

ИСО/МЭК 14882 §15.1/9 упоминает throw без блока try, что приводит к неявному вызову abort:

Если никакое исключение в настоящее время не обрабатывается, выполнение выражения броска без операндов вызывает std :: terminate()

Другие включают: бросок от деструктора: ISO/IEC 14882 §15.2/3

Ответ 12

Этот отсутствует:

int main = 42;

Ответ 13

*( ( char* ) NULL ) = 0;

Это приведет к ошибке сегментации.

Ответ 14

Как насчет вызовом рекурсивного метода мертвого цикла?

#include <windows.h>
#include <stdio.h>

void main()
{
    StackOverflow(0);
}

void StackOverflow(int depth)
{
    char blockdata[10000];
    printf("Overflow: %d\n", depth);
    StackOverflow(depth+1);
}

См. Исходный пример в Microsoft KB

Ответ 15

Это приводит к сбоям в моей системе Linux, потому что строковые литералы хранятся в постоянной памяти:

0[""]--;

Кстати, g++ отказывается компилировать это. Компиляторы становятся умнее и умнее:)

Ответ 16

int i = 1 / 0;

Ваш компилятор, вероятно, предупредит вас об этом, но он компилируется просто отлично под GCC 4.4.3 Это, вероятно, вызовет исключение SIGFPE (исключение с плавающей запятой), которое, возможно, не так вероятно в реальном приложении, как SIGSEGV (нарушение сегментации памяти), поскольку другие ответы вызывают, но это все еще крушение. На мой взгляд, это гораздо читаемо.

Другой способ, если мы собираемся обмануть и использовать signal.h, это:

#include <signal.h>
int main() {
    raise(SIGKILL);
}

Это гарантировано, чтобы убить подпроцесс, в отличие от SIGSEGV.

Ответ 17

Это более гарантированная версия прерывания, представленная в приведенных выше ответах. Она заботится о ситуации, когда sigabrt заблокирован. Вы можете использовать любой сигнал вместо прерывания, который имеет действие по умолчанию для сбоя программы.

#include<stdio.h>
#include<signal.h>
#include<unistd.h> 
#include<stdlib.h>
int main()
{
    sigset_t act;
    sigemptyset(&act);
    sigfillset(&act);
    sigprocmask(SIG_UNBLOCK,&act,NULL);
    abort();
}

Ответ 18

int* p=0;
*p=0;

Это тоже должно потерпеть крах. В Windows он падает с AccessViolation, и он должен делать то же самое на всех OS-сайтах, которые я предполагаю.

Ответ 19

Это фрагмент, предоставленный Google в Breakpad.

  volatile int* a = reinterpret_cast<volatile int*>(NULL);
  *a = 1;

Ответ 20

int main(int argc, char *argv[])
{
    char *buf=NULL;buf[0]=0;
    return 0;
}

Ответ 21

Хотя этот вопрос уже имеет принятый ответ...

void main(){
    throw 1;
}

Или... void main(){throw 1;}

Ответ 22

Запись в постоянное запоминающее устройство вызовет ошибку сегментации, если ваша система не поддерживает блоки памяти только для чтения.

int main() {
    (int&)main = 0;
}

Я тестировал его с помощью MingGW 5.3.0 на Windows 7 и GCC на Linux Mint. Я полагаю, что другие компиляторы и системы дадут аналогичный эффект.

Ответ 23

Или иначе, так как мы находимся на фургоне группы.

Прекрасная часть бесконечной рекурсии. Гарантировано, чтобы взорвать ваш стек.

int main(int argv, char* argc)
{
   return main(argv, argc)
}

Распечатывает:

Ошибка сегментации (сбрасывание ядра)

Ответ 24

Тот, о котором еще не упоминалось:

((void(*)())0)();

Это обработает нулевой указатель как указатель функции, а затем вызовет его. Так же, как и большинство методов, это не гарантирует сбой программы, но шансы на то, что ОС, позволяющая этому отключиться, и когда-либо возвращаемая программа, незначительны.

Ответ 25

очень короткий, он сработает!

int
main() {
  main();
}

Ответ 26

void main()
{

  int *aNumber = (int*) malloc(sizeof(int));
  int j = 10;
  for(int i = 2; i <= j; ++i)
  {
      aNumber = (int*) realloc(aNumber, sizeof(int) * i);
      j += 10;
  }

}

Надеюсь, что это сбой. Приветствия.

Ответ 27

int main()
{
    int *p=3;
    int s;
    while(1) {
        s=*p;
        p++;
    }
}

Ответ 28

Стильный способ сделать это - вызов чистой виртуальной функции:

class Base;

void func(Base*);

class Base
{
public:
   virtual void f() = 0;
   Base() 
   {
       func(this);
   }
};

class Derived : Base
{
   virtual void f()
   {
   }
};

void func(Base* p)
{
   p->f();
}


int main()
{
    Derived  d;
}

Скомпилированный с помощью gcc, это печатает:

чистый виртуальный метод, называемый

завершение вызова без активного исключения

Отменено (ядро сбрасывается)

Ответ 29

Возьмите один указатель

int * ptr;

попробуйте удалить ссылку на указатель (ptr) теперь как * ptr

ptr содержит мусор. мы разыскиваем адрес мусора. он автоматически сбой...

Ответ 30

Вы можете использовать сборку в c++ code НО INT 3 только для систем x86, в других системах могут быть другие инструкции прерывания/прерывания.

int main()
{
    __asm int 3;

    return 0;
}

INT 3 вызывает прерывание и вызывает вектор прерывания, установленный ОС.