Débogage de SIGBUS sur Linux x86
Ce qui peut causer des SIGBUS (erreur de bus) sur un générique x86 userland application sous Linux? Toutes les discussions que j'ai pu trouver en ligne est en ce qui concerne la mémoire des erreurs d'alignement, qui d'après ce que je comprends ne s'applique pas pour x86.
(Mon code est en cours d'exécution sur un Géodedans le cas où il y a tout de processeur spécifique de bizarreries.)
source d'informationauteur Josh Kelley
Vous devez vous connecter pour publier un commentaire.
Vous pouvez obtenir un SIGBUS à partir d'un accès non alignés si vous activez l'accès non alignés piège, mais normalement c'est off sur un système x86. Vous pouvez également l'obtenir auprès de l'accès à une mémoire périphérique mappé si il y a une erreur de quelque sorte.
Votre meilleur pari est d'utiliser un débogueur pour identifier les failles de l'enseignement (SIGBUS, synchrone), et essayer de voir ce qu'il essayait de faire.
SIGBUS
peut se produire dans Linux pour quelques raisons autres que l'alignement de la mémoire des défauts (par exemple, si vous tentez d'accéder à unemmap
région au-delà de la fin du fichier mappé.Êtes-vous en utilisant quelque chose comme
mmap
la mémoire partagée régions, ou similaire?SIGBUS sur x86 (y compris x86_64) Linux est l'un des rares de la bête. Il peut apparaître à partir de tentative d'accès au-delà de la fin de
mmap
ed de fichier, ou de certaines autres situations décrites par POSIX.Mais à partir de défauts de matériel, il n'est pas facile à obtenir SIGBUS. À savoir, non alignés l'accès de toute instruction — être il SIMD ou non — habituellement les résultats en SIGSEGV. Les débordements de pile de résultat en SIGSEGV. Même accède à des adresses non pas dans la forme canonique résultat en SIGSEGV. Tout cela à cause de #GP d'être soulevées, qui a presque toujours des cartes à SIGSEGV.
Maintenant, voici quelques façons d'obtenir SIGBUS en raison d'un PROCESSEUR exception:
Activer CA peu dans
EFLAGS
puis n'a pas d'allégeance accès par la mémoire de lecture ou d'écriture d'instruction. Voir cette discussion pour plus de détails.Ne canonique violation par l'intermédiaire d'un registre de pointeur de pile (
rsp
ourbp
), générant #SS. Voici un exemple pour GCC (compilation avecgcc test.c -o test -masm=intel
):Oh oui il y a encore une drôle de façon d'obtenir SIGBUS.
Si le noyau ne parvient pas à page dans une page de code en raison de la pression de la mémoire (OOM killer doit être désactivé) ou échec de la demande d'e /s, SIGBUS.
Cela a été brièvement mentionné ci-dessus comme un "échec de la demande d'e /s", mais je vais développer un peu.
Fréquemment le cas lorsque vous paresseusement grandir un fichier à l'aide de ftruncate, la carte dans la mémoire de commencer l'écriture de données, puis exécutez de l'espace dans votre système de fichiers. Physique de l'espace pour le fichier mappé est alloué sur les défauts de page, si il n'y a rien à gauche, puis le processus reçoit un SIGBUS.
Si vous avez besoin de votre demande correctement les récupérer à partir de cette erreur, il est logique de se réservent explicitement un espace avant de mmap à l'aide de fallocate. La manipulation ENOSPC dans errno après fallocate appel est beaucoup plus simple que de traiter avec les signaux, en particulier dans une application multi-thread.
Une cause commune d'une erreur de bus sur x86 Linux tente de déréférencement de quelque chose qui n'est pas vraiment un pointeur, ou sauvage est un pointeur. Par exemple, à défaut d'initialiser un pointeur ou de l'affectation de l'arbitraire d'un entier à un pointeur, puis de tenter de déréférencer il sera normalement produire soit une erreur de segmentation ou d'une erreur de bus.
Alignement ne s'appliquent x86. Même si la mémoire sur un système x86 est octets adressables (de sorte que vous pouvez avoir un char pointeur vers n'importe quelle adresse), si vous avez par exemple un pointeur vers un entier de 4 octets, ce pointeur doit être aligné.
Vous devez exécuter votre programme dans gdb et de déterminer le pointeur d'accès est la génération de l'erreur de bus pour diagnostiquer le problème.
C'est un peu hors des sentiers battus, mais vous pouvez obtenir SIGBUS à partir d'un non alignés SSE2 (m128) de charge.