¿Cuáles son algunas herramientas de análisis estático de C/C++ para encontrar dependencias en el código?

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?

Intentando aclarar sus requisitos: creo que lo que está buscando son "efectos secundarios de una función F". Uno puede determinar eso al inspeccionar F por sus efectos secundarios directos (si se almacena a través de un parámetro p de tipo int, podría decirse que cualquier int en el sistema podría verse afectado) y combinándolo con los efectos secundarios de todo lo que llama (recursivo/punto fijo) . ¿Tiene efectos sobre los recursos del sistema? por ejemplo, haces una fseek; la posición del archivo se ve afectada, ¿sí o no? Una variación es "efectos secundarios de F en contexto"; entonces sólo se pueden efectuar las entidades señaladas por el parámetro p.
No estoy seguro de si debería llamarlo los efectos secundarios. Tiene razón cuando dice esto: "Se puede determinar eso al inspeccionar F en busca de sus efectos secundarios directos (si se almacena a través de un parámetro p de tipo int, podría decirse que cualquier int en el sistema podría verse afectado) y combinándolo con los efectos secundarios de todo lo que llama (recursivo/punto fijo)" Entonces, supongo que necesito una herramienta que pueda decirme cuáles son los métodos que afectan el valor almacenado en un objeto/variable. Y si estos métodos leen o escriben en la variable/objeto en cuestión. ¿alguna sugerencia?
Entonces, ¿lo que quiere es una herramienta que produzca una lista de funciones que pueda leer y cuáles pueden afectar una variable? (Eso parece el equivalente/transposición de una herramienta que puede decirle qué variables puede leer una función y cuáles puede modificar/efecto secundario. Puedo informarle sobre una herramienta que hace lo último).
Me gustaría saber sobre la herramienta a la que te refieres.
No he usado CppDepend yo mismo, solo el equivalente de .NET NDepend. Echa un vistazo a la versión de prueba de 14 días de cppdepend.com

Respuestas (2)

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.

se puso en contacto con DMS, según ellos, proporcionan paquetes con los que puedo construir una herramienta que puede cumplir con mis requisitos. Estoy buscando una herramienta que ya se ha hecho. No quiero hacer una nueva herramienta. Espero que lo entiendas ahora.
Mmm. Su pregunta no está clara en cuanto a si desea hacer esto para C o para C++ (no son el mismo idioma) o ambos. AFAIK, DMS con su front-end C realiza análisis de efectos secundarios para C. Si desea esto para C ++, tendrá que construir sobre el análisis de flujo local de DMS, es cierto.
Esperaba que la gente lo descubriera mirando el mismo código que publiqué. Como tal, necesito ambos.
@lucosias El código que publicaste parece ser completamente C++, o al menos válido en C++.

Puede probar CppDepend y su matriz de dependencia que informa todos los ciclos de dependencia entre espacios de nombres y clases.ingrese la descripción de la imagen aquí