iOSアプリをクラッシュさせる信頼できる方法は何ですか?


136

実際のユーザーが誤って行う可能性が低い特定のアクションをユーザーが実行したときに意図的にクラッシュさせることにより、アプリのクラッシュレポートをフィールドでテストしたいと思います。

しかし、コンパイル時に警告を出さない、アプリをクラッシュさせる信頼できる方法は何でしょうか?

編集:この質問に対する一見明白な答えの多くは、Cocoaによってキャッチされる例外を発生させるため、アプリがクラッシュしないことに注意してください。


私は取得していますWebKit discarded an uncaught exceptionこれまでのところ、これらのアイデアのすべてのために!最近、アプリをクラッシュさせるのが難しいことを誰が知っていましたか?
Nestor

これらのどれもがWebKitとは関係ないと思います...
BoltClock

23
はい、iPad 1でSafariを開いて、画像の多いページを参照してください。いつも私のために働きます。:/
アランB

4
(void)0/0;(void)*(char*)0;
ケビン

1
未定義の動作引き起こすここでの回答のいくつかに注意してください。それは実際には非常に厄介なアドバイスです!
usr

回答:


140

Objective-Cでは、Cを直接使用して不正なアクセスを引き起こします

strcpy(0, "bla");

注:これは私が知っているすべてのシステムで機能しますが、Cランタイムまたはコンパイラの将来のバージョンでは、これによりクラッシュが発生しなくなる可能性があります。ご覧のObjective-Cで未定義の動作を逆参照されるヌルポインタを?

(これを行うには、objCにブリッジする必要があります)


これが私見の最も信頼できる方法です
ミハウ・クレット

ああ、そうです、それWebKit discarded an uncaught exceptionも問題を回避します。
Nestor

まだタイプミスがありました:Dいいえ "bla"ですが "bla"
Daij-Djan

4
どうやら(stackoverflow.com/questions/13651642/…)、これは未定義の動作であり、実際には非常に悪い答えです!コンパイラーは、両方のステートメントを合法的に最適化して、何も実行できません。この回答を削除することをお勧めします。それは人々が実際にこれをするように導くかもしれません。
usr

3
iosとosxとwindowsとredhatでは常にクラッシュしているため、指定されたコンテキストでは有効です。免責事項を追加します
Daij-Djan

97

私の現在のお気に入り:

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

クラシック:

kill( getpid(), SIGABRT );

そしていくつかのpr0n:

*(long*)0 = 0xB16B00B5;

それらすべてが、私のクラッシュレポートツールでキャプチャされたクラッシュを生成します。


14
アサートがリリースバージョンでクラッシュしない、それがアサートである理由
DarthMike

6
ビルド設定によって異なります。また、問題はテストに関するものだと思います。テストビルドでアサートを保持しても問題ないようです
djromero

3
多くの人(私を含む)は、リリースビルドにアサートを残しています。それらを無効にする理由はありません。
スルタン

5
@Sulthan:assert()デバッグ機能です。リリースビルドにそのような残骸を残しても意味がありません。そのための単体テストがあります。
MestreLion

18
IMHO assertはデバッグ機能ではありません。失敗したアサートは、あなたが不可能だと思ったバグです。予測できない結果をもたらすプログラムを実行し続けるよりも、リリースビルドでさえ、中止する方が良いです。
djromero

27

私たちはすべてClang for iOSを使用しているため、これはかなり信頼できます。

__builtin_trap();

これには、まさにこの目的のために設計されているという利点があるため、コンパイラの警告やエラーが生成されないはずです。



22

古き良きスタックオーバーフローはどうですか:)

- (void)stackOverflow
{
    [self stackOverflow];
}

16

最も人気のあるもの-認識されないセレクターのクラッシュ:

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

そのクラスに-asdfメソッドが実装されていないことを確認してください

またはバインドされた例外を超えたインデックス:

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

そしてもちろん kill( getpid(), SIGABRT );


12

私はSwiftでは簡単に致命的なエラーを投げることができると思います:

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

