Comparteix a través de


Depuración para principiantes sin experiencia

Invariablemente, el código que escribimos como desarrolladores no siempre hace lo que esperábamos que hiciera. A veces hace algo completamente diferente! Cuando ocurre lo inesperado, la siguiente tarea consiste en averiguar por qué, y aunque podríamos estar tentados a seguir mirando el código durante horas, es más fácil y eficaz usar una herramienta de depuración o un depurador.

Un depurador, desafortunadamente, no es algo que pueda revelar mágicamente todos los problemas o "errores" en nuestro código. La depuración significa ejecutar tu código paso a paso en una herramienta de depuración como Visual Studio, para encontrar el punto exacto en el que cometiste un error de programación. A continuación, comprende qué correcciones necesita realizar en el código y las herramientas de depuración a menudo le permiten realizar cambios temporales para poder seguir ejecutando el programa.

El uso eficaz de un depurador también es una aptitud que tarda tiempo y práctica en aprender, pero en última instancia es una tarea fundamental para cada desarrollador de software. En este artículo se presentan los principios básicos de la depuración y se proporcionan sugerencias para ayudarle a comenzar.

Aclarar el problema mediante la formulación de las preguntas correctas

Ayuda a aclarar el problema que ha tenido antes de intentar corregirlo. Esperamos que ya haya tenido un problema en el código; de lo contrario, no estaría aquí tratando de averiguar cómo depurarlo. Por lo tanto, antes de empezar a depurar, asegúrese de que ha identificado el problema que está intentando resolver:

  • ¿Qué esperaba que hiciera el código?

  • ¿Qué pasó en su lugar?

    Si se produce un error (excepción) al ejecutar la aplicación, puede ser algo bueno. Una excepción es un evento inesperado encontrado al ejecutar código, normalmente un error de algún tipo. Una herramienta de depuración puede llevarle al lugar exacto en el código donde se produjo la excepción y puede ayudarle a investigar posibles correcciones.

    Si ocurre algo más, ¿cuál es el síntoma del problema? ¿Ya sospecha dónde se produjo este problema en el código? Por ejemplo, si el código muestra algún texto, pero el texto es incorrecto, sabe que los datos son incorrectos o el código que establece el texto para mostrar tiene algún tipo de error. Al recorrer el código de un depurador, puede examinar cada cambio en las variables para detectar exactamente cuándo y cómo se asignan los valores incorrectos.

Examen de las suposiciones

Antes de investigar un fallo o un error, piensa en las suposiciones que te llevaron a esperar un resultado determinado. Las suposiciones ocultas o desconocidas pueden interferir en la identificación de un problema incluso cuando estás examinando la causa del problema en un depurador. Es posible que tenga una larga lista de posibles suposiciones. Estas son algunas preguntas para plantearse desafíos a sus suposiciones.

  • ¿Usa la API correcta (es decir, el objeto, la función, el método o la propiedad correctos)? Es posible que una API que use no haga lo que cree que hace. (Después de examinar la llamada API en el depurador, para corregirla puede ser necesario consultar la documentación para ayudar a identificar la API correcta).

  • ¿Usa correctamente una API? Tal vez usó la API correcta, pero no la usó de la manera correcta.

  • ¿El código contiene errores tipográficos? Algunos errores tipográficos, como un simple error ortográfico de un nombre de variable, pueden ser difíciles de ver, especialmente cuando se trabaja con lenguajes que no requieren que se declaren variables antes de que se usen.

  • ¿Ha realizado un cambio en el código y supone que no está relacionado con el problema que ve?

  • ¿Esperaba que un objeto o una variable contengan un valor determinado (o un determinado tipo de valor) diferente de lo que realmente sucedió?

  • ¿Conoce la intención del código? A menudo es más difícil depurar el código de otra persona. Si no es tu código, es posible que tengas que dedicar tiempo a aprender exactamente lo que hace antes de poder depurarlo de forma eficaz.

    Sugerencia

    Al escribir código, comience pequeño y comience con el código que funciona. (El buen código de ejemplo es útil aquí). A veces, es más fácil corregir un conjunto grande o complicado de código empezando por un pequeño fragmento de código que muestra la tarea principal que está intentando lograr. A continuación, puede modificar o agregar código de forma incremental, probando en cada punto los errores.

