Estoy buscando una herramienta que analice el código C/C++ en Windows y debería poder capturar lecturas y escrituras en variables mediante diferentes funciones. Por ejemplo:
//in file1.c
extern int a;
write_to_a(){
a = 1;
}
// in file2.c
extern int a;
write_to_a_again(){
a = 5;
}
La herramienta debe decir que la variable "a" fue escrita en estas dos funciones.
Esta herramienta debería cubrir un caso como pasar punteros o referencias a funciones. Por ejemplo:
int *p;
*p =2;
functionA(p); // function call
void functionA(int k) // function definition
{
k++;
}
En el ejemplo anterior, la herramienta debería poder decir que la variable "p" fue modificada.
También debería ser capaz de capturar el comportamiento orientado a objetos. Por ejemplo:
class objA{
int integer_objA;
char characterA;
public:
void increment_integer(){
integer_objA++;
}
void print_this(){
std::cout<<integer_objA<<"\n";
std::cout<<characterA<<"\n";
}
void write_this(){
std::cin>>integer_objA;
std::cin>>characterA;
}
};
class objB{
int integer_objB;
objA objectAB; // instance of class objA
public:
void increment_objectAB(){
objectAB.increment_integer();
}
void writeAB(){
objectAB.write_this();
}
void readAB(){
objectAB.print_this();
}
};
int main(){
objB beta;
std::cout<<"Enter a number and then a character: ";
beta.writeAB();
// increments the value of objectAB
// this also means that beta has now changed because
// one of its member object has changed
beta.increment_objectAB();
beta.readAB();
return 0;
}
En el ejemplo anterior, debería poder identificar que, dado que cambiamos el valor de objectAB, dentro de la instancia beta de objB, beta es la variable/objeto en el que se escribe y no solo objectAB. También sería genial si la misma herramienta tuviera algo así como una biblioteca API que pueda usar para que haga lo que quiero con la información que tiene.
He usado algunas herramientas como la herramienta Understand v4.0 de Scitools, pero no captura esto.
¿alguna sugerencia?
OP parece querer una herramienta que produzca para cada variable, qué funciones pueden leerla y qué funciones pueden escribirla.
Eso es equivalente a una herramienta que calcula, para cada función, qué variables podría corregir y qué variables podría escribir. Voy a llamar a esta información los "efectos secundarios" de la función.
Si piensa en esto detenidamente, se dará cuenta de que en realidad quiere saber qué efectos secundarios tiene en el contexto de la cadena de llamadas específica del método raíz (si A llama a B con un parámetro que apunta a C, pero B no no tiene ninguna referencia directa a C, entonces B podría afectar a C en el contexto de una llamada de A. Si P llama a B con un puntero a X, B no puede afectar a C en el contexto de llamada de P.
Una respuesta más conservadora proporciona efectos secundarios para todas las posibles cadenas de llamadas hasta la raíz. En la versión más conservadora, debido a que B puede llamarse desde A o P, y en alguna llamada puede modificar C, decimos que los efectos secundarios ("sin contexto de llamada") de B son (escribe en) C.
Nuestro kit de herramientas de reingeniería de software DMS con su C Front End puede calcular los efectos secundarios con un contexto de llamada completo para un gran conjunto de fuentes C vinculadas.
Con el front-end de C, DMS analiza el código fuente (expandiendo las directivas del preprocesador con el preprocesador del front-end de C) y crea AST para el conjunto de unidades de compilación en cuestión. El nombre de cada CU se resuelve y cada función se analiza para el control y los flujos de datos. Los flujos de datos resultantes se utilizan para estimar un límite superior conservador sobre cómo las funciones pueden copiar los punteros. Luego, DMS puede componer el gráfico de llamadas directas, con el gráfico de posibles llamadas indirectas y la información de efectos secundarios locales y calcula un cierre transitivo. Ese cierre transitivo proporciona el análisis de lecturas y escrituras para cada función como un conjunto de declaraciones nombradas que la función puede leer o escribir .
Este es un ejercicio bastante complejo de configurar y ejecutar, y puede ser costoso de calcular para aplicaciones grandes (ejecutamos esto en 50 000 funciones en un sistema C de 16 millones de líneas; consumía VM de 90 Gb; afortunadamente, su comportamiento de página era notablemente local y nos las arreglamos con 16Gb físicos).
En la actualidad, DMS analiza C++ y puede calcular la información del flujo de control y la información del flujo de datos local de la función y los efectos secundarios . Todavía no recopilamos suficientes datos de flujo de datos entre procedimientos para alimentar el motor de cierre transitivo. SO DMS no puede hacer esto para C++ aún teniendo en cuenta el contexto de llamada completo.
Puede probar CppDepend y su matriz de dependencia que informa todos los ciclos de dependencia entre espacios de nombres y clases.
Ira Baxter
Saitiku
Ira Baxter
Saitiku
Tomás Weller