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
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.
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).
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.
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.
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.
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
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.
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
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.
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
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.
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.