Resolver los problemas de los Servicios

A pesar de si la raíz de un error es problema de hardware o de software, necesitamos un plan fiable para resolución de problemas. Un plan efectivo comienza reuniendo información, observando los síntomas y un buen estudio.

Cuando resolvemos problemas de los servicios, necesitamos disponer de un plan preparado para determinar la causa del problema en el servicio y decidir que herramientas necesitamos para aislarlo y resolverlo, Yes we can!

Los errores pueden ser de inicio, detención y bastantes más tipos, aunque los más comunes nos sueltan los errores:

  • ERROR_SERVICE_LOGON_FAILED
  • ERROR_SERVICE_DEPENDENCY_FAILED
  • ERROR_SERVICE_START_HANG

Como ya hemos comentado varias veces, seremos capaces de elegir diversas maneras de solucionar o depurar el problema del servicio.

Herramientas

La herramienta más eficiente para la comprobación y depuración de los servicios es sc.exe. Podemos usarla para establecer las propiedades almacenadas en el registro de un servicio  para controlar cómo se inician durante el arranque y cómo se ejecutan en procesos en segundo plano.

Mientras se desarrolla y depura un servicio, esta herramienta puede ayudar ya que ofrece un generoso interfaz en línea de comandos para todas las opciones de control del servicio y puede fácilmente usarse en scripts.

Sc.exe es una herramienta de desarrollo que proporciona más información exacta y detallada sobre los servicios que las dos herramientas que proporciona el propio servicio operativo. El complemento services.msc y la herramienta en línea de comandos, Net.exe, pueden decirnos que un servicio se está ejecutando, o si está detenido o pausado. La herramienta sc.exe ayuda a la diagnosis del servicio cuando deja de responder.

Sc.exe nos permite consultar el estado del  servicio y recuperar los valores almacenados en la estructura de los campos de estado. Net.exe y Services.msc no nos proporcionan el estado completo del servicio. Sc.exe, sin embargo nos dice exactamente su estado además de mostrarnos el número del último control y un indicio de espera. El control puede entonces utilizarse como una herramienta de depuración ya que proporciona una indicación clara de en qué medida durante la inicialización había progresado antes de dejar de responder.

Sc.exe también permite la llamada de cualquier API de control de servicio y variedad de parámetros desde la línea de comandos. Esto nos da varias ventajas. Nos proporciona la facilidad una manera de crear o configurar la información de un servicio en el registro y en la base de datos de SCM. No necesitamos configurar el servicio manualmente, creando entradas en el registro y reiniciando el equipo para que la base de datos SCM se actualice.

ADVERTENCIA:No deben modificarse las claves y subclaves de los servicios directamente en el Registro ya que podríamos causar resultados impredecibles en el inicio, detención o control de los mismos.

Como herramienta en línea de comandos, sc.exe también puede utilizarse para comprobar los servicios, podemos crear archivos de lotes (batch) con llamadas a sc.exe con varios parámetros que controlen el servicio. Útil si queremos ver el comportamiento de los servicios cuando se detienen y reinician repetidamente.

sc <equipo> [comando] [nombre_servicio] <opción1> <opción2> …
<equipo> = Sólo si es remoto y en formato \nombreEquipo

Comandos:

[comando] Descripción
query Consulta el estado de un servicio si va seguido de un nombre de servicio. Enumera el estado de todos los servicios si no va seguido de un nombre de servicio.
queryex Consulta el estado extendido de un servicio si va seguido de un nombre de servicio. Enumera el estado extendido de todos los servicios si no va seguido de un nombre de servicio.
start Inicia un servicio
pause Envía una solicitud de control PAUSE a un servicio
interrogate Envía una solicitud de control INTERROGATE a un servicio
continue Envía una solicitud de control CONTINUE a un servicio
stop Envía una solicitud de STOP a un servicio
config Cambia la configuración de forma persistente de un servicio
description Cambia la descripción de un servicio
failure Cambia las acciones que emprende un servicio en caso de error
failureflag Cambia el marcador de acciones de error de un servicio
sidtype Cambia el SID de servicio de un servicio
privs Cambia los privilegios requeridos de un servicio
qc Consulta la información de configuración de un servicio
qdescription Consulta la descripción de un servicio
qfailure Consulta las acciones que emprende un servicio en caso de error
qsidtype Consulta el tipo de SID de servicio de un servicio
qprivs Consulta los privilegios requeridos de un servicio
delete Elimina un servicio del Registro
create Crea un servicio (lo agrega al Registro)
control Envía un control a un servicio
sdshow Muestra un descriptor de seguridad de un servicio
sdset Envía el descriptor de seguridad de un servicio
showsid Muestra la cadena SID de servicio correspondiente a un nombre arbitrario
GetDisplayName Obtiene el DisplayName de un servicio
GetKeyName Obtiene el ServiceKeyName de un servicio
EnumDepend Enumera las dependencias del servicio

Comandos que no necesitan un nombre de servicio:

sc <equipo> [comando] <opción>

boot (ok|bad) Indica si el último arranque debe guardarse como última configuración conocida de arranque correcto.
Lock Bloquea la base de datos del servicio.
QueryLock Consulta el LockStatus de la base de datos SCM

Opciones de Query y QueryEx en caso de que la consulta vaya seguida de un nombre de servicio, se devolverá el estado del mismo y no se aplican más opciones. Si la consulta no va seguida de nada o de una de las opciones siguientes, se enumerarán los servicios.    

