Débogage en direct du noyau Linux, comment c'est fait et quels outils sont utilisés?

quelles sont les méthodes et les outils les plus courants et pourquoi pas rares utilisés pour faire du débogage en direct sur le noyau Linux? Je connais ce Linus par exemple. est contre ce type de débogage pour le noyau Linux ou il l'était moins et donc rien de beaucoup a été fait dans ce sens au cours de ces années, mais honnêtement beaucoup de temps s'est écoulé depuis 2000 et je suis intéressé si cette mentalité a changé en ce qui concerne le projet Linux et quelles méthodes actuelles sont utilisées pour faire du débogage en direct sur le noyau Linux en ce moment (local ou distant)?

les références à des revues et des tutoriels sur les techniques et outils mentionnés sont les bienvenues.

47
demandé sur Shinnok 2011-02-09 13:53:01
la source

10 ответов

une autre option est d'utiliser ICE /JTAG controler, et GDB. Cette solution "matérielle" est particulièrement utilisée avec les systèmes embarqués,

mais par exemple Qemu offre des caractéristiques similaires:

  • démarrer qemu avec un gdb 'à distance' stub qui est à l'écoute sur localhost:1234' : qemu -s ... ,

  • puis avec GDB vous ouvrez le fichier du noyau vmlinux compilé avec les informations de débogage (vous pouvez jeter un oeil au fil de liste de diffusion ce où ils discutent de la non-optimisation du noyau).

  • se connecter GDB et Qemu: target remote localhost:1234

  • voir que vous êtes live noyau:

    (gdb) where
    #0  cpu_v7_do_idle () at arch/arm/mm/proc-v7.S:77
    #1  0xc0029728 in arch_idle () atarm/mach-realview/include/mach/system.h:36
    #2  default_idle () at arm/kernel/process.c:166
    #3  0xc00298a8 in cpu_idle () at arch/arm/kernel/process.c:199
    #4  0xc00089c0 in start_kernel () at init/main.c:713
    

malheureusement, le débogage de l'espace utilisateur N'est pas encore possible avec GDB (pas de tâche liste des informations, Pas de reprogrammation MMU pour voir différents contextes de processus,...), mais si vous restez dans kernel-space, c'est tout à fait pratique.

  • info threads vous donnera la liste et les états de la différente CPUs

EDIT:

vous pouvez obtenir plus de détails sur la procédure dans ce PDF:

Déboguer les systèmes Linux en utilisant GDB et QEMU .

25
répondu Kevin 2016-12-30 01:29:49
la source

selon le wiki , kgdb a été fusionné dans le noyau dans 2.6.26 qui est dans les dernières années. kgdb est un débogueur à distance , donc vous l'activez dans votre noyau puis vous y attachez gdb d'une manière ou d'une autre. Je dis d'une façon ou d'une autre car il semble y avoir beaucoup d'options - voir connexion gdb . Étant donné que kgdb est maintenant dans l'arbre des sources, je dirais qu'aller de l'avant c'est ce que vous voulez utiliser.

on dirait que Linus a cédé. Cependant, je voudrais souligner son argument - vous devriez savoir ce que vous faites et bien connaître le système. C'est le noyau de la terre. Si quelque chose va mal, vous n'obtenez pas segfault , vous obtenez quelque chose d'obscur problème plus tard à l'ensemble du système. Voici les dragons. Procéder avec soin, vous avez été averti.

20
répondu 2011-02-09 14:15:23
la source

pendant le débogage du noyau Linux, nous pouvons utiliser plusieurs outils, par exemple, les débogueurs (KDB, KGDB), le dumping lors du crash (LKCD), le tracing toolkit (LTT, LTTV, LTTng), les instruments personnalisés du noyau (dprobes, kprobes). Dans la section suivante, j'ai essayé de résumer la plupart d'entre eux, en espérant que ceux-ci aideront.

