Анализ gnome-shell с помощью Valgrind

Материал из Rosalab Wiki
Перейти к: навигация, поиск

Для того, чтобы с помощью Valgrind искать ошибки (утечки памяти, некорректные обращения к памяти, и т.п.) в gnome-shell нужно выполнить несколько не очень очевидных операций. Вот как всё делается.

Подготовка

Чтобы не набирать длинные команды каждый раз, полезно подготовить пару скриптов и положить их, скажем, в ~/bin/ на той системе, где нужно проверить gnome-shell.

xenv.sh - этот скрипт установит необходимые переменные окружения:

gnome_session=$(pgrep -u $USER gnome-session)
eval export $(sed 's/\o000/\n/g;' < /proc/$gnome_session/environ | grep DISPLAY)
eval export $(sed 's/\o000/\n/g;' < /proc/$gnome_session/environ | grep XAUTHORITY)
eval export $(sed 's/\o000/\n/g;' < /proc/$gnome_session/environ | grep DBUS_SESSION_BUS_ADDRESS)

vg_gnome_shell.sh - этот скрипт запускает gnome-shell под Valgrind с нужными параметрами (подробности ниже):

G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind --leak-check=full --show-reachable=yes \
  --fullpath-after= --num-callers=40 --log-file=vg.log \
  --suppressions=clutter-2.0.suppressions \
  gnome-shell --replace

То, что Valgrind считает ошибками, - не всегда ошибки. Некоторые ложные сообщения об ошибках можно убрать, передав Valgrind'у при запуске файл(ы) с соотв. данными (suppression files).

В скрипте vg_gnome_shell.sh используется suppression file clutter-2.0.suppressions, предполагается, что он лежит в текущем каталоге.

Чтобы в call stack в отчёте Valgrind были указаны строки кода, а не просто адреса, стоит установить пакеты с отладочной информацией. Вот список с одной из систем, где проводится анализ gnome-shell:

    gnome-shell-debuginfo
    gnome-desktop3-debuginfo
    gnome-session-debuginfo
    gnome-settings-daemon-debuginfo
    gnome-themes-standard-debuginfo
    gnome-utils-debuginfo
    gnome-vfs2-debuginfo
    gtk+3.0-debuginfo
    gtk-css-engine-debuginfo
    gtkmm3.0-debuginfo
    dbus-glib-debuginfo
    glib2.0-debuginfo
    glibc-debuginfo
    js-debuginfo
    pbmtozjs-debuginfo
    libjsw-debuginfo
    gjs-debuginfo
    json-glib-debuginfo
    libsvg-cairo-debuginfo
    cairo-dock-debuginfo
    gtkcairo-debuginfo
    librsvg-debuginfo
    cairo-debuginfo
    cairo-dock-plugins-debuginfo
    cairomm-debuginfo
    pixman-debuginfo
    cogl-debuginfo
    gegl-debuginfo
    mesa-debuginfo
    glew-debuginfo
    clutter-debuginfo
    clutter-gtk-debuginfo
    pango-debuginfo
    harfbuzz-debuginfo
    fontconfig-debuginfo
    mutter-debuginfo
    dconf-debuginfo

Какие-то из них, вероятно, не нужны, но кашу маслом не испортишь.

Запуск

Стоит залогиниться в системе, как обычно. Затем - перейти, например, в вирт. консоль №2 (ctrl-alt-f2) и залогиниться там тем же пользователем.

Теперь надо установить нужные переменные среды, используя подготовленный выше скрипт:

$ . ~/bin/xenv.sh

Соотв. переменные будут выставлены так же, как для данного пользователя они стоят в X11-сессии. Обратите внимание: точка перед ~/bin/xenv.sh нужна. Скрипт не выполняется в новом shell'е, а "source'ится" в текущий.

Если нужно для использовать suppression файлы для Valgrind, стоит проверить, что в vg_gnome_shell.sh правильно указаны пути к ним.

Теперь можно запускать gnome-shell под Valgrind.

$ sh ~/bin/vg_gnome_shell.sh

Запуск может занять несколько минут: Valgrind может достаточно сильно замедлить загрузку и работу анализируемого приложения. Когда gnome-shell выведет сообщение о том, что она запустилась, можно переключаться в вирт. консоль, где запущены X11. Вероятно, после этого придётся подождать ещё несколько минут пока там появится всё необходимое.

После этого можно работать с gnome-shell. В конце - выйти из системы или убить gnome-shell каким-то другим способом.

Отчёт Valgrind будет в файле vg.log в текущем каталоге.

Параметры запуска Valgrind и переменные окружения

В vg_gnome_shell.sh используется следующее.

  • G_SLICE=always-malloc G_DEBUG=gc-friendly - эти переменные полезно ставить при анализе любых GTK-приложений с помощью Valgrind;
  • --leak-check=full - выводить полную информацию о найденных утечках памяти.
  • --show-reachable=yes - выводить информацию о блоках, которые анализируемое приложение могло бы освободить перед свои завершением (указатели на них сохранились), но не освободило.
  • --fullpath-after= - выводить полный путь к файлам с исходным кодом. По умолчанию, Valgrind выдаёт только имя файла без пути. Это очень неудобно, например, если анализируемое приложение использует несколько библиотек: неясно, где искать это файл, к какому из компонентов приложения он относится. Если же поставить --fullpath-after=, отчёт будет понятнее.
  • --num-callers=40 - выводить до 40 уровней в call stack. По умолчанию, Valgrind выводит не более 10-12 вызовов функций в каждом call stack. Этого часто недостаточно. 30-40 для GTK- и Qt-приложений обычно хватает.
  • --log-file=vg.log - сохранять отчёт Valgrind в файле vg.log в текущем каталоге.
  • --suppressions=clutter-2.0.suppressions - использовать указанный suppression file, чтобы Valgrind не выдавал соотв. ложных сообщений об ошибках. Опцию --suppressions можно использовать несколько раз - полезно, если нужно задать несколько suppression файлов.

Как показала практика, --trace-children=yes лучше не использовать, если отчёт Valgrind выводится в локальный файл. Valgrind при этом может затирать часть своих результатов, а также вести себя странно и в других отношениях. Если всё-таки хочется проверить как gnome-shell, так и порождаемые им процессы, можно попробовать выводить отчёт Valgrind не в локальный файл, а по сети (см. описание опции --log-socket, а также это пояснение).

Подробная информация о параметрах Valgrind доступна здесь: http://valgrind.org/docs/manual/manual-core.html