Estou tentando criar um programa Python que faça interface com um processo travado diferente (que está fora do meu alcance). Infelizmente, o programa com o qual estou interagindo nem falha de maneira confiável! Então, eu quero criar um programa C ++ rápido que trava de propósito, mas na verdade eu não sei a melhor e mais curta maneira de fazer isso, alguém sabe o que colocar entre os meus:
int main() {
crashyCodeGoesHere();
}
fazer meu programa C ++ travar de maneira confiável
asm { cli; };
*((char*)-1) = 'x';
código a seguir para induzir uma falha, a fim de depurar, leia mais em minha resposta aqui #Respostas:
A
abort()
função é provavelmente a sua melhor aposta. Faz parte da biblioteca padrão C e é definido como "causando o encerramento anormal do programa" (por exemplo, um erro fatal ou falha).fonte
abort()
não chama destruidores ouatexit
funções, embora isso provavelmente não importe aqui.atexit
es, não seria um acidente agora, seria?abort()
a resposta é correta, 'exit (-1); `deve ser aceitável?Experimentar:
Encontrado em:
fonte
signal()
. Porém, a maioria dos aplicativos sãos não.raise()
. Isso permite testar uma tonelada de tipos diferentes de exceções, apenas alterando o argumento.Dividir por zero irá travar o aplicativo:
fonte
main
exclusão total do corpo, incluindo asret
instruções. A execução pode cair na seguinte função.fonte
Bem, estamos com excesso de pilha , ou não?
(Não há garantia de falha por nenhum padrão, mas nenhuma das respostas sugeridas, incluindo a aceita, já que
SIGABRT
poderia ter sido detectada de qualquer maneira. Na prática, isso falhará em todos os lugares.)fonte
(&i)[i] += !i
vez disso, mas temia que o compilador fosse inteligente o suficiente e quisesse otimizar isso. :-)Apenas a resposta ... :)
fonte
assert(false);
também é muito bomDe acordo com a ISO / IEC 9899: 1999, é garantido um travamento quando o NDEBUG não está definido:
fonte
assert
é equivalente a((void)0)
no modo Release.Como uma falha é um sintoma de invocar um comportamento indefinido e, uma vez que a invocação de um comportamento indefinido pode levar a qualquer coisa, incluindo uma falha, não acho que você queira realmente travar seu programa, mas apenas deixá-lo cair em um depurador. A maneira mais portátil de fazer isso é provavelmente
abort()
.Embora
raise(SIGABRT)
tenha o mesmo efeito, certamente é mais para escrever. No entanto, as duas maneiras podem ser interceptadas instalando um manipulador de sinais paraSIGABRT
. Portanto, dependendo da sua situação, você pode querer / precisar gerar outro sinal.SIGFPE
,SIGILL
,SIGINT
,SIGTERM
OuSIGSEGV
pode ser o caminho a percorrer, mas todos eles podem ser interceptadas.Quando você pode não ser portável, suas escolhas podem ser ainda mais amplas, como usar
SIGBUS
no linux.fonte
O único flash que tive foi a função abort () :
Ele interrompe o processo com uma finalização anormal do programa. Gera o sinal SIGABRT , que por padrão faz com que o programa finalize retornando um código de erro de finalização malsucedido ao ambiente host. O programa é finalizado sem executar destruidores para objetos de duração de armazenamento estático ou automático , e sem chamar nenhuma função atexit (chamada por exit () antes do programa terminar)). Ele nunca retorna ao chamador.
fonte
A resposta é específica da plataforma e depende de seus objetivos. Mas aqui está a função de travamento do Mozilla Javascript, que eu acho que ilustra muitos dos desafios para fazer esse trabalho:
fonte
Vejo que há muitas respostas postadas aqui que caem em casos de sorte para concluir o trabalho, mas nenhuma delas é 100% determinística para travar. Alguns travam em um hardware e sistema operacional, outros não. No entanto, existe uma maneira padrão, conforme o padrão oficial do C ++, de fazê-lo falhar.
Citando a norma C ++ ISO / IEC 14882 §15.1-7 :
Eu escrevi um pequeno código para demonstrar isso e pode ser encontrado e testado no Ideone aqui .
A ISO / IEC 14882 §15.1 / 9 menciona o lançamento sem o bloco try, resultando em uma chamada implícita para abortar:
Outros incluem: lançamento do destruidor: ISO / IEC 14882 §15.2 / 3
fonte
Isso produzirá uma falha de segmentação.
fonte
Este está faltando:
fonte
E o estouro de pilha por uma chamada de método recursivo de loop morto?
Consulte Exemplo original no Microsoft KB
fonte
Isso trava no meu sistema Linux, porque literais de seqüência de caracteres são armazenados na memória somente leitura:
A propósito, o g ++ se recusa a compilar isso. Compiladores estão ficando cada vez mais inteligentes :)
fonte
Seu compilador provavelmente o alertará sobre isso, mas compila muito bem no GCC 4.4.3 Isso provavelmente causará um SIGFPE (exceção de ponto flutuante), que talvez não seja tão provável em um aplicativo real quanto o SIGSEGV (violação de segmentação de memória) como as outras respostas causam, mas ainda é um acidente. Na minha opinião, isso é muito mais legível.
Outra maneira, se vamos trapacear e usar
signal.h
, é:Isso é garantido para eliminar o subprocesso, para contrastar com o SIGSEGV.
fonte
Esta é uma versão mais garantida do cancelamento apresentada nas respostas acima. Ele cuida da situação em que o sigabrt está bloqueado. Você pode usar qualquer sinal em vez de cancelar que tenha a ação padrão de travar o programa.
fonte
Isso também deve travar. No Windows, ele trava com o AccessViolation e deve fazer o mesmo em todos os sistemas operacionais, eu acho.
fonte
on all OS-es
Não, não falha em OS não protegido (por exemplo, MS-DOS.) Na verdade, às vezes não é algo em endereço 0! Para x86 modo real, interrupção Vector Table é o endereço 0.main()
.Este é o trecho fornecido pelo Google no Breakpad.
fonte
fonte
Embora esta pergunta já tenha uma resposta aceita ...
Ou...
void main(){throw 1;}
fonte
A gravação em uma memória somente leitura causará uma falha de segmentação, a menos que seu sistema não suporte blocos de memória somente leitura.
Eu testei com o MingGW 5.3.0 no Windows 7 e o GCC no Linux Mint. Suponho que outros compiladores e sistemas tenham um efeito semelhante.
fonte
Ou de outra maneira, já que estamos no vagão da banda.
Uma adorável peça de recursão infinita. Garantido para explodir sua pilha.
Imprime:
fonte
main
si mesmo é um comportamento indefinido, caso você não saiba :) Além disso, não é garantido que a recursão da cauda acabe com sua pilha. Se você quiser uma "garantia", precisará fazer algo após a chamada recursiva, caso contrário, o compilador poderá otimizar a recursão em um loop infinito.Um que ainda não foi mencionado:
Isso tratará o ponteiro nulo como um ponteiro de função e depois o chamará. Assim como a maioria dos métodos, não é garantido que isso interrompa o programa, mas as chances do sistema operacional permitir que isso ocorra e que o programa volte sempre são insignificantes.
fonte
Espero que isso trava. Felicidades.
fonte
fonte
long long
ousize_t
e começar comp
o respectivo valor máximo, ou próximo a ele, para travar mais rápido. Embora ainda não haja garantia de falha, mesmo nesse caso.Uma maneira elegante de fazer isso é uma chamada de função virtual pura:
Compilado com o gcc, ele imprime:
fonte
Você pode usar a montagem em seu c ++,
code
masINT 3
é apenas para sistemas x86 outros sistemas podem ter outras instruções de interceptação / ponto de interrupção.INT 3
causa uma interrupção e chama um vetor de interrupção configurado pelo sistema operacional.fonte
Use __builtin_trap () no GCC ou clang, ou __debugbreak () no MSVC. O não manuseio desses pontos de interrupção / interrupções levará a uma exceção / falha não tratada do ponto de interrupção. Outras sugestões que usam abort () ou exit (): podem ser tratadas por outros threads, dificultando a visualização da pilha do thread que propagou a falha.
fonte
Liberar um ponteiro não inicializado é um comportamento indefinido. Em muitas plataformas / compiladores,
freeThis
terá um valor aleatório (o que estava naquele local da memória antes). A liberação solicitará que o sistema libere a memória nesse endereço, o que geralmente causará uma falha de segmentação e causará uma falha no programa.fonte