Не было бы неплохо просто набрать debug
перед любой командой, чтобы иметь возможность отладить ее с помощью gdb
на уровне оболочки?
Под ним эта функция. Это даже работает со следующим:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
Это вызов, когда вы не можете ничего контролировать, все переменное, может содержать пробелы, переводы строки и метасимволы оболочки. В этом примере in
, out
, two
и three
- произвольные другие команды, которые принимают или генерируют данные, которые не должны быть повреждены.
После bash
функция почти без проблем запускает gdb
в такой среде [ Gist ]:
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
-ex r \
--args "$@";
}
Пример того, как применить это: Просто введите debug
перед:
До:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
После того, как:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Вот и все. Теперь отладка с gdb
абсолютно проста. За исключением нескольких деталей или более:
gdb
не завершается автоматически и, следовательно, сохраняет перенаправление ввода-вывода открытым до выхода из gdb
. Но я называю это функцией.
Вы не можете легко передать argv0
в программу, как с exec -a arg0 command args
. Следующие должны сделать этот трюк: после exec-wrapper
изменить "exec
на "exec -a \"\${DEBUG_ARG0:-\$1}\"
.
Есть открытые FD выше 1000, которые обычно закрыты. Если это проблема, замените 0<&1000 1>&1001 2>&1002
на 0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
Вы не можете запустить два отладчика параллельно. Также могут быть проблемы, если какая-то другая команда потребляет /dev/tty
(или STDIN). Чтобы это исправить, замените /dev/tty
на "${DEBUGTTY:-/dev/tty}"
. В некотором другом типе TTY tty; sleep inf
, а затем используйте напечатанный TTY (т.е. /dev/pts/60
) для отладки, как в DEBUGTTY=/dev/pts/60 debug command arg..
. В этом сила Снарядов, привыкни!
Функция объяснила:
1000<&0 1001>&1 1002>&2
удаляет первые 3 FD
- Предполагается, что FD 1000, 1001 и 1002 свободны
0</dev/tty 1>/dev/tty 2>&0
восстанавливает первые 3 FD, чтобы они указывали на ваш текущий TTY. Таким образом, вы можете контролировать gdb
.
/usr/bin/gdb -q -nx -nw
работает gdb
вызывает gdb
на оболочке
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
создает загрузочную оболочку, которая восстанавливает первые 3 FD, которые были сохранены до 1000 и выше
-ex r
запускает программу, используя exec-wrapper
--args "$@"
передает аргументы как указано
Разве это не было легко?