Tutorial: Información sobre cómo depurar código de C++ con Visual Studio

En este artículo se describen las características del depurador de Visual Studio en un tutorial paso a paso. Si quiere ahondar en las características del depurador, vea Primer vistazo al depurador. Normalmente, depurar una aplicación significa ejecutar la aplicación con el depurador activado. Al hacerlo, el depurador ofrece muchas formas de ver lo que hace el código durante la ejecución. Esto permite revisar el código y fijarse en los valores almacenados en variables, establecer inspecciones en ellas para ver cuándo cambian los valores, examinar la ruta de ejecución del código, ver si una rama de código está en funcionamiento, etc. Si esta es la primera vez que intenta depurar código, le recomendamos que lea Depuración para principiantes sin experiencia antes de continuar con este artículo.

Aunque la aplicación de demostración está en C++, la mayoría de las características son aplicables a C#, Visual Basic, F#, Python, JavaScript y otros lenguajes compatibles con Visual Studio (F# no admite Editar y continuar. F# y JavaScript no son compatibles con la ventana Automático). Las capturas de pantalla son de C++.

En este tutorial va a:

  • Iniciar el depurador y llegar a puntos de interrupción
  • Conocer los comandos para analizar el código en el depurador
  • Inspeccionar variables en la información sobre datos y las ventanas del depurador
  • Examinar la pila de llamadas

Requisitos previos

Debe tener instalado Visual Studio y la carga de trabajo Desarrollo de escritorio con C++ .

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

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

Si tiene que instalar la carga de trabajo pero ya tiene Visual Studio, vaya a Herramientas>Obtener herramientas y características… y se abrirá el Instalador de Visual Studio. Se iniciará el Instalador de Visual Studio. Seleccione la carga de trabajo Desarrollo para el escritorio con C++ y, luego, elija Modificar.

Crear un proyecto

En primer lugar, creará un proyecto de aplicación de consola de C++. En el tipo de proyecto se incluyen todos los archivos de plantilla que vamos a necesitar, sin necesidad de agregar nada más.

  1. Abra Visual Studio.

    Si la ventana de inicio no está abierta, elija Archivo>Ventana de inicio.

  2. En la ventana de inicio, elija Crear un proyecto nuevo.

  3. En el cuadro de búsqueda de la ventana Crear un proyecto, escriba consola. A continuación, elija C++ en la lista de lenguajes y, luego, Windows en la lista de plataformas.

    Después de aplicar los filtros de lenguaje y plataforma, elija la plantilla Aplicación de consola y, luego, Siguiente.

    Screenshot of choosing the C++ template for the Console App.

    Screenshot of choosing the C++ template for the Console App.

    Nota:

    Si no ve la plantilla Aplicación de consola, puede instalarla desde la ventana Crear un proyecto. En el mensaje ¿No encuentra lo que busca? , elija el vínculo Instalar más herramientas y características. Luego, en el Instalador de Visual Studio, elija la carga de trabajo Desarrollo para el escritorio con C++ .

  4. En la ventana Configurar el nuevo proyecto, escriba get-started-debugging en el cuadro Nombre del proyecto. Luego, elija Crear.

    Visual Studio se abre en el nuevo proyecto.

Crear la aplicación

  1. En get-started-debugging.cpp, reemplace todo el código predeterminado con el siguiente:

    #include <string>
    #include <vector>
    #include <iostream>
    
    void SendMessage(const std::wstring& name, int msg)
    {
        std::wcout << L"Hello, " << name << L"! Count to " << msg << std::endl;
    }
    
    int main()
    {
        std::vector<wchar_t> letters = { L'f', L'r', L'e', L'd', L' ', L's', L'm', L'i', L't', L'h' };
        std::wstring name = L"";
        std::vector<int> a(10);
        std::wstring key = L"";
    
        for (int i = 0; i < letters.size(); i++)
        {
            name += letters[i];
            a[i] = i + 1;
            SendMessage(name, a[i]);
        }
        std::wcin >> key;
        return 0;
    }
    

