Comment déboguer le noyau Linux avec GDB et QEMU?

je suis nouveau dans le développement du noyau et je voudrais savoir comment exécuter/déboguer le noyau linux en utilisant QEMU et gdb. Je suis en train de lire le livre de Robert Love mais malheureusement il n'aide pas le lecteur sur la façon d'installer les outils appropriés pour exécuter ou déboguer le noyau... Donc ce que j'ai fait était de suivre ce tutoriel http://opensourceforu.efytimes.com/2011/02/kernel-development-debugging-using-eclipse / . J'utilise eclipse comme IDE pour développer sur le noyau, mais je voulais d'abord pour que ça fonctionne sous QEMU / gdb. Alors ce que j'ai fait jusqu'à présent était:

1) compiler le noyau avec:

make defconfig (then setting the CONFIG_DEBUG_INFO=y in the .config)
make -j4

2) Une fois la compilation terminée, J'exécute Qemu en utilisant:

qemu-system-x86_64 -s -S /dev/zero -kernel /arch/x86/boot/bzImage

qui lance le noyau dans l'état" stopped

3) je dois donc utiliser gdb, j'essaie la commande suivante:

gdb ./vmlinux

qui l'exécute correctement mais... Maintenant, je ne sais pas quoi faire... Je sais que j'ai pour utiliser le débogage à distance sur le port 1234 (port par défaut utilisé par Qemu), en utilisant le vmlinux comme fichier de table de symboles pour le débogage.

donc ma question Est: Que dois-je faire pour lancer le noyau sur Qemu, y attacher mon Débogueur et ainsi, les faire travailler ensemble pour rendre ma vie plus facile avec le développement du noyau.

26

5 réponses

je voudrais essayer:

(gdb) target remote localhost:1234
(gdb) continue

en utilisant l'option '-s' rend qemu listen sur le port tcp::1234, auquel vous pouvez vous connecter comme localhost:1234 si vous êtes sur la même machine. L'option '-S' de Qemu permet à Qemu d'arrêter l'exécution jusqu'à ce que vous donniez la commande continue.

la meilleure chose serait probablement de jeter un oeil à un tutoriel gdb décent pour s'entendre avec ce que vous faites. celui-ci est très joli.

24
répondu BjoernD 2018-10-08 13:26:57

procédure étape par étape Testée sur Ubuntu 16.10 host

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/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md les principales étapes sont décrites ci-dessous.

obtenez D'abord un système de fichiers racine rootfs.cpio.gz . Si vous avez besoin d'un, prendre en considération:

puis le le noyau Linux:

git checkout v4.15
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 \
                   -append nokaslr

sur un autre terminal, à l'intérieur de L'arborescence du noyau Linux, 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

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 connexes:

limitations connues:

voir aussi:

17

la réponse de BjoernID n'a pas vraiment fonctionné pour moi. Après la première continuation, aucun point de rupture n'est atteint et à l'interruption, je verrais des lignes telles que:

0x0000000000000000 in ?? ()
(gdb) break rapl_pmu_init
Breakpoint 1 at 0xffffffff816631e7
(gdb) c
Continuing.
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..]

je suppose que cela a quelque chose à voir avec différents modes CPU (mode réel dans le BIOS vs. mode long quand Linux a démarré). Quoi qu'il en soit, la solution est D'exécuter D'abord QEMU sans attendre (i.e. sans -S ):

qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s

dans mon cas, j'avais besoin de casser quelque chose pendant boot, donc après quelques décisecondes, j'ai lancé la commande gdb. Si vous avez plus de temps (par exemple, vous devez déboguer un module qui est chargé manuellement), alors le timing n'a pas vraiment d'importance.

gdb vous permet de spécifier des commandes qui doivent être exécutées au démarrage. Cela rend l'automatisation un peu plus facile. Pour se connecter à QEMU (qui devrait déjà être démarré), casser une fonction et continuer l'exécution, utilisez:

gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux
3
répondu Lekensteyn 2014-03-22 12:15:56

lorsque vous essayez de lancer vmlinux exe en utilisant gdb, alors la première chose sur gdb est de lancer cmds:

(gdb) cible remote localhost: 1234

(gdb) break start_kernel

(suite)

cela cassera le noyau à start_kernel.

2
répondu Ritesh 2013-08-19 03:27:09

comme pour moi la meilleure solution pour déboguer le noyau - est d'utiliser gdb de L'environnement Eclipse. Vous devez juste définir le port approprié pour gdb (doit être le même avec un que vous avez spécifié dans la chaîne de lancement qemu) dans la section de débogage à distance. Voici le manuel: http://www.sw-at.com/blog/2011/02/11/linux-kernel-development-and-debugging-using-eclipse-cdt/

1
répondu Alex Hoppus 2014-03-22 17:12:42