Cómo evitar las trampas del análisis estático

17

Estoy trabajando en una empresa que obtendría un puntaje de 11 en Joel Test, al menos en papel.

En la práctica, sin embargo, nada funciona tan bien como se esperaba, y el proyecto ha estado en DEFCON 1 durante medio año. Ahora, la mayoría de mis compañeros están felices si pueden volver a casa a las 6 p.m., el domingo.

Una de las prácticas aparentemente buenas que me llamó la atención por no funcionar es el uso de herramientas de análisis estático. El proyecto rastrea gcc -Wall warnings y una herramienta "C / C ++" patentada y muy costosa .

Las advertencias de CCG suelen señalar errores reales (si la mayoría de las veces son inofensivos).

Sin embargo, las herramientas propietarias enumeran cosas tales como conversiones implícitas y el tamaño de un literal de cadena. Los moldes implícitos también están en la lista negra de su libro de estilo.

La práctica estándar es presionar a las personas para que callen cada advertencia. Tenga en cuenta que esto excluye las advertencias que son predominantemente falsos positivos, este no es el problema.

El resultado es:

  1. Las personas agregan conversiones de tipos a cada valor y a cada argumento, ocultando desajustes de tipo problemáticos reales en el proceso.
  2. Las personas se presentan por uno de los errores, o usan una característica de lenguaje problemática diferente (strlen en lugar de sizeof, strncpy en lugar de strcpy, etc.)
  3. Las advertencias son silenciadas.
  4. Los informes de errores comienzan a aparecer.

El punto principal es que el código original funcionaba y estaba escrito por personas que jugaban de manera segura dentro de sus habilidades lingüísticas, mientras que las correcciones no.

Ahora, realmente no creo que esta compañía pueda salvarse. Sin embargo, me gustaría saber si hay una mejor manera, preferiblemente trabajando, de usar las herramientas "pro" o si simplemente debería evitar usarlas por completo en caso de que yo sea quien tome la decisión en el futuro.

Una solución que no asume que todos los programadores son genios que no pueden errar. Porque bueno, si lo son, entonces no hay necesidad de usar las herramientas en primer lugar.


fuente
1
Nota al margen: el GCC además de «-Wall» también tiene la opción «-Wextra», e incluso más advertencias que no están incluidas por alguna razón en ambas metaopciones. Vea los documentos para más información. En general, todas las opciones tienen una mención si está habilitado por una metaopción. Por lo tanto, para encontrar todo lo que no está habilitado, es posible que desee resaltar en todos los documentos las palabras «-Wall» y «-Wextra», y verá cuál aún no se utiliza.
Hola Ángel
También agregaría que me pregunto si el CCG no incluyó gran parte de «-Wextra» en «-Wall». Créeme, algunas de estas banderas son muy útiles ; al menos estas advertencias me liberan de una hora de depuración.
Hola Ángel
1
Me sorprende que nadie haya mencionado revisiones de código en las respuestas. Para mí, las personas que tratan de colarse en algunos cortes de mierda habrían sido bloqueadas por las revisiones de código ...
dyesdyes

Respuestas:

16

En la práctica, sin embargo, nada funciona tan bien como se esperaba, y el proyecto ha estado en DEFCON 1 durante medio año. Ahora, la mayoría de mis compañeros están felices si pueden volver a casa a las 6 p.m., el domingo.

Esta es ciertamente una buena parte de su problema. Un ingeniero de software no puede trabajar productivamente por más de 40 horas / semana. Si superas eso, haces un daño grave a tu capacidad para trabajar, hasta el punto de que incluso trabajar 80 horas / semana aporta muy poco valor al proyecto y, a veces, los proyectos incluso pueden retroceder porque el equipo introduce más errores que Pueden arreglarlo. Si ha estado haciendo 60 horas / semana o más durante medio año, entonces todo su equipo necesita un buen descanso y volver a las 40 horas / semana. No puede resolver nada con una fuerza de trabajo que apenas es capaz de golpear el teclado porque están demasiado sobrecargados.

Sin embargo, las herramientas propietarias enumeran cosas tales como conversiones implícitas y el tamaño de un literal de cadena. Los moldes implícitos también están en la lista negra de su libro de estilo.

