#language ru ## ~-[[DebianWiki/EditorGuide#translation|Translation(s)]]: Русский - [[HowToGetABacktrace|English]] -~ ---- <> == Как получить осмысленный бэктрейс == Эта страница попытается объяснить, как получить осмысленный бэктрейс отладки из воспроизводимой ошибки в программе. В этом примере, мы установим пакет "hello" с отладочными символами или в случае если пакет не доступен, пересоберем и установим его с сохранением отладочной информации. Для справки, знак "#" в начале строки означает, что следующая команда будет выполнена от имени суперпользователя root (или с помощью sudo). "$" в начале строки означает, что следующая команда будет выполнена от имени обычного пользователя. "(gdb)" означает, что вы должны придерживаться набора текста в командной строке приглашения gdb (GNU Debugger). === Установка отладочных символов === Чтобы узнать, имеется ли у отлаживаемого вами пакета зависимость в виде пакета -dbg (например, пакет с исходным кодом ''hello'' и пакет ''hello-dbg'') найдите его с помощью пакетного менеджера. Выполните следующую команду в командной строке. {{{ $ apt-cache search hello | grep dbg p hello-dbg - hello debug symbols }}} Если ничего не нашлось, вам придется пересобрать пакет, согласно описанию в следующем разделе (или особенно если вы сопровождающий пакета, модифицируйте пакет таким образом, чтобы пакет всегда собирался с отладочными символами). Если вы нашли соответствующий пакет, просто установите соответствующую зависимость -dbg, например с помощью {{{ # apt-get install hello-dbg }}} и пропустите процесс пересборки в следующей инструкции и перейдите к запуску gdb. === Пересборка пакета, необходимого для отладки === ''Вы можете пропустить этот раздел, если имеется возможность установить необходимые пакеты(ы) -dbg с предыдущего раздела.'' * Установите основные пакеты разработки и сборочные зависимости для пакета, который нам необходимо собрать. Заметьте, что вы можете пропустить часть про пересборку, и перейти прямо к gdb, однако в таком случае, маловероятно, что вы сможете получить полезный бэктрейс. (Если build-dep выдает ошибку, проверьте наличие строки deb-src в /etc/apt/sources.list.) {{{ # apt-get install build-essential fakeroot gdb # apt-get build-dep hello }}} * Загрузите и пересоберите пакет из исходного кода, с сохранением отладочных символов {{{ $ DEB_BUILD_OPTIONS="nostrip noopt" fakeroot apt-get -b source hello }}} * Установите свежесобранные пакеты. Здесь могут быть несколько собранных пакетов, поэтому удостоверьтесь, что вы устанавливаете только то, что вам нужно. В данном примере созданный пакет называется hello_2.1.1-4_i386.deb. {{{ # dpkg -i hello_2.1.1-4_i386.deb }}} * Вы можете удостовериться, что двоичные файлы, установленные из вашего пакета, имеют отладочные символы, используя команду 'file' или с помощью самого gdb (см. ниже).{{{ $ file /usr/bin/hello # вывод должен быть "not stripped" }}} === Запуск gdb === * Теперь вы можете запустить вашу программу, заменив "[--args]" на любой необходимый вам аргумент:{{{ $ gdb hello ... gdb loads ... (gdb) set pagination 0 (gdb) run [--args] ... hello loads... }}} * Далее попробуйте воспроизвести ошибку. Если все пройдет удачно, произойдет ошибка в программе, и вы вернетесь к окну с приглашением gdb. * Если вам не удалось вызвать ошибку и вместо этого произошло зависание, вы все еще можете получить доступ к приглашению gdb, нажав CTRL+C в окне терминала с запущенным gdb. * На этом этапе можно выполнить: {{{ (gdb) bt }}} * Вы сможете получить большой вывод, который может быть скопирован в письмо с сообщением об ошибке или в другую программу для отправки сообщений об ошибках. * Для завершения работы с gdb, выполните:{{{ (gdb) quit }}} Если проблема была обнаружена в системной библиотеке, такой как libc6, xlibs, или libgtk2.0-0, вам необходимо установить соответствующий пакет -dbg (т.е. libc6-dbg в случае с libc6), затем снова запустить проблемную программу из под gdb. Чаще всего, вы можете получить бэктрейс, где первые несколько строк находятся в malloc() или g_malloc(). Это означает, что ваш бэктрейс не совсем полезен. Наилегкий путь состоит в том, чтобы найти какую-либо полезную информацию, изменив значение переменной MALLOC_CHECK_ на 2. Вы можете выполнить это во время запуска gdb с помощью:{{{ $ MALLOC_CHECK_=2 gdb hello }}} === Дополнительные команды gdb === * Если программа, с который вы собираетесь работать, является многопоточной, вам необходимо получить бэктрейс всех потоков:{{{ (gdb) thread apply all bt }}} * Кое-что еще может здорово помочь в выявлении того, какие переменные были установлены локально на каждом этапе стека:{{{ (gdb) bt full }}} * Вы можете вывести вывод комбинаций предыдущих параметров:{{{ (gdb) thread apply all bt full }}} * Если данный вывод совсем не относится к ошибке, вы можете солхранить только несколько вызовов, к примеру первые 10:{{{ (gdb) thread apply all bt full 10 }}} * Если у вас большой бэктрейс, вы можете сохранить вывод gdb в файл (по умолчанию gdb.txt):{{{ (gdb) set logging on }}} * Для проверки на наличие отладочных символов в двоичном файле:{{{ $ gdb (gdb) symbol-file /usr/bin/hello # вы можете увидеть что-то вроде этого: Reading symbols from /usr/bin/hello ... done Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb) # А вот это крайне нежелательно: Reading symbols from /usr/bin/hello...(no debugging symbols found)...done }}} === Отладка ошибок X (Xorg) === Если программа, написанная на GTK выдала ошибку; т. е. Вы увидели ошибку вида: {{{ The program 'preview1' received an X Window System error. }}} в этом случае, вы можете попробовать запустить программу с аргументом `--sync`, и сломать функцию `gdk_x_error` для того, чтобы получить бэктрейс, вот так: {{{ (gdb) break gdk_x_error (gdb) run --sync }}} === Прочие полезные ссылки === * [[http://wiki.debian.org/XStrikeForce/XserverDebugging|Debugging the Xorg server]] * [[http://wiki.ubuntu.com/Backtrace|Ubuntu Backtrace page]] Авторы: Ari Pollak и Loic Minier --AriPollak and LoicMinier CategoryDebugging