iOS 앱이 충돌하는 안정적인 방법은 무엇입니까?


136

실제 사용자가 실수로 할 수없는 특정 작업을 수행 할 때 의도적으로 충돌하여 응용 프로그램의 충돌 보고서를 현장에서 테스트하고 싶습니다.

그러나 컴파일 타임에 경고를 생성하지 않는 앱 충돌을 일으키는 신뢰할 수있는 좋은 방법은 무엇입니까?

편집 : 이 질문에 대한 많은 명백한 대답은 Cocoa에 의해 잡히는 예외를 초래하므로 앱이 중단되지 않습니다.


나는 지금 WebKit discarded an uncaught exception까지 이러한 모든 아이디어를 얻고 있습니다 ! 요즘 앱 충돌을 일으키는 것이 어렵다는 것을 누가 알았습니까?
— Nestor

나는 이것들 중 어느 것도 WebKit과 관련이 있다고 생각하지 않습니다 ...
— BoltClock

23
그렇습니다 .iPad 1에서 Safari를 열고 많은 이미지가있는 페이지를 탐색하십시오. 항상 나를 위해 일합니다. : /
— Alan B

4
(void)0/0;,(void)*(char*)0;
— 케빈

1
여기에 정의되지 않은 동작을 호출하는 일부 답변에주의하십시오 . 그것은 실제로 매우 불쾌한 조언입니다!
— usr

답변:


140

Objective-C에서 C를 직접 사용하여 액세스가 잘못됨

strcpy(0, "bla");

참고 : 이것은 내가 알고있는 모든 시스템에서 작동하지만 향후 버전의 C 런타임 또는 컴파일러에서는 더 이상 충돌을 일으키지 않을 수 있습니다. Objective-C에서 널 포인터 역 참조가 정의되지 않은 동작입니까?를 참조 하십시오 . )

(빨리이 작업을 수행하려면 objC에 브리지해야합니다)


이 가장 신뢰할 수있는 방법 이럴이다
— 마이클 KREFT

아 그래, 그 WebKit discarded an uncaught exception문제도 해결됩니다.
— Nestor

아직도 오타가 있었다 : D no @ "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
assert가 릴리스 버전에서 충돌하지 않으므로 이것이 assert 인 이유
— DarthMike

6
빌드 설정에 따라 다릅니다. 또한, 문제는 테스트에 관한 것이라고 생각합니다. 테스트 빌드에서 주장을 유지하는 것이 좋습니다.
— djromero

3
나를 포함한 많은 사람들이 릴리스 빌드에서 어서 트를 남겨둔다. 비활성화 할 이유가 없습니다.
— Sulthan

5
@Sulthan : assert()디버그 기능이며 릴리스 빌드에서 이러한 쪼개짐 을 남기는 것은 의미가 없습니다. 이에 대한 단위 테스트가 있습니다.
— MestreLion

18
IMHO assert는 디버그 기능이 아닙니다. 실패한 주장은 불가능하다고 생각한 버그입니다. 예측 불가능한 결과로 프로그램을 계속 실행하는 것보다 릴리스 빌드조차 중단하는 것이 좋습니다.
— djromero

27

우리 모두는 iOS 용 Clang을 사용하기 때문에 상당히 안정적입니다.

__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 자)


upvotes에 대한 있지만, 사실은이 앱이 종료하고 그 자체에 유용 할 수 있지만, 스프링,로 복귀 할 것 덕분에, 영업 이익은 포착되지 않은 예외 트리거 인 싶었던 것이 아니다
— 스티브 로저스

6

예외를 제기 할 수도 있습니다.

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

2
예외가 좋은 방법이라고 생각하지 않습니다. 예외를 포착하는 것이 일반적이므로 실수로 예외를 포착 할 수 있습니다. 신호 포착은 그리 일반적이지 않으므로 액세스가 좋지 않거나 이와 유사한 것이 더 안정적입니다. :)
— Michał Kreft

3

10 손가락 탭을 인식하는보기에 동작 인식기를 추가하십시오 (10 인 경우 iPhone의 경우 5 손가락은 약간 혼잡해질 수 있음). GR에는 앞서 언급 한 확실한 방법으로 앱을 중단시킬 수있는 방법이 첨부되어 있습니다. 대부분의 사용자는 앱에 손가락을 10 개 내려 놓지 않으므로 실수로 충돌을 일으킨 일반 사용자로부터 안전합니다.

그러나 Testflight와 같은 것을 사용하거나 개인 장치에 배포하고 Apple에 제출하기 전에 야생에서 테스트 할 수 있어야합니다. 강제 충돌이 발생하면 Apple이 앱을 거부 할 수 있습니다.


극단적 인 멀티 터치를 수행하면 Cocos2d 앱이 충돌하고 해결되지 않은 버그로 인식됩니다. GR이 없지만 Cocos2d에서 멀티 터치를 활성화했습니다. 내가 말한 충돌이 발생합니까? 이것이 예상되는 / 원하는 행동이라는 것을 의미합니까?
— 프레드릭 요한슨

@Fredrik 나는 당신이 묘사하고있는 충돌이라고 생각하지 않습니다 (IMO 충돌은 결코 예상되어서는 안되며 개인적으로 그 문제를 위해 앱에 의도적으로 넣는 것이 좋지 않다고 생각합니다). 충돌을 상징하고 앱이 충돌하는 원인을 정확히 알아낼 수 있습니다. Cocos2d 프레임 워크 내부에 '익스트림 멀티 터치'가 발생할 때 충돌을 일으키는 무언가가있을 수 있습니다. 이 경우 가장 좋은 방법은 Cocos2d 사람들에게 버그를 신고하는 것입니다.
— jhelzer

2

같은 것을 시도 할 수 있습니다

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

EXC_BAD_ACCESS에서 충돌해야합니다 (두 번째로 해제해야하지만 정상적으로는 이미 충돌 했음)


3
ARC가 활성화 된 상태에서는 컴파일되지 않습니다.
— vikingosegundo

물론 ARC를 사용한다면 다음과 같이 할 수도 있습니다 : NSArray * crashingArray = [NSArray arrayWithCapacity : 1]; [crashingArray objectAtIndex : 0]; 이것은 충돌해야합니다
— Saliom

1

나는 함께 갈 것이다 :int raise(int sig);

더 많은 정보를 얻으려면 >man raise


0

프로세스를 정상적으로 종료합니다.

kill(getpid(), SIGKILL);

따라서 신호가있는 핸들러를 설치하면 충돌을 처리하고 열린 파일 및 이러한 작업을 완료 할 수 있습니다.


이 이미 포함되어 madmw의 대답
— vikingosegundo

0

나는 사용한다

[self doesNotRecognizeSelector:_cmd]; 

2
이 게시물은 코드 일 뿐이므로 자동으로 품질이 낮은 것으로 표시됩니다. 이것이 왜 문제를 해결하는지 설명하는 텍스트를 추가하여 확장 하시겠습니까?
— 모니카

0

RubyMotion으로 작업 할 때 다음을 사용합니다.

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

0

이 시도:

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

-1

잘못된 NSLog진술이 그것을 할 것입니다

NSLog(@"%@",1);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.