Realmente necesita soltar la herramienta por completo o reconfigurarla / reemplazarla. Advertencia en cada elenco implícito es demasiado para que cualquiera pueda lidiar.

DeadMG
fuente
¿Podría proporcionar una referencia a una investigación sobre el límite de 40 horas a la semana?
11
aquí y aquí , solo para empezar. Está extremadamente bien documentado que no puede hacer más de 40 horas a la semana de trabajo productivo. Un simple Google le encontrará resmas de artículos.
DeadMG
55
Dos pequeñas correcciones importantes, pero en mi humilde opinión: el límite de 40 horas / semana es un valor promedio aproximado, y la regla solo se aplica durante períodos prolongados de tiempo. Está bien que un equipo invierta horas adicionales antes de una fecha límite importante y luego se recupere después (tal vez incluso tomando algunos días libres). Además, el límite varía entre las personas y con el tiempo: algunos pueden trabajar 43 horas por semana sin problemas, otros solo 35 y uno es más productivo en algunas semanas que otros. Sin embargo, dedicar horas extras significativas durante más de un par de semanas seguidas va a causar serios problemas.
Péter Török
13

Estoy trabajando en una empresa que obtendría un puntaje de 11 en Joel Test, al menos en papel.

Esa prueba es ligeramente relevante para las empresas de software. No entiendo el bombo al respecto. Puede obtener un puntaje de 12 y aún tener programadores de basura 100%. Las personas importan mucho más que las herramientas.

Sin embargo, las herramientas propietarias enumeran cosas tales como conversiones implícitas y el tamaño de un literal de cadena. Los moldes implícitos también están en la lista negra de su libro de estilo. La práctica estándar es presionar a las personas para que callen cada advertencia. Tenga en cuenta que esto excluye las advertencias que son predominantemente falsos positivos, este no es el problema.

Este es el mayor problema con todos los analizadores estáticos: demasiados falsos positivos. La única forma de manejar esto es aprender en detalle por qué la herramienta se configuró para dar una advertencia sobre un determinado problema. Solo entonces puede hacer suposiciones calificadas de si una advertencia es falsa o no.

Para el reparto específico de los tipos de letra implícitos, está allí debido a algunos errores muy comunes, sutiles y peligrosos en el lenguaje C, causados ​​por las dos reglas de promoción de tipos implícitos (imbéciles) en C. Se conocen formalmente como las reglas de promoción de enteros y Las conversiones aritméticas habituales . Creo que menos de uno de cada diez programadores profesionales de C pueden explicar qué hacen estas dos reglas y qué no hacen. Y, sin embargo, estas reglas son extremadamente fundamentales y se aplican miles de veces entre líneas en cualquier programa normal de C.

El estándar MISRA-C dedicó un capítulo entero para explicar estas peligrosas reglas de conversión implícita, y luego agregaron numerosas reglas bastante complejas sobre cómo evitar errores causados ​​por la conversión implícita. Esto tuvo bastante impacto en todos los analizadores estáticos del mercado.

Recomendaría a cualquier programador de C que lea ese capítulo de MISRA-C, o al menos busque en Google las dos reglas de promoción que mencioné y lea todo lo que pueda sobre ellas. Solo puede ignorar el analizador estático cuando sepa todo lo que hay que saber sobre estas reglas.

Ahora, realmente no creo que esta compañía pueda salvarse. Sin embargo, me gustaría saber si existe una forma mejor, preferiblemente de trabajo, de usar las herramientas "pro" o si simplemente debería evitar usarlas por completo en caso de que sea yo quien tome la decisión en el futuro.

Una solución que no asume que todos los programadores son genios que no pueden errar. Porque bueno, si lo son, entonces no hay necesidad de usar las herramientas en primer lugar.

No hay manera fácil de evitarlo. El verdadero problema no es en realidad la herramienta, sino el oscuro lenguaje C. Puede parecer un lenguaje fácil a simple vista, pero hay muchos mecanismos ilógicos y extraños entre líneas. Y también hay cientos de casos de comportamiento indefinido / no especificado / implícito en el lenguaje. La mayoría de ellos debes aprender y evitarlos.

