Cómo a JIT depurar excepciones desde un servidor local de COM en Visual C++

Seleccione idioma Seleccione idioma
Id. de artículo: 198623 - Ver los productos a los que se aplica este artículo
Nota Microsoft Visual C++ 2008, Microsoft Visual C++ 2005 y Visual C++ .NET 2003 admiten tanto el modelo de código administrado suministrada por Microsoft .NET Framework y el modelo de código nativo no administrado de Microsoft Windows. La información de este artículo sólo se aplica al código no administrado de Visual C++.
Expandir todo | Contraer todo

Resumen

Cuando se inicia una excepción (por ejemplo, una infracción de acceso) desde dentro de un método COM, el servidor obtiene la primera oportunidad para tratar la excepción. Si el servidor no controla la excepción COM o remoto llamada a procedimiento (RPC) tiempo de ejecución controla y devuelve un error que indica la excepción producido. Este comportamiento es por diseño.

El resultado de esto es que ninguna excepción en un método COM [incluyendo DebugBreak ()] nunca va no controlada. Como resultado, depuración de just-in-time (JIT) de los servidores locales COM es difícil al mejor.

Esta artículo se presenta una manera de JIT depurar algunas excepciones desde un servidor de COM local. En este artículo también se explica cómo a JIT pseudo depurar un servidor local de COM para otras excepciones.

Más información

Un servidor local de COM de depuración JIT

Establezca la siguiente clave del registro:
HKEY_LOCAL_MACHINE\Software\Microsoft\Ole
IgnoreServerExceptions="Y"

				
cuando se establece la clave anterior, el tiempo de ejecución de RPC y COM pasará las excepciones siguientes en el llamador (para fines de depuración):
  • STATUS_ACCESS_VIOLATION
  • STATUS_POSSIBLE_DEADLOCK
  • STATUS_DATATYPE_MISALIGNMENT
  • STATUS_INSTRUCTION_MISALIGNMENT
  • STATUS_ILLEGAL_INSTRUCTION
  • STATUS_PRIVILEGED_INSTRUCTION
Porque el tiempo de ejecución de RPC y COM ya no controla los tipos de excepciones anteriores, vayan no controladas y, por lo tanto, es posible la depuración Just-In-Time. Para otras excepciones, utilice los métodos de depuración de JIT pseudo descritos a continuación (o ejecutar el servidor local desde el depurador).

Servidor local de depuración COM pseudo JIT

