8
votes

Débogage des défauts de segmentation sur un Mac?

J'ai des problèmes avec un programme causant une défaillance de segmentation lorsqu'il est exécuté sur un Mac. Je pose une entrée pour le IOCCC , ce qui signifie que les choses suivantes sont vraies à propos de mon programme: < / p>

  • C'est un très petit programme C dans un seul fichier appelé PROG.c
  • Je ne le posterai pas ici, car cela ne vous aidera pas (et rendrait probablement l'entrée du concours non valide)
  • Il compile proprement sous GCC en utilisant "CC -O PROG PROG.C -WALL"
  • malgré (ou, plus précisément, à cause de) le fait qu'il contient un tas d'utilisations vraiment bizarres de C, il a été construit extrêmement attentivement. Je ne sais aucune partie de celui-ci qui est négligent avec la mémoire (qui ne veut pas dire qu'il ne peut pas y avoir des insectes, juste que s'il y ailli, s'il n'y a pas de probabilité d'être évident)
  • Je suis principalement un utilisateur de Windows, mais il y a plusieurs années, j'ai compilé avec succès et l'a rencontrée sur plusieurs machines Windows, un couple de Mac et une boîte Linux, sans aucun problème. Le code n'a pas changé depuis lors, mais je n'ai plus accès à ces machines.

    Je n'ai pas de machine Linux à réutiliser, mais comme un test final, j'ai essayé de la compiler et de l'exécuter sur un MacBook Pro - Mac OSX 10.6.7, XCode 4.2 (I.e. GCC 4.2.1). Encore une fois, il compile proprement de la ligne de commande. Il semble que sur un Mac Ticing "PROG" ne produise pas le programme compilé, mais "Open PROG" semble. Rien ne se passe pendant environ 10 secondes (mon programme prend environ une minute pour courir quand elle réussit), mais elle dit simplement "faute de segmentation" et se termine.

    Voici ce que j'ai essayé, de suivre le problème, en utilisant les réponses principalement glanées de Ce fil d'imperpillage utile :

    • sous Windows, poivré le code avec _SAserte (_crtCheckMemory ()); - Le code a ran de chien-lent, mais a couru avec succès. Aucun des affirmations tirées (ils le font lorsque j'ajouterai délibérément un code horrible afin de vous assurer que _crtCheckMemory et _Assertaine fonctionne comme prévu, mais pas autrement)
    • sur le Mac, j'ai essayé de bouer. J'ai essayé de construire le code à l'aide de variantes de "g ++ -fmudfffflap -fstack-protecteur-tout -ludfflap -wall -o prog prog.c", qui ne produit que l'erreur "CC1Plus: Erreur: MF-Runtime.h: Aucun fichier de ce type ou répertoire ". Googling La question n'a rien soulevé de manière concluante, mais il semble que ce soit un sentiment que Mudflap ne fonctionne pas sur Macs.
    • aussi sur le Mac, j'ai essayé Valgrind. J'ai installé et l'a construit et construit mon code à l'aide de "CC -O PROG -G -G -O0 PROG.c". Valgrind en cours d'exécution avec la commande "VALGRIND -Seak-Check = YES PROG" Produit l'erreur "Valgrind: PROG: commande non trouvée". Rappelez-vous que vous avez «Ouvrir» une exectable sur un Mac J'ai essayé «Valgrind», ce qui semble exécuter le programme et exécute également Valgrind, ce qui ne trouve aucun problème. Cependant, Valgrind ne manifeste pas de problèmes pour moi même lorsque je l'exécute avec des programmes conçus spécifiquement pour que cela déclenche des messages d'erreur. Je c'était également cassé sur Macs?
    • J'ai essayé d'exécuter le programme en Xcode, avec toutes les cases à cocher Diagnostics cochées dans le menu Produit-> Modifier ... Menu et avec un point d'arrêt symbolique dans Malloc_error_break. Le point d'arrêt n'est pas touché, le code s'arrête avec une pielle contenant une chose ("dlopen"), et la seule chose de note qui apparaît dans la fenêtre de sortie est la suivante:

      AVERTISSEMENT: Impossible de restaurer le cadre précédemment sélectionné. Pas de mémoire disponible pour programmer maintenant: dangereux d'appeler Malloc

      Je suis à court d'idées. J'essaie d'obtenir Cygwin mis en place (il prend des heures) pour voir si l'un des outils fonctionnera de cette façon, mais si cela échoue, je suis à perte. Il doit sûrement y avoir des outils capables de suivre les causes des défauts de segmentation sur un Mac?


2 commentaires

Comme avec n'importe quel Unix, sauf si PROG est dans votre page , vous devez spécifier le chemin d'accès à PROG pour l'exécuter, par exemple. ./ PROG Dans le répertoire, il vit. C'est la même histoire avec l'invocation Valgrind ci-dessus; Il devrait probablement être Valgrind -leak-check = yes ./prog . N'utilisez pas Ouvrir pour exécuter votre code.


Quant à ne pas avoir accès à une machine Linux ... sérieusement? Il suffit de télécharger une image de CD en direct de Ubuntu, mettez-la sur un lecteur CD / USB et démarrer dans ... omg poneys! C'est comme totalement linux . (Désolé d'être un peu snarky, mais de déterminer cette solution pas nécessite que vous soyez un chirurgien de fusée.)


3 Réponses :


9
votes

Avez-vous compilé avec -g et exécutez-le à l'intérieur gdb ? Une fois que l'application se bloque, vous pouvez obtenir une backtrage avec bt qui devrait vous montrer où le crash survient


4 commentaires

Parfait! Je n'avais pas déjà utilisé GDB auparavant, mais cela a tout de suite frappé le problème et a rendu le problème clair de manière à ce que Xcode ait complètement manqué et misérablement. Si quelqu'un est intéressé, mon problème semblait descendre à la façon dont le MacBook Pro a manipulé l'arithmétique de point flottant. Mon code contient une fonction récursive qui cesse de recouverte lorsqu'elle a trouvé la bonne réponse à une petite tolérance définie, mais sur le MacBook, il ne semblait jamais trop se rapprocher, alors il a recouvré pour toujours et soufflé la pile de pile (hehe, débordement de pile .. .). Augmenter la tolérance tout corrigé.


Insérez la référence à ici.


Notez que sur les nouvelles versions OS / XCode, vous utilisez lldb à la place. Cela fonctionne de la même manière, cependant.


Fait ma journée après une décennie (septembre 2021). Merci.



7
votes

pour plus moderne lldb saveur xxx


1 commentaires

Merci, c'était un économiseur de vie.



0
votes

Dans de nombreux cas, MacOS stocke les journaux de collision récents du programme sous ~ / Bibliothèque / Journaux / DiagnosticReports / Dossier.

Habituellement, je vais essayer les étapes suivantes lors du dépannage sur MacOS:

  1. Nettoyez les journaux de collision existants sous le ~ / Bibliothèque / Journaux / DiagnosticReports /
  2. exécutez à nouveau le programme pour reproduire le problème
  3. Attendez quelques secondes pendant quelques secondes, le journal des crash apparaîtra sous le dossier. Le journal de crash est nommé comme {votre_program} _ {crashing_date} _ {id} _ {your_host} .crash
  4. Ouvrez le journal des crash avec votre éditeur de texte, recherchez le mot-clé écrasé pour localiser le fil causant le crash. Il vous montrera la trace de la pile lors du crash et, dans de nombreux cas, la ligne exacte du code source causant également le crash sera également enregistré.

    Quelques liens:

    [1] https://mac-optimization.destreviews.net / analyser-mac-crash-rapports /


0 commentaires