Jaki jest niezawodny sposób na awarię aplikacji na iOS?


136

Chcę przetestować raportowanie awarii mojej aplikacji w terenie, celowo powodując awarię, gdy użytkownik wykonuje określoną czynność, której rzeczywisty użytkownik prawdopodobnie nie wykona przypadkowo.

Ale jaki jest dobry niezawodny sposób na spowodowanie awarii aplikacji, która nie generuje ostrzeżenia w czasie kompilacji?

Edycja: Zwróć uwagę, że wiele pozornie oczywistych odpowiedzi na to pytanie powoduje wyjątki, które zostają przechwycone przez Cocoa, a tym samym nie powodują awarii aplikacji.


Na razie dostaję WebKit discarded an uncaught exceptionza wszystkie te pomysły! Kto by pomyślał, że ostatnio tak trudno było spowodować awarię aplikacji?
Nestor

Nie sądzę, żeby to miało coś wspólnego z
WebKitem

23
Tak, otwórz Safari na iPadzie 1 i przejdź do strony z dużą ilością obrazów. Zawsze mi pasuje. : /
Alan B

4
(void)0/0;,(void)*(char*)0;
Kevin

1
Uważaj na niektóre odpowiedzi, które wywołują niezdefiniowane zachowanie . To naprawdę bardzo nieprzyjemna rada!
usr

Odpowiedzi:


140

w Objective-C użyj C bezpośrednio, aby spowodować zły dostęp

strcpy(0, "bla");

Uwaga: chociaż działa to na każdym systemie, który znam - w przyszłej wersji środowiska wykonawczego C LUB kompilatora może to już nie prowadzić do awarii. zobacz Is null pointer dereference undefined Behavior in Objective-C? )

(w szybkim tempie musiałbyś połączyć się mostem z objC, aby to zrobić)


to IMHO najbardziej niezawodny sposób
Michał Kreft

Ach tak, to też WebKit discarded an uncaught exceptionrozwiązuje problem.
Nestor

wciąż była literówka: D no @ "bla" ale "bla"
Daij-Djan.

4
Najwyraźniej ( stackoverflow.com/questions/13651642/… ) jest to niezdefiniowane zachowanie i właściwie bardzo zła odpowiedź! Kompilator może legalnie zoptymalizować obie instrukcje i po prostu nic nie robić. Proponuję usunąć tę odpowiedź. Może to skłonić ludzi do tego.
usr

3
na iOS, OSX i Windows i ponownie, że zawsze się zawieszał, więc w danym kontekście powiedziałbym, że jest poprawny. Dodam wyłączenie odpowiedzialności
Daij-Djan

97

Mój obecny ulubiony:

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

Klasyk:

kill( getpid(), SIGABRT );

I trochę pr0n:

*(long*)0 = 0xB16B00B5;

Wszystkie z nich generują awarie przechwycone przez moje narzędzie do raportowania awarii.


14
assert nie zawiesza się w wersjach wydanych, dlatego jest to
asercja

6
zależy to od ustawień kompilacji; również myślę, że pytanie dotyczy testowania, wydaje się w porządku, aby zachować potwierdzenia w kompilacjach testowych
djromero,

3
Wiele osób (w tym ja) zostawia potwierdzenia w kompilacjach wydań. Nie ma powodu, aby je wyłączać.
Sulthan

5
@Sulthan: assert()to funkcja debugowania, nie ma sensu zostawiać takich okrucieństw w kompilacjach wydań. Istnieją na to testy jednostkowe.
MestreLion

18
IMHO assertnie jest funkcją debugowania. Nieudana asercja to błąd, który uważałeś za niemożliwy. Lepiej przerwać, nawet kompilację wydania, niż kontynuować uruchamianie programu z nieprzewidywalnymi konsekwencjami.
djromero

27

Ponieważ wszyscy używamy Clang na iOS, jest to dość niezawodne:

__builtin_trap();

Ma to tę zaletę, że został zaprojektowany dokładnie w tym celu, więc nie powinien generować żadnych ostrzeżeń ani błędów kompilatora.



22

Co powiesz na stare dobre przepełnienie stosu :)

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

16

Najpopularniejszy - nierozpoznana awaria selektora:

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

Upewnij się, że nie masz metody -asdf zaimplementowanej w tej klasie haha

Lub indeks poza ograniczonym wyjątkiem:

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

I oczywiście kill( getpid(), SIGABRT );


12

Myślę, że w Swift można łatwo rzucić fatalny błąd:

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

W rzeczywistości jest nawet przeznaczone do użycia tej funkcji na wypadek, gdyby coś poszło nie tak, aby spowodować awarię aplikacji.

