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


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

int main() {
    crashyCodeGoesHere();
}

Para hacer que mi programa C++ se bloquee de manera confiable

 296
Author: Yi Jiang, 2011-12-13

28 answers

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

 240
Author: duskwuff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-12 22:27:22

Intenta:

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

Se encuentra en:

#include <signal.h>
 103
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-12 22:30:34

Dividir por cero bloqueará la aplicación:

int main()
{
    return 1 / 0;
}
 71
Author: Roee Gavirel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-03 14:52:02
*((unsigned int*)0) = 0xDEAD;
 63
Author: Keith Nicholas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 03:57:03

Bien, estamos en piladesbordamiento, o no?

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

(No se garantiza que se bloquee según ningún estándar, pero tampoco ninguna de las respuestas sugeridas, incluida la aceptada, ya que SIGABRT podría haber sido atrapada de todos modos. En la práctica, esto se estrellará en todas partes.)

 49
Author: sam hocevar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 10:06:21
 throw 42;

Solo la respuesta... :)

 34
Author: Macke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-16 21:53:11

assert(false); es bastante bueno también.

De acuerdo con ISO / IEC 9899: 1999 se garantiza que se bloqueará cuando NDEBUG no esté definido:

Si se define NDEBUG [...] la macro assert se define simplemente como

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

La macro assert se redefine de acuerdo con el estado actual de NDEBUG cada vez que se incluye.

[...]

La macro assert pone pruebas diagnósticas en programas; [...] si la expresión (que tendrá un tipo escalar) es false [...]. Se luego llama a la función abortar.

 15
Author: Dan F,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 10:18:16

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

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

Cuando puede ser importable, sus opciones pueden ser aún más amplias, como usar SIGBUS en linux.

 11
Author: PlasmaHH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-12 22:57:18

El único flash que tenía es abort() function :

Aborta el proceso con un programa anormal termination.It genera la señal SIGABRT , que de forma predeterminada hace que el programa termine devolviendo un código de error de terminación fallido 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 cualquier atexit (que se llama por exit () antes el programa termina la función). Nunca regresa a su persona que llama.

 9
Author: samridhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 08:27:48

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
}
 9
Author: Paul Biggar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 17:58:38

C++ se puede estrelló determinista por tener 2 excepciones en paralelo! El estándar dice nunca lanzar ninguna excepción de un destructor O nunca usar ninguna función en un destructor que pueda lanzar excepción.

Tenemos que hacer una función para dejar el destructor etc etc.

Un ejemplo de ISO/IEC 14882 §15.1-7. Debe ser un bloqueo según el estándar de C++. Ideun ejemplo 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 menciones throw sin try block resultando en una llamada implícita para abortar:

Si no se está manejando ninguna excepción, ejecutar un expresión throw sin llamadas a operando std:: terminate ()

Otros incluyen : lanzar desde destructor: ISO / IEC 14882 §15.2/3

 6
Author: Abhinav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-11 15:26:40
*( ( char* ) NULL ) = 0;

Esto producirá un error de segmentación.

 5
Author: wrren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-12 22:29:44

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

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

Ver Ejemplo original en Microsoft KB

 5
Author: sll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 21:23:05

Esta es una versión más garantizada de abortar presentada anteriormente answers.It se encarga de la situación cuando sigabrt está bloqueado.De hecho, puede usar cualquier señal en lugar de abortar 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();
}
 4
Author: bashrc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-17 09:19:55

Esta falta:

int main = 42;
 4
Author: mvds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-17 02:04:15

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 :)

 4
Author: fredoverflow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-27 05:50:46
int i = 1 / 0;

Su compilador probablemente le advertirá sobre esto, pero compila muy bien bajo GCC 4.4.3 Esto probablemente causará una SIGFPE (excepción de coma flotante), que quizás no sea tan probable en una aplicación real como SIGSEGV (violación de segmentación de memoria) como las otras respuestas, pero sigue siendo un bloqueo. 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, a contraste con SIGSEGV.

 3
Author: AlexWebr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 05:30:14
int* p=0;
*p=0;

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

 3
Author: laci37,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-17 09:20:40
int main(int argc, char *argv[])
{
    char *buf=NULL;buf[0]=0;
    return 0;
}
 2
Author: Aniket Inge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-13 21:46:23

Aunque esta pregunta ya tiene una respuesta aceptada...

void main(){
    throw 1;
}

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

 2
Author: noɥʇʎԀʎzɐɹƆ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-21 22:05:43

Este es el fragmento proporcionado por Google en Breakpad.

  volatile int* a = reinterpret_cast<volatile int*>(NULL);
  *a = 1;
 2
Author: Cory Trese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-07 15:10:23

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.

 2
Author: NO_NAME,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-12 01:05:25

O de otra manera ya que estamos en el vagón de la banda.

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

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

Imprime:

Falla de segmentación (núcleo volcado)

 1
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-27 01:20:45
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 bloquee. Aclamaciones.

 0
Author: senthil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-27 13:42:23
int main()
{
    int *p=3;
    int s;
    while(1) {
        s=*p;
        p++;
    }
}
 0
Author: sc_cs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-17 07:57:38

Una forma elegante de hacer esto es una llamada a una 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)

 0
Author: Martin Broadhurst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-12 23:34:44

Uno que aún no ha sido 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 se garantiza que esto bloquee el programa, pero las posibilidades de que el sistema operativo permita que esto no se controle y de que el programa regrese son insignificantes.

 -1
Author: Anton Golov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-13 18:16:29
char*freeThis;
free(freeThis);

Liberar un puntero no iniciado es un comportamiento indefinido. En muchas plataformas/compiladores, freeThis tendrá un valor aleatorio (lo que estaba en esa ubicación de memoria antes). Liberarlo le pedirá al sistema que libere la memoria en esa dirección, lo que generalmente causará un error de segmentación y hará que el programa se bloquee.

 -2
Author: Z Rev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-09 22:07:46