Debug - Getting Traces (Русский)
Ссылки по теме
Эта статья описывает создание отладочного пакета и получение с его помощью отладочной информации для отправки разработчикам в отчётах об ошибках.
Contents
Package names
Во время отладки, при получении backtrace (пример ниже):
[...] Backtrace was generated from '/usr/bin/epiphany' (no debugging symbols found) Using host libthread_db library "/lib/libthread_db.so.1". (no debugging symbols found) [Thread debugging using libthread_db enabled] [New Thread -1241265952 (LWP 12630)] (no debugging symbols found) 0xb7f25410 in __kernel_vsyscall () #0 0xb7f25410 in __kernel_vsyscall () #1 0xb741b45b in ?? () from /lib/libpthread.so.0 [...]
строки вида ??
и (no debugging symbols found)
показывают, что необходимая отладочная информация, такая, как названия функций, файлов, библиотек, отсутствует в отлаживаемом файле. Проверить, какому пакету принадлежит исполняемый файл или библиотека можно, например, с помощью pacman:
# pacman -Qo /lib/libthread_db.so.1 /lib/libthread_db.so.1 is owned by glibc 2.5-8
Пакет glibc версии 2.5-8. Следует составить список пакетов, которые необходимо заменить для отладки.
PKGBUILD
Чтобы собрать пакет из исходного кода нужно получить файл PKGBUILD. См. ABS для пакетов из официальных репозиториев и AUR#Acquire build files для пакетов из AUR.
Compilation settings
pacman получает параметры компиляции с отладочной информацией из переменных DEBUG_CFLAGS
и DEBUG_CXXFLAGS
. Чтобы включить отладку, нужно включить опцию makepkg debug
и выключить опцию strip
.
Если нужно собрать всего один пакет с отладочной информацией, достаточно внести в его файл PKGBUILD
options=(debug !strip)
Если же нужно собирать много пакетов, или makepkg не будет использоваться без отладочной информации, то можно внести в файл /etc/makepkg.conf
OPTIONS+=(debug !strip)
Также, можно включить одновременно обе опции debug
и strip
, в таком случае отладочная информация бует удалена из пакета, и будет помещена в отдельный пакет foo-debug
.
Некоторые пакеты, такие как glibc, очищаются независимо. В таком случае, для сохранения информации нужно найти в PKGBUILD секцию наподобие:
strip $STRIP_BINARIES usr/bin/{gencat,getconf,getent,iconv,iconvconfig} \ usr/bin/{ldconfig,locale,localedef,nscd,makedb} \ usr/bin/{pcprofiledump,pldd,rpcgen,sln,sprof} \ usr/lib/getconf/* [[ $CARCH = "i686" ]] && strip $STRIP_BINARIES usr/bin/lddlibc4 strip $STRIP_STATIC usr/lib/*.a strip $STRIP_SHARED usr/lib/{libanl,libBrokenLocale,libcidn,libcrypt}-*.so \ usr/lib/libnss_{compat,db,dns,files,hesiod,nis,nisplus}-*.so \ usr/lib/{libdl,libm,libnsl,libresolv,librt,libutil}-*.so \ usr/lib/{libmemusage,libpcprofile,libSegFault}.so \ usr/lib/{audit,gconv}/*.so
и удалить, там, где это возможно.
Qt
В дополнение к этому нужно добавить в configure
файла PKGBUILD
опцию -developer-build
. По-умолчанию, -developer-build
указывает компилятору опцию -Werror
, что может привести к ошибке компиляци. Чтобы избежать этого, может понадобиться также добавить -no-warnings-are-errors
.
KDE applications
KDE использует для сборки cmake. Замените -DCMAKE_BUILD_TYPE
на Debug
.
Building and installing the package
Сборка пакета осуществляется из директории, содержащей PKGBUILD, командой makepkg
. Это может занять некоторое время:
# makepkg
Установка собранного пакета:
# pacman -U имя-пакета.tar.gz
Трассирование
Текущий backtrace (or stack trace) может быть получен, например, с помощью gdb, (GNU Debugger). Запуск осуществляется так:
# gdb /path/to/file
или:
# gdb (gdb) exec /path/to/file
Если путь присутствует в $PATH
, его можно не указывать.
В gdb
, введите run
и аргументы для передачи запускаемому файлу:
(gdb) run --no-daemon --verbose
После запуска выполните действия, приводящие к возникновению бага. Также можно включить логгирование происходящего командой:
(gdb) set logging file trace.log (gdb) set logging on
Чтобы сохранить текущий backtrace в файл trace.log в текущей директории, введите:
(gdb) thread apply all bt full
Выход осуществляется так:
(gdb) set logging off (gdb) quit
Также, можно отлаживать и уже запущенные приложения, зная их PID:
# gdb --pid=$(pidof firefox) (gdb) continue