Al cuestionar las suposiciones, puede reducir el tiempo necesario para encontrar un problema en el código. También puede reducir el tiempo necesario para corregir un problema.

Recorra el código en modo de depuración para encontrar dónde se produjo el problema.

Cuando se ejecuta normalmente una aplicación, se ven errores y resultados incorrectos solo después de que se haya ejecutado el código. Un programa también puede finalizar inesperadamente sin decirle por qué.

Al ejecutar una aplicación dentro de un depurador, también denominado modo de depuración, el depurador supervisa activamente todo lo que sucede durante la ejecución del programa. También permite pausar la aplicación en cualquier momento para examinar su estado y, a continuación, recorrer la línea de código por línea para ver cada detalle a medida que sucede.

En Visual Studio, entra en el modo de depuración usando F5 (o el comando del menú Depurar>Iniciar depuración, o el botón Iniciar depuraciónIcono que muestra el botón Iniciar depuración. en la barra de herramientas de depuración). Si se produce alguna excepción, el asistente de excepciones de Visual Studio le lleva al punto exacto en el que se produjo la excepción y proporciona otra información útil. Para más información sobre cómo controlar las excepciones en el código, vea Técnicas y herramientas de depuración.

Si no ha encontrado una excepción, probablemente tenga una buena idea de dónde buscar el problema en el código. Este paso es donde usará puntos de interrupción con el depurador para examinar más detenidamente el código. Los puntos de interrupción son la característica más básica y esencial para una depuración confiable. Un punto de interrupción indica dónde debe pausar Visual Studio el código en ejecución para que pueda echar un vistazo a los valores de las variables o el comportamiento de la memoria, la secuencia en la que se ejecuta el código.

En Visual Studio, puede establecer rápidamente un punto de interrupción haciendo clic en el margen izquierdo junto a una línea de código. O bien, coloque el cursor en una línea y presione F9.

Para ayudar a ilustrar estos conceptos, le llevamos a través de algún código de ejemplo que ya tiene varios errores. Estamos usando C#, pero las características de depuración se aplican a Visual Basic, C++, JavaScript, Python y otros lenguajes admitidos. También se proporciona código de ejemplo para Visual Basic, pero las capturas de pantalla se encuentran en C#.

Creación de una aplicación de ejemplo (con algunos errores)

