Ist es sicher, sich auf statische Analysen zu verlassen, um Parallelitätsfehler zuverlässig zu „reproduzieren“?

8

Ich habe Java-Code geerbt, von dem ich vermute, dass er bei der Synchronisierung zwischen einem Thread, der Daten abfragt, und einem E / A-Ereignis, das dieselben Daten aktualisiert, einige Parallelitätsfehler aufweist. Ich probiere ein statisches Analysetool namens ThreadSafe aus, das tatsächlich verschiedene Parallelitätsprobleme erkennt (dh ein Feld, auf das über eine asynchron aufgerufene Methode ohne Synchronisation und inkonsistente Synchronisation der Zugriffe auf eine Sammlung zugegriffen wird).

Nachdem ich herausgefunden hatte, wie schwierig es ist, Datenrennen durch Schreiben von Komponententests zuverlässig zu reproduzieren, fragte ich mich, ob es ratsam ist, sich auf ThreadSafe zu verlassen, um die Fehler zuverlässig zu "reproduzieren". Was ich frage ist, ist es sicher, sich auf das statische Analysetool zu verlassen, um mir zu sagen, wann ich die Fehler behoben habe? (Um die Fehler zu beheben, muss ich natürlich jeden im Kontext verstehen).

Doughgle
quelle
6
Mit anderen Worten, Ihre Frage lautet also: "Hat die statische Analyse falsche Negative?".
@delnan: EXTREM überzeugender, einfühlsamer Kommentar. +100 wenn ich könnte.
John R. Strohm

Antworten:

3

Beantwortung Ihrer ersten Frage:

http://www.contemplateltd.com/threadsafe/faq#non-checkers

"Nach welchen Arten von Parallelitätsfehlern sucht ThreadSafe nicht?

  • Wir bieten noch keine Unterstützung für alle java.util.concurrent. Insbesondere prüft ThreadSafe nicht, ob die erweiterten Synchronisierungsfunktionen von java.util.concurrent, z. B. das Paket java.util.concurrent.atomic, missbraucht werden. Derzeit sind auch keine Prüfer auf Fehler enthalten, die beim Schreiben paralleler Programme mit dem Fork-Join-Framework auftreten können.

  • Das Auffinden von Fehlern in komplexen Algorithmen ohne Sperren erfordert eine Analysetechnologie, die nicht gut skaliert werden kann. Solche Algorithmen sollten spezialisierten Parallelitätsexperten überlassen werden. ThreadSafe kann so konfiguriert werden, dass Fehler in Anwendungen gefunden werden, die Bibliotheken verwenden, die solche Algorithmen enthalten.

  • Welche Analysen wir in neuen Versionen von ThreadSafe aufnehmen, hängt sowohl davon ab, was mit einer Analysetechnologie möglich ist, die für die Integration in ein verwendbares Produkt ausgereift ist, als auch von den Funktionen und Parallelitätsfehlern, die wir häufig in "durchschnittlichen" Java-Programmen sehen.

  • Wenn Sie ein Java-Parallelitätsproblem haben, das derzeit nicht von ThreadSafe behandelt wird, können die Java-Parallelitätsspezialisten von Contemplate möglicherweise helfen, indem sie ThreadSafe eine benutzerdefinierte Konfiguration hinzufügen und / oder erweiterte Analysetechnologien verwenden, die für die Integration in ThreadSafe noch nicht ausgereift genug sind. ""

Den
quelle
1
Hinweis für sich selbst: RTFM! Dies beantwortet meine Frage.
Doughgle
8

Nach meiner Erfahrung kann ein entschlossener, gut gemeinter, aber ahnungsloser Entwickler einen Parallelitätsfehler so verschleiern, dass das Analysetool ihn übersehen wird.

Wenn das Tool glaubt, dass ein Fehler vorliegt, gehen Sie davon aus, dass er richtig ist, bis Sie das Gegenteil beweisen. Das ist der Wert des Werkzeugs. Wenn das Tool keine Fehler findet, tun Sie am besten so, als ob das Tool nicht vorhanden wäre.

