Comment déboguer les défauts de segmentation en c?

Comment déboguer les défauts de segmentation en c?

Une violation d'accès se produit lorsque le CPU essaie de l'ensemble d'instructions en dehors de sa zone de mémoire ou lit ou écrit à un emplacement réservé qui n'existe pas, entraînant un défaut de segmentation. La présente application est interrompue à la suite de cette action, et un résultat désigné comme défaut de segmentation est généré. Étant donné que les données sont fréquemment partagées entre les régions de mémoire d'un système et que l'espace de stockage du programme est partagé entre les applications, ce problème se produit.

Certaines machines peuvent connaître une défaut de segmentation, tandis que d'autres ne le font pas. Si cela se produit, cela signifie généralement que vous avez un problème avec votre code, et nous avons réussi à s'en tirer sur ce système par chance. Tout dépend de la façon dont la mémoire est organisée et si elle est à zéro ou non. Nous examinerons comment identifier le problème de segmentation du programme dans cet article.

Quel est le défaut de segmentation?

Un défaut de segmentation, souvent connu sous le nom de segfault, est une sorte d'erreur informatique qui se produit lorsque le processeur tente d'accéder à une adresse mémoire en dehors de sa région de stockage de programme en raison d'une condition imprévue. Le terme «segmentation» fait référence à la méthode de protection de la mémoire d'un système d'exploitation de mémoire virtuelle. Lorsque nous travaillons avec des pointeurs en C ++ / C, nous rencontrons fréquemment ce problème.

Utilisation du compilateur GDB pour le défaut de segmentation

Pour découvrir pourquoi les programmes C créent un défaut de segmentation, nous utiliserons GDB. Le GDB est un débogueur C (et C ++). Il permet au programme de passer à un point spécifique, puis arrête et rapporte les valeurs des variables spécifiées à ce moment-là, ou passe à travers la ligne du programme à la fois, en imprimant les valeurs de chaque variable après que chaque ligne a été exécutée. Le débogueur GDB nous aidera à déterminer quelles lignes sont responsables du problème de segmentation.

Points clés pour empêcher les défauts de segmentation

Bien que les échecs d'accès à la mémoire provoquent la majorité des défauts de segmentation, il est essentiel de s'assurer que les pointeurs utilisés dans un programme se réfèrent toujours à des emplacements de données acceptables. Voici les moyens d'éviter les défauts de segmentation.

  • Comme les échecs d'accès à la mémoire provoquent la majorité des défauts de segmentation, il est essentiel de s'assurer que les pointeurs d'application pointent toujours vers des emplacements de données valides.
  • Avant la déréférence d'une référence susceptible, comme celle intégrée dans une structure qui est conservée dans une liste ou un tableau, nous devons invoquer ASSERT ().
  • N'oubliez pas d'initialiser correctement les pointeurs.
  • Un mutex ou un sémaphore peut être utilisé pour protéger les ressources partagées contre l'accès simultané dans le multithreading.
  • Nous devons utiliser la fonction libre ()

Exemple 1: Programme de défaut de segmentation par le pointeur de déréférence du bloc de mémoire en c

Nous avons une illustration d'un défaut de segmentation où nous essayons d'accéder à l'adresse du pointeur qui a libéré. Dans la fonction principale du programme C suivant, nous avons la déclaration de variable du pointeur «int * a» et nous avons alloué la mémoire à la variable du pointeur «A». Un défaut de segmentation sera généré lorsque le programme essaie de lire à partir du pointeur de déréférence * A.

#inclure
int main (int argc, char ** argv)

int * a;
* a = 50;
retour 0;

Sur la compilation du code ci-dessus vu sur l'écran ci-dessous, la ligne * a = 50 provoque un défaut de segmentation.

Exemple 2: Programme de défaut de segmentation en accédant au tableau hors caution en C

Un défaut de segmentation se produit dans la plupart des cas lorsqu'un programme essaie de lire ou d'écrire de la mémoire au-delà de ses limites. Dans le programme suivant, nous avons déclaré un tableau d'index «10» Ensuite, nous tentons de récupérer l'index d'un tableau qui est hors de base et de l'initialiser avec la valeur numérique. C'est le point où nous obtiendrons des défauts de segmentation après avoir exécuté la ligne hors limites du programme.

#inclure
int main (int argc, char ** argv)

int Myarr [10];
Myarr [1000] = 2;
retour 0;

Nous sommes dans le compilateur GDB où nous avons utilisé la commande GDB List. La commande GDB List a imprimé la ligne de code à partir du programme de valve. De la ligne «Myarr [1000] = 2», nous avons un défaut de segmentation. Vous pouvez le voir dans la console GDB suivante.

Exemple 3: Programme de défaut de segmentation par la déréférence du pointeur nul en c

Les références sont des pointeurs dans les langages de programmation qui indiquent où un élément est stocké en mémoire. Un pointeur nul est un pointeur qui ne pointe pas sur l'emplacement de la mémoire valide. Dans le programme ci-dessous, nous avons déclaré une variable de pointeur «pointer» et lui avons attribué une valeur nul. L'exception du pointeur nul est lancé ou une défaut de segmentation se produit lorsqu'un pointeur nul est en déréférence à la ligne «* pointerval = 10».

#inclure
int main (int argc, char ** argv)

int * pointerval = null;
* Pointerval = 10;
retour 0;

Le résultat du programme ci-dessus a lancé une défaut de segmentation lors de l'exécution en ligne «* Pointerval = 10» ci-dessous.

Exemple 4: Programme de défaut de segmentation par débordement de pile en C

Même si le code n'a pas un seul pointeur, ce n'est pas un problème de pointeur. Le débordement de pile se produit alors lorsque la fonction récursive est invoquée à plusieurs reprises, consommant toute la mémoire de la pile. La corruption de la mémoire peut également se produire lorsque la pile manque d'espace. Il peut être corrigé en revenant de la fonction récursive avec une condition de base.

Ici, dans le programme, nous avons la fonction principale et dans le corps de la fonction principale, nous avons invoqué une autre fonction principale. Cela conduit à un défaut de segmentation en raison du débordement de pile.

#inclure
int Main (vide)

principal();
retour 0;

Vous pouvez voir que le compilateur GDB donne le défaut de segmentation en ligne où nous avons invoqué la fonction principale du bloc fonction principal du programme.

Conclusion

L'article a mis en lumière ce que sont les défauts de segmentation et comment nous pouvons les déboguer en utilisant le compilateur GDB. Le compilateur GDB détermine quelles lignes sont responsables de l'échec de la segmentation. La session de débogage des défauts de segmentation est très facile à gérer avec un compilateur GDB en programmation C. Ensuite, nous avons pris différents scénarios où des défauts de segmentation peuvent se produire. J'espère que cet article a clarifié les problèmes de défaut de segmentation.