Bir C ++ program çökmesi yapmanın en kolay yolu nedir?


318

Farklı bir crashy süreci ile arayüz oluşturan bir Python programı yapmaya çalışıyorum (bu benim ellerim dışında). Maalesef arayüz ile kurduğum program güvenilir bir şekilde çökmüyor bile! Yani bilerek çökmesini hızlı bir C ++ programı yapmak istiyorum ama aslında bunu yapmak için en iyi ve en kısa yolu bilmiyorum, kimse benim arasında ne koymak biliyor mu:

int main() {
    crashyCodeGoesHere();
}

programımı güvenilir bir şekilde çökertmek için nasıl


4
ayrıcalıklı talimatları yürütmeyi denemek için satır içi montajı kullanabilirsiniz:asm { cli; };
Nate Koppenhaver

@aitchnyu Her soruya verilen cevapların kullanılabilirliğinde bir fark olduğunu düşünüyorum. (FYI: Her iki soru için de hiçbir şey
Andrew Barber

zaten propogated iken istisna atma herhangi bir yorum? plz chk cevabımı anc yorumun altında
Abhinav

4
Redis aşağıdaki kullanır *((char*)-1) = 'x';benim daha okumak ayıklama amacıyla bir kilitlenme ikna etmek kod burada cevap
Shafik Yaghmour

Bu soruyu bir kilitlenme raporlama sistemi için test senaryosu ararken buldum. Ben normal bir çalışma sırasında bir kilitlenme zorlamak için çökme muhabiri çağırmak ve yığın dökümü gönderme gerekiyordu. Teşekkürler!
Cory Trese

Yanıtlar:


264

abort()Fonksiyon muhtemelen en iyi bahistir. C standart kütüphanesinin bir parçasıdır ve "anormal program sonlandırmasına neden olma" olarak tanımlanır (örn. Önemli bir hata veya çökme).


14
Bir kilitlenmenin abort()herhangi bir yıkıcı veya atexitişlevi çağırdığını unutmayın , ancak bu muhtemelen önemli olmayacaktır.
Xeo

139
@Xeo: Yıkıcılar ve atexits olarak adlandırılmış olsaydı, şimdi bir çarpışma olmaz mıydı?
Donal Fellows

Yana abort()'kabul edilebilir, doğru yanıt 'çıkış (1) gerektiği zaman?
asir6

9
Hayır, bir çökmeye neden olmadığından, sadece bir şey yapılamadığını bildirir.
boatcoder

Pencereler. GCC-5.4.0. Çıkış kodu: 3. Hata mesajı kutusu yok. Konsol iletisi: "Bu uygulama, Çalışma Zamanından alışılmadık bir şekilde sonlandırılmasını istedi. Daha fazla bilgi için lütfen uygulamanın destek ekibine başvurun.".
Vadzim

113

Deneyin:

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

İçinde bulunan:

#include <signal.h>

3
Sadece uygulama tanımlı olmaktan daha fazlasıdır - sinyale yakalanabilir signal(). Çoğu aklı başında uygulama yok.
duskwuff -inactive-

12
Uygulamadaki normal bir SIGSEGV ile aynı şekilde çökecektir (çoğu uygulamanın çöküşü budur). Ne yaptığı iyi tanımlanmıştır (varsayılan olarak uygulamadan çıkar ve bir çekirdek dosya oluşturur). Evet, bir işleyici ayarlayabilirsiniz, ancak bir tane varsa, bunu aynı şekilde test etmek istemezsiniz !!
Martin York

1
İçin +1 raise(). Bu, yalnızca argümanı değiştirerek bir ton farklı istisna türünü test etmenizi sağlar.

3
favori çözüm, ancak platforma bağlıdır.
Nadim Farhat

@NadimFarhat: Ne şekilde. Bir sinyal tüm platformlardaki bir sinyaldir.
Martin York

74

Sıfıra bölmek uygulamayı kilitler:

int main()
{
    return 1 / 0;
}

29
Derleyicinizin ne kadar akıllı olduğuna bağlı olarak bu derleme zamanında yakalanacaktır. Visual Studio 2008'in bunu c ++ veya c # için derlemeyeceğini biliyorum.
AidanO

2
Derledim ve çalıştırdım, .exe dosyasını zımparalamamı ister misin?
Roee Gavirel

1
2010 gibi Visual Studio'nun son sürümlerindeki sürüm yapılandırmasında, sorunsuz çalışacaktır. Sanırım bu bir optimizasyon.
tedyyu

2
iirc kol üzerinde
çökmez

2
Bu tanımlanmamış bir davranıştır ve çökmesi garanti edilmez. Derleyiciler genellikle tanımlanmamış davranışın erişilemez olduğunu varsayar. Bu main, rettalimat dahil olmak üzere gövdenin tamamen silinmesine yol açabilir . Yürütme aşağıdaki işleve girebilir.
usr

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

54
Bunun çökmesi garanti edilmez.
Windows programcısı

8
@Windowsprogrammer: hayır, garanti edilmez . Ama hangi aklı başında OS gelmez bir uygulamayı durdurmak 0 adresinde erişim belleğine çalışır?
Joachim Sauer

29
"Ama hangi akıllı işletim sistemi 0 adresindeki belleğe erişmeye çalışan bir uygulamayı durdurmuyor?" - Bu gerçekten sormak istediğin şey değil, ama yine de cevaplayacağım. Bazı bilgisayarlarda 0 adresinde RAM vardır ve bir programın orada bir değer depolaması son derece anlamlıdır. Daha anlamlı bir soru, "Hangi işletim sistemi bir C ++ uygulamasının boş gösterici için ayırdığı adreste belleğe erişen bir uygulamayı durdurmaz?" Bu durumda hiç bilmiyorum. Ama orijinal program C ++ dili ile ilgili değil işletim sistemleri hakkında.
Windows programcısı

6
Tanımsız davranışı. Bunun hiçbir şey yapmaması gayet iyi. Çökmeyecek bir makine: Z80 serisi işlemci çalıştıran herhangi bir şey (sanırım (Z80a'm hiçbir şey yapmıyor)).
Martin York

28
Bu çökme garantisi olmamasına rağmen , C ++ ' da en yaygın çökme türlerinden biridir. Bir çarpışmayı simüle etmek istiyorsanız, bunu yapmak için "otantik" bir yol :)
Chris Burt-Brown

53

Peki, yığın taşması üzerinde miyiz, değil miyiz?

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

(Herhangi bir standarda göre çökmesi garanti edilmez, ancak kabul edilen cevap da dahil olmak üzere önerilen cevaplardan herhangi biri SIGABRTyine de yakalanmış olabilir. Uygulamada, bu her yerde çökecektir.)


4
Korumasız kod sayfaları olan bir sistemde komik olmanın ve yanlışlıkla hiçbir şey yapmayan sonsuz bir döngü olan bazı kodlarla programınızın üzerine yazdığınızı görebiliyorum. Oldukça yüksek oranda yüksek ihtimal dışı ancak potansiyel olarak mümkün.
Martin York

@Loki: Ya her 4000. bayttan bir okuma yaparsa? Bunun çökme olasılığı daha düşük mü? Kesinlikle daha az tehlikeli.
Mooing Duck

70
Bu çökme algoritması O (1) değil!
Anton Barkovsky

@MooingDuck: Sadece komik bir yorum yapıyorum. Bunu ciddiye almayın :-) Ama eğer birisi komik bir şey yapan bir talimatlar dizisi bulsaydı ilginç olurdu.
Martin York

1
@LokiAstari: Kesinlikle haklısın. Bunun (&i)[i] += !iyerine düşünüyordum , ama derleyicinin yeterince zeki olabileceğinden ve bunu optimize etmek isteyebileceğinden korktum. :-)
sam hocevar

35
 throw 42;

Sadece cevap ... :)