LKCD (Linux Kernel Crash Dump) outil permet au système Linux d'écrire le contenu de sa mémoire lorsqu'un crash se produit. Ces journaux peuvent être analyse plus poussée de la cause de l'accident. Ressources relatives à LKCD

Oups lorsque le noyau détecte un problème, il imprime un message Oops. Un tel message est généré par des instructions printk dans le gestionnaire de défauts (arch/*/kernel / traps.C.) Un tampon annulaire dédié dans le noyau est utilisé par les instructions printk. Oops contient des informations comme, le CPU où les Oops ont eu lieu sur, le contenu des registres CPU, le nombre de Oops, la description, stack back trace et autres. Ressources concernant le noyau oops

Dynamic Probes est l'un des outils de débogage pour Linux développé par IBM. Cet outil permet de placer une "sonde"" à presque n'importe quel endroit du système, dans l'espace utilisateur et le noyau. La sonde se compose d'un certain code (écrit dans un langage spécialisé, orienté stack) qui est exécuté lorsque le contrôle atteint le point donné. Ressources concernant Dynamic Probe énumérées ci-dessous

Linux Trace Toolkit est un correctif du noyau et un ensemble d'utilitaires connexes qui permettent de tracer les événements dans le noyau. La trace comprend des renseignements sur le moment et peut donner une image raisonnablement complète de ce qui s'est produit au cours d'une période donnée. Ressources de L'OLT, de L'observateur de L'OLT et de la prochaine génération de L'Olt

MEMWATCH est un outil de détection d'erreurs de mémoire open source. Il fonctionne par définition de MEMWATCH dans la déclaration gcc et ajout d'un fichier d'en-tête à notre code. Grâce à cela, nous pouvons suivre les fuites de mémoire et les corruptions de mémoire. Ressources concernant MEMWATCH

ftrace est un bon cadre de traçage pour le noyau Linux. ftrace trace les opérations internes du noyau. Cet outil inclus dans le Noyau Linux en 2.6.27. Avec ses différents traceurs de plugins, ftrace peut être ciblé sur différents tracepoints statiques, tels que les événements de planification, les interruptions, les e/s en mémoire, les transitions D'état de puissance CPU, et les opérations liées aux systèmes de fichiers et à la virtualisation. De plus, le suivi dynamique des appels de fonctions du noyau est disponible, avec possibilité de restriction à un sous-ensemble de fonctions en utilisant globs, et avec la possibilité de générer des graphiques d'appels et de fournir l'utilisation de la pile. Vous pouvez trouver un bon tutoriel de ftrace à https://events.linuxfoundation.org/slides/2010/linuxcon_japan/linuxcon_jp2010_rostedt.pdf

ltrace est un utilitaire de débogage sous Linux, utilisé pour afficher les appels qu'une application d'espace utilisateur fait aux bibliothèques partagées. Cet outil peut être utilisé pour tracer n'importe quel appel de fonction de bibliothèque dynamique. Il intercepte et enregistre les appels de bibliothèque dynamiques qui sont appelés par le processus exécuté et le les signaux qui sont reçus par ce processus. Il peut également intercepter et imprimer les appels système exécutés par le programme.

KDB est le débogueur du noyau Linux. KDB suit l'interface simpliste de style shell. Nous pouvons l'utiliser pour inspecter la mémoire, les registres, les listes de processus, dmesg, et même définir des points de rupture pour arrêter dans un certain endroit. Grâce à KDB, nous pouvons définir les points de rupture et exécuter un contrôle de base de l'exécution du noyau ( bien que KDB ne soit pas un débogueur de niveau source ). Plusieurs ressources pratiques concernant KDB

KGDB est destiné à être utilisé comme débogueur de niveau source pour le noyau Linux. Il est utilisé avec gdb pour déboguer un noyau Linux. Deux machines sont nécessaires pour utiliser kgdb. L'une de ces machines est une machine de développement, et l'autre est la machine cible. Le noyau à déboguer tourne sur la machine cible. On s'attend à ce que gdb puisse être utilisé pour "forcer" le noyau à inspecter la mémoire, les variables et regarder à travers les informations de la pile d'appels, de la même manière qu'un développeur d'applications utiliserait gdb pour déboguer une application. Il est possible de placer points de rupture dans le code du noyau et effectuer quelques pas d'exécution limitée. Plusieurs ressources pratiques concernant KGDB

20
répondu Md Mahbubur Rahman 2015-03-02 15:17:41
la source

un autre bon outil pour le débogage" live " est kprobes / Dynamic probes.

cela vous permet de construire dynamiquement de petits modules minuscules qui tournent lorsque certaines adresses sont exécutées - un peu comme un point de rupture.

le grand avantage d'eux sont:

  1. ils n'ont pas d'impact sur le système - i.e. quand un emplacement est touché - il ne fait qu'excécuter le code - il n'arrête pas tout le noyau.
  2. Vous n'avez pas besoin de deux systèmes différents interconnectés (target et debug) comme avec kgdb

il est préférable de faire des choses comme frapper un point de rupture, et de voir quelles sont les valeurs de données, ou de vérifier si les choses ont été changées/écrasées, etc. Si vous voulez "passer à travers le code" - il ne fait pas cela.

ajout-2018:

une autre méthode très puissante est un programme simplement appelé "perf" qui enroule de nombreux outils (comme Les sondes dynamiques) et le type de remplace / déprécie les autres (comme l'oprofile).

en particulier, la commande perf probe peut être utilisée pour créer/ajouter facilement des sondes dynamiques au système, après quoi perf record peut échantillonner le système et rapporter des informations (et des rétrotraces) lorsque la sonde est frappée pour faire rapport via perf report (ou perf script ). Si vous avez de bons symboles de débogage dans le noyau, vous pouvez obtenir de bonnes informations du système sans même démonter le noyau. Faire un man perf (dans Google ou sur votre système) pour plus d'informations sur cet outil ou de voir cette grande page sur elle:

http://www.brendangregg.com/perf.html

13
répondu Brad 2018-10-01 16:45:26
la source

en fait la blague est que Linux a un débogueur dans le noyau depuis 2.2.12, xmon , mais seulement pour l'architecture powerpc (en fait il était ppc à l'époque).

ce n'est pas un débogueur de niveau source, et c'est presque entièrement non documenté, mais tout de même.

http://lxr.linux.no/linux-old+v2.2.12 / arch/ppc/xmon / xmon.c#L119

4
répondu mpe 2011-02-10 15:44:55
la source

comme quelqu'un qui écrit beaucoup de code du noyau, je dois dire que je n'ai jamais utilisé kgdb, et que j'utilise rarement kprobes, etc.

il est encore souvent la meilleure approche à jeter dans certains stratégique printks . Dans les noyaux plus récents trace_printk est un bon moyen de le faire sans spammer dmesg.

3
répondu mpe 2011-02-10 15:52:16
la source

QEMU + GDB étape-par-étape de la procédure testé sur Ubuntu 16.10 hôte

pour démarrer à partir de zéro rapidement, j'ai fait un minimum entièrement automatisé qemu + Buildroot exemple à: https://github.com/cirosantilli/linux-kernel-module-cheat les principales étapes sont décrites ci-dessous.

obtenez D'abord un système de fichiers racine rootfs.cpio.gz . Si vous en avez besoin, pensez à:

puis sur le noyau Linux:

git checkout v4.9
make mrproper
make x86_64_defconfig
cat <<EOF >.config-fragment
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_GDB_SCRIPTS=y
EOF
./scripts/kconfig/merge_config.sh .config .config-fragment
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
                   -initrd rootfs.cpio.gz -S -s

sur un autre terminal, en supposant que vous voulez commencer à déboguer à partir de start_kernel :

gdb \
    -ex "add-auto-load-safe-path $(pwd)" \
    -ex "file vmlinux" \
    -ex 'set arch i386:x86-64:intel' \
    -ex 'target remote localhost:1234' \
    -ex 'break start_kernel' \
    -ex 'continue' \
    -ex 'disconnect' \
    -ex 'set arch i386:x86-64' \
    -ex 'target remote localhost:1234'

et c'est fini!!

pour les modules du noyau voir: comment déboguer les modules du noyau Linux avec QEMU?

Pour Ubuntu 14.04, GDB 7.7.1, hbreak , break logiciel des points d'arrêt ont été ignorés. Pas le cas aujourd'hui dans 16.10. Voir aussi: https://bugs.launchpad.net/ubuntu/+source/qemu-kvm / + bug / 901944 "1519210920

Le désordre disconnect et ce qui viendra après elle sont pour contourner le message d'erreur:

Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000

fils apparentés:

voir aussi:

limitations connues:

3
la source

KGDB + QEMU étape par étape

KGDB est un sous-système du noyau qui vous permet de déboguer le noyau lui-même à partir d'un hôte GDB.

mon exemple qemu + Buildroot est un bon moyen d'en avoir un avant-goût sans vrai matériel: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1969cd6f8d30dace81d9848c6bacbb8bad9dacd8#kgdb

pour et contre vs autres méthodes:

  • avantage vs QEMU:
    • vous n'avez souvent pas l'émulation de logiciel pour votre appareil que les vendeurs de matériel n'aiment pas libérer des modèles de logiciel précis pour leurs appareils
    • matériel réel de manière plus rapide que QEMU
  • avantage vs JTAG: pas besoin de matériel supplémentaire JTAG, plus facile à configurer
  • désavantages par rapport à QEMU et JTAG: moins visibilité et plus intrusive. KGDB s'appuie sur certaines parties du noyau qui fonctionnent pour pouvoir communiquer avec l'hôte. Ainsi, par exemple, il se décompose en panique, vous ne pouvez pas voir la séquence de démarrage.

les principales étapes sont:

  1. compilez le noyau avec:

    CONFIG_DEBUG_KERNEL=y
    CONFIG_DEBUG_INFO=y
    
    CONFIG_CONSOLE_POLL=y
    CONFIG_KDB_CONTINUE_CATASTROPHIC=0
    CONFIG_KDB_DEFAULT_ENABLE=0x1
    CONFIG_KDB_KEYBOARD=y
    CONFIG_KGDB=y
    CONFIG_KGDB_KDB=y
    CONFIG_KGDB_LOW_LEVEL_TRAP=y
    CONFIG_KGDB_SERIAL_CONSOLE=y
    CONFIG_KGDB_TESTS=y
    CONFIG_KGDB_TESTS_ON_BOOT=n
    CONFIG_MAGIC_SYSRQ=y
    CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
    CONFIG_SERIAL_KGDB_NMI=n
    

    la plupart d'entre eux ne sont pas obligatoires, mais c'est ce que j'ai testé.

  2. ajouter à votre commande QEMU:

    -append 'kgdbwait kgdboc=ttyS0,115200' \
    -serial tcp::1234,server,nowait
    
  3. exécuter GDB avec à partir de la racine de L'arbre des sources du noyau Linux avec:

    gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
    
  4. Dans GDB:

    (gdb) c
    

    et la botte devrait finir.

  5. In QEMU:

    echo g > /proc/sysrq-trigger
    

    et gdb devrait se casser.

  6. maintenant que c'est fait, vous pouvez utiliser GDB comme d'habitude:

    b sys_write
    c
    

testé dans Ubuntu 14.04.

KGDB + Raspberry Pi

la même configuration que ci-dessus a presque fonctionné sur un Raspberry Pi 2, Raspbian Jessie 2016-05-27.

vous avez juste à apprendre à faire les étapes QEMU sur le Pi, qui sont facilement Googlable:

  • ajouter les options de configuration et recompiler le noyau comme expliqué à https://www.raspberrypi.org/documentation/linux/kernel/building.md il y avait malheureusement des options manquantes sur la compilation par défaut du noyau, notamment aucun symbole de débogage, donc la recompilation est nécessaire.

  • modifier cmdline.txt de la partition de démarrage et d'ajouter:

    kgdbwait kgdboc=ttyAMA0,115200
    
  • connecter gdb à la série avec:

    arm-linux-gnueabihf-gdb -ex 'file vmlinux' -ex 'target remote /dev/ttyUSB0'
    

    si vous n'êtes pas familier avec la série, vérifiez ceci: https://www.youtube.com/watch?v=da5Q7xL_OTo Tout ce dont vous avez besoin est un adaptateur pas cher comme celui-ci . Assurez-vous que vous pouvez obtenir un shell à travers la série pour s'assurer qu'il fonctionne avant d'essayer KGDB.

  • :

    echo g | sudo tee /proc/sysrq-trigger
    

    de l'intérieur d'une session SSH, puisque la série est déjà prise par GDB.

avec cette configuration, j'ai pu mettre un point de rupture dans sys_write , interrompre l'exécution du programme, lister les sources et continuer.

cependant, parfois quand j'ai fait next dans sys_write GDB juste accroché et imprimé ce message d'erreur plusieurs fois:

Ignoring packet error, continuing...

donc je ne suis pas sûr si quelque chose ne va pas avec mon installation, ou si on peut s'y attendre en raison de ce qu'un processus de fond fait dans l'image plus complexe du Raspabe.

on m'a aussi dit d'essayer de désactiver le multiprocessing avec les options de démarrage de Linux, mais je ne l'ai pas encore essayé.

2
la source

mode utilisateur Linux (UML)

https://en.wikipedia.org/wiki/User-mode_Linux

une autre virtualisation une autre méthode qui permet de déboguer le code du noyau par étapes.

UML est très ingénieux: il est implémenté comme un ARCH , tout comme x86 , mais au lieu d'utiliser des instructions de bas niveau, il implémente les fonctions ARCH avec le système userland appeler.

le résultat est que vous êtes capable d'exécuter le code du noyau Linux comme un processus d'utilisation sur un hôte Linux!

faire D'abord un rootfs et l'exécuter comme indiqué à: https://unix.stackexchange.com/questions/73203/how-to-create-rootfs-for-user-mode-linux-on-fedora-18/372207#372207

Le um defconfig ensembles CONFIG_DEBUG_INFO=y par défaut (ouais, c'est un développement de la chose), donc nous sommes bien.

sur invité:

i=0
while true; do echo $i; i=$(($i+1)); done

sur hôte dans un autre shell:

ps aux | grep ./linux
gdb -pid "$pid"

In GDB:

break sys_write
continue
continue

et maintenant vous contrôlez le compte à partir de GDB, et pouvez voir la source comme prévu.

Pour:

  • entièrement contenu dans L'arbre principal du noyau Linux
  • plus léger que L'émulation système complète de QEMU

Inconvénients:

voir aussi: https://unix.stackexchange.com/questions/127829/why-would-someone-want-to-run-usermode-linux-uml

1
la source

kgdb et gdb sont presque inutiles pour déboguer le noyau parce que le code est tellement optimisé qu'il n'a aucun rapport avec la source originale et que de nombreuses variables sont optimisées. Cela rend la marche, donc passer par la source est impossible, l'examen des variables est impossible et est donc très pointu.

en fait, il est pire que inutile, il donne en fait de fausses informations si détaché est le code que vous ollooking à l'actuelle code en cours d'exécution.

et non, vous ne pouvez pas désactiver les optimisations dans le noyau, il ne compile pas.

je dois dire, venant d'un environnement de noyau windows, que le manque de débogueur décent est angoissant, étant donné qu'il y a du code indésirable là-bas à maintenir.

-4
répondu matt 2013-07-08 18:25:11
la source

Autres questions sur linux debugging kernel linux-kernel