A continuación, creará una aplicación que tiene algunos errores.

  1. Debe tener instalados Visual Studio y la carga de trabajo Desarrollo de escritorio de .NET.

    Si todavía no ha instalado Visual Studio, vaya a la página de descargas de Visual Studio para instalarlo de forma gratuita.

    Si necesita instalar la carga de trabajo pero ya tiene Visual Studio, seleccione Tools>Obtener herramientas y características. Se inicia el instalador de Visual Studio. Elija la carga de trabajo Desarrollo de escritorio de .NET y, luego, seleccione Modificar.

  2. Abra Visual Studio.

    En la ventana de inicio, elija Crear un nuevo proyecto. Escriba Consola en el cuadro de búsqueda, seleccione C# o Visual Basic como idioma y, a continuación, elija Aplicación de Consola para .NET. Elija Siguiente. Escriba ConsoleApp_FirstApp como nombre del proyecto y seleccione Siguiente.

    Si usa un nombre de proyecto diferente, deberá modificar el valor del espacio de nombres para que coincida con el nombre del proyecto al copiar el código de ejemplo.

    Elija la plataforma de destino recomendada o .NET 8 y, después, elija Crear.

    Si no ve la plantilla de proyecto Aplicación de consola para .NET, vaya a Herramientas>Obtener herramientas y características y se abrirá el Instalador Visual Studio. Elija la carga de trabajo Desarrollo de escritorio de .NET y, luego, seleccione Modificar.

    Visual Studio crea el proyecto de consola, que aparece en Explorador de soluciones en el panel derecho.

  3. En Program.cs (o Program.vb), reemplace todo el código predeterminado por el código siguiente. (Seleccione primero la pestaña de idioma correcta, C# o Visual Basic).

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApp_FirstApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Welcome to Galaxy News!");
                IterateThroughList();
                Console.ReadKey();
            }
    
            private static void IterateThroughList()
            {
                var theGalaxies = new List<Galaxy>
            {
                new Galaxy() { Name="Tadpole", MegaLightYears=400, GalaxyType=new GType('S')},
                new Galaxy() { Name="Pinwheel", MegaLightYears=25, GalaxyType=new GType('S')},
                new Galaxy() { Name="Cartwheel", MegaLightYears=500, GalaxyType=new GType('L')},
                new Galaxy() { Name="Small Magellanic Cloud", MegaLightYears=.2, GalaxyType=new GType('I')},
                new Galaxy() { Name="Andromeda", MegaLightYears=3, GalaxyType=new GType('S')},
                new Galaxy() { Name="Maffei 1", MegaLightYears=11, GalaxyType=new GType('E')}
            };
    
                foreach (Galaxy theGalaxy in theGalaxies)
                {
                    Console.WriteLine(theGalaxy.Name + "  " + theGalaxy.MegaLightYears + ",  " + theGalaxy.GalaxyType);
                }
    
                // Expected Output:
                //  Tadpole  400,  Spiral
                //  Pinwheel  25,  Spiral
                //  Cartwheel, 500,  Lenticular
                //  Small Magellanic Cloud .2,  Irregular
                //  Andromeda  3,  Spiral
                //  Maffei 1,  11,  Elliptical
            }
        }
    
        public class Galaxy
        {
            public string Name { get; set; }
    
            public double MegaLightYears { get; set; }
            public object GalaxyType { get; set; }
    
        }
    
        public class GType
        {
            public GType(char type)
            {
                switch(type)
                {
                    case 'S':
                        MyGType = Type.Spiral;
                        break;
                    case 'E':
                        MyGType = Type.Elliptical;
                        break;
                    case 'l':
                        MyGType = Type.Irregular;
                        break;
                    case 'L':
                        MyGType = Type.Lenticular;
                        break;
                    default:
                        break;
                }
            }
            public object MyGType { get; set; }
            private enum Type { Spiral, Elliptical, Irregular, Lenticular}
        }
    }
    

    Nuestra intención para este código es mostrar el nombre de la galaxia, la distancia a la galaxia y el tipo de galaxia todo en una lista. Para depurar, es importante comprender la intención del código. Este es el formato de una línea de la lista que queremos mostrar en la salida:

    nombre de galaxia, distancia, tipo de galaxia.

Ejecución de la aplicación

Presione F5 o botón Iniciar depuración icono que muestra el botón Iniciar depuración. en la barra de herramientas de depuración, ubicada encima del editor de código.

La aplicación se inicia y el depurador no nos muestra ninguna excepción. Sin embargo, la salida que ve en la ventana de la consola no es lo que espera. Este es el resultado esperado:

Tadpole  400,  Spiral
Pinwheel  25,  Spiral
Cartwheel, 500,  Lenticular
Small Magellanic Cloud .2,  Irregular
Andromeda  3,  Spiral
Maffei 1,  Elliptical

Sin embargo, verá esta salida en su lugar:

Tadpole  400,  ConsoleApp_FirstApp.GType
Pinwheel  25,  ConsoleApp_FirstApp.GType
Cartwheel, 500,  ConsoleApp_FirstApp.GType
Small Magellanic Cloud .2,  ConsoleApp_FirstApp.GType
Andromeda  3,  ConsoleApp_FirstApp.GType
Maffei 1, 11,  ConsoleApp_FirstApp.GType

Al examinar la salida y nuestro código, sabemos que GType es el nombre de la clase que almacena el tipo de galaxia. Estamos tratando de mostrar el tipo de galaxia real (como "Espiral"), no el nombre de la clase!