1
Pencereler. GCC-5.4.0. Çıkış kodu: 3. Hata mesajı kutusu yok. Konsol iletisi: "'int' örneğini attıktan sonra sonlandır çağrıldı Bu uygulama, Çalışma Zamanının alışılmadık bir şekilde sonlandırmasını istedi. Daha fazla bilgi için lütfen uygulamanın destek ekibine başvurun."
Vadzim

15

assert(false); de oldukça iyi.

ISO / IEC 9899: 1999'a göre NDEBUG tanımlanmadığında çökmesi garanti edilir:

NDEBUG tanımlanmışsa [...] onaylama makrosu basitçe şu şekilde tanımlanır:

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

Assert makrosu, her dahil edildiğinde geçerli NDEBUG durumuna göre yeniden tanımlanır.

[...]

Onay makrosu, tanılama testlerini programlara yerleştirir; [...] ifade (skaler tipte olacaktır) yanlışsa [...]. Daha sonra iptal işlevini çağırır.


VC 2005'in hata ayıklama ve ileri sürmeler arasında farklı davrandığını hatırlıyorum.
Tom Kerr

8
@Tom assert, ((void)0)Release modundakine eşdeğerdir .
Seth Carnegie

2
@SethCarnegie Bu konuda neyin yanlış olduğunu görmüyorum - sadece tanımlı NDEBUG tanımlı olacak değilse? Dans cevabı oldukça adil bir IMHO idi.
Adrian Cornish