Inicio del depurador

  1. Presione F5 (Depurar > Iniciar depuración) o el botón Iniciar depuraciónStart Debugging en la barra de herramientas de depuración.

    Al pulsar F5, la aplicación se inicia con el depurador activado para analizar los procesos. Como de momento no hemos hecho nada especial para examinar el código, la aplicación solo se carga y se muestra la salida de la consola.

    Hello, f! Count to 1
    Hello, fr! Count to 2
    Hello, fre! Count to 3
    Hello, fred! Count to 4
    Hello, fred ! Count to 5
    Hello, fred s! Count to 6
    Hello, fred sm! Count to 7
    Hello, fred smi! Count to 8
    Hello, fred smit! Count to 9
    Hello, fred smith! Count to 10
    

    En este tutorial, analizaremos con más profundidad el uso de esta aplicación junto con el depurador y veremos las características del depurador.

  2. Para detener el depurador, presione el botón de detención rojo Stop Debugging (Mayús + F5).

  3. En la ventana de consola, presione una tecla y Entrar para cerrarla.

Establecer un punto de interrupción e iniciar el depurador

  1. En el bucle for de la función main, establezca un punto de interrupción haciendo clic en el margen izquierdo de la línea de código siguiente:

    name += letters[i];

    En el lugar en el que establezca el punto de interrupción aparecerá un círculo rojo Breakpoint.

    Los puntos de interrupción son una de las características más básicas y esenciales de una depuración confiable. Un punto de interrupción indica dónde Visual Studio debe suspender la ejecución de código para poder echar un vistazo a los valores de las variables o al comportamiento de la memoria, o determinar si se está ejecutando o no una bifurcación de código.

  2. Presione F5 o el botón Iniciar depuraciónStart Debugging. La aplicación se iniciará y el depurador se ejecutará en la línea de código en la que haya establecido el punto de interrupción.

    Screenshot of setting and hitting a breakpoint.

    La flecha amarilla representa la instrucción en la que el depurador se ha puesto en pausa, lo cual también suspende la ejecución de la aplicación en el mismo punto (esta instrucción todavía no se ha ejecutado).

    Si la aplicación todavía no se está ejecutando, F5 permite iniciar el depurador, que se detendrá en el primer punto de interrupción. En caso contrario, F5 permite continuar ejecutando la aplicación hasta el siguiente punto de interrupción.

    Los puntos de interrupción son una característica de utilidad cuando se conoce la línea o la sección de código que se quiere examinar en detalle. Para obtener información sobre los diferentes tipos de puntos de interrupción que se pueden establecer, como los puntos de interrupción condicionales, vea Uso de puntos de interrupción.

Normalmente, aquí usamos métodos abreviados de teclado porque son una buena forma de ejecutar rápidamente la aplicación en el depurador, pero los comandos equivalentes, como los comandos de menú, se muestran entre paréntesis.

  1. Mientras está en pausa en el bucle for del método main, presione F11 dos veces (o bien elija Depurar > Depurar paso a paso por instrucciones) para avanzar a la llamada al método SendMessage.

    Después de presionar F11 dos veces, debería estar en esta línea de código:

    SendMessage(name, a[i]);

  2. Presione F11 una vez más para entrar en el método SendMessage.

    El puntero de color amarillo avanza hasta el método SendMessage.

    Screenshot of using F11 to Step Into code.

    F11 es el comando Depurar paso a paso por instrucciones y permite avanzar la ejecución de la aplicación de instrucción en instrucción. F11 es una buena forma de examinar el flujo de ejecución con más detalle. Más adelante le mostraremos otras opciones para moverse más rápido por el código. De forma predeterminada, el depurador omite el código que no es de usuario (si quiere más detalles, vea Solo mi código).

    Imagine que ha terminado de examinar el método SendMessage y quiere salir de él, pero permanecer en el depurador. Puede hacerlo con el comando Salir de la depuración.

  3. Presione Mayús + F11 (o Depurar > Salir de la depuración).

    Este comando reanuda la ejecución de la aplicación (y hace avanzar el depurador) hasta que se devuelve el método o la función actual.

    Debería volver a estar en el bucle for del método main, detenido en la llamada al método SendMessage.

  4. Presione F11 varias veces hasta que vuelva a la llamada al método SendMessage.

  5. Mientras está en pausa en la llamada de método, presione F10 una vez (o bien, elija Depurar > Paso a paso por procedimientos).

    Screenshot of using F10 to Step Over code.

    En este caso, tenga en cuenta que el depurador no depura paso a paso por instrucciones el método SendMessage. F10 hace avanzar el depurador sin depurar las funciones o los métodos en el código de la aplicación paso a paso por instrucciones (el código todavía se ejecuta). Al presionar F10 en la llamada de método SendMessage (en vez de F11), se omite el código de implementación de SendMessage (algo que quizás no nos interese en este momento). Para más información sobre las distintas formas de desplazarse por el código, vea Navegación por el código en el depurador.

  1. Presione F5 para avanzar hasta el punto de interrupción.

  2. En el editor de código, desplácese hacia abajo y mantenga el puntero sobre la función std::wcout en el método SendMessage hasta el botón verde Ejecutar hasta hacer clicRun to Click aparece a la izquierda. La información sobre herramientas del botón muestra "Ejecutar hasta aquí".

    Screenshot of using the Run to Click feature.

    Nota:

    El botón Run to Click (Ejecutar hasta hacer clic) es una novedad de Visual Studio 2017. (Si no ve el botón con la flecha de color verde, presione F11 en este ejemplo para hacer avanzar el depurador hasta el lugar correcto).

  3. Haga clic en el botón Run to Click (Ejecutar hasta hacer clic) Run to Click .

    El depurador avanza hasta la función std::wcout.

    Usar este botón es similar a establecer un punto de interrupción temporal. La característica Ejecutar hasta clic es útil para desplazarse rápidamente por un área visible del código de la aplicación (puede hacer clic en cualquier archivo abierto).

Reiniciar la aplicación rápidamente

Haga clic en el botón ReiniciarRestart App en la barra de herramientas de depuración(Ctrl + Mayus + F5).

El botón Reiniciar permite ahorrar tiempo, ya que hace que no sea necesario detener la aplicación y reiniciar el depurador. El depurador se detiene en el primer punto de interrupción que se alcanza al ejecutar el código.

El depurador se detiene de nuevo en el punto de interrupción que ha establecido antes dentro del bucle for.

Inspeccionar variables con información sobre datos

Las características que le permiten inspeccionar las variables son una de las más útiles del depurador y ofrecen diferentes formas de hacerlo. A menudo, para depurar un problema, debe intentar averiguar si las variables están almacenando los valores que espera que tengan en un momento determinado.

  1. Mientras está en pausa en la instrucción name += letters[i], mantenga el mouse sobre la variable letters y verá su valor predeterminado, size={10}.

  2. Expanda la variable letters para ver sus propiedades, que incluyen todos los elementos que contiene.

  3. Después, mantenga el mouse sobre la variable name y verá su valor actual, una cadena vacía.

  4. Presione F5 varias veces (o bien, seleccione Depurar>Continuar) para iterar varias veces por el bucle for, deténgase de nuevo en el punto de interrupción y mantenga el mouse sobre la variable name cada vez para comprobar su valor.

    Screenshot of viewing a data tip.

    El valor de la variable cambia con cada iteración del bucle for y muestra los valores de f, después, fr, luego, fre, etc.

    A menudo, al realizar una depuración, queremos una forma rápida de comprobar los valores de las propiedades de las variables para ver si se almacenan los valores correspondientes, y las sugerencias de datos son una buena forma de verlo.

Inspeccionar variables con las ventanas Automático y Variables locales

  1. Vea la ventana Automático, en la parte inferior del editor de código.

    Si está cerrada, ábrala mientras está en pausa en el depurador seleccionando Depurar>Ventanas>Automático.

    En la ventana Automático puede ver las variables y su valor actual. En la ventana Automático se muestran todas las variables que se usan en la línea actual o en la anterior. Para consultar el comportamiento específico de los lenguajes, vea la documentación.

  2. A continuación, examine la ventana Variables locales en una pestaña situada junto a la ventana Automático.

  3. Expanda la variable letters para mostrar los elementos que contiene.

    Screenshot of inspecting variables in the Locals Window.

    Screenshot of inspecting variables in the Locals Window.

    En la ventana Variables locales se muestran las variables que se encuentran en el ámbito actual, es decir, en el contexto de ejecución actual.

Establecer una inspección

  1. En la ventana del editor de código principal, haga clic con el botón derecho en la variable name y elija Agregar inspección.

    En la parte inferior del editor de código se abre la ventana Inspección. Puede usar una ventana Inspección para especificar una variable (o una expresión) que quiera supervisar.

    Ahora, ha establecido una inspección en la variable name y puede ver cómo cambia su valor según avanza en el depurador. A diferencia de las otras ventanas de variables, en la ventana Inspección siempre se muestran las variables que está viendo (y se atenúan cuando están fuera del ámbito).

Examinar la pila de llamadas

  1. Mientras esté en pausa en el bucle for, haga clic en la ventana Pila de llamadas, que se abrirá de forma predeterminada en el panel inferior derecho.

    Si está cerrada, ábrala mientras está en pausa en el depurador seleccionando Depurar>Ventanas>Pila de llamadas.

  2. Presione F11 varias veces hasta que vea que el depurador se detiene en el método SendMessage. Eche un vistazo a la ventana Pila de llamadas.

    Screenshot of examining the call stack.

    Screenshot of examining the call stack.

    En la ventana Pila de llamadas se muestra el orden en el que se llama a los métodos y las funciones. En la línea superior se muestra la función actual (el método SendMessage en esta aplicación). En la segunda línea se mostrará que se ha llamado a SendMessage desde el método main, y así sucesivamente.

    Nota

    La ventana Pila de llamadas es similar a la perspectiva de depuración de algunos IDE, como Eclipse.

    La pila de llamadas es una buena forma de examinar y entender el flujo de ejecución de una aplicación.

    Puede hacer doble clic en una línea de código para ver ese código fuente. De este modo, también puede cambiar el ámbito que el depurador va a inspeccionar. Esta acción no hace avanzar el depurador.

    También puede usar los menús contextuales de la ventana Pila de llamadas para hacer otras cosas. Por ejemplo, puede insertar puntos de interrupción en funciones especificadas, avanzar el depurador mediante Ejecutar hasta el cursor y examinar el código fuente. Para obtener más información, vea Cómo: Examinar la pila de llamadas.

Cambio del flujo de ejecución

  1. Presione F11 dos veces para ejecutar la función std::wcout.

  2. Con el depurador en pausa en la llamada al método SendMessage, use el mouse para seleccionar la flecha de color amarillo (el puntero de ejecución) de la izquierda y moverla una línea hacia arriba, para volver a std::wcout.

  3. Presione F11.

    El depurador volverá a ejecutar la función std::wcout (lo puede ver en la salida de la ventana de la consola).

    Al cambiar el flujo de ejecución, puede, por ejemplo, comprobar las diferentes rutas de ejecución de código o volver a ejecutar código sin tener que reiniciar el depurador.

    Advertencia

    A menudo es necesario tener cuidado con esta característica, ya que puede ser que vea una advertencia en la información en pantalla. También puede ser que reciba otras advertencias. El hecho de mover el puntero no permite revertir la aplicación a un estado anterior.

  4. Presione F5 para seguir ejecutando la aplicación.

    Enhorabuena por completar este tutorial.

Pasos siguientes

En este tutorial, ha aprendido a iniciar el depurador, a ejecutar el código paso a paso y a inspeccionar variables. Puede ser que le interese analizar las características del depurador con más detenimiento, así como consultar los vínculos disponibles con más información.