Saya akan mencoba:
(gdb) target remote localhost:1234
(gdb) continue
Menggunakan opsi '-s' membuat qemu mendengarkan di port tcp::1234, yang dapat Anda sambungkan sebagai localhost:1234 jika Anda menggunakan mesin yang sama. Opsi '-S' Qemu membuat Qemu menghentikan eksekusi sampai Anda memberikan perintah continue.
Hal terbaik mungkin adalah melihat tutorial GDB yang layak untuk memahami apa yang Anda lakukan. Yang ini terlihat cukup bagus.
Prosedur langkah demi langkah diuji pada host Ubuntu 16.10
Untuk memulai dari awal dengan cepat, saya telah membuat contoh QEMU + Buildroot otomatis minimal di:https://github.com/cirosantilli/linux-kernel-module-cheat/blob/c7bbc6029af7f4fab0a23a380d1607df0b2a3701/gdb-step-debugging.md Major langkah-langkah dibahas di bawah ini.
Pertama dapatkan filesystem root rootfs.cpio.gz
. Jika Anda membutuhkannya, pertimbangkan:
- minimal
init
-hanya gambar yang dapat dieksekusi:https://unix.stackexchange.com/questions/122717/custom-linux-distro-that-runs-just-one-program-nothing-else/238579#238579 - sistem interaktif Busybox:https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902
Kemudian pada kernel 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
Di terminal lain, dari dalam pohon kernel Linux, misalkan Anda ingin memulai debug dari 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'
dan kita selesai!!
Untuk modul kernel, lihat:Bagaimana cara men-debug modul kernel Linux dengan QEMU?
Untuk Ubuntu 14.04, GDB 7.7.1, hbreak
diperlukan, break
breakpoint perangkat lunak diabaikan. Tidak demikian lagi di 16.10. Lihat juga:https://bugs.launchpad.net/ubuntu/+source/qemu-kvm/+bug/901944
disconnect
yang berantakan dan apa yang terjadi setelahnya untuk mengatasi kesalahan:
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
Utas terkait:
- https://sourceware.org/bugzilla/show_bug.cgi?id=13984 mungkin bug GDB
- Balasan paket 'g' jarak jauh terlalu panjang
- http://wiki.osdev.org/QEMU_and_GDB_in_long_mode osdev.org seperti biasa merupakan sumber yang luar biasa untuk masalah ini
- https://lists.nongnu.org/archive/html/qemu-discuss/2014-10/msg00069.html
nokaslr
:https://unix.stackexchange.com/questions/397939/turning-off-kaslr-to-debug-linux-kernel-using-qemu-and-gdb/421287#421287
Batasan yang diketahui:
- kernel Linux tidak mendukung (dan bahkan tidak dapat dikompilasi tanpa tambalan) dengan
-O0
:Bagaimana cara menonaktifkan kernel Linux dan mengompilasinya dengan -O0? - GDB 7.11 akan menghabiskan memori Anda pada beberapa jenis penyelesaian tab, bahkan setelah
max-completions
perbaikan:Interupsi penyelesaian tab untuk binari besar Kemungkinan beberapa kasus sudut yang tidak tercakup dalam tambalan itu. Jadi sebuahulimit -Sv 500000
adalah tindakan bijak sebelum debugging. Meledakkan secara khusus ketika tab saya menyelesaikanfile<tab>
untukfilename
argumensys_execve
seperti di:https://stackoverflow.com/a/42290593/895245
Lihat juga:
- https://github.com/torvalds/linux/blob/v4.9/Documentation/dev-tools/gdb-kernel-debugging. "dokumentasi" kernel Linux resmi pertama
- Linux kernel live debugging, bagaimana melakukannya dan alat apa yang digunakan?
Jawaban BjoernID tidak terlalu berhasil untuk saya. Setelah kelanjutan pertama, tidak ada breakpoint yang tercapai dan saat interupsi, saya akan melihat baris seperti:
0x0000000000000000 in ?? ()
(gdb) break rapl_pmu_init
Breakpoint 1 at 0xffffffff816631e7
(gdb) c
Continuing.
^CRemote 'g' packet reply is too long: 08793000000000002988d582000000002019[..]
Saya kira ini ada hubungannya dengan mode CPU yang berbeda (mode nyata di BIOS vs. mode panjang ketika Linux telah di-boot). Bagaimanapun, solusinya adalah menjalankan QEMU terlebih dahulu tanpa menunggu (yaitu tanpa -S
):
qemu-system-x86_64 -enable-kvm -kernel arch/x86/boot/bzImage -cpu SandyBridge -s
Dalam kasus saya, saya perlu memecahkan sesuatu saat boot, jadi setelah beberapa detik, saya menjalankan perintah gdb. Jika Anda memiliki lebih banyak waktu (mis. Anda perlu men-debug modul yang dimuat secara manual), waktu tidak terlalu penting.
gdb
memungkinkan Anda menentukan perintah yang harus dijalankan saat dimulai. Ini membuat otomatisasi sedikit lebih mudah. Untuk terhubung ke QEMU (yang seharusnya sudah dimulai), hentikan fungsi dan lanjutkan eksekusi, gunakan:
gdb -ex 'target remote localhost:1234' -ex 'break rapl_pmu_init' -ex c ./vmlinux