Ich suche nach einem Tool, das C/C++-Code unter Windows analysiert und in der Lage sein sollte, Lese- und Schreibzugriffe auf Variablen durch verschiedene Funktionen zu erfassen. Zum Beispiel:
//in file1.c
extern int a;
write_to_a(){
a = 1;
}
// in file2.c
extern int a;
write_to_a_again(){
a = 5;
}
Das Tool sollte sagen, dass die Variable "a" in diese beiden Funktionen geschrieben wurde.
Dieses Tool sollte einen Fall wie das Übergeben von Zeigern oder Verweisen auf Funktionen abdecken. Zum Beispiel:
int *p;
*p =2;
functionA(p); // function call
void functionA(int k) // function definition
{
k++;
}
Im obigen Beispiel sollte das Tool sagen können, dass die Variable "p" geändert wurde.
Es sollte auch in der Lage sein, objektorientiertes Verhalten zu erfassen. Zum Beispiel:
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;
}
Im obigen Beispiel sollte es in der Lage sein zu erkennen, dass Beta die Variable/das Objekt ist, in das geschrieben wird, und nicht nur ObjektAB, da wir den Wert von objectAB in der Instanz beta von objB ändern. Es wäre auch großartig, wenn das gleiche Tool so etwas wie eine API-Bibliothek hätte, die ich verwenden könnte, damit es mit den darin enthaltenen Informationen macht, was ich will.
Ich habe einige Tools wie das Understand-Tool v4.0 von Scitools verwendet, aber es erfasst dies nicht.
irgendwelche Vorschläge?
OP scheint ein Tool zu wollen, das für jede Variable erzeugt, welche Funktionen sie lesen und welche Funktionen sie schreiben können.
Das ist gleichbedeutend mit einem Werkzeug, das für jede Funktion berechnet, welche Variablen sie richtig sein könnte und welche Variablen sie schreiben könnte. Ich werde diese Informationen die "Nebenwirkungen" der Funktion nennen.
Wenn Sie genau darüber nachdenken, werden Sie feststellen, dass Sie eigentlich wissen möchten, welche Nebenwirkungen es im Kontext der spezifischen Aufrufkette von der Wurzelmethode hat (wenn A B mit einem Parameter aufruft, der auf C zeigt, B jedoch nicht keinen direkten Bezug zu C haben, dann könnte B im Kontext eines Aufrufs von A Nebeneffekte auf C haben. Wenn P B mit einem Zeiger auf X aufruft, kann B C im Aufrufkontext von P nicht beeinflussen.
Eine konservativere Antwort liefert Nebeneffekte für alle möglichen Aufrufketten zurück zur Wurzel. In der konservativeren Version sagen wir, weil B entweder von A oder P aufgerufen werden kann und bei einigen Aufrufen C modifizieren kann, die Nebeneffekte ("ohne Aufrufkontext") von B (schreibt in) C.
Unser DMS Software Reengineering Toolkit mit seinem C-Frontend kann die Nebeneffekte mit vollem Aufrufkontext für eine große Menge verknüpfter C-Quellen berechnen.
Unter Verwendung des C-Frontends analysiert DMS den Quellcode (Erweitern von Präprozessordirektiven mit dem C-Frontend-Präprozessor) und erstellt ASTs für den betreffenden Satz von Kompilierungseinheiten. Jede CU wird namentlich aufgelöst, und jede Funktion wird dann auf Steuer- und Datenflüsse analysiert. Die resultierenden Datenflüsse werden verwendet, um eine konservative Obergrenze dafür abzuschätzen, wie Zeiger von den Funktionen kopiert werden können. DMS kann dann den Graphen für direkte Aufrufe mit dem Graphen für indirekte mögliche Aufrufe und die Informationen zu lokalen Nebeneffekten zusammenstellen und einen transitiven Abschluss berechnen. Dieser transitive Abschluss liefert die Lese- und Schreibanalyse für jede Funktion als eine Reihe benannter Deklarationen, die von der Funktion gelesen oder geschrieben werden können .
Dies ist eine ziemlich komplexe Übung zum Einrichten und Ausführen, und die Berechnung für große Anwendungen kann teuer sein (Wir haben dies mit 50.000 Funktionen in einem C-System mit 16 Millionen Zeilen ausgeführt; es hat 90 GB VM gefressen; glücklicherweise war sein Seitenverhalten bemerkenswert lokal und wir kamen mit 16 GB physisch aus).
Derzeit analysiert DMS C++ und kann die Kontrollflussinformationen sowie funktionslokale Datenflussinformationen und Nebeneffekte berechnen . Wir sammeln noch nicht genügend interprozedurale Datenflussfakten, um die transitive Closure-Engine zu füttern. SO DMS kann dies für C++ nicht tun, wobei der vollständige Aufrufkontext berücksichtigt wird.
Sie können CppDepend und seine Abhängigkeitsmatrix ausprobieren, die alle Abhängigkeitszyklen zwischen Namespaces und Klassen melden.
Ira Baxter
Saitiku
Ira Baxter
Saitiku
Thomas Weller