2012-05-06 5 views
5

decir que hay dos métodos en mi biblioteca:¿Qué herramienta de análisis estático utilizar para escanear el flujo de datos de un método a otro?

void com.somepackage.SomeClass.someSink(String s)

y

int com.someotherpackage.SomeOtherClass.someSource(int i)

El primer método se utiliza como sumidero de datos, mientras que el segundo como una fuente de datos en mi código . Los parámetros de tipo int, String se acaban de dar como ejemplo y pueden cambiar en la situación real.

quiero para detectar el uso de estos métodos en un código que satisfacen un cierto patrón se indica a continuación:

  1. algunos datos (por ejemplo x) es generada por la fuente
  2. algunos datos (por ejemplo y) se genera utilizando una serie de transformaciones f1(f2(... fn(x))
  3. y se entrega al receptor.

Las transformaciones pueden ser cualquier función arbitraria, siempre que exista una secuencia de llamadas desde la función que genera los datos del receptor a una función que toma datos de la fuente. Las funciones también pueden tomar otros parámetros y se deben usar como caja negra.

El escaneo puede realizarse en el nivel de código fuente o byte. ¿Cuáles son las herramientas disponibles para este tipo de análisis?

Prefiera las herramientas no basadas en IDE con las API de Java.

[EDIT:] para aclarar más, someSink y someSource son nombres métodos arbitrarios en las clases de SomeSome y SomeOtherClass respectivamente. Pueden o no ser static y pueden tomar un número arbitrario de parámetros (que yo debería ser capaz de definir). El tipo de los parámetros tampoco es arbitrario. El único requisito es que la herramienta escanee el código y los números de línea de salida donde ocurre el patrón. Por lo tanto, la herramienta podría funcionar de esta manera:

  • Obtenga el receptor y los nombres de fuente (nombre completo de clase y nombre de método) del usuario.
  • escanear estáticamente el código y encontrar todos los lugares donde el fregadero y fuente dada se utilizan
  • Comprobar si un camino existe, donde se da una cierta salida de datos de la fuente al sumidero, ya sea directa o indirectamente a través de una serie de operaciones (operadores, métodos)
  • Ignore esas fuentes/sumideros donde no existe tal ruta y genere las restantes (si las hay).

Ejemplo de salida:

MyClass1.java:12: value1 = com.someotherpackage.SomeOtherClass.someSource(...) 
MyClass2.java:23: value2 = foo(value1, ...) 
MyClass3.java:3: value3 = bar(value2) 
MyClass4.java:22: com.somepackage.SomeClass.someSink(value3, ...) 

Nota: Si una función no toma parámetros, pero tiene algunos efectos secundarios de los datos también debe tenerse en cuenta. (El ejemplo a = source(); void foo(){ c = a+b }; foo(); sink(c) es un patrón que debe capturarse.)

+0

¿Estás describiendo qué es un diagrama de secuencia UML? Si es así, entonces hay muchas herramientas (principalmente comerciales) para hacer esto. – mazaneicha

+0

Es un subconjunto del diagrama de secuencia que satisface los criterios de 'dependencia de datos'. – Jus12

+0

¿Entonces todo lo que realmente quieres es que la segunda clase tenga alguna dependencia indirecta de datos con la primera? –

Respuesta

3

Después de hacer algunas investigaciones, considero que soot es el más adecuado para este tipo de tareas. El hollín es más maduro que otras alternativas de código abierto como PQL.

2

lo tanto, el papel de los métodos de fuente y sumidero es simplemente que x se origina en la técnica de la fuente (en algún lugar) y se consume (en algún lugar) en el método de destino? ¿Cómo se caracteriza "x", o simplemente quiere todas las x que tienen esta propiedad?

Suponiendo que haya identificado una x específicas en la técnica de la fuente, lo que a) insistir en que x ser pasado al método de destino única mediante llamadas a métodos [que haría que el método de destino la última llamada en su cadena de llamadas ], o se puede copiar uno de los valores intermedios? b) insisten en que cada llamada a función tiene exactamente un argumento?

hemos hecho algo como esto para sistemas grandes C. El problema era rastrear una variable asignada a un uso en otras funciones donde quiera que estuvieran, incluyendo valores no idénticos en la representación pero idénticos en la intención ("copia abstracta"; la cadena "1.0" es en abstracto equivalente al entero 1 si yo uso la cadena finalmente como un número; "int_to_string" es una función de "copia abstracta" que convierte un valor en una representación en un valor equivalente en otro.).

Lo que necesitamos para esto es un análisis de definiciones de alcance para cada función ("¿A dónde va el valor de una asignación específica?") Y un análisis de "copia abstracta" que determina dónde se consume un valor de alcance funciones etiquetadas como "copias abstractas", y donde el resultado de esa función de copia abstracta llega a. Luego, un cierre transitivo de "x alcanza z" y "x alcanza f (x) alcanza z" calculado donde x puede ir.

Lo hicimos uso de nuestro DMS Software Reengineering Toolkit, que proporciona análisis genérico y maquinaria análisis de flujo, y DMS de C Front End, que implementa el alcance y abstracto-copia alcance cálculos para C. DMS tiene un Java Front End que calcula las definiciones de alcance específico; uno debería haber agregado la lógica de alcanzar la copia absoluta y volver a implementar el código de cierre transitivo.

+0

Cada función llamada puede tener cualquier cantidad de parámetros. El tipo de devolución también puede ser cualquier cosa. He actualizado mi pregunta. Por favor, hágame saber si esto lo aclara. – Jus12

+0

¿Existe una alternativa al juego de herramientas DMS? Preferiblemente algo de código abierto. – Jus12

+0

Bueno, está la API del compilador de Java, y está Wala. Estos pueden tener algunas capacidades de análisis de flujo. Pero creo que quieres un análisis de flujo entre los métodos en las clases, y no estoy seguro de cuánto apoyo brindan para eso. Ofrezco DMS porque es lo que sé, y porque hemos visto antes este tipo de problema y es lo que pretendemos que soporte una herramienta como DMS. –

Cuestiones relacionadas