Eine C-Firmware, die ich mit dem Unit-Testframework "Google Test" testen muss, wird mit der Compileroption "-fshort-enums" übersetzt. Enums werden auch in Strukturen benutzt. Es ist wichtig, dass die Strukturen die selbe Größe wie in der originalen Firmware besitzen. Die Firmware wird mit dem AVR-GCC und das Testprogramm mit dem MINGW compiliert. Das Testprogramm soll auf dem PC laufen. Benutze ich "-fshort-enums" um das Testprogramm zu übersetzen, stürzt das Programm mit einem Segmentation Fault ab. Das passiert beim Verlassen eines Testfalls, der eine C-Funktion testet, in der ein Enum benutzt wird. Entferne ich die Compileroption, tritt der "Segmentation Fault" nicht mehr auf. Allerdings schlagen dann die Testfälle fehl. Die Option nur für das C-File zu benutzten ist leider nicht möglich. Denn es gibt globale Variablen und Funktionsparameter (zu testende Funktionen und Mocks) die entsprechende Strukturen benutzen, und diese müssen aus dem C++ Testprogramm heraus ebenfalls benutzt werden. Meine Suche im Internet nach diesem Problem hat leider kein Ergebnis zutage gefördert. Hat jemand eine Idee, wie man diesen Widerspruch lösen kann? Gibt es relevante Optionen mit dem man das Google Test steuern kann? Oder muss man das Google Test selbst mit dieser Option übersetzen?
hast du dir schon die alignment optionen für structs angeschaut?
Hast Du alle Bestandteile von "Google Test" ebenfalls mit -fshort-enums kompiliert? Vielleicht hilft es auch einfach nur das besagte Enum mit dem Attribute _packed_ zu belegen und die Compileroptionen diesbezüglich komplett in Ruhe zu lassen, das hat den gewünschten Effekt für die Größe genau dieses enums und beeinflußt keinerlei anderen Sachen:
1 | #define PACKED __attribute__ ((__packed__))
|
2 | |
3 | typedef enum PACKED { // sizeof == 1 |
4 | OT_NO_NC, |
5 | OT_NC_NO, |
6 | OT_NO, |
7 | OT_NC
|
8 | } settings_outtype_t; |
Vielen Dank für Eure Antworten. Bernds Antwort war die Lösung: #define PACKED _attribute_ ((_packed_)) typedef enum PACKED { // sizeof == 1 OT_NO_NC, OT_NC_NO, OT_NO, OT_NC } settings_outtype_t; Mir war nicht bewusst, daß man das Attribut _packed_ auch bei Enums benutzen kann. @Cer Entsprechend Bernds Vorschlag, wird dieses Attribut auch für die Strukturen angewendet. Ansonsten werden außerdem die folgenden Optionen benutzt: -mno-ms-bitfields -Wno-packed-bitfield-compat
Bitschubser schrieb: > Entsprechend Bernds Vorschlag, wird dieses Attribut auch für die > Strukturen angewendet. Das würd ich nicht machen, stattdessen würde ich (wenn es nicht schon zu spät ist) die Elemente so anordnen daß gemäß self-alignment Regeln gar kein Padding entstehen kann! (Vgl. ESR: "Lost Art of Structure Packing") Somit hast Du sowohl platzmäßig das selbe Ergebnis wie packed und zusätzlich noch die Gewissheit daß der Compiler dennoch keine Verrenkungen im Code erzeugen muß um auf krumm verschobene Datenworte zuzugreifen weil alles trotz dichtestmöglicher Packung immer noch sauber aligned ist.
Nur eine Frage am Rande: Das int beim avr-gcc 16 Bit, im PC-Tetsprogramm aber 32 Bit hat, spielt keine Rolle bei den Tests? Oliver
@Bernd Das ist mir schon klar, daß das die ideale Lösung wäre. Leider ist das eine große Firmware und ich bin lediglich der Tester. Mal sehen ob sich die Programmierer überzeugen lassen. :-) @Oliver Es werden die Datentypen aus der std_int.h benutzt. Also z.B.: int32_t Nochmals vielen Dank!
Oliver S. schrieb: > Das int beim avr-gcc 16 Bit, im PC-Tetsprogramm aber 32 Bit hat, spielt > keine Rolle bei den Tests? Wenn er vorausschauend ist (was ich vermute wenn er sich schon Gedanken über Enum-Größen macht und diese erzwingen will) benutzt er keine solchen Gummidatentypen wie int in binären Interfaces zur Außenwelt sondern nagelt dort alles aufs Bit genau fest und dokumentiert das.
Nur mal so aus Interesse. Ein bisschen verwirrt mich diese Lösung. Allerdings habe ich noch nie mit Google Test gearbeitet. Ich vermute, dass Google Test zusammen mit dem Anwendungscode compiliert und zu einem Objekt gelinkt wird. Richtig? An sich sollte doch -fshort_enums alle enum-Grössen minimieren (sofern es bei allen Compileraufrufen verwendet wird). D.h. wird Google Test zusammen mit dem AVR-Code mit MinGW compiliert, dann sollte -fshort_enums sowohl die enums im AVR-Code als auch die in Google Test beeinflussen. Richtig? Warum wirkt dann das Attribut, aber nicht -fshort_enums?
@Theor Ich habe die Entwicklungsumgebung inclusive dem Google Test von einem Kollegen bekommen. Das Google Test war bereits als Libraries compiliert, die ich nur hinzu linke.
Theor schrieb: > Ich vermute, dass Google Test zusammen mit dem Anwendungscode compiliert > und zu einem Objekt gelinkt wird. Richtig? > > An sich sollte doch -fshort_enums alle enum-Grössen minimieren (sofern > es bei allen Compileraufrufen verwendet wird). Spekulation: Vielleicht benutzt das irgendwelche unter-makefiles die ein Eigenleben haben und eigene Optionen setzen oder die man separat noch irgendwie konfigurieren müsste um da was zu ändern.
Damit meinte ich das Google Test selbst. Das Testprogramm mit den Testfällen wird natürlich mit dem zu testenden C-File zusammen kompiliert.
Bitschubser schrieb: > @Theor > Ich habe die Entwicklungsumgebung inclusive dem Google Test von einem > Kollegen bekommen. Das Google Test war bereits als Libraries compiliert, > die ich nur hinzu linke. Ah. Verstehe. Irgendwie hat mich dieser Satz: Bitschubser schrieb: > [,,,] Oder muss man das Google Test selbst mit dieser Option übersetzen? angezupft. D.h. also: 1. Google Test Infrastruktur ist vermutlich ohne -fshort_enum übersetzt. Ergibt eine Lib oder ein Object-File, das gelinkt wird. (Ich vermute, dass die Infrastruktur selbst garnicht auf die Daten der Anwendung zugreift). 2. Das Testprogramm ist sowohl mit als auch ohne -fshort_enum übersetzt worden. 3. Das Anwendungsprogramm (der AVR-Code) ist sowohl mit als auch ohne -fshort_enum übersetzt worden. 4. Alle vier möglichen Kombinationen von Punkt 2. und 3. ergeben einen Segmentation-Fault. 5. ABER: attribute packed angewendet auf eine bestimmte Struktur beseitigt den Fehler. Hm. Das scheint mir auffällig widersprüchlich und klärungsbedürftig. Aber das sind nur meine 5 Cents.
Bitschubser schrieb: > Damit meinte ich das Google Test selbst. Das Testprogramm mit den > Testfällen wird natürlich mit dem zu testenden C-File zusammen > kompiliert. Naja, dann ist es kein Wunder. Wenn Du eine Compileroption setzt die die Macht hat das ABI zu ändern dann kannst Du die nicht mehr mit vorkompilierten Libs zusammenlinken die ohne diese Option kompiliert wurden. Ich hab früher auch -fshort-enums verwendet für den selben Zweck wie Du, bin aber wieder davon abgekommen mit derart schweren Geschützen mit so einer Reichweite und Zerstörungskraft zu schießen nur um an 2 oder 3 kleinen Stellen was zu erzwingen. Da es ab dem Moment eh compilerabhängig wird kann ich von 2 Möglichkeiten auch diejenige nehmen die gezielter wirkt und weniger breit einschlägt. Was ich außerdem noch immer mache an solchen Stellen ist mit _Static_assert() zur Kompilezeit das sizeof() der betreffenden structs zu prüfen um sicherzugehen daß da in der Zukunft absolut nichts mehr unbemerkt verrutschen kann ohne daß sofort die Alarmglocken losgehen weil es sich dann weigern wird zu kompilierten.
Bernd K. schrieb: > Bitschubser schrieb: >> [...] > > [...] Wenn Du eine Compileroption setzt die die > Macht hat das ABI zu ändern dann kannst Du die nicht mehr mit > vorkompilierten Libs zusammenlinken die ohne diese Option kompiliert > wurden. > > [...] Sehe ich ähnlich. Die tatsächlichen Auswirkungen wg. der ABI sollte man mal untersuchen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.