type= Tipo de servicios que se enumerar n (controlador, servicio, todos)(valor predeterminado = servicio)
state= Estado de los servicios que se enumeran (inactivo, todos)(valor predeterminado = activo)
bufsize= Tamaño (en bytes) del búfer de enumeración (valor predeterminado = 4096)
ri= El número de índice de reanudación en el que comenzar la enumeración (valor predeterminado = 0)
group= Grupo de servicio que se enumerar (valor predeterminado = todos los grupos)

Ejemplos de sintaxis:

sc query

– Enumera el estado de controladores y servicios activos

sc query eventlog

– Muestra el estado del servicio de registro de eventos

sc queryex eventlog

– Muestra el estado extendido del servicio de registro de eventos

sc query type= driver

– Enumera sólo los controladores activos

sc query type= service

– Enumera sólo los servicios de Win32

sc query state= all

– Enumera todos los servicios y controladores

sc query bufsize= 50

– Enumera con un búfer de 50 bytes

sc query ri= 14

– Enumera con índice de reanudación = 14

sc queryex group= «»

– Enumera los servicios activos que no están en un grupo

sc query type= interact

– Enumera todos los servicios interactivos

sc query type= driver group= NDIS

– Enumera todos los controladores NDIS

 ERRORES DE INICIO DEL SERVICIO

Estos errores se producen cuando SCM carga un servicio durante el inicio del sistema. Algunos mensajes comunes de error de inicio:

ERROR_SERVICE_ALREADY_RUNNING

ERROR_SERVICE_DEPENDENCY_FAIL

Cuando un controlador o servicio devuelve un error en respuesta al comando de inicio del SCM, el valor de la entrada ErrorControl en el registro determina la reacción del SCM.

  • Si el valor es 0 o no está especificado, SCM ignora el error y sigue procesando el inicio del servicio.
  • Si el valor es 1, SCM registra un evento en el registro de sucesos del sistema, que dice, «El Servicio <nombre_servicio> ha fallado en su inicio debido al siguiente error:» y sigue procesando el inicio del servicio. SCM incluye la representación en texto del código de error de Win32 que el servicio ha devuelto al SCM como la razón de su fallo de inicio en el registro del suceso grabado.
  • Si el valor es 2 o 3, SCM registra un evento en el registro de sucesos y cambia la configuración del registro de la última configuración buena conocida, con la que el equipo inicio correctamente la última vez. Y entonces reinicia el equipo usando la función shutdown, que está implementada en la parte ejecutiva del kernel. Si el equipo ya está en ejecución con la última configuración buena conocida, simplemente se reinicia.

Detectar servicios que no responden

Determinar si un servicio está detenido o colgado puede ser a veces difícil. Si un servicio deja de responder en cualquier estado a excepción de SERVICE_STOPPED, el complemento Services y Net.exe informarán que sigue en ejecución. Por ejemplo, si un servicio deja de responder cuando se encuentra en el estado SERVICE_STOP_PENDING, el comando Net start informará que su estado es ejecutándose y el complemento Servicios indicará que se encuentra detenido. Una comparación de como informan del estado las herramientas:

Estado

Services

Net.exe

Sc.exe

SERVICE_STOP_PENDING SERVICE_RUNNING SERVICE_RUNNING SERVICE_STOP_PENDING
SERVICE_START_PENDING SERVICE_RUNNING SERVICE_RUNNING SERVICE_START_PENDING

Si intentamos iniciar un servicio detenido con el estado SERVICE_STOP_PENDING o SERVICE_START_PENDING, Net.exe indicará que el servicio ya está en ejecución.

La forma de conocer los servicios que no se están ejecutando en un equipo es usando el comando:

sc query type= service state= inactive

Y si queremos consultar un servicio en concreto:

sc query service nombre_servicio

Los servicios tienen tendencia a colgarse cuando están en estado SERVICE_START_PENDING. También en el estado SERVICE_STOP_PENDING si hay problemas su apagado.

Algunas veces pueden aparecer como colgados porque SCM está esperando a que un servicio cambie de estado. SCM espera a que un servicio se inicie en dos casos:

  • El servicio se está iniciando automáticamente.
  • El servicio está siendo iniciado por SCM ya que se llamo a StartService por un servicio que depende de él.

En ambos casos, SCM espera 80 segundos extra para que el servicio cambie su estado de SERVICE_START_PENDING o para llamar a SetServiceStatus otra vez con un punto de comprobación nuevo.

Si el servicio tarda demasiado en iniciarse, supera el tiempo total de espera de SCM, éste lo marcará como fallado (colgado en el inicio), registrará un suceso, EVENT_SERVICE_START_HUNG, y sigue adelante. Este evento se registra sólo si el nivel de error del servicio no se ignora. Si se ignora, podremos ver el mensaje la próxima vez que Windows se inicie. Ya que SCM no detiene un servicio colgado, podemos utilizar sc.exe para ver cuales servicios permanecen en un estado SERVICE_START_PENDING y de ellos cuales no responden.

Si el servicio llama a SetServiceStatus en algún momento durante este intervalo y especifica un nuevo punto de comprobación, SCM reiniciará su tiempo de espera. Un nuevo punto de comprobación le indica a SCM que sigue pendiente pero que ha realizado algún progreso.

El tiempo de espera puede detectarse mediante el campo dwWaitHint de la estructura SERVICE_STATUS que se pasa. Podemos comprobar este valor mediante el comando sc query servicio, donde servicio es el que no responde (el tiempo de espera es válido sólo cuando el servicio está en el estado SERVICE_START_PENDING).

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *