Apa cara yang dapat diandalkan untuk membuat aplikasi iOS mogok?

136

Saya ingin menguji pelaporan kerusakan aplikasi saya di lapangan dengan sengaja membuatnya mogok saat pengguna melakukan tindakan tertentu yang tidak mungkin dilakukan oleh pengguna sebenarnya secara tidak sengaja.

Tapi apa cara andal yang baik untuk membuat aplikasi mogok yang tidak membuat peringatan pada waktu kompilasi?

Sunting: Perhatikan bahwa banyak jawaban yang tampaknya jelas untuk pertanyaan ini menghasilkan pengecualian yang ditangkap oleh Cocoa dan karenanya tidak mengakibatkan aplikasi mogok.

Nestor
sumber
Saya mendapatkan WebKit discarded an uncaught exceptionsemua ide ini sejauh ini! Siapa yang tahu sangat sulit membuat aplikasi mogok akhir-akhir ini?
Nestor
Saya tidak berpikir semua ini ada hubungannya dengan WebKit ...
BoltClock
23
Ya, buka Safari di iPad 1 dan telusuri ke halaman dengan banyak gambar. Selalu bekerja untuk saya. : /
Alan B
4
(void)0/0;,(void)*(char*)0;
Kevin
1
Berhati-hatilah dengan beberapa jawaban di sini yang memicu perilaku tidak terdefinisi . Itu sebenarnya nasihat yang sangat buruk!
usr

Jawaban:

140

di Objective-C gunakan C secara langsung untuk menyebabkan akses yang buruk

strcpy(0, "bla");

Catatan: meskipun ini berfungsi pada sistem apa pun yang saya tahu - di versi runtime C yang akan datang ATAU kompiler, hal ini mungkin tidak akan menyebabkan crash lagi. lihat Apakah null pointer dereference perilaku tidak terdefinisi di Objective-C? )

(secepatnya Anda harus menjembatani objC untuk melakukan ini)

Daij-Djan
sumber
ini adalah IMHO cara yang paling dapat diandalkan
Michał Kreft
Ah ya, itu juga mengatasi WebKit discarded an uncaught exceptionmasalah.
Nestor
masih ada kesalahan ketik: D tidak @ "bla" tapi "bla"
Daij-Djan
4
Rupanya ( stackoverflow.com/questions/13651642/… ), ini adalah perilaku yang tidak ditentukan dan sebenarnya jawaban yang sangat buruk! Kompiler secara legal dapat mengoptimalkan kedua pernyataan dan tidak melakukan apa-apa. Saya sarankan Anda menghapus jawaban ini. Ini mungkin membuat orang benar-benar melakukan ini.
usr
3
di ios dan osx dan windows dan redhat itu selalu macet jadi dalam konteks yang diberikan, saya akan mengatakan itu valid. Saya akan menambahkan penafian
Daij-Djan
98

Favorit saya saat ini:

assert(! "crashing on purpose to test <insert your reason here>");

Sebuah klasik:

kill( getpid(), SIGABRT );

Dan beberapa pr0n:

*(long*)0 = 0xB16B00B5;

Semuanya menghasilkan kerusakan yang ditangkap oleh alat pelaporan kerusakan saya.

djromero.dll
sumber
14
menegaskan tidak macet pada versi rilis, itulah mengapa ini merupakan
pernyataan
6
itu tergantung pada pengaturan build Anda; juga, saya pikir pertanyaannya adalah tentang pengujian, tampaknya oke untuk tetap menegaskan dalam
versi
3
Banyak orang (termasuk saya) meninggalkan pernyataan di build rilis. Tidak ada alasan untuk menonaktifkannya.
Sulthan
5
@Sulthan: assert()adalah fitur debug, tidak masuk akal untuk membiarkan hal semacam itu dalam build rilis. Ada tes unit untuk itu.
MestreLion
18
IMHO assertbukanlah fitur debug. Penegasan yang gagal adalah bug yang menurut Anda tidak mungkin. Lebih baik membatalkan, bahkan rilis build, daripada terus menjalankan program dengan konsekuensi yang tidak dapat diprediksi.
djromero
27

Karena kita semua menggunakan Clang untuk iOS, ini cukup dapat diandalkan:

__builtin_trap();

Ini memiliki keuntungan karena dirancang untuk tujuan ini, jadi tidak akan menghasilkan peringatan atau kesalahan kompiler.

Dietrich Epp
sumber
22

Bagaimana dengan stack overflow lama yang bagus :)

- (void)stackOverflow
{
    [self stackOverflow];
}
Taum
sumber
16

Yang paling populer - kerusakan pemilih yang tidak dikenal:

NSObject *object = [[NSObject alloc] init];
[object performSelector:@selector(asfd)];

Pastikan Anda tidak menerapkan metode -asdf di kelas itu haha

Atau indeks di luar pengecualian terikat:

NSArray * array = [NSArray array];
[array objectAtIndex:5];

Dan tentu saja kill( getpid(), SIGABRT );

wirrwarr.dll
sumber
13

Saya pikir di Swift Anda dapat dengan mudah membuat kesalahan fatal:

func foo() {
    fatalError("crash!")
}

Bahkan sebenarnya dimaksudkan untuk menggunakan fitur ini jika terjadi kesalahan untuk membuat aplikasi macet.

Untuk menghindari pernyataan if dalam kasus khusus, Anda dapat menggunakan preconditionjuga. Ini mirip dengan assert, membuat niat (jika diinginkan) cukup jelas dan tidak dihapus dalam rilis final sebagai assert. Ini digunakan seperti precondition(myBoolean, "This is a helpful error message for debugging.").

