Was sind einige statische C/C++-Analysetools zum Auffinden von Abhängigkeiten im Code?

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?

Der Versuch, Ihre Anforderungen zu klären: Ich denke, was Sie suchen, sind "Nebenwirkungen einer Funktion F". Man kann das feststellen, indem man F auf seine direkten Nebenwirkungen untersucht (wenn es über einen Parameter p vom Typ int speichert, könnte wohl jedes int im System beeinflusst werden) und dies mit den Nebenwirkungen von allem kombinieren, was es aufruft (rekursiv/fixpoint). . Haben Sie Auswirkungen auf Systemressourcen? zB machen Sie ein fseek; Die Position der Datei wird seitlich beeinflusst, ja oder nein? Eine Variation ist "Nebenwirkungen von F im Kontext"; dann können nur die Entitäten beeinflusst werden, auf die der Parameter p zeigt.
Ich bin mir nicht sicher, ob ich es die Nebenwirkungen nennen sollte. Sie haben Recht, wenn Sie Folgendes sagen: "Man kann dies feststellen, indem man F auf seine direkten Nebenwirkungen untersucht (wenn es über einen Parameter p vom Typ int speichert, könnte wohl jedes int im System beeinflusst werden) und dies mit den Nebenwirkungen von kombinieren alles, was es aufruft (rekursiv/Fixpunkt)" Also brauche ich wohl ein Tool, das mir sagen kann, welche Methoden den in einem Objekt/einer Variablen gespeicherten Wert beeinflussen. Und ob diese Methoden die betreffende Variable / das betreffende Objekt lesen oder schreiben. irgendwelche Vorschläge?
Was Sie also wollen, ist ein Tool, das eine Liste von Funktionen erstellt, die lesen können und welche eine Variable beeinflussen können? (Das scheint das Äquivalent/Transponieren eines Tools zu sein, das Ihnen sagen kann, welche Variablen eine Funktion lesen kann und welche sie ändern/nebenwirken kann. Ich kann Ihnen von einem Tool erzählen, das letzteres tut).
Ich würde gerne etwas über das Tool wissen, auf das Sie sich beziehen.
Ich habe CppDepend selbst nicht verwendet, nur das .NET-Äquivalent NDepend. Sehen Sie sich die 14-tägige Testversion von cppdepend.com an

Antworten (2)

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.

kontaktierte DMS, laut denen bieten sie Pakete an, mit denen ich ein Tool bauen kann, das meine Anforderungen erfüllen kann. Ich suche ein Werkzeug, das bereits hergestellt wurde. Ich möchte kein neues Tool machen. Ich hoffe du verstehst es jetzt.
Hmm. Ihre Frage ist unklar, ob Sie dies für C oder C++ (sie sind nicht dieselbe Sprache) oder beides tun möchten. AFAIK, DMS mit seinem C-Frontend führt Nebeneffektanalysen für C durch. Wenn Sie dies für C++ wollen, müssen Sie auf der lokalen Flussanalyse von DMS aufbauen, stimmt.
Ich hatte gehofft, die Leute würden es herausfinden, indem sie sich denselben Code ansehen, den ich gepostet habe. Daher benötige ich beides.
@lucosias Der von Ihnen gepostete Code scheint vollständig C ++ zu sein oder zumindest in C ++ gültig zu sein.

Sie können CppDepend und seine Abhängigkeitsmatrix ausprobieren, die alle Abhängigkeitszyklen zwischen Namespaces und Klassen melden.Geben Sie hier die Bildbeschreibung ein