Debug (modo de depuración) — es una configuración de compilación para aplicaciones móviles en la que el compilador incluye información simbólica, desactiva la optimización del código y conecta el depurador para un análisis paso a paso de la ejecución. Según Android Developers, una compilación Debug contiene símbolos de depuración, no comprime recursos y permite conectar un inspector de bases de datos y solicitudes de red. El modo Debug se contrapone a la compilación Release: en Debug el desarrollador sacrifica rendimiento por transparencia en la ejecución del código.
Puntos clave
Debug no es solo una bandera del compilador, sino un conjunto completo de ajustes que hacen que la aplicación sea transparente para el desarrollador. En modo Debug, el compilador añade una tabla de nombres simbólicos (DWARF) al archivo ejecutable, que vincula el código máquina con las líneas de código fuente. Sin esta tabla, el depurador no puede mostrar qué línea de código se está ejecutando en ese momento.
Depurador (debugger) es un programa que ejecuta tu aplicación en un entorno controlado. Puedes pausar la ejecución en cualquier línea (breakpoint), ver los valores de todas las variables en el ámbito actual, modificarlos sobre la marcha y continuar la ejecución. Para plataformas móviles, el depurador estándar es LLDB — un componente de LLVM utilizado tanto en Xcode como en Android Studio.
El modo Debug también incluye verificaciones adicionales que están desactivadas en Release: aserciones, comprobaciones de límites de arrays, detectores de fugas de memoria y registro ampliado. Estas comprobaciones ralentizan la aplicación pero detectan errores en las primeras etapas del desarrollo — antes de que el código llegue al usuario.
La diferencia entre las compilaciones Debug y Release es fundamental: son dos conjuntos diferentes de banderas del compilador, configuraciones de firma y ajustes de empaquetado. Comprender estas diferencias ayuda a evitar situaciones en las que “funciona en el simulador pero no en un dispositivo real”.
| Parámetro | Debug | Release |
|---|---|---|
| Optimización | Desactivada (-O0) | Activada (-Os o -O2) |
| Símbolos | Tabla DWARF completa | Eliminados (stripped) |
| Firma | Certificado de desarrollo | Certificado de distribución |
| Perfiles | Perfil de aprovisionamiento Debug | Perfil App Store / Ad Hoc |
| Registro | Completo (todos los niveles) | Desactivado o mínimo |
| Ofuscación | Desactivada | Activada (ProGuard/R8) |
| Tamaño .apk/.ipa | Mayor (símbolos + sin compresión) | Menor (R8 + recursos) |
Compilación Debug se utiliza en todas las etapas de desarrollo y pruebas en dispositivos locales. La compilación Release se genera antes de enviar a App Store Connect o Google Play Console. Depurar en una compilación Release es técnicamente posible pero extremadamente incómodo debido a los métodos renombrados (R8) y la falta de symbolication para los registros de fallos.
Un problema común es el código que funciona en Debug pero falla en Release. La causa es UB (comportamiento indefinido) en el código que el compilador maneja de forma diferente con distintos niveles de optimización. Un ejemplo típico: leer una variable no inicializada o violar strict aliasing. Para detectar estos errores, usa un analizador estático (Clang Static Analyzer, ktlint) antes de cada compilación Release.
LLDB es un depurador de alto rendimiento basado en LLVM, compatible con C, C++, Objective-C, Swift y Kotlin/Native. LLDB proporciona una interfaz REPL en la que puedes ejecutar expresiones arbitrarias, cambiar valores de variables y llamar funciones en el contexto de una aplicación pausada.
Breakpoint es una herramienta clave del depurador. Colocas un punto en una línea de código y la aplicación se pausa cuando la ejecución llega a esa línea. LLDB admite varios tipos de puntos de interrupción: condicionales (se activan solo cuando se cumple una condición), simbólicos (en llamadas a funciones) y de un solo uso (se activan una vez y se eliminan automáticamente).
Watchpoint es un punto de observación de cambios en una variable. Especificas una dirección de memoria y el depurador pausa la ejecución ante cualquier escritura en esa dirección. Esta herramienta es indispensable para encontrar condiciones de carrera y mutaciones incorrectas de objetos compartidos. Para ver la jerarquía de UIKit, usa el UIView Inspector disponible en Xcode.
// Establecer breakpoint condicional
(lldb) breakpoint set --name "viewDidLoad" --condition "self.isViewLoaded == false"
// Watchpoint en propiedad
(lldb) watchpoint set variable self->_loadingState
// Ejecutar código en el contexto detenido
(lldb) expr self.view.backgroundColor = UIColor.redColor
Ambos IDEs proporcionan inspectores gráficos sobre LLDB. Android Studio incluye Layout Inspector (jerarquía de vistas), Network Inspector (trazado de solicitudes HTTP) y Database Inspector (SQLite en tiempo real). Xcode proporciona Debug Memory Graph (análisis de fugas de memoria) y View Debugger (vista 3D de capas UIKit).
A partir de Android 11, la depuración por Wi-Fi funciona sin conexión USB: basta con escanear el código QR desde Android Studio. iOS admite depuración por Wi-Fi desde Xcode 9+ — el dispositivo se conecta una vez por USB, después las sesiones de depuración pueden realizarse por red. La depuración por Wi-Fi no es adecuada para servidores CI debido a la latencia impredecible y la pérdida de paquetes, por lo que los pipelines automatizados siempre usan USB. Sin embargo, para el desarrollo local, la depuración por Wi-Fi es notablemente más conveniente — el desarrollador no está atado a un cable y puede probar la aplicación en un dispositivo al otro extremo de la habitación.
Android Debug Bridge (ADB) es una herramienta universal para interactuar con un dispositivo Android desde la línea de comandos. A través de ADB puedes instalar una aplicación, iniciar la depuración, copiar archivos, ejecutar comandos shell y ver registros. Android Studio usa ADB internamente para todas las operaciones de depuración.
Android Studio admite dos modos de depuración: Run (inicio normal) y Debug (inicio con el depurador conectado). En modo Debug puedes establecer breakpoints directamente en el editor, inspeccionar variables en la ventana Debug Tool y evaluar expresiones en Evaluate Expression. Para depurar procesos en segundo plano (Service, BroadcastReceiver), usa Attach Debugger to Android Process.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Breakpoint aquí pausará la ejecución
val button = findViewById<Button>(R.id.btn_debug)
button.setOnClickListener {
startDebugProcess()
}
}
private fun startDebugProcess() {
val data = fetchDataFromApi()
Log.d("Debug", "Data loaded: $data")
}
}
Los comandos shell de ADB proporcionan acceso al sistema de archivos del dispositivo sin necesidad de derechos root. Puedes ver el contenido del directorio databases, copiar el archivo .db a tu ordenador y abrirlo con cualquier cliente SQLite. Android Studio Database Inspector automatiza este proceso: ves los datos de la base de datos en vivo en tiempo real y puedes ejecutar consultas SQL directamente desde el IDE.
Xcode proporciona un entorno de depuración integrado basado en LLDB. El desarrollador puede ejecutar la aplicación en un simulador o dispositivo físico, establecer breakpoints y usar el Debug Navigator para controlar los hilos de ejecución. A diferencia de Android, iOS no permite ejecutar dos compilaciones Debug simultáneamente en el mismo dispositivo sin una configuración especial.
El simulador ejecuta la aplicación como un proceso nativo de macOS, lo que proporciona el ciclo de depuración más rápido. En un dispositivo físico, la depuración se realiza mediante USB o Wi-Fi (a partir de iOS 16), y LLDB se comunica con debugserver en el dispositivo. El rendimiento de la depuración en el dispositivo es menor debido al ancho de banda limitado de USB 2.0, pero solo un dispositivo físico permite probar escenarios reales: notificaciones push, cámara, sensores.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
private func setupUI() {
let label = UILabel()
label.text = "Modo Debug"
label.textColor = .systemBlue
view.addSubview(label)
}
}
Xcode Organizer recopila registros de fallos de los dispositivos de los testers mediante Crash Logs. Para la symbolication (convertir direcciones en nombres de funciones) se requiere el archivo .dSYM, que se genera con cada compilación Debug. En una compilación Release, dSYM también se crea, pero los registros de fallos de App Store deben cargarse en Organizer manualmente o mediante el servicio bitcode.
Preguntas frecuentes
Técnicamente sí — mediante distribución Ad Hoc con un certificado Debug, pero Apple y Google no lo recomiendan. Una compilación Debug contiene símbolos de depuración y rendimiento reducido, lo que degrada la UX y aumenta el tamaño de la aplicación en 2–3 veces.
La razón es la optimización del compilador desactivada (-O0). El compilador no integra funciones, no elimina código muerto y conserva todas las variables intermedias. Además, Debug incluye comprobaciones de aserciones y límites de arrays que están ausentes en Release.
En Xcode elige Window → Devices and Simulators, marca “Connect via network” para tu dispositivo. El dispositivo y el Mac deben estar en la misma red Wi-Fi. Después de conectar por USB una vez, la depuración funcionará por Wi-Fi en ejecuciones posteriores.
Attach to process permite conectar el depurador a un proceso ya en ejecución sin reiniciar la aplicación. Esto es útil para depurar Services, BroadcastReceivers o procesos que se inician por un evento del sistema, donde el Debug Run estándar no es aplicable.
NSLog y print por defecto muestran registros solo en configuración Debug. Para Release, usa os_log con la bandera OSLogType.default — guarda mensajes en el Unified Logging System y es accesible a través de Console.app en Mac.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también