borchero.dll
sumber
9

Mengirim pesan ke objek yang tidak dialokasikan

Andrey Chernukha
sumber
34
Ini sebenarnya sangat tidak bisa diandalkan. Anda masih dapat mengirim pesan ke objek yang dibatalkan alokasinya selama memorinya tidak digunakan kembali. Ini adalah alasan utama mengapa orang secara historis sangat sulit men-debug kesalahan rilis ganda. Hanya ketika memori diambil kembali oleh objek lain yang mengirim pesan dapat menyebabkan pengecualian.
Mike Weller
7
exit(0);

(harus ... ketik ... 30 karakter)

Steve Rogers
sumber
Terima kasih atas upvote-nya tetapi sebenarnya ini akan membuat aplikasi berhenti dan kembali ke Springboard, yang, meskipun bisa berguna sendiri, bukanlah yang diinginkan OP, yang memicu pengecualian yang tidak terikat
Steve Rogers
6

Anda juga dapat mengajukan pengecualian:

[NSException raise:NSInternalInconsistencyException
            format:@"I want to test app crashes!."];
Alessandro Vendruscolo
sumber
2
Menurut saya pengecualiannya bukan cara yang baik, menangkap pengecualian adalah hal biasa sehingga Anda dapat menangkapnya secara tidak sengaja. Menangkap sinyal tidak begitu umum sehingga akses yang buruk atau hal serupa akan lebih dapat diandalkan. :)
Michał Kreft
3

Tambahkan pengenal gerakan ke tampilan yang mengenali ketukan 10 jari (5 jari untuk iPhone 10 bisa menjadi agak ramai). GR memiliki metode yang menyertainya yang mengeksekusi salah satu cara pasti yang disebutkan sebelumnya untuk membuat aplikasi Anda mogok. Sebagian besar pengguna tidak akan meletakkan 10 jari ke bawah pada aplikasi Anda, jadi Anda aman dari pengguna umum yang secara tidak sengaja menyebabkan crash.

Namun Anda harus dapat menggunakan sesuatu seperti Testflight atau hanya menyebarkannya ke perangkat pribadi dan menguji di alam liar sebelum mengirimkannya ke Apple. Memiliki crash paksa dapat membuat aplikasi Anda ditolak oleh Apple.

jhelzer
sumber
Aplikasi Cocos2d saya mogok saat saya melakukan multi sentuh yang ekstrem, dan saya mendapatkannya sebagai bug yang belum terselesaikan. Saya tidak memiliki GR, tetapi saya telah mengaktifkan multitouch di Cocos2d. Apakah saya mengalami kecelakaan yang Anda gambarkan? Maksud Anda ini adalah perilaku yang diharapkan / diinginkan?
Fredrik Johansson
@Fredrik Saya tidak berpikir Anda crash yang Anda gambarkan diharapkan (IMO crash seharusnya tidak pernah diharapkan dan saya pribadi tidak berpikir itu ide yang baik untuk sengaja meletakkannya di aplikasi Anda dalam hal ini). Anda dapat mencoba menyimbolkan crash dan mencari tahu metode apa yang menyebabkan aplikasi crash. Bisa jadi sesuatu di dalam kerangka Cocos2d yang menyebabkan crash ketika 'ekstrim multi touch' terjadi. Jika itu masalahnya maka taruhan terbaik Anda adalah melaporkan bug dengan orang-orang Cocos2d.
jhelzer
2

bisa mencoba sesuatu seperti

NSArray* crashingArray = [NSArray arrayWithCapacity:1];
[crashingArray release];

harus macet di EXC_BAD_ACCESS (mungkin perlu merilisnya untuk kedua kalinya tetapi normalnya seharusnya sudah macet seperti ini)

Saliom
sumber
3
Tidak akan dikompilasi dengan ARC diaktifkan.
vikingosegundo
nah jika ouy menggunakan ARC Anda juga bisa melakukan ini: NSArray * crashingArray = [NSArray arrayWithCapacity: 1]; [crashingArray objectAtIndex: 0]; ini harus menerjang
Saliom
1

Saya akan pergi dengan:int raise(int sig);

Untuk mendapatkan info lebih lanjut >man raise

Vytautas
sumber
0

Saya hanya akan menghentikan proses secara normal:

kill(getpid(), SIGKILL);

Jadi jika Anda menginstal penangan dengan sinyal Anda juga dapat menangani crash, menyelesaikan untuk menulis file yang dibuka dan hal-hal ini.

Ramy Al Zuhouri
sumber
ini sudah termasuk dalam jawaban
madmw
0

saya menggunakan

[self doesNotRecognizeSelector:_cmd]; 
Duyen-Hoa
sumber
2
Posting ini secara otomatis ditandai sebagai kualitas rendah karena ini hanya kode. Maukah Anda mengembangkannya dengan menambahkan beberapa teks untuk menjelaskan mengapa hal ini menyelesaikan masalah?
gung - Pulihkan Monica
0

Saat bekerja dengan RubyMotion saya menggunakan ini:

    n=Pointer.new ('c', 1)
    n[1000] ='h'
Raymond
sumber
0

Coba ini:

- (IBAction)Button:(id)sender
{
    NSArray *array = [NSArray new];
    NSLog(@"%@",[array objectAtIndex:8]);
}
Rajesh Loganathan
sumber
-1

NSLogpernyataan yang salah akan berhasil

NSLog(@"%@",1);
Mutawe
sumber