移动开发中的 Debug — 调试模式的实质及其工作原理

作者: IT Sectr 发布日期: 2026-05-06 阅读时间: 8 分钟

Debug(调试模式)— 是移动应用程序的一种构建配置,其中编译器包含符号信息,关闭代码优化并连接调试器以进行逐步分析。据Android Developers innehåller en Debug-build felsökningssymboler, komprimerar inte resurser och gör det möjligt att ansluta en inspektör för databas och nätverksförfrågningar. Läget Debug står i motsats till Release-builden: i Debug offrar utvecklaren prestanda för transparens i kodexekveringen.

Huvudpunkter

  • Debug — byggkonfiguration med felsökningsinformation, avstängd optimering och åtkomst till felsökaren
  • Felsökaren gör det möjligt att sätta brytpunkter, visa variabler och exekvera kod steg för steg
  • Debug-build signeras med ett felsökningscertifikat och kan inte publiceras i appbutiker
  • LLDB — den primära felsökaren för iOS/macOS, och LLDB i Android Studio — för Android
  • Prestanda för Debug-build är lägre än Release på grund av avsaknad av kompilatoroptimeringar

Innebörden av Debug-läget i mobil utveckling

Debug (felsökning) — är inte bara en kompilatorflagga, utan en hel uppsättning inställningar som gör appen transparent för utvecklaren. I Debug-läget lägger kompilatorn till en tabell med symboliska namn (DWARF) i den körbara filen som kopplar maskinkod till ursprungliga källkodsrader. Utan denna tabell kan felsökaren inte visa vilken kodrad som för närvarande exekveras.

Felsökaren — ett program som kör din app i en kontrollerad miljö. Du kan pausa exekveringen på valfri rad (brytpunkt), visa värdena för alla variabler i det aktuella scopet, ändra dem i farten och fortsätta exekveringen. För mobila plattformar är standardfelsökaren LLDB — en LLVM-komponent som används både i Xcode och Android Studio.

Debug-läget aktiverar också ytterligare kontroller som är avstängda i Release: påståenden (assertions), kontroll av arraygränser, detektorer för minnesläckor och utökad loggning. Dessa kontroller saktar ner appen men upptäcker fel i tidiga utvecklingsstadier — innan koden når användaren.

Debug och Release: viktiga skillnader mellan byggen

Skillnaden mellan Debug- och Release-byggen är grundläggande: det är två olika uppsättningar kompilatorflaggor, signeringskonfigurationer och paketeringsinställningar. Att förstå dessa skillnader hjälper till att undvika situationer där "det fungerar i simulatorn, men på en riktig enhet — inte".

ParameterDebugRelease
OptimeringAvstängd (-O0)Påslagen (-Os eller -O2)
SymbolerFull DWARF-tabellStrip-symboler (borttagna)
SigneringDevelopment-certifikatDistribution-certifikat
ProfilerDebug provisioning profileApp Store / Ad Hoc profile
LoggningFullständig (alla nivåer)Avstängd eller minimal
ObfuskeringAvstängdPåslagen (ProGuard/R8)
Storlek .apk/.ipaStörre (symboler + utan komprimering)Mindre (R8 + resurser)

När ska vad användas

Debug-build används i alla skeden av utveckling och testning på lokala enheter. Release-build byggs innan den skickas till App Store Connect eller Google Play Console. Att utföra felsökning på en Release-build är tekniskt möjligt, men extremt obekvämt på grund av omdöpta metoder (R8) och avsaknad av symbolisering för kraschloggar.

Problem med att växla lägen

Ett av de vanliga problemen är kod som fungerar i Debug men kraschar i Release. Orsaken är UB (odefinierat beteende) i koden som kompilatorn hanterar olika vid olika optimeringsnivåer. Typiskt exempel: läsning av en oinitierad variabel eller brott mot strict aliasing. För att upptäcka sådana fel, använd en statisk analysator (Clang Static Analyzer, ktlint) före varje Release-build.

Felsökningsverktyg: LLDB, brytpunkter och inspektörer

LLDB — är en högpresterande felsökare baserad på LLVM som stöder C, C++, Objective-C, Swift och Kotlin/Native. LLDB tillhandahåller ett REPL-gränssnitt där du kan exekvera godtyckliga uttryck, ändra variabelvärden och anropa funktioner i kontexten av den pausade appen.

Brytpunkter och deras typer

Brytpunkt — felsökarens viktigaste verktyg. Du placerar en punkt på en kodrad, och appen stannar när exekveringen når den raden. LLDB stöder flera typer av punkter: villkorliga (aktiveras endast när ett villkor uppfylls), symboliska (vid funktionsanrop) och engångs-punkter (aktiveras en gång och tas automatiskt bort).

Watchpoints och minnesinspektörer

Watchpoint — en observationspunkt för ändring av en variabel. Du anger en minnesadress, och felsökaren pausar exekveringen vid varje skrivning till den adressen. Detta verktyg är oumbärligt vid sökning efter datarace och felaktiga mutationer av delade objekt. För att visa UIKit-hierarkin, använd UIView Inspector som finns i Xcode.

lldb
// 设置条件断点
(lldb) breakpoint set --name "viewDidLoad" --condition "self.isViewLoaded == false"

// 属性观察点
(lldb) watchpoint set variable self->_loadingState

// 在停止上下文中执行代码
(lldb) expr self.view.backgroundColor = UIColor.redColor

Xcode och Android Studio inspektörer

