Herramienta general del comprobador de controladores estáticos y limitaciones técnicas
SDV tiene las siguientes limitaciones generales:
SDV comprueba solo un controlador a la vez y el controlador debe seguir uno de estos modelos de controladores para que se comprueben completamente: WDM, KMDF, NDIS o Storport. Para obtener más información sobre los controladores admitidos, consulte Determinar si el Comprobador de controladores estáticos admite el controlador o la biblioteca.
Los controladores que no se dividen en una de las categorías anteriores se limitarán gravemente en las reglas que se pueden comprobar y es más probable que se produzcan errores durante el análisis.
El archivo del proyecto de controlador y el código fuente deben residir en el equipo local. No se pueden comprobar los controladores de forma remota.
SDV se instala con la configuración regional inglés (Estados Unidos). Como resultado, los elementos dependientes de la configuración regional, como el formato de cadena, usan las variantes en inglés (Estados Unidos). Esta limitación está presente incluso cuando SDV está instalado en versiones localizadas de Windows que no sean inglés (Estados Unidos).
El motor de verificación de SDV tiene limitaciones técnicas que impiden que interprete correctamente algún código de controlador. En concreto, el motor de comprobación:
No reconoce que los enteros de 32 bits están limitados a 32 bits. Como resultado, no detecta errores de desbordamiento o de subdesbordamiento.
Asegúrese de que los controladores que declaran sus puntos de entrada con la palabra clave static se procesan correctamente. Sin embargo, para asegurarse de que se reconocen los puntos de entrada estáticos, SDV requería un cambio en los archivos Sdv-map.h para las funciones estáticas: por ejemplo, si declara un punto de entrada estático:
static DRIVER_UNLOAD Unload;
Sdv-map.h no contendrá la entrada habitual para fun_DriverUnload.
#define fun_DriverUnload Unload
En su lugar, verá que el nombre de la función es mangled:
#define fun_DriverUnload sdv_static_function_Unload_1
Esto es necesario, ya que varios módulos pueden tener una función estática denominada Unload. El nombre se ha alterado para evitar posibles conflictos.
No se pueden interpretar las funciones de devolución de llamada de controlador o distribución de controladores definidas en un controlador de exportación donde el controlador de exportación tiene un archivo de definición de módulo (.def) que oculta la función de distribución del controlador. Para evitar este problema, agregue la función de distribución del controlador a la sección EXPORTS del archivo de definición de módulo (.def).
No se puede detectar correctamente el tipo de rol de una función si las siguientes referencias a esta función no están en la misma unidad de compilación.
- Declaración de la función.
- Definición de la función.
- Asignación de la función a un punto de entrada del controlador o a una función de devolución de llamada.
La unidad de compilación se define aquí como el conjunto más pequeño de archivos de código fuente y otros archivos de código fuente incluidos en este archivo de código fuente.
Si SDV no detecta un tipo de rol de función, SDV no comprobará los seguimientos que se originan en esta función.
Por ejemplo, si un controlador define (o implementa) una función EvtDriverDeviceAdd en el archivo mydriver.c. Esta unidad de compilación (o cualquier archivo .h que incluya mydriver.c) debe contener la declaración de tipo de rol de función para la función EvtDriverDeviceAdd .
No interpreta el control estructurado de excepciones. En el caso de las instrucciones try/except , SDV analiza la sección protegida como si no se produce ninguna excepción. No analiza la expresión ni el código del controlador de excepciones.
// The try/except statement __try { // guarded section } __except ( expression ) { // exception handler }
Para las instrucciones try/finally , SDV analiza la sección protegida y, a continuación, el controlador de terminación, como si no se produce ninguna excepción.
// The try/finally statement __try { // guarded section } __finally { // termination handler }
Para las instrucciones try/except y try/finally , SDV omite la instrucción leave .
Para las instrucciones try/except y try/finally , un salto fuera del bloque try impide el análisis de las instrucciones except o finally . Para obtener información sobre cómo volver a escribir para que pueda usar una instrucción leave, consulte el tema sobre la advertencia del compilador C6242.
Omite la aritmética del puntero. Por ejemplo, se perderán situaciones en las que se incrementa o disminuye un puntero. Esta limitación puede dar lugar a resultados falsos negativos y falsos positivos.
Omite uniones. En la mayoría de las circunstancias, una unión se trata como una estructura y esto podría dar lugar a falsos positivos o falsos negativos.
Omite las operaciones de conversión, por lo que se perderán ambos errores que se resuelven mediante la redifusión y los errores causados por la conversión. Por ejemplo, el motor supone que un entero que se redifusión como carácter sigue teniendo el valor entero.
Solo inicializa matrices que son matrices de punteros de función. SDV emite una advertencia y comprime el inicializador de matriz en los primeros 1000 elementos. Para otros tipos de matriz, solo se inicializa el primer elemento.
No se llama a los constructores de objetos que se inicializan en matrices. Por ejemplo, en el siguiente fragmento de código, x no se establece en 10 porque SDV no llama al constructor.
class A { public: A() { x = 10; } int x; }; void main() { A a[1]; }
SDV no admite el uso de constructores para inicializar matrices. Por ejemplo, en el siguiente fragmento de código, el constructor de P no se llamará correctamente en la función principal y no inicializará el elemento en la matriz p2:
class P { public: P() : x(0) {} int x; }; void main() { P* p1 = new P[1]; P p2[1] = {P()}; }
SDV omite los encabezados precompilados. Los controladores que usan encabezados precompilados únicamente para acelerar la compilación se compilarán más lentamente con SDV. Los controladores que deben usar encabezados precompilados para una compilación correcta no se compilarán con SDV.
No se pueden deducir algunos tipos de asignaciones implícitas que se realizan mediante llamadas a RtlZeroMemory o NdisZeroMemory. El motor realiza un análisis de mejor esfuerzo para inicializar la memoria en cero, pero solo cuando puede identificar su tipo. Como resultado, el código que depende de estas funciones para inicializar la memoria podría producir defectos falsos en algunas rutas de acceso de código.
No admite un modelo de memoria que le permita realizar un seguimiento del envío manual de solicitudes de E/S a un controlador KMDF. El motor solo admite métodos que dependen del marco para entregar las solicitudes de E/S al controlador (para la distribución secuencial o paralela).
No admite el uso del tipo de datos float para las comparaciones. Esta limitación técnica puede producir resultados falsos negativos y falsos positivos.
SDV no admite la herencia virtual ni las funciones virtuales. SDV no genera defectos que siguen una ruta de acceso de código a través de funciones virtuales, lo que podría provocar la pérdida de defectos verdaderos. La herencia virtual se trata como herencia regular, lo que podría provocar defectos falsos o defectos verdaderos perdidos.