Compartir a través de


Preguntas más frecuentes sobre la depuración de código nativo

¿Cómo puedo depurar infracciones de acceso al ejecutar mi programa fuera del depurador de Visual Studio?

Set the Just-in-time debugging option and run your program stand-alone until the access violation occurs. Then, in the Access Violation dialog box, you can click Cancel to start the debugger.

¿Cómo puedo depurar una infracción de acceso de C++?

Si obtiene una infracción de acceso en una línea de código que desreferencia varios punteros, puede ser difícil averiguar qué puntero provocó la infracción de acceso. En Visual Studio, el cuadro de diálogo de excepción denomina explícitamente el puntero que provocó la infracción de acceso.

Por ejemplo, dado el código siguiente, debe obtener una infracción de acceso:

#include <iostream>
using namespace std;

class ClassC {
public:
  void printHello() {
    cout << "hello world";
  }
};

class ClassB {
public:
  ClassC* C;
  ClassB() {
    C = new ClassC();
  }
};

class ClassA {
public:
  ClassB* B;
  ClassA() {
    // Uncomment to fix
    // B = new ClassB();
  }
};

int main() {
  ClassA* A = new ClassA();
  A->B->C->printHello();

}

Si ejecuta este código en Visual Studio, debería ver el siguiente cuadro de diálogo de excepción:

Captura de pantalla de un cuadro de diálogo de excepción de Microsoft Visual Studio que muestra una infracción de acceso de lectura para

Si no puede determinar por qué el puntero provocó una infracción de acceso, realice un seguimiento a través del código para asegurarse de que el puntero que causa el problema se ha asignado correctamente. If it is passed as a parameter, make sure that it is passed correctly, and you aren't accidentally creating a shallow copy. A continuación, compruebe que los valores no se cambian involuntariamente en algún lugar del programa mediante la creación de un punto de interrupción de datos para el puntero en cuestión para asegurarse de que no se está modificando en otro lugar del programa. For more information about data breakpoints, see the data breakpoint section in Using Breakpoints.

¿Cómo puedo averiguar si mis punteros dañan una dirección de memoria?

Compruebe si hay daños en el montón. La mayoría de los daños en la memoria se deben a daños en el montón. Pruebe a usar la Utilidad de marcas globales (gflags.exe) o pageheap.exe. Consulte GFlags y PageHeap.

Para buscar dónde se modifica la dirección de memoria:

  1. Establezca un punto de interrupción de datos en 0x00408000. Consulte Establecimiento de un punto de interrupción de cambio de datos (solo C++ nativo).

  2. When you hit the breakpoint, use the Memory window to view memory contents starting at 0x00408000. For more information, see Memory Windows.

¿Cómo puedo averiguar quién pasa un valor de parámetro incorrecto?

Para resolver este problema:

  1. Establezca un punto de interrupción de ubicación al principio de la función.

  2. Right-click the breakpoint and select Condition.

  3. In the Breakpoint Condition dialog box, click on the Condition check box. See Advanced Breakpoints.

  4. Escriba una expresión, como Var==3, en el cuadro de texto, donde Var es el nombre del parámetro que contiene el valor incorrecto y 3 es el valor incorrecto que se le pasa.

  5. Select the is True radio button, and click the OK button.

  6. Ahora vuelva a ejecutar el programa. El punto de interrupción hace que el programa se detenga al principio de la función cuando el Var parámetro tiene el valor 3.

  7. Use la ventana Pila de llamadas para buscar la función de llamada y navegar hasta su código fuente. Para obtener más información, vea Cómo: Usar la ventana Pila de llamadas.

Al llamar a una función cientos de veces, ¿cómo sé qué llamada produjo un error?

Ejemplo: Mi programa produce un error en una llamada a una determinada función, CnvtV. Es probable que el programa llame a esa función un par de cientos de veces antes de que se produzca un error. Si se establece un punto de interrupción de ubicación en CnvtV, el programa se detiene en cada llamada a esa función y no quiero eso. No sé qué condiciones hacen que se produzca un error en la llamada, por lo que no puedo establecer un punto de interrupción condicional. ¿Qué puedo hacer?

You can set a breakpoint on the function with the Hit Count field to a value so high that it will never be reached. In this case, because you believe the function CnvtV is called a couple hundred times, you might set Hit Count to 1000 or more. A continuación, ejecute el programa y espere a que se produzca un error en la llamada. Cuando se produce un error, abra la ventana Puntos de interrupción y examine la lista de puntos de interrupción. Aparece el punto de interrupción en el que se ha establecido CnvtV , seguido del número de iteraciones y el número de iteraciones restantes:

CnvtV(int) (no condition) when hit count is equal to 1000 (currently 101)

Ahora sabe que la función produjo un error en la llamada 101. Si restablece el punto de interrupción con un recuento de aciertos de 101 y vuelve a ejecutar el programa, el programa se detiene en la llamada a CnvtV que provocó un error.

¿Dónde puedo buscar códigos de error de Win32?

WINERROR.H in the INCLUDE directory of your default system installation contains the error code definitions for the Win32 API functions.

You can look up an error code by typing the code in the Watch window or the QuickWatch dialog box. For example:

0x80000004,hr

¿Cómo puedo mantener el foco al recorrer mi aplicación?

Ejemplo: Mi programa tiene un problema de activación de ventana. Recorrer el programa con el depurador interfiere con mi capacidad de reproducir el problema porque mi programa sigue perdiendo el foco. ¿Hay alguna manera de evitar perder el foco?

Si tiene un segundo equipo, use la depuración remota. Puede operar el programa en el equipo remoto mientras ejecuta el depurador en el host. Para obtener más información, vea Cómo: Seleccionar un equipo remoto.

¿Cómo puedo depurar las funciones de la API de Windows?

Para establecer un punto de interrupción en una función de la API de Windows con símbolos NT cargados:

  • In the function breakpoint, enter the function name together with the name of the DLL where the function resides (see the context operator). En el código de 32 bits, use la forma decorada del nombre de la función. To set a breakpoint on MessageBeep, for example, you must enter the following.

    {,,USER32.DLL}_MessageBeep@4
    

    Para obtener el nombre decorado, vea Ver nombres decorados.

    Puede probar el nombre decorado y verlo en código de desensamblaje. Mientras se pausa en la función del depurador de Visual Studio, haga clic con el botón derecho en la función en el editor de código o en la ventana pila de llamadas y elija Ir al desensamblado.

  • En código de 64 bits, puede usar el nombre sin codificar.

    {,,USER32.DLL}MessageBeep
    

Next steps

Puede obtener más información sobre la depuración de código nativo en Visual Studio mediante estos vínculos: