02/04/2023
Aplikace jsou nedílnou součástí našeho digitálního života, ale stejně jako jakýkoli složitý software, i ty na iOS zařízeních se občas setkávají s nepříjemnými pády. Tyto pády jsou pro uživatele frustrující a pro vývojáře představují kritické momenty, které vyžadují rychlou a efektivní reakci. Když se publikovaná aplikace zhroutí na zařízení uživatele, Apple automaticky odešle protokol pádu (crash log) vývojáři. Klíčem k opravě těchto chyb je schopnost tyto protokoly číst a správně analyzovat. V tomto článku se ponoříme hluboko do světa pádů aplikací na iOS, prozkoumáme důvody, proč k nim dochází, naučíme se, jak k protokolům pádů přistupovat, jak je analyzovat, symbolizovat a rozlišovat mezi různými typy výjimek. Cílem je poskytnout vám uceleného průvodce, který vám pomůže identifikovat a odstranit problémy, čímž zajistíte, že vaše aplikace budou stabilní a poskytnou uživatelům bezproblémový zážitek.

Proč aplikace padají?
Pády aplikací jsou běžnou, avšak nežádoucí součástí životního cyklu softwaru. Mohou nastat z mnoha různých důvodů, a pochopení těchto příčin je prvním krokem k jejich prevenci a opravě. Zde jsou některé z nejčastějších důvodů, proč se aplikace na iOS zařízeních zhroutí:
- Problémy s Watchdogem: iOS má vestavěný systém zvaný Watchdog, který monitoruje, zda aplikace reaguje. Pokud aplikace například trvá příliš dlouho na spuštění nebo nereaguje na události po určitou dobu (typicky desítky sekund), Watchdog ji automaticky ukončí, aby zabránil zamrznutí celého systému. To je běžná příčina pádů, zejména při spouštění aplikací s velkým množstvím dat nebo složitými inicializačními procesy.
- Problémy s vlákny: Moderní aplikace využívají více vláken pro paralelní zpracování úloh. Hlavní vlákno (main thread) je zodpovědné za aktualizaci uživatelského rozhraní a zpracování uživatelských interakcí. Pokud je hlavní vlákno blokováno dlouhotrvající operací (například stahováním dat, složitými výpočty nebo přístupem k databázi), aplikace přestane reagovat a systém ji může ukončit.
- Klasické vývojářské chyby: Některé pády jsou výsledkem základních programovacích chyb, které jsou pro zkušené vývojáře často snadno rozpoznatelné. Mezi ně patří například dělení nulou, přístup k neexistující paměti (null pointer dereference), nebo nekorektní správa paměti (memory leaks, use-after-free). Tyto chyby často vedou k výjimkám, které systém zachytí a ukončí proces aplikace.
- Chyba v nejnovější verzi iOS: Někdy nejsou na vině vývojáři aplikace, ale samotný operační systém. Nové verze iOS mohou obsahovat chyby, které ovlivňují fungování aplikací, a to i těch, které dříve fungovaly bez problémů. V takových případech je řešením obvykle aktualizace iOS nebo čekání na opravu od společnosti Apple.
- Chyba v open-source balíčku: Mnoho aplikací využívá open-source knihovny a frameworky pro zrychlení vývoje. Pokud se v těchto balíčcích objeví chyba, může to vést k pádům i ve vaší aplikaci. V takových případech je nutné aktualizovat problematický balíček na novější verzi, která chybu opravuje, nebo najít alternativní řešení.
Pochopení těchto základních příčin pádů je klíčové pro efektivní ladění a zlepšování stability vašich aplikací.
Jak získat protokoly pádů?
Získávání protokolů pádů je prvním krokem k jejich analýze. Existuje několik způsobů, jak se k těmto cenným datům dostat, v závislosti na tom, kde k pádu došlo a zda jste vývojář nebo koncový uživatel.
Protokoly z App Store (pro vývojáře)
Pokud je vaše aplikace publikována v App Store a zhroutí se na zařízení uživatele, Apple automaticky shromažďuje protokoly pádů a zpřístupňuje je vývojářům prostřednictvím portálu App Store Connect. Tato metoda je pro vývojáře velmi důležitá, protože poskytuje přehled o problémech, se kterými se setkávají skuteční uživatelé v reálném světě. Protokoly jsou zde již symbolizované, což znamená, že hexadecimální adresy jsou převedeny na čitelné názvy funkcí a řádků kódu, což výrazně usnadňuje ladění.
Protokoly z fyzického zařízení (přes Xcode)
Pro vývojáře je nejběžnějším způsobem, jak získat protokoly pádů z fyzického zařízení, použití Xcode. Tato metoda je ideální pro ladění během vývoje, kdy můžete kontrolovaně vyvolat pád a okamžitě zkontrolovat protokol.
- Připojte svůj iPhone/iPad k Macu.
- Otevřete Xcode.
- V horním menu klikněte na
Windowa poté naDevices and Simulators. - V levém panelu vyberte své připojené zařízení.
- V hlavním okně se zobrazí seznam protokolů, včetně protokolů pádů. Tyto protokoly jsou v Xcode automaticky symbolizovány.
Protokoly přímo na iOS zařízení
Uživatelé i vývojáři mohou přistupovat k protokolům pádů přímo na samotném iOS zařízení, i když tato verze není symbolizovaná a je méně čitelná pro běžného uživatele.
- Na vašem iPhonu/iPadu přejděte do
Nastavení(Settings). - Přejděte na
Soukromí a zabezpečení(Privacy & Security). - Vyberte
Analýza a vylepšení(Analytics & Improvements). - Klikněte na
Data analýzy(Analytics Data). - Zde uvidíte dlouhý seznam souborů. Protokoly pádů obvykle začínají názvem aplikace a končí datem a příponou
.ipsnebo.crash. Můžete je ručně prohledávat.
Protokoly ze simulátoru
Pokud se aplikace zhroutí během testování na simulátoru v Xcode, můžete k protokolům pádů přistupovat přímo z vašeho Macu.
- Otevřete Finder.
- V horním menu klikněte na
Goa poté naGo to Folder...(Přejít do složky...). - Do zobrazeného pole zadejte
~/Library/Logs/CoreSimulatora stiskněte Enter. - Zde najdete složky pro různé simulátory. V každé složce najdete složku
CrashLogs, která obsahuje protokoly pádů pro aplikace spuštěné na daném simulátoru. Tyto soubory lze otevřít libovolným textovým editorem.
Pamatujte, že protokoly získané přímo ze zařízení nebo simulátoru nemusí být symbolizované, což znamená, že adresy paměti budou v hexadecimálním formátu. Pro plné pochopení je často nutné je symbolizovat, což si vysvětlíme v další části.
Jak analyzovat protokoly pádů?
Protokol pádu se může na první pohled zdát jako chaotická změť textu a čísel, ale má jasnou strukturu, která vám po jejím pochopení umožní rychle identifikovat příčinu chyby. Typický protokol pádu se skládá ze tří hlavních sekcí:
1. Záhlaví (Header)
Záhlaví protokolu pádu obsahuje základní informace o procesu a okolnostech pádu. Je to jako identifikační karta nehody, která poskytuje kontext.
- Incident Identifier: Unikátní identifikátor pro tento konkrétní pád.
- CrashReporter Key: Další unikátní klíč, často svázaný s konkrétním zařízením.
- Hardware Model: Model zařízení (např. iPhone13,4 pro iPhone 12 Pro Max).
- Process: Název aplikace, která se zhroutila, a její ID procesu (PID). Například:
My iPhone App [2599]. - Path: Plná cesta k spustitelnému souboru aplikace na zařízení.
- Identifier: Bundle ID aplikace.
- Version: Verze aplikace a číslo sestavení (build number).
- Code Type: Typ architektury procesoru. Pro iOS zařízení je to obvykle
ARM(Native), protože iPhony/iPady používají procesory ARM. - Parent Process: Rodičovský proces, který spustil vaši aplikaci (obvykle
launchd). - Date/Time: Přesné datum a čas pádu, včetně časového posunu.
- OS Version: Verze operačního systému iOS, na kterém k pádu došlo (např. iPhone OS 15.2).
- Report Version: Verze formátu protokolu pádu.
Příklad části záhlaví:
Incident Identifier: 14FFD847-61CB-435B-9E98-C06B3B661429
CrashReporter Key: 7c5fd78cf04b38cfd2aa153f61eb1655ed671274
Hardware Model: iPhone4,1
Process: My iPhone App [2599]
Path: /var/mobile/Applications/ABAB96ED-A203-48A5-8B50-B34BA3A8E4A4/My iPhone App.app/My iPhone App
Identifier: My iPhone App
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2012-07-01 22:17:43.458 -0600
OS Version: iPhone OS 5.1 (9B179)
Report Version: 1042. Informace o výjimce (Exception Information)
Tato sekce je často tou nejdůležitější, protože obsahuje nejpravděpodobnější příčinu pádu. Poskytuje stručné vysvětlení, proč systém ukončil vaši aplikaci.
- Exception Type: Typ výjimky, která vedla k pádu. Toto je klíčový ukazatel. Například
EXC_CRASH (SIGKILL),EXC_BAD_ACCESS (SIGSEGV),EXC_BREAKPOINT (SIGTRAP). Každý typ má specifický význam, který si podrobněji rozebereme v další sekci. - Exception Codes: Další kódy související s výjimkou, které mohou poskytnout více detailů.
- Exception Note: Doplňující poznámka k výjimce.
- Termination Reason: Důvod ukončení procesu. Zde můžete často najít konkrétní kód, jako je
0x8badf00d, který indikuje Watchdog timeout. Kód0x8badf00dje notoricky známý a znamená „did not finish good“ (špatně dokončeno) – aplikace se nespustila, neukončila nebo nereagovala dostatečně rychle.
Příklad části informací o výjimce:
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d3. Zpětná trasování výjimky (Exception Backtrace / Thread State)
Tato sekce je páteří protokolu pádu a poskytuje přesné trasování volání funkcí, které vedly k chybě. Je to jako záznam o tom, co se stalo těsně před pádem.
- Thread X name: Název vlákna, ve kterém k pádu došlo (např.
main-thread, což je hlavní uživatelské rozhraní). - Thread X Crashed: Označuje vlákno, které se zhroutilo.
- Následuje seznam volání funkcí (tzv. stack trace), kde každá řádka představuje jednu funkci v zásobníku volání. Řádky jsou číslovány od 0, přičemž 0 je funkce, která přímo způsobila pád.
- Každá řádka obvykle obsahuje:
- Číslo rámce zásobníku (stack frame number).
- Název binárního souboru nebo knihovny (např.
libobjc.A.dylib,UIKit,My iPhone App). - Hexadecimální adresu v paměti, kde k události došlo.
- Název funkce nebo metody, pokud je protokol symbolizovaný. Pokud není, uvidíte pouze hexadecimální adresy.
- Posun (offset) od začátku funkce.
Příklad nespymbolizovaného zpětného trasování:
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x35a65f7e objc_msgSend + 22
1 UIKit 0x33c31042 -[UIImageView isAnimating] + 130
2 UIKit 0x33c3b100 -[UIImageView stopAnimating] + 96
3 UIKit 0x33d5d1de -[UIActivityIndicatorView _tearDownAnimation] + 30
4 UIKit 0x33cdb972 -[UIActivityIndicatorView _applicationDidEnterBackground:] + 34
5 Foundation 0x37d8f4f8 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 12
6 CoreFoundation 0x37531540 ___CFXNotificationPost_block_invoke_0 + 64
7 CoreFoundation 0x374bd090 _CFXNotificationPost + 1400
8 Foundation 0x37d033e4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 60
9 UIKit 0x33c813f6 -[UIApplication _handleApplicationSuspend:eventInfo:] + 786
10 UIKit 0x33c120a0 -[UIApplication handleEvent:withNewEvent:] + 2088
11 UIKit 0x33c11708 -[UIApplication sendEvent:] + 48
12 UIKit 0x33c110dc _UIApplicationHandleEvent + 5820
13 GraphicsServices 0x323c9224 PurpleEventCallback + 876
14 CoreFoundation 0x3753951c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
15 CoreFoundation 0x375394be __CFRunLoopDoSource1 + 134
16 CoreFoundation 0x3753830c __CFRunLoopRun + 1364
17 CoreFoundation 0x374bb49e CFRunLoopRunSpecific + 294
18 CoreFoundation 0x374bb366 CFRunLoopRunInMode + 98
19 GraphicsServices 0x323c8432 GSEventRunModal + 130
20 UIKit 0x33c3fe76 UIApplicationMain + 1074
21 My iPhone App 0x000f7ec2 0xdc000 + 114370
22 My iPhone App 0x000ddc50 0xdc000 + 7248Jak vidíte, tento výpis obsahuje mnoho hexadecimálních adres. Abychom z něj získali smysluplné informace a přesně určili řádek kódu ve vaší aplikaci, který způsobil pád, je nutné provést symbolizaci.