Depurar la aplicación

  1. Con la aplicación aún en ejecución, inserte un punto de interrupción.

    En el bucle foreach, haga clic con el botón derecho que hay junto al método Console.WriteLine para obtener el menú contextual y seleccione Punto de interrupción>Insertar punto de interrupción en el menú desplegable.

    foreach (Galaxy theGalaxy in theGalaxies)
    {
        Console.WriteLine(theGalaxy.Name + "  " + theGalaxy.MegaLightYears + ",  " + theGalaxy.GalaxyType);
    }
    

    Al establecer el punto de interrupción, aparece un punto rojo en el margen izquierdo.

    Al ver un problema en la salida, comienzas a depurar examinando el código previo que establece la salida en el depurador.

  2. Seleccione el botón ReiniciarIcono que muestra el botón Reiniciar aplicación en la barra de herramientas de depuración. en la barra de herramientas de depuración (Ctrl + Mayús + F5).

    La aplicación se detiene en el punto de interrupción establecido. El resaltado amarillo indica dónde está en pausa el depurador (la línea amarilla de código aún no se ha ejecutado).

  3. Mantenga el puntero sobre la variable GalaxyType a la derecha y, a continuación, a la izquierda del icono de llave, expanda theGalaxy.GalaxyType. Verá que GalaxyType contiene una propiedad MyGTypey el valor de la propiedad está establecido en Spiral.

    Captura de pantalla del depurador de Visual Studio con una línea de código en amarillo y un menú abierto debajo de la propiedad Galaxy GalaxyType.

    “Espiral” es realmente el valor correcto que se esperaba que se imprimiese en la consola. Por lo tanto, es un buen comienzo que tú puedas acceder al valor de este código mientras ejecutas la aplicación. En este escenario, se usa la API incorrecta. Veremos si puede corregir esto mientras se ejecuta código en el depurador.

  4. En el mismo código, mientras todavía se depura, coloque el cursor al final de theGalaxy.GalaxyType y cámbielo a theGalaxy.GalaxyType.MyGType. Aunque puede realizar la edición, el editor de código muestra un error (línea ondulada roja). (En Visual Basic, el error no se muestra y esta sección del código funciona).

  5. Presione F11 (Depurar>Paso a paso por instrucciones o el botón Paso a paso por instrucciones en la barra de herramientas Depurar) para ejecutar la línea de código actual.

    F11 hace avanzar el depurador (y ejecuta código) en una instrucción cada vez. F10 (Saltar) es un comando similar y ambos son útiles para aprender a usar el depurador.

    Al intentar avanzar en el depurador, aparece el cuadro de diálogo Hot Reload, lo que indica que no se pueden compilar los cambios.

    Captura de pantalla del depurador de Visual Studio con una línea de código resaltada en rojo y un cuadro de mensaje con la opción Editar seleccionada.

    Aparece el cuadro de diálogo Editar y continuar, lo que indica que no se pueden compilar las modificaciones.

    Captura de pantalla del depurador de Visual Studio con una línea de código resaltada en rojo y un cuadro de mensaje con la opción Editar seleccionada.

    Nota

    Para depurar el código de ejemplo de Visual Basic, omita los pasos siguientes hasta que se le indique que haga clic en el botón ReiniciarIcono que muestra el botón Reiniciar aplicación en la barra de herramientas de depuración.

  6. Seleccione Editar en el cuadro de mensaje Recarga activa o Editar y continuar. Ahora verá un mensaje de error en la ventana Lista de errores. El error indica que el 'object' no contiene una definición para MyGType.

    Captura de pantalla del depurador de Visual Studio con una línea de código resaltada en rojo y una ventana Lista de errores con dos errores enumerados.

    Aunque establecemos cada galaxia con un objeto de tipo GType (que tiene la propiedad MyGType), el depurador no reconoce el objeto theGalaxy como un objeto de tipo GType. ¿Qué pasa? Quieres revisar cualquier código que establezca el tipo de galaxia. Cuando haces esto, verás que la clase GType definitivamente tiene una propiedad de MyGType, pero algo no es correcto. El mensaje de error sobre object resulta ser la pista; en el intérprete de lenguaje, el tipo parece ser un objeto de tipo object en lugar de un objeto de tipo GType.

  7. Al examinar el código relacionado con el establecimiento del tipo de galaxia, encontrará la propiedad GalaxyType de la clase Galaxy se especifica como object en lugar de GType.

    public object GalaxyType { get; set; }
    
  8. Cambie el código anterior de la siguiente manera:

    public GType GalaxyType { get; set; }
    
  9. Seleccione el botón ReiniciarIcono que muestra el botón Reiniciar aplicación en la barra de herramientas de depuración. de la barra de herramientas Depurar (Ctrl + Mayús + F5) para volver a compilar el código y reiniciar.

    Ahora, cuando el depurador se detiene en Console.WriteLine, puede mantener el puntero sobre theGalaxy.GalaxyType.MyGType y ver que el valor se estableció correctamente.

  10. Quite el punto de interrupción haciendo clic en el círculo del punto de interrupción en el margen izquierdo (o haga clic con el botón derecho y elija punto de interrupción>Eliminar punto de interrupción) y presione F5 para continuar.

    La aplicación se ejecuta y muestra la salida. Tiene buena pinta, pero observas una cosa. Esperaba que la Pequeña Nube de Magallanes apareciera como una galaxia irregular en la salida de la consola, pero no muestra ningún tipo de galaxia en absoluto.

    Tadpole  400,  Spiral
    Pinwheel  25,  Spiral
    Cartwheel, 500,  Lenticular
    Small Magellanic Cloud .2,
    Andromeda  3,  Spiral
    Maffei 1,  Elliptical
    
  11. Establezca un punto de interrupción en esta línea de código antes de la instrucción switch (antes de la instrucción Select en Visual Basic).

    public GType(char type)
    

    Este código es donde se establece el tipo de galaxia, por lo que queremos echar un vistazo más detallado.

  12. Haga clic en el botón ReiniciarIcono que muestra el botón Reiniciar aplicación en la barra de herramientas de depuración. en la barra de herramientas de depuración (Ctrl + Mayús + F5) para reiniciar.

    El depurador se detiene en la línea de código donde pones el punto de interrupción.

  13. Mantenga el mouse sobre la variable type. Ve un valor de S (siguiendo el código de carácter). Te interesa un valor de I, como sabes que es un tipo de galaxia irregular.

  14. Presione F5 y mantenga el puntero sobre la variable type de nuevo. Repita este paso hasta que vea un valor de I en la variable type.

    Captura de pantalla del depurador de Visual Studio con una línea de código en amarillo y una ventana con el valor de variable de tipo 73 I.

  15. Ahora, presione F11 (o Depurar>Depurar paso a paso por instrucciones).

  16. Presione F11 hasta que se detenga en la línea de código en la instrucción switch para un valor de “I” (instrucción Select en Visual Basic). Aquí verá un problema claro resultante de un error tipográfico. Esperaba que el código avanzara hasta donde establece MyGType como un tipo de galaxia irregular, pero el depurador omite este código por completo y, en su lugar, se detiene en la sección default de la instrucción switch (Else instrucción en Visual Basic).

    Captura de pantalla que muestra el error tipográfico.

    Al examinar el código, verá un error tipográfico en la instrucción case 'l'. Debería ser case 'I'.

  17. Seleccione el código para case 'l' y reemplácelo por case 'I'.

  18. Elimine el punto de interrupción y luego seleccione el botón Reiniciar, para reiniciar la aplicación.

    Los errores se han corregido ahora y verá el resultado que espera.

    Presione cualquier tecla para finalizar la aplicación.