Por lo tanto, debe convertirse en un programador veterano de C que comprende todas estas advertencias oscuras, o debe estar en un equipo con al menos una de esas personas. Las compañías que solo contratan a un grupo de programadores junior sin veteranos en el equipo no deberían usar estas herramientas, ni deberían trabajar con el desarrollo de software de alta integridad.


fuente
Hice la prueba con una pizca de sal desde el principio, pero no es una herramienta para evaluar a los programadores, sino una herramienta para evaluar a los empleadores. Supongo que podría incluir a los compañeros de trabajo aptos como "las mejores herramientas que el dinero puede pagar". Y tomo su respuesta para tirar las herramientas de SA y contratar y / o entrenar mejor. El primer punto parece ser el común denominador.
@qpr Tampoco prueba al empleador, solo la voluntad del empleador de gastar dinero en el desarrollo de software. No se mencionan cosas como el procedimiento de contratación, los objetivos corporativos, el conocimiento del mercado, etc. Creo que la mayoría de las empresas de "burbuja de TI" obtendrían un puntaje de 12 en esa prueba, con una administración que ni siquiera sabe qué productos se están desarrollando o si hay algún mercado para ellos.
4

No está claro si está preguntando cómo solucionar el problema o cómo podría haberlo evitado en primer lugar. Estoy asumiendo lo último.

Parece que ha estado confiando en el análisis estático como su medio principal para detectar y evitar errores. Quizás hubiera sido mejor concentrarse más en las pruebas unitarias y las herramientas dinámicas ... como los verificadores de memoria.

Es una mala idea confiar en una herramienta que genera muchos falsos positivos, especialmente si no puede suprimir esos falsos positivos. Alienta a los programadores cansados ​​/ con exceso de trabajo (o perezosos) a hacer "arreglos" para que las advertencias desaparezcan. Si no puede suprimir selectivamente los falsos positivos (por ejemplo, con comentarios) o adaptar el conjunto de reglas, entonces necesita una herramienta mejor. O al menos, solo debes usarlo con moderación.

Parece que tiene un problema con las personas que son descuidadas y / o cometen errores debido al exceso de trabajo. Tal vez debería haber pasado más tiempo / esfuerzo en revisiones de código. Esto aborda directamente su observación de que los programadores no son genios.

Finalmente, parece que puede haber estado sufriendo bajo plazos poco realistas, recursos de personas pobres y / o requisitos cambiantes. Este es un problema de gestión y debe abordarse a ese nivel ... o de lo contrario existe un riesgo significativamente elevado de fracaso del proyecto y daños a largo plazo en la productividad y la moral del personal.

Stephen C
fuente
3

Además de la excelente respuesta de user29079, me gustaría agregar una deficiencia más del lenguaje C que se suma al problema. No era consciente de esta deficiencia hasta que me mudé a Java.

El propósito de una advertencia es llamar la atención del escritor y los futuros lectores del código sobre el hecho de que está sucediendo algo sospechoso. Eso, como concepto, está perfectamente bien: cuantas más advertencias hayas habilitado, más cosas sospechosas descubrirás.

Lo que está muy mal , es la noción de que cada pequeña cosa sospechosa debe repararse a toda costa, cambiando el código . Eso es lo que causó el problema que está describiendo el OP: los intentos fallidos de hacer que las advertencias desaparezcan rápidamente al alterar el código que funciona bien.

Al mismo tiempo, no queremos que nuestro código arroje cientos de advertencias cada vez que compilamos, porque muy pronto las advertencias dejan de tener sentido y ya nadie presta atención a las nuevas advertencias.

Entonces, esto parece ser un caso de objetivos en conflicto; Una contradicción.

Una muy buena solución para este dilema aparentemente imposible es ser capaz de suprimir selectivamente una cierta advertencia en una declaración por declaración, para que podamos suprimirla precisamente allí donde queremos indicar que realmente sabemos lo que estamos haciendo, sin tener que alterar cualquier código.

Java tiene una buena solución para esto, con la @SuppressWarnings( "" )anotación. Si está haciendo, por ejemplo, una llamada conversión no verificada en Java, el compilador emite una advertencia para llamar su atención, la examina, determina que este es uno más de esos casos en los que sabe lo que está haciendo, así que precedes la declaración ofensiva con una @SuppressWarnings( "unchecked" )anotación que afecta solo la declaración que la sigue inmediatamente, y continúas con tu vida.

Entonces, la advertencia desaparece, el código permanece inalterado y la anotación de supresión se queda allí, coloreada en verde por el resaltado de sintaxis, para documentar el hecho de que se está produciendo una conversión dudosa, pero el autor promete que es buena. (*) Todos están felices.

En java, incluso puede prefijar parámetros individuales a funciones con el @SuppressWarnings()fin de deshabilitar una advertencia específica que puede emitirse solo en ese parámetro específico.

Sin embargo, hasta donde yo sé, C nunca apoyó ningún mecanismo estándar para suprimir selectivamente las advertencias en las declaraciones, y ciertos compiladores que implementaron sus propios mecanismos propietarios lo hicieron de manera astuta, por ejemplo, las #pragma warning (nnn:N)directivas de Microsoft C. El problema con estas directivas es que necesita dos líneas de directivas para suprimir una advertencia para una sola declaración y dejar esa advertencia habilitada para las siguientes declaraciones. Por lo tanto, es muy poco probable que los programadores de C adopten el hábito de suprimir una advertencia en base a una declaración individual, incluso cuando saben que esta advertencia particular en esta declaración particular está bien.


(*) alguien podría argumentar que si permite esto, todos los programadores de la casa suprimirán las advertencias sin pensarlo; La respuesta a esto es que puede hacer todo lo posible para ayudar a los programadores a hacer su trabajo mejor, pero no hay nada que pueda hacer si deciden sabotearlo activamente.

Mike Nakis
fuente
En otras palabras, si bien la alteración de la fuente para eliminar cada última advertencia es clave para una buena práctica, la alteración del código compilable no lo es, ya que elimina el código directo que simplemente es correcto sin una buena razón. Buena distincion.
Nathan Tuggy
2

Yo diría (sin conocer los detalles) que su empresa ha cometido errores más significativos y esto es solo el síntoma: no pudo determinar adecuadamente el dominio del software producido, administrar el equipo adecuadamente y definir objetivos razonables.

Si el software que escribe su equipo es algo crítico de lo que depende la vida humana, las herramientas de análisis estático son importantes y útiles. Dado que el "costo" de un error, medido en dinero (ignorando lo cínico que es) es alto, se requieren herramientas especiales para el trabajo. Existen pautas para C y C ++ para usar de forma segura las características del lenguaje (lea qué evitar y qué tan lejos llegar para evitarlo).
Sin embargo, en tal situación, tener empleados trabajando los domingos es una muy mala idea, además del contexto que ha proporcionado, extrapolo que el trabajo descuidado no es infrecuente. Entonces, si este es el caso, el problema es muy muygrande, y su administración está tratando de resolverlo utilizando herramientas "mejores". Desafortunadamente, no es así como funcionan las cosas. Si incluso estoy cerca de corregir, iría tan lejos como para sugerirle que comience a buscar un trabajo diferente. El software de misión crítica hecho mal es algo que puede perseguirlo y arruinar su reputación profesional, sin mencionar las perspectivas de una demanda.

Si, por otro lado, su equipo está escribiendo algo que es mucho menos crítico, las herramientas de 'análisis estático' con una alta tasa de falsos positivos solo lo retrasarán y, como ha notado, las personas generalmente reaccionan a esto encontrar el máximo local en su efectividad, en este caso simplemente haciendo trampa en las advertencias, en lugar de tratar de arreglar la razón subyacente. Por lo tanto, en su situación, el uso de estas herramientas puede deteriorar la calidad del código fuente y, por lo general, deben evitarse.

