terminar resueltos programas programa funciones ejercicios ejemplos dev como codigos clases c++ crash

resueltos - ¿Cuál es la forma más fácil de hacer que un programa C++ se bloquee?



ejemplos de programas en c++ pdf (28)

Estoy tratando de hacer un programa Python que se interconecte con un proceso diferente (eso está fuera de mis manos). Desafortunadamente, el programa con el que estoy interactuando ni siquiera falla de manera confiable! Así que quiero hacer un programa rápido de C ++ que se bloquee a propósito, pero en realidad no sé cuál es la mejor y más corta manera de hacerlo, ¿alguien sabe qué poner entre mi

int main() { crashyCodeGoesHere(); }

hacer que mi programa de C ++ se cuelgue de manera confiable


¡C ++ se puede bloquear de manera determinista al tener 2 excepciones en paralelo! El estándar dice que nunca se debe lanzar ninguna excepción desde un destructor O nunca se debe usar ninguna función en un destructor que pueda generar una excepción.

Tenemos que hacer una función, así que dejemos el destructor, etc.

Un ejemplo de ISO / IEC 14882 §15.1-7 . Debe ser un choque según el estándar de C ++. El ejemplo de Ideone se puede encontrar aquí .

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 menciona el lanzamiento sin bloque try que resulta en una llamada implícita para abortar:

Si actualmente no se maneja una excepción, ejecutar una expresión de lanzamiento sin llamadas de operandos std :: terminate ()

Otros incluyen: lanzamiento de destructor: ISO / IEC 14882 §15.2 / 3


¿Qué pasa con el desbordamiento de pila por una llamada de método recursivo de bucle muerto?

#include <windows.h> #include <stdio.h> void main() { (0); } void (int depth) { char blockdata[10000]; printf("Overflow: %d/n", depth); (depth+1); }

Ver ejemplo original en Microsoft KB


Aunque esta pregunta ya tiene una respuesta aceptada ...

void main(){ throw 1; }

O ... void main(){throw 1;}


Bueno, ¿estamos en la pila de desbordamiento , o no?

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

(No se garantiza que se bloquee según ninguna norma, pero tampoco lo es ninguna de las respuestas sugeridas, incluida la aceptada, ya que SIGABRT podría haber sido capturado de todos modos. En la práctica, esto se bloqueará en todas partes).


Dado que un bloqueo es un síntoma de invocar un comportamiento indefinido, y dado que el invocar un comportamiento indefinido puede llevar a cualquier cosa, incluido un bloqueo, no creo que realmente desee bloquear su programa, sino que simplemente lo deje caer en un depurador. La forma más portátil de hacerlo es probablemente abort() .

Si bien el raise(SIGABRT) tiene el mismo efecto, ciertamente es más que escribir. Sin embargo, ambas formas pueden interceptarse instalando un controlador de señal para SIGABRT . Entonces, dependiendo de su situación, es posible que desee / necesite elevar otra señal. SIGFPE , SIGILL , SIGINT , SIGTERM o SIGSEGV pueden ser el camino a seguir, pero todos pueden ser interceptados.

Cuando puede ser unportable, sus opciones pueden ser incluso más amplias, como usar SIGBUS en linux.


Dividir por cero bloqueará la aplicación:

int main() { return 1 / 0; }


El único flash que tuve es la función abort () :

Anula el proceso con una terminación anormal del programa. Genera la señal SIGABRT , que de manera predeterminada hace que el programa termine devolviendo un código de error de terminación fallida al entorno host. El programa se termina sin ejecutar destructores para objetos de duración de almacenamiento automática o estática , y sin llamar a ninguna función atexit (que es llamada por exit () antes de que finalice el programa). Nunca vuelve a su llamador.


Escribir en una memoria de solo lectura causará un error de segmentación a menos que su sistema no admita bloques de memoria de solo lectura.

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

Lo he probado con MingGW 5.3.0 en Windows 7 y GCC en Linux Mint. Supongo que otros compiladores y sistemas darán un efecto similar.


Esta es una versión más garantizada de la cancelación presentada en las respuestas anteriores. Se encarga de la situación cuando se bloquea sigabrt. Puede utilizar cualquier señal en lugar de la cancelación que tenga la acción predeterminada de bloquear el programa.

#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(); }


Este es el fragmento proporcionado por Google en Breakpad.

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


Este falta

int main = 42;


Esto se bloquea en mi sistema Linux, porque los literales de cadena se almacenan en la memoria de solo lectura:

0[""]--;

Por cierto, g ++ se niega a compilar esto. Los compiladores son cada vez más inteligentes :)


La función abort() es probablemente su mejor apuesta. Es parte de la biblioteca estándar de C, y se define como "que causa la terminación anormal del programa" (por ejemplo, un error fatal o un fallo).


La respuesta es específica de la plataforma y depende de sus objetivos. Pero aquí está la función de bloqueo de JavaScript de Mozilla, que creo que ilustra muchos de los desafíos para hacer que esto funcione:

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 }


O de otra manera ya que estamos en el carro de la banda.

Una hermosa pieza de recursión infinita. Garantizado para volar tu pila.

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

Imprime:

Fallo de segmentación (núcleo volcado)


Tratar:

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

Encontrado en:

#include <signal.h>


Una forma elegante de hacer esto es una llamada de función virtual pura:

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

Compilado con gcc, esto imprime:

método virtual puro llamado

terminar llamada sin una excepción activa

Abortado (núcleo volcado)


Una que aún no se ha mencionado:

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

Esto tratará el puntero nulo como un puntero de función y luego lo llamará. Al igual que la mayoría de los métodos, no está garantizado que el programa se cuelgue, pero las posibilidades de que el sistema operativo permita que esto no se controle y que el programa nunca regrese son insignificantes.


assert(false); es bastante bueno tambien

Según ISO / IEC 9899: 1999, se garantiza que se bloquea cuando no se define NDEBUG:

Si se define NDEBUG, [...] la macro de confirmación se define simplemente como

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

La macro de afirmación se redefine según el estado actual de NDEBUG cada vez que se incluye.

[...]

La macro assert pone pruebas de diagnóstico en programas; [...] si la expresión (que tendrá un tipo escalar) es falsa [...]. Entonces llama a la función abortar.


throw 42;

Solo la respuesta ... :)


*( ( char* ) NULL ) = 0;

Esto producirá una falla de segmentación.


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


char*freeThis; free(freeThis);

La liberación de un puntero sin inicializar es un comportamiento indefinido. En muchas plataformas / compiladores, freeThis tendrá un valor aleatorio (lo que haya estado en esa ubicación de memoria antes). Al liberarlo se le pedirá al sistema que libere la memoria en esa dirección, lo que generalmente causará un fallo de segmentación y hará que el programa se bloquee.


int i = 1 / 0;

Es probable que su compilador le advierta acerca de esto, pero se compila perfectamente en GCC 4.4.3 Esto probablemente causará un SIGFPE (excepción de punto flotante), que tal vez no sea tan probable en una aplicación real como SIGSEGV (violación de segmentación de memoria) como Las otras respuestas causan, pero sigue siendo un choque. En mi opinión, esto es mucho más legible.

Otra forma, si vamos a hacer trampa y usar signal.h , es:

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

Esto está garantizado para matar el subproceso, para contrastar con SIGSEGV.


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


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


int* p=0; *p=0;

Esto debería chocar también. En Windows se bloquea con AccessViolation y debería hacer lo mismo en todos los sistemas operativos, supongo.


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

Espero que esto se estrella. Aclamaciones.