Compartir a través de


Preparación para depurar la aplicación de servicio

En este tema se enumeran todos los pasos preparatorios que pueden ser necesarios antes de depurar una aplicación de servicio. Los pasos necesarios en el escenario dependen de la opción de adjuntar que haya elegido y de la configuración de depuración que haya elegido. Para obtener una lista de estas opciones, vea Elegir el mejor método.

Cada uno de los pasos preparatorios descritos en este tema especifica las condiciones en las que es necesario. Estos pasos se pueden realizar en cualquier orden.

Habilitación de la depuración del código de inicialización

Si tiene previsto depurar la aplicación de servicio desde el principio de su ejecución, incluido su código de inicialización, se requiere este paso preparatorio.

Busque o cree la siguiente clave del Registro, donde ProgramName es el nombre del archivo ejecutable de la aplicación de servicio:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName 

ProgramName debe incluir la extensión de nombre de archivo, pero no la ruta de acceso. Por ejemplo, ProgramName puede ser Myservice.exe o Thisservice.dll.

En esta clave del Registro, cree un valor de datos de cadena titulado Depurador. El valor de esta cadena debe establecerse en la ruta de acceso completa y el nombre de archivo de un depurador que se va a adjuntar a la aplicación de servicio.

  • Si tiene previsto depurar localmente, use una cadena como la siguiente:

    c:\Debuggers\windbg.exe 
    

    No elija esta opción si ejecuta Windows Vista o una versión posterior de Windows.

  • Si tiene previsto usar la depuración remota, especifique NTSD con la opción -noio. Esto hace que NTSD se ejecute sin ninguna consola propia, accesible solo a través de la conexión remota. Por ejemplo:

    c:\Debuggers\ntsd.exe -server ServerTransport -noio -y SymbolPath 
    

    Si la sesión de depuración comienza antes de que Windows se cargue por completo, es posible que no pueda acceder a símbolos desde un recurso compartido remoto; en tal caso, debe usar símbolos locales. ServerTransport debe especificar un protocolo de transporte implementado por el kernel de Windows sin interactuar con un servicio en modo de usuario, como TCP o NPIPE. Para obtener la sintaxis de ServerTransport, consulte Activación de un servidor de depuración.

  • Si tiene previsto controlar el depurador en modo de usuario desde un depurador en modo kernel, especifique NTSD con la opción -d. Por ejemplo:

    c:\Debuggers\ntsd.exe -d -y SymbolPath 
    

    Si tiene previsto usar este método y se accederá a los símbolos en modo de usuario desde un servidor de símbolos, debe combinar este método con la depuración remota. En este caso, especifique NTSD con la opción -ddefer. Elija un protocolo de transporte implementado por el kernel de Windows sin interactuar con un servicio en modo de usuario, como TCP o NPIPE. Por ejemplo:

    c:\Debuggers\ntsd.exe -server ServerTransport -ddefer -y SymbolPath 
    

    Para obtener más información, consulte Control del depurador de User-Mode desde el depurador de kernel.

Una vez completada esta edición del Registro, el depurador se inicia cada vez que se inicia o reinicia un servicio con este nombre.

Permitir que la aplicación de servicio se interrumpa en el depurador

Si desea que la aplicación de servicio se interrumpa en el depurador cuando se bloquea o encuentra una excepción, se requiere este paso preparatorio. Este paso también es necesario si desea que la aplicación de servicio se interrumpa en el depurador mediante una llamada a la función DebugBreak .

Nota Si ha habilitado la depuración del código de inicialización (el paso descrito en la subsección "Habilitación de la depuración del código de inicialización"), debe omitir este paso. Cuando se habilita la depuración de código de inicialización, el depurador se adjunta a la aplicación de servicio cuando se inicia, lo que hace que se enruten todos los bloqueos, excepciones y llamadas a DebugBreak para enrutarse al depurador sin necesidad de realizar preparativos adicionales.