Aby uniknąć instrukcji if w szczególnym przypadku, możesz również użyć precondition. Jest podobny do assert, sprawia, że ​​zamiar (jeśli jest potrzebny) jest dość jasny i nie jest usuwany w ostatecznej wersji jako assert. Jest używany jak precondition(myBoolean, "This is a helpful error message for debugging.").


9

Wyślij wiadomość do zwolnionego obiektu


34
W rzeczywistości jest to bardzo zawodne. Nadal możesz wysyłać wiadomości do zwolnionych obiektów, o ile ich pamięć nie zostanie ponownie wykorzystana. To jest cały powód, dla którego ludzie mieli historycznie bardzo trudne debugowanie błędów podwójnego wydania. Dopiero gdy pamięć jest odzyskiwana przez inny obiekt, wysłanie wiadomości może spowodować wyjątek.
Mike Weller

7
exit(0);

(należy ... wpisać ... 30 znaków)


Dzięki za upvotes ale w rzeczywistości to uczynią aplikacja zakończyć i powrócić do Springboard, która, choć może on być przydatny w sobie, nie jest to, co chciała PO, która ma wyzwalać untrapped wyjątek
Steve Rogers

6

Możesz również zgłosić wyjątek:

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

2
Nie sądzę, żeby wyjątek był taki dobry, wychwytywanie wyjątku jest powszechne, więc można go przypadkowo złapać. Wyłapywanie sygnałów nie jest tak powszechne, więc zły dostęp lub podobne rzeczy byłyby bardziej niezawodne. :)
Michał Kreft

3

Dodaj rozpoznawanie gestów do widoku, który rozpoznaje stuknięcie 10 palcami (5 palców w przypadku iPhone'a 10 może być trochę zatłoczonych). GR ma dołączoną metodę, która wykonuje każdy z wcześniej wspomnianych niezawodnych sposobów spowodowania awarii aplikacji. Większość użytkowników nie położy 10 palców na twojej aplikacji, więc jesteś bezpieczny przed przypadkowym spowodowaniem awarii przez ogólnego użytkownika.

Jednak powinieneś być w stanie użyć czegoś takiego jak Testflight lub po prostu wdrożyć go na urządzeniach osobistych i przetestować na wolności, zanim prześlesz go do Apple. Wymuszona awaria może spowodować odrzucenie aplikacji przez Apple.


Moja aplikacja Cocos2d ulega awarii, gdy wykonuję ekstremalny multi-touch, i mam to jako nierozwiązany błąd. Nie mam żadnego GR, ale włączyłem multitouch w Cocos2d. Czy doświadczam awarii, którą opisujesz? Masz na myśli, że jest to oczekiwane / pożądane zachowanie?
Fredrik Johansson

@Fredrik Nie sądzę, abyś się spodziewał awarii, którą opisujesz (awarie IMO nigdy nie powinny się spodziewać i osobiście nie uważam, aby celowo umieszczać ją w swojej aplikacji w tym celu). Możesz spróbować symbolizować awarię i dowiedzieć się, jaka metoda powoduje awarię aplikacji. Może to być coś wewnątrz struktury Cocos2d, które powoduje awarię, gdy wystąpi „ekstremalny multi-touch”. Jeśli tak jest, najlepszym rozwiązaniem jest zgłoszenie błędu z chłopakami z Cocos2d.
jhelzer

2

mógłby spróbować czegoś takiego

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

powinien się zawiesić na EXC_BAD_ACCESS (może wymagać zwolnienia go po raz drugi, ale normalnie powinien już się zawiesić)


3
Nie można skompilować z włączonym ARC.
vikingosegundo

cóż, jeśli używasz ARC, możesz również zrobić to: NSArray * crashingArray = [NSArray arrayWithCapacity: 1]; [crashingArray objectAtIndex: 0]; to powinno się
zawiesić

1

Pójdę z:int raise(int sig);

Aby uzyskać więcej informacji >man raise


0

Po prostu zabiłbym ten proces normalnie:

kill(getpid(), SIGKILL);

Więc jeśli zainstalujesz program obsługi z sygnałem, możesz również obsłużyć awarię, kończąc zapisywanie otwartych plików i innych rzeczy.


jest to już zawarte w odpowiedzi
madmw

0

używam

[self doesNotRecognizeSelector:_cmd]; 

2
Ten post jest automatycznie oznaczany jako niskiej jakości, ponieważ zawiera tylko kod. Czy mógłbyś go rozszerzyć, dodając tekst wyjaśniający, dlaczego to rozwiązuje problem?
gung - Przywróć Monikę

0

Podczas pracy z RubyMotion używam tego:

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

0

Spróbuj tego:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.