Co je to symbolizace a proč je důležitá?
Symbolizace je proces převodu nečitelných hexadecimálních adres paměti v protokolu pádu na lidsky čitelné názvy funkcí a řádky kódu ve vašem zdrojovém kódu. Bez symbolizace by zpětné trasování bylo téměř k ničemu, protože byste viděli pouze řadu adres, které vám nic neřeknou o tom, kde přesně ve vaší aplikaci k chybě došlo.
Automatická symbolizace v Xcode
Pokud získáváte protokoly pádů přímo z fyzického zařízení připojeného k Macu prostřednictvím Xcode (jak bylo popsáno výše v sekci „Protokoly z fyzického zařízení“), Xcode provede symbolizaci automaticky. To je nejjednodušší způsob, jak získat symbolizované protokoly. Xcode používá k tomuto procesu debug symboly (soubory .dSYM), které jsou generovány během kompilace vaší aplikace.
Když otevřete protokoly v Window > Devices and Simulators, uvidíte již plně symbolizované informace, které vám ukáží přesné názvy metod a souborů, kde k pádu došlo.
Manuální symbolizace
Existují situace, kdy obdržíte protokol pádu z jiných zdrojů – například od Apple z App Store Connect, nebo od uživatele, který vám poslal soubor .ips. V takových případech nemusí být protokol automaticky symbolizován, a je potřeba provést manuální symbolizaci.
Pro úspěšnou manuální symbolizaci potřebujete:
- Originální binární soubor aplikace (
.app). - Odpovídající symboly ladění (
.dSYMsoubor) pro konkrétní verzi a sestavení aplikace, která se zhroutila. Tyto soubory jsou klíčové, protože obsahují mapování mezi adresami paměti a vaším kódem.
Proces manuální symbolizace je dobře zdokumentován na webových stránkách pro vývojáře společnosti Apple a obvykle zahrnuje použití nástrojů jako symbolicatecrash (součástí Xcode) nebo import protokolu do Xcode. Bez správných .dSYM souborů (které musí přesně odpovídat verzi aplikace a systému, na kterém k pádu došlo) není symbolizace možná.
Symbolizace je naprosto nezbytná pro efektivní ladění a je to nejdůležitější krok k tomu, abyste mohli z protokolu pádu vyčíst smysluplné informace a identifikovat kořenovou příčinu problému.
Typy výjimek v informacích o výjimce
Sekce „Informace o výjimce“ v protokolu pádu obsahuje Exception Type, který je klíčovým indikátorem povahy problému. Každý typ výjimky má specifický význam a poukazuje na odlišnou základní příčinu pádu.
EXC_CRASH (SIGKILL)
Tento typ výjimky znamená, že proces byl ukončen systémem. Nejčastějším důvodem je ukončení Watchdogem. iOS očekává, že se aplikace spustí a bude reagovat v určitém časovém rámci. Pokud aplikace trvá příliš dlouho na spuštění, nereaguje na události nebo používá příliš mnoho systémových zdrojů, systémový Watchdog ji ukončí, aby zabránil zamrznutí celého zařízení. Často se s tímto typem setkáte s Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d. Kód 0x8badf00d je notoricky známý a značí, že aplikace „bad food“ (špatné jídlo), tedy že aplikace nespustila, neukončila nebo nereagovala dostatečně rychle, což vedlo k jejímu ukončení systémem.
EXC_CRASH (SIGQUIT)
Tato výjimka naznačuje, že proces byl ukončen hlavním procesem. To se může stát v situacích, kdy jedna část aplikace (nebo systémová komponenta, jako je klávesnice) trvá příliš dlouho na načtení nebo reagování, a hlavní aplikace (nebo systém) požádá o její ukončení. Je to méně běžné než SIGKILL, ale stále indikuje problém s výkonem nebo deadlockem mezi procesy.
EXC_CRASH (SIGABRT)
Tento typ výjimky znamená, že proces byl ukončen kvůli výjimce v kódu Objective-C/C++. Často k ní dochází, když se v kódu objeví neošetřená chyba, která vede k volání funkce abort(). Může se také objevit, pokud inicializace Objective-C/C++ kódu trvá příliš dlouho. Typickým příkladem je, když se pokusíte přistupovat k objektu, který byl již uvolněn z paměti, nebo když nastane chyba v běhovém prostředí Objective-C, která vede k předčasnému ukončení aplikace.
EXC_BREAKPOINT (SIGTRAP)
Tato výjimka signalizuje, že proces byl ukončen kvůli výjimce v kódu Swift. Většinou se jedná o chyby, které by v Objective-C vedly k EXC_BAD_ACCESS nebo EXC_CRASH (SIGABRT), ale ve Swiftu jsou zachyceny jako breakpoint. Nejčastějšími příčinami jsou:
- Přístup k nepovinnému (optional) typu, který má hodnotu
nil, aniž by byl bezpečně rozbalen (např. vynucené rozbalení!pro nil hodnotu). - Vynucená konverze typu (např.
as!), která selhala. - Nekorektní použití předpokládaně rozbalených optionalů (Implicitly Unwrapped Optionals).
Tento typ výjimky je často spojen s vývojářskými chybami, které by měly být řešeny pomocí bezpečnějších programovacích vzorů Swiftu.