Este paso preparatorio implica registrar el depurador elegido como depurador posterior. Esto se hace mediante las opciones -iae o -iaec en la línea de comandos del depurador. Se recomiendan los siguientes comandos, pero si desea variarlos, consulte los detalles de sintaxis en Habilitación de la depuración postmortem.

  • Si tiene previsto depurar localmente, use un comando como el siguiente:

    windbg -iae 
    

    No elija esta opción si ejecuta Windows Vista o una versión posterior de Windows.

  • Si tiene previsto usar la depuración remota, especifique NTSD con la opción -noio. Esto hace que NTSD se ejecute sin ninguna consola propia, accesible solo a través de la conexión remota. Para instalar un depurador postmortem que incluya el parámetro -server, debe editar manualmente el registro; para obtener más información, consulte Habilitación de la depuración postmortem. Por ejemplo, el valor debugger de la clave AeDebug podría ser el siguiente:

    ntsd -server npipe:pipe=myproc%x -noio -p %ld -e %ld -g -y SymbolPath 
    

    En la especificación de canalización, el token %x se reemplaza por el identificador de proceso del proceso que inicia el depurador. Esto garantiza que si más de un proceso inicia un depurador posterior, cada uno tiene un nombre de canalización único. Si la sesión de depuración comienza antes de que Windows se cargue por completo, es posible que no pueda acceder a símbolos desde un recurso compartido remoto; en tal caso, debe usar símbolos locales. ServerTransport debe especificar un protocolo de transporte implementado por el kernel de Windows sin interactuar con un servicio en modo de usuario, como TCP o NPIPE. Para obtener la sintaxis de ServerTransport, consulte Activación de un servidor de depuración.

  • Si tiene previsto controlar el depurador en modo de usuario desde un depurador en modo kernel, especifique NTSD con la opción -d. Por ejemplo:

    ntsd -iaec -d -y SymbolPath 
    

    Si elige este método e intenta acceder a símbolos en modo de usuario desde un servidor de símbolos, debe combinar este método con la depuración remota. En este caso, especifique NTSD con la opción -ddefer. Elija un protocolo de transporte implementado por el kernel de Windows sin interactuar con un servicio en modo de usuario, como TCP o NPIPE. Para instalar un depurador postmortem que incluya el parámetro -server, debe editar manualmente el registro; para obtener más información, consulte Habilitación de la depuración postmortem. Por ejemplo, el valor debugger de la clave AeDebug podría ser el siguiente:

    ntsd -server npipe:pipe=myproc%x -ddefer -p %ld -e %ld -g -y SymbolPath 
    

    Para obtener más información, consulte Control del depurador de User-Mode desde el depurador de kernel.

Cuando se emite uno de estos comandos, se registra el depurador posterior a la memoria. Este depurador se iniciará siempre que cualquier programa en modo de usuario, incluida una aplicación de servicio, encuentre una excepción o ejecute una función DebugBreak .

Ajustar el tiempo de espera de la aplicación de servicio

Si tiene previsto iniciar el depurador automáticamente (ya sea cuando se inicia el servicio o cuando encuentra una excepción), se requiere este paso preparatorio.

Busque la clave del Registro siguiente:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

En esta clave, busque o cree un valor de datos DWORD denominado ServicesPipeTimeout. Establezca esta entrada en la cantidad de tiempo en milisegundos que desea que el servicio espere antes de que se agote el tiempo de espera. Por ejemplo, un valor de 60 000 es de un minuto, mientras que un valor de 86 400 000 es de 24 horas. Cuando no se establece este valor del Registro, el tiempo de espera predeterminado es de unos treinta segundos.

La importancia de este valor es que un reloj comienza a ejecutarse cuando se inicia cada servicio y, cuando se alcanza el valor de tiempo de espera, se finaliza cualquier depurador asociado al servicio. Por lo tanto, el valor que elija debe ser mayor que la cantidad total de tiempo que transcurre entre el inicio del servicio y la finalización de la sesión de depuración.

Esta configuración se aplica a todos los servicios que se inician o reinician una vez completada la edición del Registro. Si algún servicio se bloquea o se bloquea y esta configuración sigue en vigor, Windows no detecta el problema. Por lo tanto, debe usar esta configuración solo durante la depuración y devolver la clave del Registro a su valor original una vez completada la depuración.

Aislamiento del servicio

A veces, varios servicios se combinan en un único proceso de host de servicio (Svchost). Si desea depurar este tipo de servicio, primero debe aislarlo en un proceso Svchost independiente.

Hay tres métodos por los que puede aislar un servicio. Microsoft recomienda el método Mover el servicio a su propio grupo, como se indica a continuación. Los métodos alternativos (cambiar el tipo de servicio y duplicar el binario SvcHost) se pueden usar de forma temporal para la depuración, pero porque modifican la forma en que se ejecuta el servicio, no son tan confiables como el primer método.