@AdrianCornish Sadece Tom Kerr'in sorusuna cevap veriyordum, bu cevabın yanlış olduğunu söylemiyorum. Bu cevabı küçümsemedim.
Seth Carnegie

3
Neden bu test kodunun "sürüm" derlemesini yaptığını bilmiyorum.
Joel B

11

Bir kilitlenme, tanımlanmamış davranışları çağırmanın bir belirtisi olduğundan ve tanımlanmamış davranışları çağırmak, kilitlenme de dahil olmak üzere herhangi bir şeye yol açabileceğinden, programınızı gerçekten kilitlemek istediğinizi düşünmüyorum, ancak sadece bir hata ayıklayıcıya düşmesini sağlayın. Bunu yapmanın en taşınabilir yolu muhtemelen abort().

raise(SIGABRT)Aynı etkiye sahip olsa da, kesinlikle yazmak daha fazladır. Bununla birlikte, her iki yol da için bir sinyal işleyici takılarak önlenebilir SIGABRT. Durumunuza bağlı olarak, başka bir sinyal yükseltmek isteyebilir / ihtiyacınız olabilir. SIGFPE, SIGILL, SIGINT, SIGTERMVeya SIGSEGVgitmek için bir yol olabilir, ama hepsi ele geçirilebilir.

Portatif olamayacağınız zaman, linux'da kullanmak gibi seçenekleriniz daha da geniş olabilir SIGBUS.


1
Gerçekten bir hata ayıklayıcı olmasını istediğinden şüpheliyim. Bir çökmekte olan programın arayanı bir çökme yoluna girdiğinde ne olduğunu test etmek istiyor gibi görünüyor. Bu çok makul.
Donal Fellows

9

Sahip olduğum tek flaş abort () işlevidir :

Bu anormal bir program termination.It proses oluşturur iptal SIGABRT sinyali varsayılan program çevreyi programı sonlandırılır konakçıya başarısız bir sonlandırma hata kodu dönen sona neden olur, yıkıcı çalıştırmadan otomatik veya statik depolama süresi nesneler için ve herhangi bir atexit (program sonlanmadan önce exit () tarafından çağrılır) işlevini çağırmadan . Asla arayanına geri dönmez.


9

Cevap platforma özgüdür ve hedeflerinize bağlıdır. Ama işte Mozilla Javascript kilitlenme işlevi, bence bu işi yapmak için birçok zorluğu gösteriyor:

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
}

2
Bunu tamamen bırakmalı ve bunun yerine jQuery kullanmalısınız.
Thomas Weller

1
Bu tanımlanmamış bir davranıştır ve çökmesi garanti edilmez. Derleyiciler genellikle tanımlanmamış davranışın erişilemez olduğunu varsayar. Bu durumda, en azından kilitlenen satır silinir ve diğer kod da olabilir.
usr

8

Burada işi yapmak için şanslı vakalara düşecek birçok cevap olduğunu görüyorum, ancak hiçbiri çökmeye% 100 belirleyici değil. Bazıları bir donanım ve işletim sisteminde çökecek, diğerleri olmayacak. Ancak, resmi C ++ standardına göre çökmesini sağlamak için standart bir yol vardır.

Alıntı C ++ Standart IEC 14882 §15.1-7 ISO / :

Kural dışı durum işleme mekanizması, kural dışı durum nesnesinin başlatılmasını tamamladıktan sonra ancak kural dışı durum için bir işleyicinin etkinleştirilmesinden önce, kural dışı durum yoluyla çıkan bir işlevi çağırırsa, std :: terminate çağrılır (15.5.1).

