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.