Método preferido: Mover el servicio a su propio grupo

  1. Emita el siguiente comando de la herramienta de configuración de servicio (Sc.exe), donde ServiceName es el nombre del servicio:

    sc qc ServiceName 
    

    Esto muestra los valores de configuración actuales para el servicio. El valor de interés es BINARY_PATH_NAME, que especifica la línea de comandos utilizada para iniciar el programa de control de servicio. En este escenario, dado que el servicio aún no está aislado, esta línea de comandos incluye una ruta de acceso de directorio, Svchost.exe y algunos parámetros de SvcHost, incluido el modificador -k, seguido de un nombre de grupo. Por ejemplo, puede tener un aspecto similar al siguiente:

    %SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork 
    

    Recuerde esta ruta de acceso y el nombre del grupo; se usan en los pasos 5 y 6.

  2. Busque la clave del Registro siguiente:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost 
    

    Cree un nuevo valor de REG_MULTI_SZ con un nombre único (por ejemplo, TempGrp).

  3. Establezca este nuevo valor igual al nombre del servicio que desea aislar. No incluya ninguna ruta de acceso de directorio ni extensión de nombre de archivo. Por ejemplo, puede establecer el nuevo valor TempGrp igual a MyService.

  4. En la misma clave del Registro, cree una nueva clave con el mismo nombre que usó en el paso 2. Por ejemplo:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp 
    

    Ahora la clave SvcHost contiene un valor con el nuevo nombre y también tiene una clave subordinada con este mismo nombre.

  5. Busque otra clave subordinada a la clave SvcHost que tenga el mismo nombre que el grupo que encontró en el paso 1. Si existe dicha clave, examine todos los valores de ella y cree duplicados en la nueva clave que creó en el paso 4.

    Por ejemplo, la clave antigua podría denominarse esto:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\LocalServiceNoNetwork 
    

    y pueden contener valores como CoInitializeSecurityParam, AuthenticationCapabilities y otros valores. Debería ir a la clave recién creada:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost\TempGrp 
    

    y crean valores que son idénticos en nombre, tipo y datos a los de la clave antigua.

    Si la clave antigua no existe, no es necesario crear una clave nueva.

  6. Use el siguiente comando de la herramienta de configuración del servicio para revisar la ruta de acceso que se encuentra en el paso 1:

    sc config ServiceName binPath= "RevisedPath" 
    

    En este comando, ServiceName es el nombre del servicio y RevisedPath es el nuevo valor que se proporciona para BINARY_PATH_NAME. Para RevisedPath, use la misma ruta de acceso exacta que la que se muestra en el paso 1, incluidas todas las opciones que se muestran en esa línea, realizando solo un cambio: reemplace el parámetro que sigue al modificador -k por el nombre del nuevo valor del Registro que creó en el paso 2. Incluya RevisedPath entre comillas. Espacio después de que se requiera el signo igual.

    Por ejemplo, el comando podría tener el siguiente aspecto:

    sc config MyService binPath= "%SystemRoot%\System32\svchost.exe -k TempGrp" 
    

    Es posible que desee volver a usar el comando sc qc para revisar el cambio realizado.

Esta configuración surtirá efecto la próxima vez que se inicie el servicio. Para borrar los efectos del servicio anterior, se recomienda reiniciar Windows en lugar de reiniciar el servicio.

Después de completar la depuración, si desea devolver este servicio al host de servicio compartido, use de nuevo el comando sc config para devolver la ruta de acceso binaria a su valor original y elimine las nuevas claves y valores del Registro que ha creado.

Método alternativo: Cambio del tipo de servicio

  1. Emita el siguiente comando de la herramienta de configuración de servicio (Sc.exe), donde ServiceName es el nombre del servicio:

    sc config ServiceName type= own 
    

    Espacio después de que se requiera el signo igual.

  2. Reinicie el servicio mediante los siguientes comandos:

    net stop ServiceName 
    net start ServiceName 
    

Esta alternativa no es el método recomendado porque puede modificar el comportamiento del servicio. Si usa este método, use el siguiente comando para revertir al comportamiento normal después de haber completado la depuración:

sc config ServiceName type= share 

Método alternativo: Duplicación del binario SvcHost

  1. El archivo ejecutable Svchost.exe se encuentra en el directorio system32 de Windows. Realice una copia de este archivo, asígnelo el nombre svhost2.exe y colóquelo en el directorio system32.

  2. Emita el siguiente comando de la herramienta de configuración de servicio (Sc.exe), donde ServiceName es el nombre del servicio:

    sc qc ServiceName 
    

    Este comando muestra los valores de configuración actuales del servicio. El valor de interés es BINARY_PATH_NAME, que especifica la línea de comandos utilizada para iniciar el programa de control de servicio. En este escenario, dado que el servicio aún no está aislado, esta línea de comandos incluirá una ruta de acceso de directorio, Svchost.exe y probablemente algunos parámetros de SvcHost. Por ejemplo, puede tener un aspecto similar al siguiente:

    %SystemRoot%\System32\svchost.exe -k LocalServiceNoNetwork 
    
  3. Para revisar esta ruta de acceso, emita el siguiente comando:

    sc config ServiceName binPath= "RevisedPath" 
    

    En este comando, ServiceName es el nombre del servicio y RevisedPath es el nuevo valor que se proporciona para BINARY_PATH_NAME. Para RevisedPath, use la misma ruta de acceso exacta que la que se muestra en el paso 2, incluidas todas las opciones que se muestran en esa línea, realizando solo un cambio: reemplace Svchost.exe por Svchost2.exe. Incluya RevisedPath entre comillas. Espacio después de que se requiera el signo igual.

    Por ejemplo, el comando podría tener el siguiente aspecto:

    sc config MyService binPath= "%SystemRoot%\System32\svchost2.exe -k LocalServiceNoNetwork" 
    

    Puede volver a usar el comando sc qc para revisar el cambio realizado.

  4. Reinicie el servicio mediante los siguientes comandos:

    net stop ServiceName 
    net start ServiceName 
    

Esta alternativa no es el método recomendado porque puede modificar el comportamiento del servicio. Si usa este método, use el comando sc config para volver a cambiar la ruta de acceso a su valor original después de haber completado la depuración.