struct C {
    C() { }
    C(const C&) {
        if (std::uncaught_exceptions()) {
            throw 0; // throw during copy to handler’s exception-declaration object (15.3)
        }
    }
};
int main() {
    try {
    throw C(); // calls std::terminate() if construction of the handler’s
    // exception-declaration object is not elided (12.8)
    } catch(C) { }
}

Bunu göstermek için küçük bir kod yazdım ve burada bulunabilir ve Ideone üzerinde denenebilir .

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 , engelleme çağrısı yapılmasına neden olan deneme bloğu olmadan atıyor :

Şu anda bir istisna işlenmiyorsa, işlenen çağrısı olmadan bir atma ifadesi yürütmek std :: terminate ()

Diğerleri: yıkıcıdan atma: ISO / IEC 14882 §15.2 / 3


7
*( ( char* ) NULL ) = 0;

Bu bir segmentasyon hatası üretecektir.


10
Bunun çökmesi garanti edilmez.
Windows programcısı

23
"Bunun yerine ne olacak?" - Bunun yerine her şey olabilir. Davranış tanımlanmadı, bu nedenle uygulama programınızın değişkenlerinden birine 0 atayabilir veya programınızın değişkenlerinden birine 42 atayabilir veya sabit sürücünüzü biçimlendirebilir ve programınızı yürütmeye devam edebilir.
Windows programcısı

7
("Windows programcısı" akıl kümesi devam) Bilgisayar patlayabilir, ya da bir canlı gelip insanlık devralmaya neden olabilir. ya da ...% 99,9'da çökecek ve "tanımlanmamış davranış" olarak tanımlanacak, çünkü kimse bu konuda sorumluluk almak istemiyor.
Roee Gavirel

1
Aslında, tanımsız davranışlarda bile olduğu garanti edilmez - tamamen tanımlanabilir ve düzgün çalışabilir. Bu kodu göz önünde bulundurun: pastebin.com/WXCtTiDD (Linux'ta kök olarak test edilmiştir, bazı yapılandırma değişiklikleri yaparsanız bunu root olmayan bir kullanıcı olarak da yapabilirsiniz wiki.debian.org/mmap_min_addr )
cha0site

2
@ cha0site: Standart tarafından tanımlanmamış bir davranış olduğu garanti edilir, çünkü bu bir boş göstergenin kayıttan çıkarılmasıdır. Linux'ta gözlemlediğiniz her davranış, "tanımsız davranış" çatısı altında izin verilebilir
Ben Voigt


5

Ölü döngü özyinelemeli yöntem çağrısı ile yığın taşmasına ne dersiniz?

#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'deki Orijinal örneğe bakın


4
Yeterli Akıllı Derleyicinin kullanılmayan yığın tahsisini ve kuyruk çağrısını optimize etmesini ne engeller?
JB.

@JB: ne yazık ki hiçbir fikrim yok çünkü mevcut derleyiciler optimizasyon mantığı ile familar değil
sll

8
Burada, optimizasyon seviyeleri -O2 ve üstü gcc 4.6.0 ile derlendiğinde, gayet iyi optimize eder. Segfault için -O1 veya daha düşük bir değere ihtiyaç duyar.
JB.

@Abhinav: Cevabınızı C ++ ile örnek olarak ifade edilen tüm bu yollarla
gönderin

5

Dize değişmezleri salt okunur bellekte saklandığından, bu benim Linux sistemimde çöküyor:

0[""]--;

Bu arada, g ++ bunu derlemeyi reddediyor. Derleyiciler daha da akıllılaşıyor :)


4
int i = 1 / 0;

Derleyiciniz muhtemelen sizi bu konuda uyaracaktır, ancak GCC 4.4.3 altında iyi derler. Bu muhtemelen bir SIGFPE'ye (kayan nokta istisnası) neden olur; diğer cevaplar neden olur, ama yine de bir çökme. Bence bu çok daha okunaklı.

Başka bir yol, hile yapacak ve kullanacaksak signal.h:

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

Bu, SIGSEGV ile zıt olmak üzere alt süreci öldürmek için garantilidir.


2
Bunun çökmesi garanti edilmez.
Windows programcısı