Para que este método funcione, la excepción generada debe continuable y debe reproducir de continuación. Por ejemplo, una infracción de acceso es una excepción continuable, y si la misma instrucción se ejecuta dos veces en el mismo contexto, la excepción se genera dos veces. Para obtener más información sobre generar excepciones discontinuo, vea el tema de ayuda para RaiseException .
  1. Todas las funciones deben incluirse en un Win32 estructurado de excepciones intente - excepto bloque; por ejemplo:
    LONG MyUnhandledExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo);
    
    #define PJITTry  \ 
        __try { \ 
            UINT __oldErrMode = SetErrorMode(0);
    
    #define PJITExcept(x) \ 
        SetErrorMode(__oldErrMode); \ 
        } __except (MyUnhandledExceptionFilter(GetExceptionInformation())) {}
    
    HRESULT MyClass::MyMethod (BSTR bstrName) {
        PJITTry {
            return MyClass::_MyMethod(bstrName);
        }
        PJITExcept {}
    
    }
    tenga en cuenta que si utiliza control de excepciones de C++ ( try-catch ), a continuación, deberá proporcionar funciones de código auxiliar en un archivo diferente que llamar las funciones reales, por lo que puede ajustar la función de la llamada un intente - excepto bloque.

    Según las circunstancias, se pueden introducir las funciones contenedoras de distintas maneras. Tiene que pensar detenidamente, el enfoque antes de comenzar, a reducir la cantidad total de trabajo. Por ejemplo, en el ejemplo anterior, si MyClass tiene muchos métodos, puede ser fácil de derivar una clase y reemplazar todos los métodos de interfaz que para cambiar el nombre todos los métodos reales:
    class MyDebugClass : public MyClass {
        //... lots of methods
        virtual HRESULT MyMethod (BSTR bstrName) {
            PJITTry {
                return MyClass::_MyMethod(bstrName);
            }
            PJITExcept {}
        }
    
    }
    si utiliza las macros STDMETHOD y STDMETHODIMP , puede ser tan fácil como undefining y redefinir estas macros.

    Hay muchas otras formas para ajustar sus funciones. No es posible proporcionar una lista exhaustiva en este artículo.

  2. El siguiente paso es incluya la función siguiente como un archivo .cpp independiente en el proyecto:
    #ifndef _WIN32_WINNT
    #define _WIN32_WINNT 0x400
    #endif
    #include <windows.h>
    #include <tchar.h>
    extern "C"
    LONG MyUnhandledExceptionFilter(EXCEPTION_POINTERS *ExceptionInfo)
    {
        __try {
            CHAR AeDebuggerCmdLine[MAX_PATH];
            if(IsDebuggerPresent()) return EXCEPTION_CONTINUE_SEARCH;
            if (0 == GetProfileString(
                _T("AeDebug"),
                _T("Debugger"),
                NULL,
                AeDebuggerCmdLine,
                sizeof(AeDebuggerCmdLine)-1)
                )
            {
                return EXCEPTION_CONTINUE_SEARCH;
            }
            BOOL b;
            STARTUPINFO si;
            PROCESS_INFORMATION pi;
            CHAR CmdLine[MAX_PATH];
            DWORD Status;
            HANDLE hEvent;
            SECURITY_ATTRIBUTES sa;
            sa.nLength = sizeof(sa);
            sa.lpSecurityDescriptor = NULL;
            sa.bInheritHandle = TRUE;
            hEvent= CreateEvent(&sa,TRUE,FALSE,NULL);
            ZeroMemory(&si,sizeof(si));
            wsprintf(CmdLine,AeDebuggerCmdLine,GetCurrentProcessId(),hEvent);
            si.cb = sizeof(si);
            si.lpDesktop = _T("Winsta0\\Default");
            b =  CreateProcess(NULL,CmdLine,0,0,TRUE,0,0,0,&si,&pi);
            if ( b && hEvent) {
                Status = WaitForSingleObject(hEvent,INFINITE);
                return EXCEPTION_CONTINUE_EXECUTION;
            }
            return EXCEPTION_CONTINUE_SEARCH;
        } // end __try
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            return EXCEPTION_CONTINUE_SEARCH;
        }
    }
    						
    son las advertencias con este código:
    • El código requiere la excepción que repetible. Cuando se adjunta el depurador, podemos continuar la ejecución para hacer que otra excepción. Si la ejecución continuada no causar la excepción nuevo, a continuación, se ha perdido la oportunidad de depurar.
    • De forma predeterminada, el depurador no detener en excepciones de primera oportunidad. Ya que esta excepción es controlada por una llamada RPC, se debe forzar al depurador que detenga en la notificación de primera oportunidad.
  3. Forzar el depurador se detenga en excepciones de primera oportunidad como sigue:
    • en Visual C++ 2005 y en Visual C++ 2008:
      1. Inicie Visual Studio.
      2. En el menú archivo , elija Abrir , haga clic en archivo y, a continuación, busque el archivo ejecutable para el servidor local.
      3. En el menú Depurar , haga clic en excepciones .
      4. En el cuadro de diálogo excepciones , desactive la casilla de verificación derecha después de Excepciones de Win32 en producida y, a continuación, haga clic en Aceptar .
      5. En el menú archivo , haga clic en Cerrar solución .
    • en Visual C++. NET:
      1. Inicie Visual Studio .NET
      2. En el menú archivo , elija Abrir , haga clic en archivo y, a continuación, busque el archivo ejecutable para el servidor local.
      3. En el menú Depurar , haga clic en excepciones .
      4. En el cuadro de diálogo excepciones , haga clic para seleccionar Excepciones de Win32 en excepciones y, a continuación, haga clic para seleccione interrumpir el depurador bajo cuando se produce la excepción .
      5. En el menú archivo , haga clic en Cerrar solución .
    • en versiones anteriores de Visual C++:
      1. Iniciar Developer Studio.
      2. En el menú archivo , haga clic en Abrir y, a continuación, busque el archivo ejecutable para el servidor local.
      3. En el menú Generar , haga clic en la depuración y haga clic en Ir (o haga clic en Ir A ).
      4. En el menú Depurar , haga clic en excepciones .
      5. Cambiar todas las excepciones para Detener siempre .
      6. En el menú Depurar , haga clic en Detener depuración .
      7. En el menú archivo , haga clic en Cerrar área de trabajo . Cuando se le pida, guarde las opciones del área de trabajo.
      Este método genera un archivo de opciones de área de trabajo (.opt) en el mismo directorio que el archivo .exe para el servidor local. El problema con este método es que el archivo .opt almacena la ruta de acceso completa del ejecutable y, por lo tanto, si el servidor local se copia a otro equipo, debe utilizar la misma estructura de directorio para utilizar el mismo archivo .OPT. En caso contrario, debe crear un nuevo archivo .OPT.
En general, este método no es bastante tan buena como la forma general de depuración Just-In-Time. Cuando sea posible, ejecute el servidor local desde el depurador. Sin embargo, la mayoría de circunstancias donde se requiere la depuración Just-In-Time, este método debe ser útil. Hay algunas circunstancias (mencionados anteriormente) donde este método no funciona; en estas circunstancias, debe ejecutar el servidor local desde el depurador.

Propiedades

Id. de artículo: 198623 - Última revisión: jueves, 22 de mayo de 2008 - Versión: 6.0
La información de este artículo se refiere a:
  • Microsoft Visual C++ 2008 Express Edition
  • Microsoft Visual C++ 2005 Express Edition
  • Microsoft Visual C++ .NET 2003 Standard
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Windows 2000 Server
  • Microsoft Windows 2000 Advanced Server
Palabras clave: 
kbmt kbsweptvs2008 kbdebug kbhowto KB198623 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 198623

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com