2012-04-13 10 views
8

En un código similar a cada uno de los ejemplos siguientes, me gustaría poder analizar el código de forma estática para determinar la lista de valores posibles que pasan a SpecialFunction().C# Análisis estático, valores posibles para una variable/parámetro

SpecialFunction(5); // A 

int x = 5; 
SpecialFunction(x); // B 

int x = 5; 
x = condition ? 3 : 19; 
SpecialFunction(x); // C 

ya puedo analizar el C# en un árbol de sintaxis abstracta y ya puedo manejar casos como A, y supongo que pude realizar un seguimiento de las asignaciones iniciales de los valores de adivinar el caso B, pero los casos tan fácil como C parece complicarse rápidamente.

Estoy casi seguro de que no podremos resolver para x en todos los casos estáticamente y eso está bien. Me gustaría saber estrategias para intentarlo, formas de reconocer cuándo no se puede hacer. ¿Qué pasa si tenemos que incluir campos de nivel de clase y multi-threading? Cierres? ¿Ayudaría si sabemos que para el conjunto X de todos los valores posibles para x, |X| < 50?

De la sugerencia de @Vladimir Perevalov, ¿cómo podrían los conceptos en Pex pueden aplicar a la búsqueda de posibles valores para el código de puntos específicos (en lugar de lo Pex parece hacer lo que es descubrir las rutas de código y los valores que conducen a sin marcar (?) casos excepcionales)?

+1

+1. No crea que es un "deber" de análisis estático adivinar la posible falla/éxito del rango de valores del parámetro especificado, es más probable que sea el "deber" del "análisis dinámico". Pero incluso si es así, en * este * caso solo se trata de una * pareja * de parámetros, ¿qué ocurre si se ocupa de una función, por ejemplo, 'IEnumerable GetValuesForx (...) '? – Tigran

+0

@Tigran: ejecutar o simular el programa (o fragmento) no es una opción. Además, es evidente que hay ALGUNOS casos en que el análisis estático puede proporcionar la respuesta, y es evidente que ALGUNOS casos en los que no podría hacerlo. Intento identificar y alcanzar los casos donde podría. –

Respuesta

3

Hay un proyecto que hace lo que quiere (al menos muy cerca). Es Pex. Intenta mirar sus documentos, también podrías descompilar las fuentes y ver qué hacen.

+0

Buena idea, no había considerado Pex. ¿Pex es el único de su tipo? ¿Hay algo más pequeño que Pex? –

+0

No conozco otras herramientas que hagan cosas realmente similares. Al igual que encontrar automáticamente casos de esquina, etc. –

+0

"descompilar las fuentes [¿código objeto?] Y ver qué hacen?" I Si te refieres a "código objeto" y lo dices en serio, simplemente estás loco. Este es un problema difícil y la ingeniería inversa de la solución sofisticada de otra persona es lo último que debería intentar. –

3

Lo que desea es un análisis de flujo de datos global ("qué asignaciones de valor/efectos secundarios alcanzan qué puntos de uso") [que requiere análisis de flujo de control como precursor] y algún tipo de análisis de rango ("resumiendo el conjunto de valores que pueden alcanzar un punto ").

El flujo de datos de computación requiere tener un extremo frontal completo de C#, control local y análisis de flujo de datos, y luego unir esas respuestas en un análisis de flujo de datos global.

El análisis de rangos requiere primero definir cómo piensa codificar el conjunto de valores posibles; ¿Qué sistema de especificaciones está permitido? El más simple, solo un conjunto de valores, tiende a explotar. Un esquema de especificación intermedio sería algo así como la sola relación-a-constante del OP, por ejemplo, "x < 50". El problema con un esquema tan limitado es que la riqueza del conjunto de valores puede hacer que obtengas respuestas inútiles, especialmente si hay otros predicados de interés (si x es siempre impar, el modelo de relación simple a constante solo puede modelar esto como "x < infinito" que claramente no es útil. Por lo tanto, desea elegir un esquema de especificación que sea lo suficientemente complicado como para modelar los tipos de valores que le interesan. Sin embargo, a medida que su esquema de especificación se vuelve más sofisticado, correctamente obtener más complicado, por lo que no puede hacer que sea demasiado complicado

Sobre todo el herramientas de análisis disponibles no tienen este tipo de análisis, y mucho menos expuesta para que se PEX de hecho puede tener dicha maquinaria;.. Si tienes suerte está expuesto, también.

Nuestro DMS Software Reengineering Toolkit tiene un análisis genérico, creación de tablas de símbolos, análisis de control/flujo de datos e incluso maquinaria de análisis de rango (especificación: x < k1 * a + k2 * b donde k1 y k2 son constantes, a y b son otras variables de programa visibile donde x se consume). DMS tiene interfaces frontales C#, Java, GNU C y COBOL, y de hecho hemos instanciado esta maquinaria para GNU C e IBM Enterprise COBOL (y parcialmente para Java 7) recopilando datos (análisis estático!) Específicos de esos idiomas y alimentando estos hechos a la maquinaria genérica. No hemos instanciado esta maquinaria para C#, todavía. Pero si no puede obtener una buena respuesta de otra fuente, es probable que esté muy cerca.

+0

Temas de interés –

+0

Pude llegar bastante lejos con MSR Roslyn. Lo utilicé hasta el punto de analizar el AST e hice mi propio razonamiento (defectuoso) sin mucho esfuerzo. Creo que Roslyn puede hacer más por mí, pero no está bien documentada. Fue suficiente para una prueba de concepto. Podría consultar con su empresa si este proyecto continúa. –

+0

Supongo que Roslyn hace poco análisis de flujo global. Según lo entiendo, C# es principalmente un compilador JIT. –

Cuestiones relacionadas