11
C ++ dili, 1 / 0'ın SIGFPE'ye neden olacağını garanti etmez. Davranış tanımsız. Uygulama sonucun 42 olduğunu söyleyebilir.
Windows programcısı

1
Davranış tanımlanmadığında, uygulama istediği her şeyi yapabilir. C ++ dili bir çökme dökümü yazmak için bir uygulamayı engellemez veya gerektirmez, C ++ dili 42, vb. Atamak için bir uygulamayı engellemez veya gerektirmez.
Windows programcısı

2
@Giorgio, donanımın otomatik olarak yakalanmasının bir yolu yoksa, derleyicileri en az iki komut yayınlamaya zorlarsınız, bunlardan biri de bir şube olabilir. Bu, bir bölümün maliyetini yaklaşık iki katına çıkarır. Herkes bu bedeli böyle öder. İsteğe bağlıysa ve isterseniz, bunun için her zaman bir kütüphane işlevi kullanabilirsiniz. İsteğe bağlı değilse ve istemiyorsanız, yine de maliyeti ödersiniz.
Flekso

2
@Giorgio: 100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000 Derleyicinin bunu bilmesinin bir yolu olmamasına rağmen, bunların 0'ın sıfıra bölüneceği gerçeğini biliyorum. Derleyicinin bölünme kontrolü için sıfırı kontrol etmesini kesinlikle istemiyorum .
Martin York

4

Bu, yukarıdaki cevaplarda sunulan daha düşük bir garantili sürümdür. Sigabrt engellendiğinde durumla ilgilenir.

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

3
int* p=0;
*p=0;

Bu da çökmeli. Windows'da AccessViolation ile çöküyor ve sanırım tüm işletim sistemlerinde aynı şeyi yapmalı.


5
on all OS-esHayır, sigara korumalı OS çökmez (örneğin MS-DOS.) Aslında, bazen ise adresinde 0 şey! X86 gerçek modu için Kesme Vektör Tablosu 0 adresindedir.
ikh

Irix'e çarpmadı. Biz bile ulaşmadı nereye Linux (bu kodu portu yaparken ne yazık ki fark main().
Scheff

3

Bu, Google tarafından Breakpad'de sağlanan snippet'tir.

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

1
Breakpad'i test ettiğim için bu tam olarak istediğim şey! Bazı Breakpad minidumps kodum satır çökmesine neden gösteren bir yığın iz üretmediğini buldum. Bunu yapar, bu yüzden iyi bir poc testi olarak kullanabilirim.
BuvinJ

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

2

Bu sorunun zaten kabul edilmiş bir yanıtı olmasına rağmen ...

void main(){
    throw 1;
}

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


2

Salt okunur bir belleğe yazmak, sisteminiz salt okunur bellek bloklarını desteklemediği sürece segmentasyon hatasına neden olur.

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

Windows 7 üzerinde MingGW 5.3.0 ve Linux Mint üzerinde GCC ile test ettim. Sanırım diğer derleyiciler ve sistemler de benzer bir etki yaratacak.


1

Ya da grup vagonunda olduğumuzdan beri başka bir yol.

Sonsuz bir özyineleme güzel bir parçası. Yığınızı havaya uçurmak garantilidir.

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

Çıktılar:

Segmentasyon hatası (çekirdek boşaltıldı)


13
Bilmemeniz durumunda mainkendinizi aramak aslında tanımsız bir davranıştır :) Ayrıca, kuyruk özyinesinin yığınızı havaya uçuracağı garanti edilmez . Bir "garanti" istiyorsanız , özyinelemeli çağrıdan sonra bir şeyler yapmanız gerekir , aksi takdirde derleyici özyinelemeyi sonsuz bir döngüye optimize edebilir.
fredoverflow

0

Henüz bahsedilmeyen biri:

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

Bu, boş işaretçiyi bir işlev işaretçisi olarak görür ve sonra çağırır. Çoğu yöntem gibi, bunun programın çökmesi garanti edilmez, ancak işletim sisteminin bunun kontrol edilmemesine izin veren ve şimdiye kadar dönen programın şansı ihmal edilebilir.


3
İşletim sisteminin başlangıç ​​kodu 0 adresiyle etkili bir şekilde eşleştirildiği için bunun yeniden önyüklemeye neden olacağını birkaç makine biliyorum. Her şeyin PC'niz gibi çalışacağını düşünmeyin. Bunun bir çökme olduğunu söyleyebilirsiniz, ancak başlangıçta tüm durum silindiğinden hata ayıklayamayacağınız için çok yararlı değildir.
Martin York