Båda IDE:erna tillhandahåller grafiska inspektörer ovanpå LLDB. Android Studio inkluderar Layout Inspector (visning av View-hierarki), Network Inspector (spårning av HTTP-förfrågningar) och Database Inspector (realtids-SQLite). Xcode tillhandahåller Debug Memory Graph (analys av minnesläckor) och View Debugger (3D-visning av UIKit-lager).

Fjärrfelsökning och felsökning via Wi-Fi

Från och med Android 11 fungerar felsökning via Wi-Fi utan USB-anslutning: skanna bara QR-koden från Android Studio. iOS stöder Wi-Fi-felsökning från Xcode 9+ — enheten ansluts en gång via USB, varefter felsökningssessioner kan ske över nätverket. För CI-servrar är Wi-Fi-felsökning inte lämplig på grund av oförutsägbara fördröjningar och paketförlust, därför används alltid USB i automatiserade pipelines. För lokal utveckling är Wi-Fi-felsökning dock betydligt bekvämare — utvecklaren är inte bunden till en kabel och kan testa appen på en enhet i andra änden av rummet.

Debug på Android: Android Studio och felsökning via ADB

Android Debug Bridge (ADB) — ett universellt verktyg för interaktion med en Android-enhet från kommandoraden. Via ADB kan du installera appen, starta felsökning, kopiera filer, exekvera shell-kommandon och visa loggar. Android Studio använder ADB i bakgrunden för alla felsökningsoperationer.

Ansluta felsökaren i Android Studio

Android Studio stöder två felsökningslägen: Run (normal start) och Debug (start med ansluten felsökare). I Debug-läget kan du sätta brytpunkter direkt i redigeraren, visa variabler i Debug Tool Window och utvärdera uttryck i Evaluate Expression. För felsökning av bakgrundsprocesser (Service, BroadcastReceiver), använd Attach Debugger to Android Process.

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 此处的断点将暂停执行
        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 och databasinspektion

ADB shell-kommandon ger åtkomst till enhetens filsystem utan root-rättigheter. Du kan visa innehållet i databases-katalogen, kopiera .db-filen till datorn och öppna den med valfri SQLite-klient. Android Studio Database Inspector automatiserar denna process: du ser databasens live-data i realtid och kan exekvera SQL-frågor direkt från IDE.

Debug på iOS: Xcode, felsökare och diagnostik

Xcode tillhandahåller en integrerad felsökningsmiljö baserad på LLDB. Utvecklaren kan köra appen på simulatorn eller en fysisk enhet, sätta brytpunkter och använda Debug Navigator för att kontrollera exekveringstrådar. Till skillnad från Android tillåter iOS inte att två Debug-byggen körs samtidigt på en enhet utan särskild konfiguration.

Felsökning i simulatorn och på enheten

Simulatorn kör appen som en inbyggd macOS-process, vilket ger den snabbaste felsökningscykeln. På en fysisk enhet sker felsökning via USB eller Wi-Fi (från iOS 16), och LLDB kommunicerar med debugserver på enheten. Felsökningsprestandan på enheten är lägre på grund av den begränsade bandbredden hos USB 2.0, men endast en fysisk enhet möjliggör testning av verkliga scenarier: push-notiser, kamera, sensorer.

swift
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)
    }
}

Diagnostik och kraschrapporter

Xcode Organizer samlar in kraschloggar från testares enheter via Crash Logs. För symbolisering (omvandling av adresser till funktionsnamn) krävs en .dSYM-fil som genereras vid varje Debug-build. I Release-build skapas också dSYM, men kraschloggar från App Store måste laddas in i Organizer manuellt eller via bitcode-tjänsten.

Vanliga frågor

Kan en Debug-build köras på användarens enhet?

Tekniskt ja — via Ad Hoc med ett Debug-certifikat, men Apple och Google rekommenderar inte detta. En Debug-build innehåller felsökningssymboler och lägre prestanda, vilket försämrar UX och ökar appens storlek 2–3 gånger.

Varför är en Debug-build långsammare än Release?

Orsak — avstängd kompilatoroptimering (-O0). Kompilatorn inline:ar inte funktioner, tar inte bort död kod och behåller alla mellanliggande variabler. Dessutom aktiverar Debug kontroller av påståenden och arraygränser som saknas i Release.

Hur konfigurerar jag Wi-Fi-felsökning för iOS?

I Xcode välj Window → Devices and Simulators, markera "Connect via network" för din enhet. Enheten och Mac måste vara på samma Wi-Fi-nätverk. Efter en anslutning via USB kommer felsökning att fungera via Wi-Fi vid efterföljande start.

Vad är "attach to process" i Android Studio?

Attach to process gör det möjligt att ansluta felsökaren till en redan körande process utan att starta om appen. Detta är användbart för felsökning av Service, BroadcastReceiver eller processer som startas av en systemhändelse, där standard Debug Run inte är tillämpligt.

Hur ser jag NSLog och print i en Release-build?

NSLog och print visar som standard bara logg i Debug-konfigurationen. För Release, använd os_log med flaggan OSLogType.default — den sparar meddelanden i Unified Logging System och är tillgänglig via Console.app på Mac.

Sammanfattning

  • Debug-build innehåller felsökningssymboler, stänger av optimering och använder ett development-signeringscertifikat
  • LLDB — den primära felsökaren för båda plattformarna, stöder brytpunkter, watchpoints och REPL
  • Skillnaderna mellan Debug och Release rör optimering, symboler, signering, obfuskering och byggstorlek
  • ADB för Android och debugserver för iOS säkerställer IDE-kommunikation med enheten
  • Prestanda för Debug-build är 2–5 gånger lägre på grund av avstängda optimeringar
  • Kraschloggar för Debug-build innehåller läsbara funktionsnamn, Release kräver symbolisering via dSYM

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读