2017-08-18 1 views
0

J'ai quelques problèmes pour essayer de déboguer ce qui semble être des comportements très étranges. Par exemple, nous avons:Problèmes de débogage de la mémoire ARM7

static const char* LOG_FORMAT = "0x%02x,%.5f,"; 

et le pointeur change pour aucune raison évidente. Parfois à la poubelle, parfois à d'autres chaînes constantes (ou une partie de) définies ailleurs dans le code. Nous voyons aussi parfois le code sauter vers une section différente qui ne devrait pas être en cours d'exécution (la variable d'état semble changer sans qu'on le lui demande). Il y a 2 ou 3 modes de défaillance communs, et ils semblent se produire au hasard. C'est une base de code relativement grande et l'ajout ou la suppression de certaines sections modifie le comportement de l'échec (ou le supprime complètement) même si ces sections ne sont JAMAIS référencées. La meilleure théorie à l'heure actuelle est qu'il s'agit d'un problème lié à la mémoire car nous avons examiné tous les changements récents avec un peigne fin, et le simple fait d'insérer des sections de code pour déplacer les choses semble changer ou supprimez le comportement.

Quelles sont les meilleures façons de voir le débogage ce problème ou des problèmes similaires? J'ai trouvé le débogueur utile à certains moments, et pas à d'autres (mais cela pourrait être une erreur de l'utilisateur).

Notes supplémentaires. ARM7, utilisant Keil μVision 4 et le compilateur armcc v4.1.

+0

Il a été un moment que je travaillais avec ARM7, mais je crois qu'il avait un matériel breakpoints deux disponibles. Définissez-en un à surveiller pour écrire dans la variable de pointeur 'LOG_FORMAT', puis voyez ce qui est en train de le modifier. –

+1

Semble bien UB pour moi, mais vous le saviez probablement déjà. Même comportement bizarre sur un matériel différent mais identique? – yano

+0

Au lieu de pointer directement sur la chaîne, allouez de la mémoire à LOG_FORMAT, puis copiez la chaîne dans LOG_FORMAT. – Rajeshkumar

Répondre

1

Cela signifie que vous avez des bugs pointeur/corruption de mémoire quelque part dans le programme ... qui pourrait être causée par beaucoup de choses différentes.

La meilleure façon de repérer c'est d'exécuter le programme jusqu'au début principal, puis ajouter « écrire » à la variable des points d'arrêt. Cela devrait signaler directement le code incriminé.

Une cause probable est le débordement de la pile, où la pile est placée dans un mauvais emplacement de mémoire, de sorte qu'en cas de débordement, elle commence à remplacer .data ou .bss. Voir this article. Vous pouvez déboguer des débordements de pile en définissant toute la mémoire de pile à une valeur connue au démarrage (comme 0xAA), laissez le programme s'exécuter pendant un moment, essayez de l'exposer à autant de cas d'utilisation que possible, puis cassez et vérifiez la mémoire de la pile, pour voir à quel point les valeurs connues sont toujours conservées. Si c'est proche de la fin de la pile, alors vous avez très probablement un débordement de pile.

0

Cela ressemble à un problème d'alignement de pile. Votre pile est probablement alignée sur une limite de un seul mot (quatre octets) au lieu d'une autre de deux mots (huit octets).

Voilà pourquoi la suppression et l'ajout de sections sans rapport avec les causes des comportements différents. La pile va d'être alignée à désalignée selon la quantité de données qui la précède.

Le spécificateur de format corrompu est un autre indice. Une pile mal alignée peut souvent ne causer aucun problème jusqu'à ce qu'une fonction variadique soit appelée - en particulier celle qui est passée une valeur qui doit être alignée en double mot.

Pour déboguer cela, vous devez définir un point d'arrêt à l'appel à printf (ou toute autre fonction pour laquelle le spécificateur de format est utilisé) et jetez un oeil au pointeur de la pile. Si SP n'est pas aligné sur une limite de huit octets, vous avez trouvé le problème.