@Loki Astari: Bunun bir çökme olduğunu daha az söylemeyeceğim - eğer buna neden olabilirse, hata ayıklanan program da olabilir, yani herhangi bir test kadar iyi. Öte yandan, bu makinelerin hangilerinin Python'u çalıştırabileceğini merak ediyorum.
Anton Golov

Bence bu noktayı kaçırdın. 0'da OS kodunu gördüm. Normalde iyi çalışacak sistemlerin 0'da iyi çalışacağı anlamına gelmez. Veya 0'daki baytlar kolayca geri dönüş için opcode olabilir.
Martin York

0'da OS kodunun farkındayım; Bu, 0'daki baytların dönüş için opcode olacağından şüphe duymamın nedenlerinden biridir. Program artık açıkça yürütmüyor ve her zamanki gibi çıkmadı, yani çöktü - eğer bu asker için yeterince iyi değilse, onun hakkında yorum yapmasını bekliyorum.
Anton Golov

2
Yalnızca makineniz için işletim sistemi kodunun farkındasınız. Söylemeye çalıştığım şey senin için başarısız olabileceğidir. Ama bu hiçbir şey ifade etmiyor. Dışarıda bir sürü sistem var. Bazılarının bu işe yarayacağından eminim (yani çarpışmada değil). Makineye / işletim sistemine özgü davranışlara güvenmek kötü bir fikirdir ve uzun vadede bakım sorunlarına neden olur. Sitenin fikri iyi kodu tanıtmaktır (sadece bu tür işleri kodlamak değil).
Martin York

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

}

Umarım bu çöker. Şerefe.


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

2
Bazı açıklamalara sahip olmak harika olurdu :)
olyv

1
p işaretçisi, bir işlem başka bir işlemin belleğine erişemediğinden, programın bir bellek hatası olan adres alanının ötesine geçecektir. Bu programın çökmesine neden olacaktır. işaretçi p, adres alanında rastgele bir konuma işaret ediyor, eğer bir noktada sonsuza dek artırılıp kayıttan çıkarılıyorsa, başka bir programın (işlem) adres alanına işaret edecektir. bu yüzden bir süre sonra çökecek.
sc_cs

Ya da varsayımsal olarak, tamsayı taşması elde edebilir ve sonsuz koşarak etrafına sarılabilir. Ben kullanmayı çalışacaktı long longya size_tve başlamak pilgili maksimum değerde veya buna yakın, daha hızlı çökmesine. Yine de bu durumda bile çökmesi garanti edilmez.
Patrick Roberts

0

Bunu yapmanın şık bir yolu, saf bir sanal işlev çağrısıdır:

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 ile derlendi, bu yazdırır:

saf sanal yöntem denir

etkin bir istisna olmadan çağrılan sonlandır

Durduruldu (çekirdek boşaltıldı)


0

code Montajınızı c ++ cihazınızda kullanabilirsiniz, ancakINT 3 sadece x86 sistemleri için diğer sistemlerin diğer tuzak / kesme noktası talimatları olabilir.

int main()
{
    __asm int 3;

    return 0;
}

INT 3 bir kesmeye neden olur ve işletim sistemi tarafından ayarlanan bir kesme vektörünü çağırır.


0

GCC veya clang'da __builtin_trap () veya MSVC'de __debugbreak () kullanın. Bu kesme noktalarını / tuzakları işlememek işlenmemiş bir kesme noktası istisnasına / çökmesine neden olacaktır. Abort () veya exit () kullanan diğer öneriler: bunlar diğer iş parçacıkları tarafından işlenebilir ve bu da kilitlenmeyi ilerleten iş parçacığının yığınını görmeyi zorlaştırır.


-2
char*freeThis;
free(freeThis);

Başlatılmamış bir işaretçiyi serbest bırakmak tanımlanmamış bir davranıştır. Birçok platformda / derleyicide, freeThisrastgele bir değere sahip olacaktır (daha önce o bellek konumunda ne varsa). Boşaltıldığında, sistemde genellikle bir segmentasyon hatasına neden olacak ve programın çökmesine neden olacak şekilde bu adresteki belleği boşaltması istenir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.