Parasoft
MISRA C:2023 – das ist neu
MISRA C:2023 ist veröffentlicht! Mit dem Standard lässt sich Software ‚safe & secure’ erstellen. Doch was bringt die neue Version mit sich? Welche neuen Regelungen gibt es?
Nach der Veröffentlichung von MISRA C:2012 Amendment 4 im März 2023 wurde im Mai das lang erwartete Release MISRA C:2023 von der MISRA Organisation veröffentlicht. Dabei handelt es sich um die dritte Ausgabe und zweite Revision des MISRA C-Standards. Sie aktualisiert und beinhaltet die MISRA C:2012 Amendments 2 - 4 und das Technical Corrigendum 2. Mit ihr haben die Embedded-Industrie und Software-Teams, die C-Sprachversionen nach ISO/IEC 9899:2011 (C11) und ISO/IEC 9899:2018 (C18) entwickeln, einen aktualisierten C-Codierungsstandard, der weiterhin auf Sicherheitslücken in der C-Sprache abzielt. Parasoft engagiert sich im Standardisierungsprozess und ist Mitglied der MISRA C und C++ Arbeitsgruppen. Die Softwaretest- lösung C/C++test 2023 bietet die vollständige Abdeckung für MISRA C:2023 und das Vorgängermodell MISRA C:2012 AMD (Bild). Mit C/C++test 2023.1 können ab sofort statische Code-Analysen nach dem aktuellen Standard durchgeführt werden. So können Softwareentwickler sicherstellen, dass ihr Code dem aktuellen MISRA-Codierungsstandard entspricht.
Drei neue Richtlinien
Das Parasoft Compliance Reporting Modul stellt sicher, dass MISRA-konforme Berichte in Parasoft DTP verfügbar sind und Testergebnisse in intelligenten Dashboards, detaillierten Berichten und umsetzbaren Analysen konsolidiert werden.
© ParasoftMISRA C:2012 Amendment 4, sprich: MISRA C:2023, konzentriert sich auf Multithreading und die Anwendung von atomaren Funktionen. Insbesondere die in C11 eingebaute Unterstützung für Threads, atomare Operationen, gegenseitigen Ausschluss, Bedingungsvariablen und threadspezifischen Speicher. Multithreading ist die vom Betriebssystem unterstützte Fähigkeit einer CPU, mehrere Threads gleichzeitig auszuführen. Multithreading-Anwendungen können manchmal zu unvorhersehbaren Ergebnissen führen, da im Wesentlichen mehrere Teile eines Programms gleichzeitig ausgeführt werden. Beispielsweise treten unvorhersehbare Probleme auf, wenn Threads gemeinsam genutzte Daten lesen und schreiben. Deshalb ist die Synchronisation der Threads beim Multithreading so wichtig.
Es wurden drei neue Richtlinien zu Gleichzeitigkeitsbetrachtungen erstellt:
Richtlinie 5.1 besagt, dass kein Datenwettlauf zwischen Threads stattfinden darf. Daher müssen Threads durch einen Synchronisationsmechanismus geschützt werden. Es ist üblich, einen Mutex (wechselseitiger Ausschluss) oder eine Semaphore zu verwenden, um Datenwettläufe zu verhindern, z.B. Lese- und Schreibzugriffe auf die gleichen Daten zur gleichen Zeit. Threads, die Daten sperren, können jedoch ihre eigenen Probleme verursachen, weshalb die Richtlinie 5.2 festlegt, dass es keine Deadlocks zwischen Threads geben darf. Dies ist gleichbedeutend mit absolut keine zyklischen Abhängigkeiten zwischen Threads. Aufgrund der Ungewissheit, wie viele Threads zu einem bestimmten Zeitpunkt laufen, ist die Richtlinie 5.3 gerechtfertigt, nach der es keine dynamische Erzeugung von Threads geben darf. Das Anlegen von Threads ist nur beim Programmstart möglich.
Unterstützung von C11-Sprachmerkmalen
MISRA C:2012 AMD4 hat auch neue Regeln zur Unterstützung von C11-Sprachmerkmalen geschaffen, insbesondere für Threading und durch atomare Funktionen <stdatomic.h>. Die C11-Sprache hat eine Reihe von atomaren Typen und Operationen eingeführt, die es ermöglichen, portable Multithread-Software zu schreiben, die Objekte effizient, unteilbar und ohne Datenrennen handhabt. Um dies zu gewährleisten, schreibt die neue Regel 9.7 vor, dass atomare Objekte vor dem Zugriff entsprechend initialisiert werden müssen. Hier ist ein einfaches Beispiel unter Verwendung der Funktion atomic_init():
_Atomic int32_t ai3;
atomic_init(&ai3, 333); /* Compliant */
Die neue Regel 21.25 schreibt vor, dass alle Speichersynchronisations- operationen in sequentiell konsistenter Reihenfolge durchgeführt werden müssen. C11 bietet eine Reihe von Bibliotheksfunktionen, die implizit die strengste Variante der Speicher- anordnung „memory_order_seq_cst” verwenden.
- atomic_store()
- atomic_load()
- atomic_exchange()
- atomic_compare_exchange_strong()
- atomic_compare_exchange_weak()
- atomic_fetch_add()
- atomic_fetch_sub()
- atomic_fetch_or()
- atomic_fetch_xor()
- atomic_fetch_and()
- atomic_flag_test_and_set()
- atomic_flag_clear()
- atomic_thread_fence()
- atomic_signal_fence()
„memory_order_seq_cst“ stellt eine globale Lese- und Schreibreihenfolge zur Verfügung, und sequentiell konsistente Operationen sind in allen Threads in der gleichen Reihenfolge sichtbar.
Da ein Mutex stark von der Synchronisation abhängt, hat sich die MISRA-C-Arbeitsgruppe auch eingehend mit der Härtung der Verwendung von C11 mtx_timedlock() befasst. Die Funktion mtx_timedlock() blockiert den aktuellen Thread, bis der Mutex, auf den sie verweist, gesperrt ist oder bis ein angegebener Timeout abläuft. Wenn jedoch der aktuelle Thread den Mutex bereits blockiert hat und der Mutex nicht rekursiv ist oder er kein Timeout unterstützt, ist das Verhalten undefiniert. Daher besagt die neue Regel 21.26, dass die Standardbibliotheksfunktion mtx_timedlock() nur für Mutex-Objekte des entsprechenden Mutex-Typs aufgerufen werden darf. Das erste Argument der Funktion mtx_timedlock() muss ein Mutex-Objekt vom Typ mtx_timed oder ( mtx_timed | mtx_recursive ) sein. Damit dies funktioniert, muss das Mutex-Objekt korrekt initialisiert sein.
Die neue Regel 22.14 verlangt die Initialisierung der Synchronisationsobjekte von Threads vor dem Zugriff auf diese Objekte. Die Initialisierung aller Synchronisationsobjekte vor dem Erstellen der Threads, die darauf zugreifen, ist ein deterministischer Weg, um zu verhindern, dass Threads auf Synchronisationsobjekte mit unbestimmtem Zustand zugreifen. Die C11-Standardbibliotheksfunktion mtx_init() mit einem anderen Typparameterwert wie unten aufgeführt, gilt als undefiniertes Verhalten und ist nicht konform:
- mtx_plain – ein einfacher, nicht rekursiver Mutex.
- mtx_timed – ein nicht rekursiver Mutex, der Timeout unterstützt.
- mtx_plain | mtx_recursive – ein rekursiver Mutex.
- mtx_timed | mtx_recursive – ein rekursiver Mutex, der Timeout unterstützt.
Zusätzliche Regeln sollen sicherstellen, dass die Verwendung von Nebenläufigkeit oder Threads, die in C11 definiert sind, sicher ist, ebenso wie die Synchronisierung, Bedingungen und die thread-lokale Speicherung (Tabelle).
| thrd_create() | mtx_init() | cnd_init() | tss_create() |
|---|---|---|---|
| thrd_current() | mtx_lock() | cnd_signal() | tss_get() |
| thrd_sleep() | mtx_timedlock() | cnd_broadcast() | tss_set() |
| thrd_yield() | mtx_trylock() | cnd_wait() | tss_delete() |
| thrd_exit() | mtx_unlock() | cnd_timedwait() | thrd_join() |
| thrd_detach() | mtx_destroy() | cnd_destroy() |
Natürlich gibt es auch einige neue Regeln, die nichts mit Nebenläufigkeit zu tun haben. Zum Beispiel die obligatorische Regel 18.10, welche die Verwendung von Zeigern auf variabel modifizierte Array-Typen verbietet. MISRA C:2012 AMD 4 enthält insgesamt drei neue Richtlinien und 19 neue Regeln. Auch hier bietet Parasoft C/C++test 2023.1 volle Unterstützung, genauso wie für MISRA C:2023.