Resumen

Cuando vea un problema, utilice el depurador y los comandos de paso como F10 y F11 para buscar la región de código con el problema.

Nota

Si es difícil identificar la región del código donde se produce el problema, establezca un punto de interrupción en el código que se ejecuta antes de que se produzca el problema y, a continuación, use comandos de paso hasta que vea el manifiesto del problema. También puede usar puntos de seguimiento para registrar mensajes en la ventana Salida. Al examinar los mensajes registrados (y observar qué mensajes aún no se registraron), a menudo puede aislar la región del código con el problema. Es posible que tenga que repetir este proceso varias veces para restringirlo.

Cuando encuentre la región del código con el problema, use el depurador para investigar. Para encontrar la causa de un problema, inspeccione el código del problema mientras ejecuta la aplicación en el depurador:

  • Inspeccionar variables y comprobar si contienen el tipo de valores que deben contener. Si encuentra un valor incorrecto, averigüe dónde se estableció el valor incorrecto (para encontrar dónde se estableció el valor, es posible que tenga que reiniciar el depurador, examine la pila de llamadas o ambos).

  • Compruebe si la aplicación está ejecutando el código que espera. (Por ejemplo, en la aplicación de ejemplo, esperamos que el código de la instrucción switch establezca el tipo de galaxia en Irregular, pero la aplicación omitió el código debido al error tipográfico).

Sugerencia

Use un depurador para ayudarle a encontrar errores. Una herramienta de depuración puede encontrar errores automáticamente solo si conoce la intención del código. Una herramienta solo puede conocer la intención del código si usted, el desarrollador, expresa esa intención. Puede hacerlo escribiendo pruebas unitarias.

Pasos siguientes

En este artículo, ha aprendido algunos conceptos generales de depuración. A continuación, puede empezar a aprender más sobre el depurador.