web-dev-qa-db-fra.com

Que se passe-t-il exactement lors de la compilation avec -funwind-tables?

De: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

-fexceptions: active la gestion des exceptions. Génère le code supplémentaire nécessaire pour propager les exceptions. Pour certaines cibles, cela implique que GCC génère des informations de déroulement de trame pour toutes les fonctions,

-funwind-tables Similaire à -fexceptions, sauf qu'il ne génère que les données statiques nécessaires, mais n'affecte en rien le code généré. Vous n'avez normalement pas besoin d'activer cette option; à la place, un processeur de langage qui a besoin de cette gestion le permet en votre nom.

Quelqu'un pourrait-il expliquer, à partir de -funwind-tables, que signifie "toute donnée statique nécessaire". À quelles données ils se réfèrent. Et pourquoi les données doivent-elles être générées? Que se passe-t-il si ces données ne sont pas générées? Où ces données sont-elles utilisées?

Et il dit également "similaire à -fexception ". Je pense donc que cela génère également des informations de déroulement de trame. Qu'est-ce que les informations de déroulement de trame? Qui utilise les informations de trame et comment?

Dans certains SO posts, j'ai lu que les programmes doivent être compilés avec cet indicateur pour le _Unwind_Backtrace doit fonctionner correctement. Veuillez expliquer comment _Unwind_Backtrace utilise les informations générées par -funwind-tables.

16
Pendyala

Les données statiques mentionnées pour l'option -funwind-tables Sont les informations de déroulement de trame, c'est-à-dire les données qui permettent à un programme en cours d'exécution de remonter la pile d'appels de fonction à partir d'un point d'exécution donné. Revenir en arrière dans la pile d'appels de fonction signifie passer du contexte d'exécution d'une fonction appelée au contexte de l'appelant, c'est-à-dire ce qui se passe normalement lorsque vous retournez à partir d'un fonction, sauf que les informations de déroulement de trame vous permettent de le faire à partir d'un point arbitraire à l'intérieur du corps d'une fonction; vous n'êtes pas non plus obligé de quitter réellement la fonction appelée, vous pouvez simplement "jeter un œil" à l'intérieur du contexte de l'appelant (par exemple pour récupérer l'emplacement à partir duquel la fonction appelée a été appelée), également de manière récursive, mais continuer ensuite le flux d'exécution normal dans le fonction appelée.

Pour pouvoir faire ce qui précède, vous devez avoir accès à plus d'informations sur le code compilé que ce qui est strictement nécessaire pour qu'un programme suive un flux d'exécution "normal". Ces informations (c'est-à-dire les informations de déroulement de trame) sont placées par l'éditeur de liens dans des sections spéciales de l'éditeur de liens (par exemple, la section .eh_frame pour la plate-forme x86, ou les sections ARM.exidx et .ARM.extab pour la plate-forme ARM ) dédié à cet effet; ces sections de l'éditeur de liens sont les mêmes qui sont nécessaires dans des langages tels que C++ pour implémenter la gestion des exceptions, où le flux d'exécution pourrait passer d'une fonction appelée à son appelant à la suite d'une exception levée. Si vous désactivez la génération de ces données à l'aide de l'option -fno-unwind-tables, Vous ne pourrez pas parcourir la pile d'appels de fonction ou utiliser des exceptions C++.

Notamment, les informations de déroulement de trame sont utilisées par libunwind , une bibliothèque multiplateforme qui prend en charge la génération de backtraces, le saut vers des points arbitraires dans la pile des appels, et plus encore.

_Unwind_Backtrace() est une fonction implémentée dans les bibliothèques de base de GCC (plus spécifiquement dans libgcc_s) qui permet d'exécuter une fonction de rappel (fournie en argument) pour chaque trame de la pile des appels, c'est-à-dire à partir du contexte de la fonction appelante , le déplacement vers son interlocuteur, etc. Voir https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib--unwind-backtrace.html . Encore une fois, cette fonction pour pouvoir faire son travail doit accéder aux informations de déroulement de trame à partir des sections de l'éditeur de liens appropriées.

8
Francesco Lavra