Я пытаюсь создать программу 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
вызывает прерывание и вызывает вектор прерывания, установленный ОС.