У меня была та же самая проблемная неспособность переварить несколько страниц вывода от bind
Встроенная команда Bash, особенно при предоставлении -p
опция.
Я поэтому придумал следующие две функции, которые я определил в моем .bashrc
файл:
alias def=function
alias val="declare -r"
alias var=declare
alias final="readonly -f"
def keyfunctions {
if (( "$#" )); then
var a
OPTIND=1
getopts ":auI:E:" a
else
var a=E
OPTIND=1
OPTARG='self-insert$|digit-argument$|do-lowercase-version$'
fi
case "$a" in
a)
bind -p |\
sort |\
pr -l1 -W"$COLUMNS" -"$(($COLUMNS/30))"
;;
I)
bind -p |\
grep -E "$OPTARG" |\
sort |\
pr -l1 -W"$COLUMNS" -"$(($COLUMNS/30))"
;;
E)
bind -p |\
grep -Ev '(^$)|^#|'"$OPTARG" |\
sort |\
pr -l1 -W"$COLUMNS" -"$(($COLUMNS/30))"
;;
u|*)
echo >&2 "$FUNCNAME: Usage: $FUNCNAME [-a|-i <eregex>|-e <eregex>]"
echo >&2 "$FUNCNAME: Invoking $FUNCNAME without arguments assumes -E'self-insert$|digit-argument$|do-lowercase-version$'."
val -i b="$((OPTIND-1))"
if [[ "$OPTARG" == : ]]; then
echo >&2 "$FUNCNAME: Error: Invalid argument \"$OPTARG\" at position $b."
elif [[ "$OPTARG" == ? ]]; then
echo >&2 "$FUNCNAME: Error: Invalid option \"$OPTARG\" at position $b."
fi
;;
esac
}
final keyfunctions
def keymacros {
bind -s |\
sort |\
pr -l1 -W"$COLUMNS" -"$(($COLUMNS/40))"
}
final keyfunctions
Просто выполните вышеупомянутые два определения и решите, нравится ли Вам отсортированный (sort
) и сведенный в таблицу (pr -t
) вывод. width
из столбцов фиксируется, число столбцов касается отношения $(($COLUMNS/$width))
.
Кажется, что Вы ищете gdbserver.
gdbserver является управляющей программой для подобных Unix систем, которая позволяет Вам соединять свою программу с удаленным GDB через целевой удаленный---, но не связываясь в обычном тупике отладки.
На целевой машине
У Вас должна быть копия программы, которую Вы хотите отладить. gdbserver не нужна таблица символов Вашей программы, таким образом, можно разделить программу при необходимости для оставления свободного места. GDB в хост-системе делает всю обработку символа.
target$ gdbserver host:2345 emacs foo.txt
Примечание: Можно также присоединить к выполнению процессов как так:
target$ gdbserver comm --attach pid
Один хост-машина GDB
Вам нужна неразделенная копия Вашей программы, так как GDB нужны символы и отладочная информация. Запустите GDB, как обычно, с помощью названия локальной копии программы как первый аргумент. (Вам, возможно, также понадобится
--baud' option if the serial line is running at anything other than 9600bps.) After that, use target remote to establish communications with gdbserver. Its argument is either a device name (usually a serial device, like
/dev/ttyb'), или дескриптор порта TCP в форме host:PORT. Например:(gdb) target remote the-target:2345
Существует другой метод, обсужденный в руководствах, названных "удаленный тупик". Официальные руководства расположены здесь, Документация GDB, на веб-сайте gnu.org. При просмотре Пользовательского Руководства GDB разделите 20.5, Реализации Удаленного Тупика, объясняет, как использовать эту функцию вместо gdbserver
.
Этот метод описан следующим образом в документах:
Следующий шаг должен принять меры, чтобы Ваша программа использовала последовательный порт для общения с машиной, куда gdb работает (хост-машина). В общих чертах схема похожа на это:
Таким образом, Вы смогли устанавливать последовательный порт и на хосте VM и на госте и отлаживать ядро гостя с помощью этого метода.
KGDB + QEMU шаг за шагом
Мой пример QEMU + Buildroot — хороший способ почувствовать вкус без реального оборудования: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1969cd6f8d30dace81d9848c6bacbb8bad9dacd8#kgdb
Плюсы и минусы по сравнению с другими методами:
Основные шаги:
Скомпилируйте ядро с помощью:
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=у
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
Большинство из них не являются обязательными, но это то, что я тестировал.
Добавьте в команду QEMU:
-append 'kgdbwait kgdboc=ttyS0,115200' \
-serial tcp::1234,сервер,сейчас
Запустите GDB из корня исходного дерева ядра Linux с помощью:
gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
В GDB:
(gdb) c
и загрузка должна завершиться.
В QEMU:
echo g > /proc/sysrq-trigger
И GDB должен сломаться.
Теперь мы закончили, вы можете использовать GDB как обычно:
b sys_write
с
Протестировано в Ubuntu 14.04.
KGDB + Raspberry Pi
Та же установка, что и выше, почти работала на Raspberry Pi 2, Raspbian Jessie 27 мая 2016 г.
Вам просто нужно научиться выполнять шаги QEMU на Pi, которые легко Google:
добавьте параметры конфигурации и перекомпилируйте ядро, как описано в https://www.raspberrypi.org/documentation/linux/kernel/building.md. К сожалению, в ядре по умолчанию отсутствуют параметры. build, в частности без символов отладки, поэтому требуется перекомпиляция.
отредактируйте cmdline.txt
загрузочного раздела и добавьте:
kgdbwait kgdboc=ttyAMA0,115200
подключить gdb
к последовательному порту с помощью:
gdb -ex 'file vmlinux' -ex 'target remote /dev/ttyUSB0'
Если вы не знакомы с серийным номером, посмотрите это: https://www.youtube.com/watch?v=da5Q7xL_OTo Все, что вам нужно, это дешевый адаптер , подобный этому . Убедитесь, что вы можете получить оболочку через последовательный порт, чтобы убедиться, что она работает, прежде чем пробовать KGDB.
do:
echo g | sudo тройник /proc/sysrq-триггер
из сеанса SSH, поскольку серийный номер уже занят GDB.
С помощью этой настройки я смог поставить точку останова в sys_write
, приостановить выполнение программы, вывести список источников и продолжить.
Однако иногда, когда я делал next
в sys_write
, GDB несколько раз зависал и печатал это сообщение об ошибке:
Ignoring packet error, continuing...
, так что я не уверен, что что-то не так с моим setup, или если это ожидается из-за того, что какой-то фоновый процесс делает в более сложном образе Raspbian.