Holen Sie sich die neuesten wichtigen Update-Informationen für die Log4j-Sicherheitslücke. Sehen Sie sich an, wie Sie das Problem mithilfe der Parasoft-Anleitung beheben können. Erfahren Sie mehr >>

X
BLOG

Statische Analyse und Laufzeitfehlererkennung auf 64-Bit-Plattformen

Statische Analyse und Laufzeitfehlererkennung auf 64-Bit-Plattformen Lesezeit: 3 Minuten

In meinem Frühere BeiträgeIch habe eine vierstufige Strategie zur Vorbereitung der Anwendung für den 64-Bit-Portierungsprozess behandelt:

  1. Wenden Sie Mutationstests an, um eine Laufzeitfehlererkennung durchzuführen
  2. Verwenden Sie unsere Größentabelle, um die Rasse und das Gewicht Ihres Hundes einer der XNUMX verfügbaren Bettgrößen zuzuordnen. Wenn Sie Fragen zur Größe Ihres Hundes haben, können Sie sich gerne mit uns in Verbindung setzen. statische Code-Analyse um fehleranfälligen und nicht portablen Code zu identifizieren
  3. Wiederholen Sie die Laufzeitfehlererkennung
  4. Perform unit testing (Optional)

Zum Abschluss dieses Themas möchte ich eine Strategie zur Identifizierung von Fehlern auf dem 64-Bit-Prozessor vorstellen:

  1. Kompilieren Sie den Code auf dem 64-Bit-Prozessor neu
  2. Wiederholen statischer Analysecode Inspektion
  3. Verknüpfen und bauen
  4. Starten Sie die Anwendung
  5. Wiederholen Sie die Laufzeitfehlererkennung

Schritt 1: Kompilieren Sie den Code auf dem 64-Bit-Prozessor neu

Kompilieren Sie Ihre Anwendung auf dem 64-Bit-Prozessor neu. Wenn Sie Probleme beim Kompilieren haben, klären Sie alle Macken im Zusammenhang mit Compilervariationen. Vielleicht möchten Sie auch erstellen statische Code-Analyse Regeln, die den mit diesen Macken verbundenen Code automatisch identifizieren, damit Sie verhindern können, dass diese Kompilierungsprobleme in Zukunft auftreten.

Einige zu berücksichtigende Regeln weisen auf schwer zu portierende (auf 64 Bit) und fehleranfälligen Code hin. Betrachten Sie beispielsweise die folgenden Beispiele (weitere Details finden Sie hier Post):

Regeln, die fehleranfälligen Code verfügbar machen

  • Geben Sie niemals einen Verweis auf ein lokales Objekt oder einen dereferenzierten Zeiger zurück, der durch "new" innerhalb der Funktion initialisiert wurde.
  • Konvertieren Sie niemals eine Konstante in eine Nicht-Konstante. Dies kann die Datenintegrität untergraben, indem sich Werte ändern, die als konstant angenommen werden.
  • Wenn eine Klasse virtuelle Funktionen hat, muss sie einen virtuellen Destruktor haben. Dieser Standard verhindert Speicherlecks in abgeleiteten Klassen.
  • Öffentliche Mitgliedsfunktionen geben const-Handles an Mitgliedsdaten zurück.
  • Wenn Sie Mitgliedsdaten nicht konstante Handles bereitstellen, untergraben Sie die Kapselung, indem Sie Anrufern erlauben, Mitgliedsdaten außerhalb der Mitgliedsfunktionen zu ändern.
  • Ein Zeiger auf eine Klasse darf nicht in einen Zeiger einer zweiten Klasse konvertiert werden, es sei denn, er erbt von der zweiten. Dieses "ungültige" Downcasting kann zu Platzhaltern, Datenbeschädigungsproblemen und anderen Fehlern führen.
  • Greifen Sie nicht direkt von einem Konstruktor auf globale Daten zu.

Ein benutzerdefinierter Regelsatz kann erstellt werden, indem die kritischen Regeln ausgewählt werden, die nur für diese bestimmte Aufgabe benötigt werden. Weitere Regeln können später nach Bedarf hinzugefügt werden.

Regeln, die schwer zu portierenden Code verfügbar machen