実際には、アプリがクラッシュするために何か問題が発生した場合に、この機能を使用することさえ意図されています。

特殊なケースでifステートメントを回避するにはprecondition、も使用できます。これはに似て assertいるため、意図が(必要な場合)かなり明確になり、最終リリースではとして削除されませんassert。のように使用されprecondition(myBoolean, "This is a helpful error message for debugging.")ます。


9

割り当て解除されたオブジェクトにメッセージを送信する


34
これは実際には非常に信頼できません。メモリが再利用されない限り、割り当てを解除したオブジェクトにメッセージを送信できます。これが、これまで人々が二重解放エラーをデバッグすることが非常に困難であった理由のすべてです。メッセージを送信すると例外が発生する可能性があるのは、メモリが別のオブジェクトによって解放されたときだけです。
Mike Weller、

7
exit(0);

(必須...タイプ... 30文字)


賛成投票に感謝しますが、実際にはこれによりアプリが終了し、Springboardに戻ります。これはそれ自体は有用ですが、OPが望んでいたものではなく、トラップされない例外をトリガーします
Steve Rogers

6

例外を発生させることもできます:

[NSException raise:NSInternalInconsistencyException
            format:@"I want to test app crashes!."];

2
例外は良い方法だとは思いません。例外をキャッチするのが一般的であるため、誤ってキャッチする可能性があります。シグナルをキャッチすることはそれほど一般的ではないので、不正アクセスまたは同様のものはより信頼できるでしょう。:)
のMichałKreft

3

10本の指のタップを認識するビューにジェスチャーレコグナイザーを追加します(iPhoneでは5本の指で10が少し混雑する可能性があります)。GRには、前述の確実な方法を実行してアプリをクラッシュさせるメソッドがアタッチされています。ほとんどのユーザーはアプリ上で10本の指を下に置くことはないので、一般ユーザーが誤ってクラッシュを引き起こしても安全です。

ただし、Appleに送信する前に、Testflightのようなものを使用したり、個人用デバイスに展開して実際にテストしたりできるはずです。強制クラッシュすると、アプリがAppleに拒否される可能性があります。


極端なマルチタッチを実行すると、Cocos2dアプリがクラッシュし、未解決のバグとしてそれが発生します。GRはありませんが、Cocos2dでマルチタッチを有効にしました。あなたが説明するクラッシュを経験しますか?これは期待される/望まれる動作であることを意味しますか?
Fredrik Johansson、

@Fredrikあなたが説明しているクラッシュだとは思わない(IMOのクラッシュは予想されないはずであり、個人的には意図的にアプリに1つ置くのは良い考えではない)。クラッシュを象徴して、アプリがクラッシュする原因となっている方法を正確に見つけてみてください。これはCocos2dフレームワーク内の何かであり、「極端なマルチタッチ」が発生したときにクラッシュを引き起こしている可能性があります。その場合は、Cocos2dの担当者にバグを報告するのが最善の策です。
jhelzer、

2

のようなものを試すことができます

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

EXC_BAD_ACCESSでクラッシュするはずです(2回目に解放する必要があるかもしれませんが、通常はすでにこのようにクラッシュするはずです)。


3
ARCを有効にしてコンパイルしないでください。
vikingosegundo

ARCを使用している場合は、次のようにすることもできます。NSArray * crashingArray = [NSArray arrayWithCapacity:1]; [crashingArray objectAtIndex:0]; これはクラッシュするはずです
サリオム2014


0

私は普通にプロセスを殺すでしょう:

kill(getpid(), SIGKILL);

したがって、シグナル付きのハンドラーをインストールすると、クラッシュを処理して、開いたファイルやこれらのものを書き終えることができます。


これはすでにmadmwの回答に
vikingosegundo

0

私が使う

[self doesNotRecognizeSelector:_cmd]; 

2
この投稿はコードのみであるため、自動的に低品質としてフラグが付けられています。これで問題が解決する理由を説明するテキストを追加して、拡張していただけませんか?
ガン-モニカを2014年

0

RubyMotionで作業するとき、これを使用します。

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.