dans un logiciel embarqué, comment gérez-vous un débordement d'une pile de manière générique? Je rencontre un peu de processeur qui protège de manière matérielle comme des processeurs AMD récents. Il y a des techniques sur Wikipedia, mais sont ces approches pratiques réelles? p>
Quelqu'un peut-il donner une approche suggérée claire qui fonctionne dans tous les cas sur les processeurs intégrés de 32 bits d'aujourd'hui? P>
4 Réponses :
Un débordement de pile se produit que la mémoire de la pile est épuisée par trop grande d'une pile d'appels? par exemple. une fonction récursive trop de niveaux profond. p>
Il existe des techniques permettant de détecter un débordement de pile en plaçant des données connues après la pile afin de pouvoir être détectée si la pile a trop poussé et l'a écrasé. P>
Il existe des outils d'analyse de code source statique tels que Gnatstack, Stackanalyzer depuis Absint et Louid-T, qui peuvent être utilisés pour déterminer ou faire une suppression à la taille maximale de la pile d'exécution. P>
tandis que le débordement de pile embarqué peut être causé par des fonctions récursives qui deviennent incontrôlables, il peut également être causé par une utilisation errante du pointeur (bien que cela puisse être considéré comme un autre type d'erreur) et le fonctionnement normal du système avec une pile inférieure. En d'autres termes, si vous ne proférez pas de votre utilisation de la pile, il peut se produire en dehors d'une situation de défaut ou de bogue. P>
Avant de pouvoir "gérer" le débordement de pile, vous devez l'identifier. Une bonne méthode pour le faire est de charger la pile avec un motif lors de l'initialisation, puis de surveiller la quantité de motif disparaît pendant le temps d'exécution. De cette manière, vous pouvez identifier le point le plus élevé que la pile a atteint. p>
L'algorithme de contrôle de modèle doit exécuter dans le sens opposé de la croissance de la pile. Donc, si la pile augmente de 0x1000 à 0x2000, votre vérification de modèle peut commencer à 0x2000 pour augmenter l'efficacité. Si votre motif était 0xAA et la valeur à 0x2000 contient autre chose que 0xaa, vous savez que vous avez probablement obtenu un débordement. P>
Vous devez également envisager de placer un tampon de bélier vide immédiatement après la pile de sorte que si vous détectez le débordement, vous pouvez arrêter le système sans perdre de données. Si votre pile est suivie immédiatement par les données du tas ou de la SRAM, l'identification d'un débordement signifie que vous avez déjà subi une corruption. Votre tampon vous protégera un peu plus longtemps. Sur un micro 32 bits, vous devez avoir assez de RAM pour fournir au moins un petit tampon. P>
L'utilisation de la pile sera également augmentée par l'utilisation de variables automatiques (en particulier des grandes matrices) et par des interruptions. Ce dernier est en particulier difficile à évaluer à l'avance, et peut donc nécessiter d'exécuter votre code pendant un moment, comme mentionné dans la réponse de Craig McQueen.
Très vrai - et à ce point, la rédaction du prologue d'interruption vous aidera à contrôler la quantité de données dont vous aurez besoin pour appuyer sur la pile pour chaque interrupteur de contexte d'interruption. Certains micros vous permettent même de désactiver les interruptions logicielles imbriquées, ce qui vous permettrait de calculer encore plus avant l'utilisation du pire des piles à cause d'interruptions.
... et évitez tous les problèmes autres i> les interruptions imbriquées peuvent causer!
Idéalement, vous écrivez votre code avec l'utilisation de la pile statique (sans appels récursifs). Ensuite, vous pouvez évaluer l'utilisation maximale de la pile par: p>
Mais même avec cela, vous voulez toujours avoir un moyen de détection strong>, puis sur manipulation strong> débordement de pile si elle se produit, si possible, pour plus de robustesse. Cela peut être particulièrement utile pendant la phase de développement du projet. Certaines méthodes à détecter strong> overflow: p>
Une fois que vous avez détecté, alors vous devez poignée strong> il. Je ne connais pas beaucoup de façons que le code peut récupérer grâce d'un débordement de la pile, car une fois qu'il est arrivé, votre logique de programme est presque certainement invalidée. Donc, tout ce que vous pouvez faire est p>
Existe-t-il un moyen de mesurer l'utilisation de la pile (non statique) en enveloppant chaque appel de fonction et en vérifiant le pointeur de la pile dans l'emballage? Je suis préoccupé par le cas où un débordement de pile tombe en BSS ou à des données et apporte des modifications sans gâcher le "garde de la pile".
@CODEPOET: Je suppose que vous voulez dire le faire de manière à ce que cela ne nécessite pas de modification de chaque appel de fonction dans votre code source. Cela devrait être soutenu par votre compilateur et je ne sais pas si de tels crochets existent dans la plupart des cas. (Je pense en principe que vous souhaitez envelopper des fonctions, pas les appels de fonction, car l'appelant ne peut pas prédire l'utilisation de la pile de la callee.)
@CODEPOET: Je pense qu'une solution plus simple serait d'avoir un grand gardien de la pile: vous pouvez le rendre arbitrairement grand (par exemple 100 octets) et cela rendrait moins probable que le gardien de la pile puisse être «sauté» sans le toucher, et courir dans les BSS / données. La principale chose à faire attention serait de grandes matrices de variables locales, ce qui pourrait permettre à la pile de "sauter" le gardien de la pile comme vous le dites.
Si vous utilisez un processeur avec une unité de gestion de la mémoire, votre matériel peut le faire pour vous avec un logiciel minimal. La plupart des processeurs modernes 32 bits ont et de plus en plus de micro-contrôleurs 32 bits les comportent également. P>
Configurez une zone de mémoire dans la MMU qui sera utilisée pour la pile. Il devrait être bordé par deux zones de mémoire où la MMU n'autorise pas l'accès. Lorsque votre application est en cours d'exécution, vous recevrez une exception / une interruption dès que vous débordez la pile. p>
Parce que vous obtenez une exception pour le moment où l'erreur se produit, vous savez exactement où dans votre application, la pile a été mauvaise. Vous pouvez regarder la pile d'appels pour voir exactement comment vous êtes arrivé là où vous êtes. Cela rend beaucoup plus facile de trouver votre problème que d'essayer de déterminer ce qui ne va pas en détectant votre problème longtemps après l'arrivée. P>
J'ai utilisé cela avec succès sur les processeurs PPC et AVR32. Lorsque vous commencez à utiliser un MMU, vous vous sentez comme si vous êtes une perte de temps depuis que vous vous êtes bien compris pendant de nombreuses années, mais une fois que vous avez vu les avantages d'une exception à l'endroit exact où votre problème de mémoire se produira, vous ne reviendrez jamais. Un MMU peut également détecter l'accès à zéro pointeur si vous interdisez l'accès à la mémoire au parc inférieur de votre RAM. P>
Si vous utilisez un RTO, votre MMU protège la mémoire et les piles d'erreurs d'autres tâches dans une tâche ne doivent pas les affecter. Cela signifie que vous pouvez également redémarrer facilement votre tâche sans affecter les autres tâches. p>
En plus de cela, un processeur avec une MMU a généralement beaucoup de RAM Votre programme est beaucoup moins susceptible de déborder votre pile et vous n'avez pas besoin de toucher tout pour vous permettre de vous procurer une application correctement avec une petite mémoire. Imprimé sur pied. P>
Une alternative à ce sujet serait d'utiliser les installations de débogage du processeur pour provoquer une interruption sur un accès à la mémoire à la fin de votre pile. Ce sera probablement très spécifique au processeur. p>
Quel processeur intégré, spécifiquement? Il n'y a vraiment pas de solution générique que tous les processeurs mettront en œuvre de la même manière, car chacun est assez différent.
Processeur indépendant alrogithm ou technique. La technique utilisée par un piratère sur l'environnement PC peut être appliquée en jouant avec des pointeurs et en écrasant votre système sur un SW incorporé. Il bas sur la manière de protéger l'adresse de retour dans votre zone de pile ..
Par pile overflow Vous voulez dire lorsque la mémoire de pile est épuisée par trop grande d'une pile d'appels? par exemple. Une fonction récursive trop de niveaux profonde? La protection des adresses de retour consiste davantage à la prévention des débordements de tampon sur la pile que de «piles débordements».