EXC_BAD_ACCESS (SIGSEGV)
K této výjimce dochází, když se aplikace pokusí přistupovat k neplatné paměťové adrese. Je to klasická chyba správy paměti. Většinou se objevuje v kódu Objective-C, který se spoléhá na ruční správu paměti (reference counting). S příchodem ARC (Automatic Reference Counting) v Objective-C a Swiftu je tato chyba méně častá, ale stále se může objevit, například při přístupu k uvolněným objektům (zombie objects) nebo při poškození paměti (memory corruption) způsobeném například chybou v C/C++ knihovnách.
EXC_BAD_INSTRUCTION (SIGILL)
Tato výjimka nastane, když se proces v aplikaci pokusí spustit nelegální instrukci, která není povolena v iOS nebo je poškozena. To může být způsobeno:
- Poškozením kódu nebo dat v paměti.
- Pokusem o spuštění dat jako kódu.
- Chybou v kompilátoru nebo optimalizaci kódu, která generovala neplatné instrukce.
- Použitím funkcí nebo instrukcí, které nejsou podporovány na daném procesoru nebo verzi iOS.
Tento typ pádu je obvykle závažnější a může naznačovat hlubší problém v kompilaci nebo runtime prostředí.
Pochopení těchto různých typů výjimek vám umožní rychleji zúžit oblast hledání chyby a zaměřit se na relevantní části kódu nebo systémové chování.
Tabulka shrnující typy výjimek
Pro rychlý přehled a snazší orientaci v typech výjimek, zde je shrnující tabulka:
| Typ výjimky | Popis | Typická příčina |
|---|---|---|
| EXC_CRASH (SIGKILL) | Proces ukončen systémem. | Watchdog timeout (aplikace nereaguje/spouští se příliš dlouho). |
| EXC_CRASH (SIGQUIT) | Proces ukončen rodičovským procesem. | Deadlock nebo dlouhé čekání na podproces/komponentu. |
| EXC_CRASH (SIGABRT) | Proces ukončen kvůli neošetřené výjimce (Objective-C/C++). | Volání abort(), chyby v Objective-C runtime, inicializace trvající příliš dlouho. |
| EXC_BREAKPOINT (SIGTRAP) | Proces ukončen kvůli výjimce v Swift kódu. | Vynucené rozbalení nil Optionalu, selhání vynucené konverze typu. |
| EXC_BAD_ACCESS (SIGSEGV) | Aplikace se pokusila přistoupit k neplatné paměti. | Chyby správy paměti (uvolněné objekty, poškození paměti). |
| EXC_BAD_INSTRUCTION (SIGILL) | Aplikace se pokusila spustit nelegální instrukci. | Poškození kódu, neplatné instrukce, chyby kompilátoru. |
Často kladené otázky (FAQ)
Zde jsou odpovědi na některé běžné otázky týkající se pádů aplikací a protokolů pádů na iOS:
1. Jaký je nejčastější důvod pádů aplikací na iOS?
Jedním z nejčastějších důvodů jsou problémy s Watchdogem, které vedou k výjimce EXC_CRASH (SIGKILL). To se stává, když aplikace nereaguje nebo se nespustí včas. Další běžnou příčinou jsou chyby programování, jako je přístup k nil optionalům ve Swiftu (EXC_BREAKPOINT) nebo problémy s pamětí.
2. Mohu získat protokoly pádů z iPhonu bez připojení k Macu?
Ano, můžete. Přejděte do Nastavení > Soukromí a zabezpečení > Analýza a vylepšení > Data analýzy. Zde najdete seznam protokolů pádů, ale nebudou symbolizované, což znamená, že je pro vývojáře obtížnější je číst a pochopit bez dalšího zpracování.
3. Proč je symbolizace protokolů pádů tak důležitá?
Symbolizace převádí nečitelné hexadecimální adresy paměti v protokolu pádů na lidsky srozumitelné názvy funkcí a řádky kódu ve vašem zdrojovém kódu. Bez symbolizace byste nevěděli, která konkrétní část vašeho kódu způsobila pád, což by znemožnilo efektivní ladění a opravu.
4. Co znamenají čísla v zpětném trasování (stack trace)?
Čísla v zpětném trasování (např. 0, 1, 2 atd.) představují rámce zásobníku volání (stack frames). Rámec 0 je funkce, která přímo způsobila pád, a každý následující rámec ukazuje funkci, která tu předchozí zavolala. Tímto způsobem můžete sledovat cestu volání funkcí až k původní příčině problému.
5. Co mám dělat, když moje aplikace padá pouze na zařízeních uživatelů, ale ne během testování?
To je běžný scénář. V takovém případě se spolehněte na protokoly pádů shromážděné společností Apple prostřednictvím App Store Connect. Tyto protokoly jsou symbolizované a poskytují cenné informace o tom, co se děje v reálném prostředí. Zvažte také implementaci nástrojů pro sledování pádů třetích stran, které mohou poskytnout podrobnější data a kontext.
Závěr
Pády aplikací jsou nevyhnutelnou součástí vývoje softwaru, ale s nástroji a znalostmi, které máte nyní k dispozici, můžete efektivně identifikovat, analyzovat a opravovat problémy, které ovlivňují stabilitu vašich iOS aplikací. Pochopení struktury protokolu pádu – záhlaví, informací o výjimce a zpětného trasování – je prvním krokem k úspěšné diagnostice. Klíčová je také symbolizace, která převádí technické detaily na srozumitelný kontext vašeho kódu. Navíc, rozpoznání různých typů výjimek vám umožní rychleji zúžit oblast hledání chyby a zaměřit se na konkrétní aspekty vašeho kódu nebo systémového chování.
Tento průvodce vám poskytl ucelený přehled o tom, jak číst iOS protokoly pádů, jak k nim přistupovat z různých zdrojů a jak interpretovat jejich obsah. Vyzbrojeni těmito informacemi byste nyní měli být schopni efektivněji identifikovat a opravovat problémy ve vašich vlastních iOS aplikacích, což povede k robustnějším, spolehlivějším a uživatelsky přívětivějším produktům. Stabilní aplikace jsou základem dobrého uživatelského zážitku a vaší reputace jako vývojáře.
Chceš-li si přečíst další články podobné jako Analýza pádů aplikací na iOS: Váš průvodce, navštiv kategorii iPhone.