Wenn Sie zuverlässigen gleichzeitigen Code (in einer beliebigen Sprache) wünschen, sollten Ihre Ziele Folgendes umfassen:

  1. Die kritischen Abschnitte sollten winzig und einfach sein, damit sie trivial zu verstehen sind.
  2. Die kritischen Abschnitte sollten auf Quellenebene vollständig von anderem Code isoliert sein .
  3. Eine Funktion / Methode / Unterroutine, die an gleichzeitigem Code beteiligt ist, sollte nur eines tun . Wenn es ein Synchronisationsprimitiv (Sperre, Semaphor usw.) manipuliert, sollte es NICHT mit einer der gemeinsam genutzten Ressourcen herumspielen und KEINE Schleifen oder bedingten Code enthalten. Verschieben Sie die "echte Arbeit" in eine separate Funktion. Dies unterstützt Punkt 1.
  4. Wenn Sie eine Sperre haben, sollte ein Entwickler in der Lage sein, den Code zu lesen und genau zu bestimmen , welche Ressource (n) diese Sperre innerhalb von 30 Sekunden oder weniger schützt. Wenn es Ihnen nicht klar ist, wird es dem nächsten Mann nicht klar sein. Und dem Kollegen, der den Code geschrieben hat, war es wahrscheinlich nicht klar. Also ist es wahrscheinlich kaputt.
  5. Die Sichtbarkeit der Ressource, die Sie schützen, sollte nicht größer sein als die Sichtbarkeit des Synchronisationsprimitivs, das sie schützt. Keine der Komponenten sollte für den größeren Code sichtbar sein.
  6. Usw. Der Rest der Liste ist wirklich nur eine Vielzahl von Möglichkeiten, die Punkte 1 und 2 neu zu formulieren.

Wenn Ihr Code richtig entworfen und organisiert ist, sollten Sie in der Lage sein, einen winzigen Teil des Codes zu betrachten, um die Parallelität zu verstehen und ihr zu vertrauen. Wenn Sie dieses Ziel zu erreichen, dann füttern Sie den Code zum statischen Analyse - Tool und sehen , ob es stimmt.

Und geben Sie den Code einigen anderen Nicht-Guru-Entwicklern zur Überprüfung. Bitten Sie sie zu erklären, wie die Parallelität funktioniert und warum sie korrekt ist. Wenn sie es nicht erklären können, ist es immer noch zu komplex.

GraniteRobert
quelle
2
etwas, das zu 4 hinzugefügt werden muss: Jede durch ein Schloss geschützte Ressource muss dokumentiert werden, dass sie durch das Schloss geschützt ist, und darf niemals außerhalb des Ortes verwendet werden, an dem das Schloss erworben wurde
Ratschenfreak
1
Etwas hinzuzufügen: 6) NIEMALS mehr als ein Schloss zu einem bestimmten Zeitpunkt erwerben und halten. 7) Wenn Sie unbedingt mehr als eine Sperre zu einem bestimmten Zeitpunkt erwerben und halten MÜSSEN, stellen Sie verdammt sicher, dass sie IMMER in derselben Reihenfolge erworben wurden. Wenn Prozess A und Prozess B beide Sperren Rot und Grün erwerben müssen, können sie blockieren, wenn einer der beiden zuerst Rot und der andere zuerst Grün erwirbt.
John R. Strohm
2

Um ein nützliches statisches Analysewerkzeug zu erstellen, müssen eine Reihe widersprüchlicher Bedenken abgewogen werden, darunter mindestens die folgenden:

  • Falsch positive (Fehlalarm-) Rate
  • Falsch negative Rate (nicht gefangener Fehler)
  • Laufzeit und Skalierbarkeit

False Positives sind ein kritisches Problem bei Tools zur Fehlererkennung, da sie Entwicklerzeit verschwenden. Es ist möglich, falsch negative Ergebnisse zu eliminieren, aber für viele Arten von Fehlern, einschließlich Parallelitätsfehlern, würde dies eine inakzeptable Erhöhung der Rate falsch positiver Ergebnisse bedeuten. Die Rate sowohl von falsch positiven als auch von falsch negativen Ergebnissen kann auf Kosten einer längeren Laufzeit verringert werden, aber die genauesten Analysetechniken lassen sich nicht über kleine Anwendungen hinaus skalieren, und sie können ohnehin nicht beide auf Null verringert werden.

Dynamische Analysetools geben häufig eine falsch positive Rate von 0% an. Dies liegt jedoch daran, dass sie Fehler erst dann finden, wenn sie tatsächlich auftreten. Für eine Rennbedingung oder einen Deadlock, der nur einmal in einem blauen Mond auftritt, ist das nicht so nützlich.

Aus diesen Gründen verspricht ThreadSafe nicht, alle Parallelitätsfehler zu finden - es zielt darauf ab, die wichtigsten mit einer niedrigen Falsch-Positiv-Rate zu finden. Einige Benutzer haben ThreadSafe für Code mit einem bekannten Parallelitätsfehler ausprobiert, den sie tagelang gesucht haben, und festgestellt, dass dieser Fehler - und häufig andere echte Fehler, von denen sie nichts wussten - innerhalb von Minuten ohne Fehlalarme gefunden wurden.

Ein guter Ausgangspunkt für Informationen zu ThreadSafe ist dieser InfoQ-Artikel . Weitere Informationen finden Sie auf der ThreadSafe-Website, auf der Sie sich für eine kostenlose Testversion anmelden können.

(Offenlegung: ThreadSafe ist ein kommerzielles Tool und ich bin Mitbegründer von Contemplate, dem Unternehmen, das es produziert.)

dsannella
quelle