Nachdem Sie diesen fehleranfälligen Code gefunden und repariert haben, suchen Sie nach Code, der auf Ihrer aktuellen Plattform / Architektur einwandfrei funktioniert, aber möglicherweise nicht gut portiert werden kann. Einige Regeln, die für die meisten 64-Bit-Portierungsprojekte gelten, umfassen:

  • Verwenden Sie gegebenenfalls Standardtypen.
  • Überprüfen Sie alle vorhandenen Verwendungen langer Datentypen im Quellcode.
  • Untersuchen Sie alle Fälle der Verengung der Zuordnung. Vermeiden Sie solche Zuweisungen, da die Zuweisung eines langen Werts zu einem int zum Abschneiden des 64-Bit-Werts führt.
  • Finden Sie verengte Abgüsse. Verwenden Sie schmalere Umwandlungen für Ausdrücke, nicht für Operanden.
  • Finde Casts von long * bis int *. In einer 32-Bit-Umgebung wurden diese möglicherweise synonym verwendet. Untersuchen Sie alle Instanzen inkompatibler Zeigerzuweisungen.
  • Finde Casts von int * bis long *. In einer 32-Bit-Umgebung wurden diese möglicherweise synonym verwendet. Untersuchen Sie alle Instanzen inkompatibler Zeigerzuweisungen.
  • Suchen Sie lange Werte, die mit int-Literalen initialisiert werden. Vermeiden Sie solche Initialisierungen, da Integralkonstanten möglicherweise als 32-Bit-Typen dargestellt werden, selbst wenn sie in Ausdrücken mit 64-Bit-Typen verwendet werden.
  • Suchen Sie int-Literale in binären Operationen, für die das Ergebnis einem langen Wert zugewiesen ist. Eine 64-Bit-Multiplikation ist erwünscht, wenn das Ergebnis ein 64-Bit-Wert ist.
  • Suchen Sie nach int-Konstanten, die in 64-Bit-Ausdrücken verwendet werden. Verwenden Sie 64-Bit-Werte in 64-Bit-Ausdrücken.
  • Suchen Sie nach Verwendungen multiplikativer Ausdrücke, die in keinem der Operanden einen 64-Bit-Typ enthalten. Damit integrale Ausdrücke 64-Bit-Ergebnisse erzeugen, muss mindestens einer der Operanden einen 64-Bit-Datentyp mit oder ohne Vorzeichen haben.
  • Verwenden Sie geeignete Suffixe für ganzzahlige und schwebende Literalkonstanten, wenn Ihr Compiler dies zulässt.

Schritt 2: Wiederholen Sie die Überprüfung des statischen Analysecodes

Sobald Sie den Code neu kompiliert haben, führen Sie statische Code-Analyse erneut, um zu überprüfen, ob der neue Code allen geeigneten Codierungsstandards entspricht. Zu diesem Zeitpunkt ist jede Änderung, die hätte vorgenommen werden sollen, aber nicht vorgenommen wurde, ein Fehler. Beheben Sie diese Fehler sofort! Sie möchten nicht nach diesen Fehlern suchen, während die Anwendung ausgeführt wird.

Schritt 3: Verknüpfen und erstellen

Verknüpfen Sie Ihre Anwendung und versuchen Sie, sie zu erstellen.

Schritt 4: Starten Sie die Anwendung

An diesem Punkt sollten Sie versuchen, Ihren Code auszuführen. Wenn Sie Probleme haben, Code auf dem 64-Bit-Prozessor auszuführen, verwenden Sie a Unit-Test-Framework den Code Funktion für Funktion ausführen; Auf diese Weise können Sie genau das spülen, was im Code nicht portierbar ist. Testen Sie die Funktion und beheben Sie das Problem. Setzen Sie diesen Vorgang fort, bis die gesamte Anwendung ausgeführt wird.

Schritt 5: Wiederholen Sie die Laufzeitfehlererkennung

Sobald die Anwendung ausgeführt wird, sollten Sie die Erkennung von Laufzeitfehlern wiederholen, da der Portierungsprozess wahrscheinlich einige neue Probleme verursacht, die vor dem Port nicht erkannt werden konnten (z. B. neue Speicherbeschädigungsprobleme oder anderes Verhalten). Wenn bei der Erkennung von Laufzeitfehlern Probleme auftreten, beheben Sie alle Fehler im Zusammenhang mit der Portierung.

***
Photo Credit: Jurvetson

Möchten Sie mehr erfahren? Schauen Sie sich unsere an Parasoft Insure ++Auf der Produktseite erfahren Sie, wie die Erkennung von Laufzeitfehlern Speicherbeschädigungen, Speicherlecks, Zugriff außerhalb der Array-Grenzen, ungültige Zeiger und andere Fehler aufdecken kann.

Geschrieben von

Parasoft

Die branchenführenden automatisierten Softwaretest-Tools von Parasoft unterstützen den gesamten Softwareentwicklungsprozess, vom Schreiben der ersten Codezeile über Unit- und Funktionstests bis hin zu Leistungs- und Sicherheitstests, wobei simulierte Testumgebungen genutzt werden.

Erhalten Sie die neuesten Nachrichten und Ressourcen zum Testen von Software sofort.