Si usted necesita para administrar un equipo de software que está escribiendo un poco de código C o C ++, yo diría que primero determinar cuáles son los principales objetivos del proyecto. Si escribir código libre de errores es de suma importancia (p. Ej., La nueva aplicación social súper increíble para iOS y Android no se ajusta a esto), entonces use análisis estático, tal vez incluso llegue a la especificación formal y la verificación formal. Pero si este es el caso, elegir buenos programadores y hacer que trabajen en un entorno sano con una carga de trabajo adecuada y 40 horas semanales adecuadas es mucho más importante.

La gente no puede trabajar de manera responsable si son tratados como esclavos (y alguien que está ocupando mis vacaciones es exactamente esto) y los buenos programadores simplemente se negarán a hacer esto de manera regular, a menos que no sepan mejor (y si son buenos, es probable ellas hacen).

Punto final: calcule sus objetivos, luego determine las herramientas y el proceso que utiliza, no permita que las herramientas disponibles definan el proceso (ergo los objetivos) ya que la administración (mala) podría obligarlo.

K.Steff
fuente
1

Como se indica en la respuesta de k.steff, las herramientas de análisis estático para 'C' son útiles si está construyendo software en una situación crítica (software de avión) y deben usarse desde el primer día (no después de meses de desarrollo cuando ocurre un error no reproducible )

El uso de este tipo de herramientas al final del proceso de desarrollo suele ser una señal de malas elecciones de diseño al principio del proceso.

En el software no crítico, este tipo de herramientas son útiles para:
-gestión de seguros, hacer que se sientan útiles (hemos hecho algo, hemos gastado mucho dinero para arreglar el software). Les da acciones que son fáciles de cumplir en sus informes de PowerPoint).
-Mantener ocupados a los desarrolladores 'tóxicos'. Permítales configurar la herramienta y analizar los resultados de la herramienta, para que pueda tener tiempo para corregir sus errores desagradables.
-forzar reglas de codificación. En ese caso, debe usarse desde el primer día. Pero una buena herramienta de revisión de código puede ser una mejor opción.

Entonces, mi opinión es que debe evitar este tipo de herramientas costosas y que consumen mucho tiempo o utilizarlas para mantener ocupadas a las personas 'tóxicas'.

FrenchKiss Dev
fuente
1

Estoy trabajando en una empresa que obtendría un puntaje de 11 en Joel Test, al menos en papel.

La validación por la prueba de Joel no es una medida de buenas prácticas; Sin embargo, la invalidación por parte de Joel Test es una medida de prácticas incorrectas / faltantes. En otras palabras, puede verse como necesario, pero no suficiente.

Ahora, la mayoría de mis compañeros están felices si pueden volver a casa a las 6 p.m., el domingo.

Parece que tienes un problema de gestión. Las horas extraordinarias sistemáticas no son una solución para hacer las cosas; en todo caso, es una solución para hacer que las cosas parezcan que funcionan y acumular deuda técnica.

Ahora, realmente no creo que esta compañía pueda salvarse. Sin embargo, me gustaría saber si existe una forma mejor, preferiblemente de trabajo, de usar las herramientas "pro" o si simplemente debería evitar usarlas por completo en caso de que sea yo quien tome la decisión en el futuro.

Sí, hay una manera de usar el análisis de código estático de manera sensata.

Pueden, y usualmente proporcionan mucho valor. Solo debe recordar que, (como las advertencias del compilador), una herramienta de análisis estático puede (a lo sumo) proporcionar indicios de que algo va mal, no informes de errores y ninguna certeza.

Parece que sus tomadores de decisiones confunden las banderas de análisis estático con defectos de aplicación.

Los moldes implícitos también están en la lista negra de su libro de estilo.

Esto suena como un problema de competencia gerencial, no como un problema de análisis estático.

El resultado es:

Las personas agregan conversiones de tipos a cada valor y a cada argumento, ocultando desajustes de tipo problemáticos reales en el proceso.

Las personas se presentan por uno de los errores, o usan una característica de lenguaje problemática diferente (strlen en lugar de sizeof, strncpy en lugar de strcpy, etc.)

Las advertencias son silenciadas.

Los informes de errores comienzan a aparecer.

Todas estas son formas de hacer que los informes periódicos se vean bien, no formas de solucionar los problemas en el código (parece que tiene un problema de competencia administrativa, nuevamente).

utnapistim
fuente