2016-06-01 9 views
4

Wir haben ein großes C++ - Projekt, das wir mit GCC und MSVC erstellen, und wir haben die static initialization order fiasco gefunden. Gibt es eine Möglichkeit, eine Liste von Symbolen zu generieren, die an der statischen Initialisierung teilnehmen, damit ich einen Plan erstellen kann, um das Problem zu lösen?Wie kann ich einfach eine Liste von Symbolen mit statischem Speicher generieren?

Ich habe eine Map-Datei von beiden GCC und MSVC erstellt. Die Ausgabe von MSVC sah nicht sehr nützlich aus. Es scheint, dass die Kartendatei von GCC verwendet werden könnte - ich habe alles extrahiert, was mit dem Abschnitt bss zusammenhängt. Viele der Symbole stammen jedoch aus Bibliotheken und fügen der Information lediglich Rauschen hinzu.

Gibt es einen Trick oder eine andere bequeme Möglichkeit, die Informationen zu erhalten, die ich suche (kurz, jede Quelldatei manuell zu lesen)?

Antwort

1

Für Visual C++: Sortieren Sie die Zeilen der .map-Datei. Dies stellt sicher, dass die Symbole nach Adresse geordnet sind.

Suche nach Symbolen __xc_a und __xc_z. Die Symbole zwischen diese beiden Symbole sind alle dynamischen Initialisierer für Objekte mit statischer Speicherdauer. Die Initialisierer werden in der Reihenfolge ausgeführt, in der sie in der Liste erscheinen.

Jeder Eintrag in der .map-Datei enthält sowohl

  1. der Namen der globalen Variablen (zB die Initialisierung für globalen Variable fred wird fred$initializer$ sowie die erforderlichen C++ Name Dekoration) und
  2. die Objektdatei, die die globale Variable enthielt (zB fred.obj). Wenn das Symbol aus einer statischen Bibliothek stammt, wird die statische Bibliothek aufgelistet (z. B.).

(Ich weiß nicht genug über GCC zu beantworten, wie diese mit ihren Werkzeugen zu tun.)

+1

GCC komplex ist, wegen seiner Wurzeln als „Ersatz-C-Compiler“ - weder ein wahrer C++ Compiler noch ein vollständiger C-Compiler. Insbesondere ist es für einige verschiedene Standard-Bibliotheksimplementierungen (entweder die GNU C-Bibliothek) verantwortlich, die normalerweise mit dem Betriebssystem geliefert werden, und nicht GCC selbst. Als Ergebnis implementiert GCC "main" auf verschiedene Arten und dies beeinflusst auch, wie ctors ausgeführt werden. Siehe auch http://stackoverflow.com/questions/28564078/why-does-gcc-put-calls-to-constructors-of-global-instances-into-different-sectio – MSalters