Debug (debugmodus) — is een buildconfiguratie van een mobiele app waarbij de compiler symbolische informatie toevoegt, codeoptimalisatie uitschakelt en de debugger koppelt voor stapsgewijze analyse. Volgens Android Developers bevat een Debug-build debugsymbolen, comprimeert het geen bronnen en maakt het mogelijk om een database- en netwerkverzoekinspector te koppelen. De Debug-modus staat tegenover de Release-build: in Debug offert de ontwikkelaar prestaties op voor transparantie van code-uitvoering.
Belangrijkste
Debug (debuggen) — is niet alleen een compiler-vlag, maar een hele reeks instellingen die de app transparant maken voor de ontwikkelaar. In de Debug-modus voegt de compiler een tabel met symbolische namen (DWARF) toe aan het uitvoerbare bestand, die machinecode koppelt aan de oorspronkelijke bronregels. Zonder deze tabel kan de debugger niet tonen welke coderegel momenteel wordt uitgevoerd.
Debugger — een programma dat uw app in een gecontroleerde omgeving uitvoert. U kunt de uitvoering op elke regel onderbreken (breakpoint), de waarden van alle variabelen in het huidige bereik bekijken, ze tijdens het uitvoeren wijzigen en de uitvoering hervatten. Voor mobiele platforms is de standaarddebugger LLDB — een LLVM-component die zowel in Xcode als in Android Studio wordt gebruikt.
De Debug-modus activeert ook extra controles die in Release zijn uitgeschakeld: asserts (assertions), controles op arraygrenzen, geheugenlekdetectoren en uitgebreide logging. Deze controles vertragen de app, maar detecteren fouten in een vroeg stadium van de ontwikkeling — voordat de code bij de gebruiker terechtkomt.
Het verschil tussen Debug- en Release-builds is fundamenteel: het zijn twee verschillende sets compiler-vlaggen, ondertekeningsconfiguraties en verpakkingsinstellingen. Inzicht in deze verschillen helpt situaties te voorkomen zoals „werkt in de simulator, maar op een echt apparaat — niet”.
| Parameter | Debug | Release |
|---|---|---|
| Optimalisatie | Uitgeschakeld (-O0) | Ingeschakeld (-Os of -O2) |
| Symbolen | Volledige DWARF-tabel | Strip-symbolen (verwijderd) |
| Ondertekening | Development-certificaat | Distribution-certificaat |
| Profielen | Debug provisioning profile | App Store / Ad Hoc profile |
| Logging | Volledig (alle niveaus) | Uitgeschakeld of minimaal |
| Obfuscatie | Uitgeschakeld | Ingeschakeld (ProGuard/R8) |
| Grootte .apk/.ipa | Groter (symbolen + zonder compressie) | Kleiner (R8 + bronnen) |
Debug-build wordt gebruikt in alle fasen van ontwikkeling en testen op lokale apparaten. Release-build wordt gemaakt voordat deze naar App Store Connect of Google Play Console wordt verzonden. Debuggen op een Release-build is technisch mogelijk, maar uiterst onhandig vanwege hernoemde methodes (R8) en het ontbreken van symbolication voor crashlogs.
Een van de vaak voorkomende problemen is code die werkt in Debug maar faalt in Release. De oorzaak is UB (undefined behavior) in code die de compiler anders behandelt bij verschillende optimalisatieniveaus. Typisch voorbeeld: het lezen van een niet-geïnitialiseerde variabele of schending van strict aliasing. Gebruik een statische analyser (Clang Static Analyzer, ktlint) voor elke Release-build om dergelijke fouten op te sporen.
LLDB — is een hoogwaardige debugger op basis van LLVM die C, C++, Objective-C, Swift en Kotlin/Native ondersteunt. LLDB biedt een REPL-interface waarin u willekeurige expressies kunt uitvoeren, variabelewaarden kunt wijzigen en functies kunt aanroepen in de context van de gestopte app.
Breakpoint — het belangrijkste hulpmiddel van de debugger. U plaatst een punt op een coderegel en de app stopt wanneer de uitvoering die regel bereikt. LLDB ondersteunt verschillende soorten punten: voorwaardelijke (alleen geactiveerd bij een bepaalde voorwaarde), symbolische (bij een functieaanroep) en eenmalige (één keer geactiveerd en automatisch verwijderd).
Watchpoint — een observatiepunt voor het wijzigen van een variabele. U geeft een geheugenadres op en de debugger stopt de uitvoering bij elke schrijfactie naar dat adres. Dit hulpmiddel is onmisbaar bij het zoeken naar dataraces en onjuiste mutaties van gedeelde objecten. Gebruik UIView Inspector in Xcode om de UIKit-hiërarchie te bekijken.
// Voorwaardelijk breakpoint instellen
(lldb) breakpoint set --name "viewDidLoad" --condition "self.isViewLoaded == false"
// Watchpoint op eigenschap
(lldb) watchpoint set variable self->_loadingState
// Code uitvoeren in stopcontext
(lldb) expr self.view.backgroundColor = UIColor.redColor
Beide IDE's bieden grafische inspectors bovenop LLDB. Android Studio bevat Layout Inspector (weergave van de View-hiërarchie), Network Inspector (traceren van HTTP-verzoeken) en Database Inspector (realtime SQLite). Xcode biedt Debug Memory Graph (analyse van geheugenlekken) en View Debugger (3D-weergave van UIKit-lagen).
Vanaf Android 11 werkt debuggen via Wi-Fi zonder USB-verbinding: scan gewoon de QR-code vanuit Android Studio. iOS ondersteunt Wi-Fi-debuggen vanaf Xcode 9+ — het apparaat maakt één keer verbinding via USB, waarna debugsessies via het netwerk kunnen verlopen. Voor CI-servers is Wi-Fi-debuggen niet geschikt vanwege onvoorspelbare vertragingen en pakketverlies, daarom wordt in geautomatiseerde pipelines altijd USB gebruikt. Voor lokale ontwikkeling is Wi-Fi-debuggen echter aanzienlijk handiger — de ontwikkelaar is niet aan een kabel gebonden en kan de app testen op een apparaat aan de andere kant van de kamer.
Android Debug Bridge (ADB) — een universeel hulpmiddel voor interactie met een Android-apparaat vanaf de opdrachtregel. Via ADB kunt u de app installeren, debuggen starten, bestanden kopiëren, shell-opdrachten uitvoeren en logs bekijken. Android Studio gebruikt ADB onder de motorkap voor alle debugbewerkingen.
Android Studio ondersteunt twee debugmodi: Run (normaal starten) en Debug (starten met aangesloten debugger). In de Debug-modus kunt u breakpoints direct in de editor instellen, variabelen bekijken in Debug Tool Window en expressies evalueren in Evaluate Expression. Gebruik Attach Debugger to Android Process voor het debuggen van achtergrondprocessen (Service, BroadcastReceiver).
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Breakpoint stopt hier de uitvoering
val button = findViewById<Button>(R.id.btn_debug)
button.setOnClickListener {
startDebugProcess()
}
}
private fun startDebugProcess() {
val data = fetchDataFromApi()
Log.d("Debug", "Data loaded: $data")
}
}
ADB shell-opdrachten geven toegang tot het bestandssysteem van het apparaat zonder root-rechten. U kunt de inhoud van de databases-map bekijken, het .db-bestand naar de computer kopiëren en openen met elke SQLite-client. Android Studio Database Inspector automatiseert dit proces: u ziet live databasegegevens in realtime en kunt SQL-query’s direct vanuit de IDE uitvoeren.
Xcode biedt een geïntegreerde debugomgeving op basis van LLDB. De ontwikkelaar kan de app op de simulator of een fysiek apparaat uitvoeren, breakpoints instellen en Debug Navigator gebruiken om uitvoeringsthreads te beheren. In tegenstelling tot Android staat iOS niet toe dat twee Debug-builds tegelijk op één apparaat worden uitgevoerd zonder speciale configuratie.
De simulator voert de app uit als een native macOS-proces, wat de snelste debugcyclus biedt. Op een fysiek apparaat verloopt debuggen via USB of Wi-Fi (vanaf iOS 16), en LLDB communiceert met debugserver op het apparaat. De prestaties van debuggen op het apparaat zijn lager vanwege de beperkte bandbreedte van USB 2.0, maar alleen een fysiek apparaat maakt het testen van realistische scenario’s mogelijk: pushmeldingen, camera, sensoren.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private func setupUI() {
let label = UILabel()
label.text = "Debug Mode"
label.textColor = .systemBlue
view.addSubview(label)
}
}
Xcode Organizer verzamelt crashlogs van de apparaten van testers via Crash Logs. Voor symbolication (conversie van adressen naar functienamen) is een .dSYM-bestand vereist, dat wordt gegenereerd bij elke Debug-build. In de Release-build wordt ook dSYM aangemaakt, maar crashlogs van de App Store moeten handmatig of via de bitcode-service in Organizer worden geladen.
Veelgestelde vragen
Technisch ja — via Ad Hoc met een Debug-certificaat, maar Apple en Google raden dit af. Een Debug-build bevat debugsymbolen en lagere prestaties, wat de UX verslechtert en de app-grootte 2–3 keer vergroot.
Oorzaak — uitgeschakelde compileroptimalisatie (-O0). De compiler inlineert geen functies, verwijdert geen dode code en bewaart alle tussenvariabelen. Bovendien activeert Debug controles op asserts en arraygrenzen die in Release ontbreken.
In Xcode kiest u Window → Devices and Simulators, vinkt u „Connect via network” aan voor uw apparaat. Het apparaat en de Mac moeten in hetzelfde Wi-Fi-netwerk zitten. Na eenmalige verbinding via USB werkt debuggen via Wi-Fi bij volgende starts.
Attach to process maakt het mogelijk de debugger aan te sluiten op een reeds draaiend proces zonder de app opnieuw te starten. Dit is handig voor het debuggen van Service, BroadcastReceiver of processen die worden gestart door een systeemgebeurtenis, waar de standaard Debug Run niet van toepassing is.
NSLog en print tonen standaard alleen log in de Debug-configuratie. Gebruik voor Release os_log met de vlag OSLogType.default — het slaat berichten op in het Unified Logging System en is toegankelijk via Console.app op de Mac.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook