Próbuję stworzyć program w języku Python, który będzie współpracował z innym procesem powodującym awarie (który jest poza moim zasięgiem). Niestety program, z którym się komunikuję, nie ulega awarii nawet niezawodnie! Chcę więc stworzyć szybki program C ++, który celowo ulega awarii, ale tak naprawdę nie znam najlepszego i najkrótszego sposobu, aby to zrobić, czy ktoś wie, co umieścić między moim:
int main() {
crashyCodeGoesHere();
}
aby niezawodnie zawiesić mój program C ++
asm { cli; };
*((char*)-1) = 'x';
kodu, aby wywołać awarię w celu debugowania, przeczytaj więcej w mojej odpowiedzi tutajOdpowiedzi:
Ta
abort()
funkcja jest prawdopodobnie najlepszym wyborem. Jest to część standardowej biblioteki C i jest zdefiniowana jako „powodująca nieprawidłowe zakończenie programu” (np. Błąd krytyczny lub awaria).źródło
abort()
nie wywołuje żadnych niszczycieli aniatexit
funkcji, choć prawdopodobnie nie będzie to miało znaczenia.atexit
, nie byłoby teraz awarii, prawda?abort()
jest prawidłowa, należy „wyjść (-1);„ być do przyjęcia?Próbować:
Znaleziono w:
źródło
signal()
. Jednak większość rozsądnych aplikacji tego nie robi.raise()
. To pozwala przetestować mnóstwo różnych rodzajów wyjątków, po prostu zmieniając argument.Dzielenie przez zero spowoduje awarię aplikacji:
źródło
main
całkowitego usunięcia treści, w tymret
instrukcji. Wykonanie może po prostu należeć do następującej funkcji.źródło
Cóż, jesteśmy na przepełnieniu stosu , czy nie?
(Nie ma gwarancji
SIGABRT
, że nastąpi awaria według jakichkolwiek standardów, ale nie ma też żadnej z sugerowanych odpowiedzi, w tym tej zaakceptowanej, ponieważ i tak można ją złapać. W praktyce nastąpi awaria wszędzie).źródło
(&i)[i] += !i
, ale obawiałem się, że kompilator może być wystarczająco sprytny i chce to zoptymalizować. :-)Tylko odpowiedź ... :)
źródło
assert(false);
też jest całkiem niezły.Zgodnie z ISO / IEC 9899: 1999 gwarantuje się awarię, gdy NDEBUG nie jest zdefiniowany:
źródło
assert
jest równoważny((void)0)
w trybie zwolnienia.Ponieważ awaria jest objawem wywoływania nieokreślonego zachowania, a ponieważ wywoływanie niezdefiniowanego zachowania może prowadzić do czegokolwiek, w tym awarii, nie sądzę, że chcesz naprawdę zawiesić swój program, ale po prostu upuść go w debuggerze. Najbardziej przenośnym sposobem na to jest prawdopodobnie
abort()
.Chociaż
raise(SIGABRT)
ma ten sam efekt, na pewno jest więcej do napisania. Oba sposoby można jednak przechwycić, instalując moduł obsługi sygnału dlaSIGABRT
. Więc w zależności od twojej sytuacji, możesz chcieć / potrzebować podnieść inny sygnał.SIGFPE
,SIGILL
,SIGINT
,SIGTERM
LubSIGSEGV
może być droga, ale wszystkie mogą zostać przechwycone.Gdy możesz być nie do przeniesienia, twoje wybory mogą być jeszcze szersze, jak
SIGBUS
na przykład na Linuksie.źródło
Jedyny flash, jaki miałem to funkcja abort () :
Przerywa proces z nienormalnym zakończeniem programu, generuje sygnał SIGABRT , który domyślnie powoduje, że program przerywa zwracanie nieudanego kodu błędu zakończenia do środowiska hosta. Program zostaje zakończony bez wykonywania niszczycieli dla obiektów o automatycznym lub statycznym czasie przechowywania i bez wywoływania jakichkolwiek atexit (która jest wywoływana przez exit () przed wygaśnięciem programu) funkcja. Nigdy nie wraca do dzwoniącego.
źródło
Odpowiedź zależy od platformy i zależy od twoich celów. Ale oto funkcja awarii Mozilla Javascript, która moim zdaniem ilustruje wiele wyzwań, które sprawiają, że ta funkcja działa:
źródło
Widzę, że opublikowano tutaj wiele odpowiedzi, które trafią w szczęśliwe przypadki, aby wykonać zadanie, ale żadna z nich nie jest w 100% deterministyczna w przypadku awarii. Niektóre ulegną awarii na jednym sprzęcie i systemie operacyjnym, inne nie. Istnieje jednak standardowy sposób, zgodnie z oficjalnym standardem C ++, aby spowodować awarię.
Cytowanie z normy C ++ ISO / IEC 14882 §15.1-7 :
Napisałem mały kod, aby to zademonstrować i można go znaleźć i wypróbować na Ideone tutaj .
ISO / IEC 14882 §15.1 / 9 wspomina o rzucaniu bez bloku próbnego, co powoduje niejawne wezwanie do przerwania:
Inne obejmują: rzut z destruktora: ISO / IEC 14882 § 15.2 / 3
źródło
Spowoduje to błąd segmentacji.
źródło
Brakuje tego:
źródło
Co z przepełnieniem stosu wywołaniem metody rekurencyjnej w pętli martwej?
Zobacz oryginalny przykład w Microsoft KB
źródło
Występuje awaria w moim systemie Linux, ponieważ literały łańcuchowe są przechowywane w pamięci tylko do odczytu:
Nawiasem mówiąc, g ++ nie chce tego skompilować. Kompilatory stają się coraz mądrzejsze :)
źródło
Twój kompilator prawdopodobnie ostrzeże Cię o tym, ale kompiluje się dobrze w GCC 4.4.3. To prawdopodobnie spowoduje SIGFPE (wyjątek zmiennoprzecinkowy), co być może nie jest tak prawdopodobne w prawdziwej aplikacji jak SIGSEGV (naruszenie segmentacji pamięci) jak inne odpowiedzi powodują, ale wciąż jest to awaria. Moim zdaniem jest to o wiele bardziej czytelne.
Innym sposobem, jeśli chcemy oszukiwać i używać
signal.h
, jest:Gwarantuje to zabicie podprocesu, w przeciwieństwie do SIGSEGV.
źródło
Jest to bardziej gwarantowana wersja przerwania przedstawiona w powyższych odpowiedziach, która zajmuje się sytuacją, gdy sigabrt jest zablokowany. Możesz infact użyć dowolnego sygnału zamiast przerywania, który domyślnie powoduje zawieszenie programu.
źródło
To też powinno się zawiesić. W Windows zawiesza się z AccessViolation i chyba powinien działać tak samo na wszystkich systemach operacyjnych.
źródło
on all OS-es
Nie, nie ulega awarii w niezabezpieczonym systemie operacyjnym (np. MS-DOS). Właściwie czasami coś jest pod adresem 0! W trybie rzeczywistym x86 tablica wektorów przerwań znajduje się pod adresem 0.main()
.To jest fragment kodu dostarczony przez Google w Breakpad.
źródło
źródło
Chociaż to pytanie ma już zaakceptowaną odpowiedź ...
Lub...
void main(){throw 1;}
źródło
Zapis w pamięci tylko do odczytu spowoduje błąd segmentacji, chyba że system nie obsługuje bloków pamięci tylko do odczytu.
Przetestowałem to z MingGW 5.3.0 na Windows 7 i GCC na Linux Mint. Przypuszczam, że inne kompilatory i systemy dadzą podobny efekt.
źródło
Lub w inny sposób, odkąd jesteśmy na wozie zespołu.
Cudowny kawałek nieskończonej rekurencji. Gwarantowane wysadzenie twojego stosu.
Wydruki:
źródło
main
siebie jest tak naprawdę niezdefiniowanym zachowaniem, na wypadek, gdybyś nie wiedział :) Poza tym nie ma gwarancji , że rekurencja ogona zniszczy Twój stos. Jeśli chcesz mieć „gwarancję”, musisz coś zrobić po wywołaniu rekurencyjnym, w przeciwnym razie kompilator może zoptymalizować rekurencję w nieskończoną pętlę.Ten, o którym jeszcze nie wspomniano:
Spowoduje to potraktowanie wskaźnika zerowego jako wskaźnika funkcji, a następnie wywołanie go. Podobnie jak w przypadku większości metod, nie ma gwarancji, że spowoduje to awarię programu, ale szanse systemu operacyjnego na pozostawienie go niezaznaczonego i powrotu programu są znikome.
źródło
Mam nadzieję, że to się zawiesi. Twoje zdrowie.
źródło
źródło
long long
lubsize_t
i zacząćp
od odpowiedniej maksymalnej wartości lub blisko niej, aby szybciej ulec awarii. Chociaż nadal nie ma gwarancji awarii nawet w tym przypadku.Stylowym sposobem na zrobienie tego jest czysto wirtualne wywołanie funkcji:
Skompilowany z gcc, wyświetla:
źródło
Możesz użyć asemblera w swoim c ++
code
ALEINT 3
jest tylko dla systemów x86, inne systemy mogą mieć inne instrukcje pułapki / punktu przerwania.INT 3
powoduje przerwanie i wywołuje wektor przerwania ustawiony przez system operacyjny.źródło
Użyj __builtin_trap () w GCC lub clang, lub __debugbreak () w MSVC. Brak obsługi tych punktów przerwania / pułapek doprowadzi do nieobsługiwanego wyjątku / awarii punktu przerwania. Inne sugestie, które używają abort () lub exit (): mogą być obsługiwane przez inne wątki, co utrudnia zobaczenie stosu wątku, który propagował awarię.
źródło
Uwolnienie niezainicjowanego wskaźnika jest niezdefiniowanym zachowaniem. Na wielu platformach / kompilatorach
freeThis
będzie miał losową wartość (cokolwiek wcześniej znajdowało się w tym miejscu pamięci). Zwolnienie go spowoduje, że system zwolni pamięć pod tym adresem, co zwykle spowoduje błąd segmentacji i spowoduje awarię programu.źródło