Il existe de nombreuses raisons possibles à cela. Gammes à partir de laquelle vous accédez aux objets non encore créés (car l'ordre de création des objets entre les différentes unités de traduction est indéfini), ce qui est assez probable dans ce cas, et varie en une erreur sur votre environnement de construction.
Pour que votre propre fonction soit appelée avant une autre fonction de constructeur, vous avez un attribut constructor (priority)
décrit here. GCC conserve une priorité pour la section d'entrée du constructeur de chaque fichier. Et cela les relie dans l'ordre de ces priorités. Dans le script éditeur de liens de mon système Linux, ce code ressemble à ceci (sortie à l'aide ld -verbose
):
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
Vous voulez donner une priorité faible pour faire exécuter avant que d'autres fonctions ctor enregistrées ayant une priorité plus élevée nombre.Cependant, à première vue, il semble que les constructeurs n'ayant aucun numéro seront exécutés en premier. Pas tout à fait sûr. Le mieux c'est de l'essayer. Si vous voulez que votre fonction soit appelée avant _do_global_ctors_aux, vous devez libérer la fonction _init
d'origine qui est normalement exécutée lorsque votre programme est chargé par le chargeur ELF (regardez dans l'option -init
de ld). Cela fait un certain temps que je me suis trompé, mais je me souviens qu'il doit faire quelques détails intimes d'initialisation, donc je n'essaierais pas de le remplacer. Essayez d'utiliser l'attribut constructeur auquel je suis lié. Cependant, soyez très prudent. Votre code sera éventuellement exécuté avant que d'autres objets importants tels que cout
ne soient construits.
Mise à jour: J'ai fait un test, et il exécute en fait les fonctions ctor en sens inverse. Ainsi, les fonctions ctor qui sont liées en premier sont exécutées plus tard. Ce code se trouve être dans crtstuff.c du code source gcc:
func_ptr *p;
for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
(*p)();
J'ai fait un petit test:
void dothat() { }
struct f {
f() { dothat(); }
} f_;
void doit() __attribute__((constructor (0)));
void doit() { }
int main() { }
Établir des liens avec des rendements --print-map
, entre autres, cette sortie:
.ctors 0x080494f4 0x10
*crtbegin.o(.ctors)
.ctors 0x080494f4 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtbegin.o
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
.ctors 0x080494f8 0x4 /tmp/ccyzWBjs.o
*(SORT(.ctors.*))
.ctors.65535 0x080494fc 0x4 /tmp/ccyzWBjs.o
*(.ctors)
.ctors 0x08049500 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtend.o
Notez comment .ctors.65535
est la section que nous avons implicitement créée par notre attribut de priorité 0
. Maintenant, si vous donnez la priorité, gcc met en garde contre et il est tout à fait raison: p
test.cpp: 7: avertissement: priorités constructeur de 0 à 100 sont réservés à la mise en œuvre
Je l'ai testé il en cassant doit
et dothat
, et il les a appelés dans l'ordre que nous attendons. S'amuser!