Пошаговая процедура QEMU + GDB, протестированная на хосте Ubuntu 16.10
Чтобы быстро начать с нуля, я сделал минимальный полностью автоматизированный QEMU + Пример Buildroot по адресу: https://github.com/cirosantilli/linux-kernel-module-cheat Основные шаги описаны ниже.
Сначала получите корневую файловую систему rootfs.cpio.gz
. Если он вам нужен, рассмотрите:
только для init
: Пользовательский дистрибутив Linux, который запускает только одну программу, больше ничего | Unix & Linux Stack Exchange Затем в ядре Linux:
git checkout v4.9
make mrproper
make x86_64_defconfig
cat <.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
На другом терминале, предположим, вы хотите начать отладку из 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'
и все готово !!
Информацию о модулях ядра см .: Как отлаживать модули ядра Linux с помощью QEMU? | Переполнение стека
Для Ubuntu 14.04, GDB 7.7.1, требовалось hbreak
, программные точки останова break
игнорировались. В 16.10 это уже не так. См. Также: https: //bugs.launchpad.net / ubuntu / + source / qemu-kvm / + bug / 901944
Беспорядочное отключение
и то, что последует за ним, призвано обойти ошибку:
Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000
Связанные темы:
См. также:
Известные ограничения:
-O0
: Как деоптимизировать ядро Linux и скомпилировать это с -O0? | Переполнение стека максимального завершения
: Прерывание завершения табуляции для больших двоичных файлов | Stack Overflow Вероятно, какой-то угловой случай, который не был рассмотрен в этом патче. Так что ulimit -Sv 500000
- это разумное действие перед отладкой. В частности, взорвался, когда я завершил вкладку file
для аргумента filename
аргумента sys_execve
как в: Может ли системный вызов sys_execve () в Ядро Linux получает как абсолютные, так и относительные пути? | Переполнение стека Следующее работает только в systemd v236 и новее:
StandardOutput=file:/var/log/flume-ng/log1.log
StandardError=file:/var/log/flume-ng/log2.log
как задокументировано здесь .
Если systemd старше v236, вы можете использовать:
ExecStart=/bin/sh -c 'exec /usr/bin/my_binary [arguments] >/var/log/flume-ng/log1.log 2>/var/log/flume-ng/log2.log'
Обратите внимание, что таким образом все содержимое файлов журналов будет перезаписываться при каждом перезапуске службы.
Если вы хотите вести журнал файлов между перезапусками службы и просто добавлять в него новые строки журнала:
# Works only in systemd v240 and newer!
StandardOutput=append:/var/log/flume-ng/log1.log
StandardError=append:/var/log/flume-ng/log2.log
Если systemd старше v240, вы можете использовать:
ExecStart=/bin/sh -c 'exec /usr/bin/my_binary [arguments] >>/var/log/flume-ng/log1.log 2>>/var/log/flume-ng/log2.log'
exec
означает, что программа оболочки будет заменена программой my_binary
после настройки перенаправления без форка. Так что не будет никакой разницы от запуска my_binary
сразу после ExecStart=
.
Для записи в файл без перезаписи (требуется system.d версии 240+):
StandardOutput=append:/var/log/flume-ng/log1.log
StandardError=append:/var/log/flume-ng/log2.log
или
StandardOutput=append:/var/log/flume-ng/log.log
StandardError=inherit
Надеюсь, это кому-нибудь поможет. для Унунту
[Unit]
Description=name-service
After=syslog.target
After=mysql.service
Requires=mysql.service
[Service]
Type=idle
PIDFile=/path_to_PID/****.pid
WorkingDirectory=/path_to_directory
User=root
Group=root
ExecStart=****.py
Restart=always
TimeoutStartSec=1min
RestartSec=1min
KillMode=process
StandardOutput=append:/path_to_log/service.log
StandardError=append:/path_to_log/service_error.log
[Install]
WantedBy=multi-user.target
для CENTOS
[Unit]
Description=name-service
After=syslog.target
After=mysql.service
Requires=mysql.service
[Service]
Type=idle
PIDFile=/path_to_PID/****.pid
WorkingDirectory=/path_to_directory
User=root
Group=root
ExecStart=****.py >>/path_to_log/log.log
Restart=always
TimeoutStartSec=1min
RestartSec=1min
KillMode=process
[Install]
WantedBy=multi-user.target
«После» и «Требуется» по необходимости. Внимание «Пользователь» и «Группа»
Другой вариант :добавить ведение журнала внутри исполняемых скриптов.