Linux debugging with gdb

Debugging kernel and modules via gdbВ¶

The kernel debugger kgdb, hypervisors like QEMU or JTAG-based hardware interfaces allow to debug the Linux kernel and its modules during runtime using gdb. Gdb comes with a powerful scripting interface for python. The kernel provides a collection of helper scripts that can simplify typical kernel debugging steps. This is a short tutorial about how to enable and use them. It focuses on QEMU/KVM virtual machines as target, but the examples can be transferred to the other gdb stubs as well.

RequirementsВ¶

gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true for distributions)

SetupВ¶

Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and www.qemu.org for more details). For cross-development, https://landley.net/aboriginal/bin keeps a pool of machine images and toolchains that can be helpful to start from.

Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports CONFIG_FRAME_POINTER, keep it enabled.

Install that kernel on the guest, turn off KASLR if necessary by adding “nokaslr” to the kernel command line. Alternatively, QEMU allows to boot the kernel directly using -kernel, -append, -initrd command line switches. This is generally only useful if you do not depend on modules. See QEMU documentation for more details on this mode. In this case, you should build the kernel with CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR.

Enable the gdb stub of QEMU/KVM, either

at VM startup time by appending “-s” to the QEMU command line

during runtime by issuing “gdbserver” from the QEMU monitor console

Start gdb: gdb vmlinux

Note: Some distros may restrict auto-loading of gdb scripts to known safe directories. In case gdb reports to refuse loading vmlinux-gdb.py, add:

/.gdbinit. See gdb help for more details.

Attach to the booted guest:

Examples of using the Linux-provided gdb helpersВ¶

Load module (and main kernel) symbols:

Set a breakpoint on some not yet loaded module function, e.g.:

Continue the target:

Load the module on the target and watch the symbols being loaded as well as the breakpoint hit:

Dump the log buffer of the target kernel:

Examine fields of the current task struct(supported by x86 and arm64 only):

Make use of the per-cpu function for the current or a specified CPU:

Dig into hrtimers using the container_of helper:

List of commands and functionsВ¶

The number of commands and convenience functions may evolve over the time, this is just a snapshot of the initial version:

Detailed help can be obtained via “help ” for commands and “help function ” for convenience functions.

© Copyright The kernel development community.

Источник

Debug Applications with gdb Command In Linux

gdb is the short form of GNU Debugger. A debugger is a tool used to search and find and get detailed information about bugs in application binaries. gdb is popular in the Linux community which is used by most of the IDE, Programming tools event in Android IDE’s. In this tutorial, we will look at how to start and use the basic features of gdb .

Example Code

During this tutorial, we will use the following simple application code which is written in C Programming language. This code just calculates factorial.

Install gdb For Ubuntu, Debian, Mint, Kali

We can install gdb for Ubuntu, Debian, Mint and Kali with the following lines.

Install gdb For CentOS, RHEL, Fedora

Installation for gdb in RPM based distros like CentOS, RHEL and Fedora

Compile Application

We will start by compiling our example application. We will use GCC or GNU Compiler Collection which is a defacto compiler for the Linux environment. gcc can be installed with the following line if not installed.

Now we will compile our application just providing the source code file name which is poftut.c in this case.

Compile Application with Debug Info

We can debug all ready compiled applications but there is some useful option that can be used to provide more information about the application while debugging. We can enable debugging information which can be used to match debugging code with source code and provides more detailed information. We can use -g option while compiling with gcc like below.

Читайте также:  Htc windows phone 8s или

Setup Debugging By Running Executable

We can start applications for debugging with different methods but the most basic and practical way is starting with the application name. We will start poftut app like below.

We can see gdb interactive shell is started after loading app and related debugging information.

Start Debugging

We can start debugging the given application by using run command. But keep in mind that this will start process run which will end in this case without a problem. While running the standard output will be put to the screen. and the last thing is exit status which is normal in this case.

Inspect Crashes

One of the use case for gbd is inspecting crashes to find the cause. The application can be exited by crashing and in this case crash information is get by gdb . We can list crash information with backtrace command like below.

Breakpoints

In big applications, we generally need to inspect the flow of the application. While inspecting we need to look specific situation which is important for us. We can set breakpoints that will stop the execution of the application. We can check the current register and memory values easily. In this example, we set a break for the line printf .

List Breakpoints

We can list existing breakpoints and their hit count with the info break command like below.

List Register Values

We can list current register values with info registers command like below. Keep in mind that register values are very volatile and changes in each step in general.

Stepping

During debugging we generally want to go one step further which will change current memory and register values. We can use step command for this.

We can also spefiy the step count which is 3 in this case.

Источник

Debugging with GDB on linuxВ¶

This page describes how to setup GDB on Linux to debug issues with ArduPilot with SITL.

IntroductionВ¶

This guide assumes that you have already successfully use SITL on your machine following the instructions to setup SITL .

Installing GDBВ¶

To install GDB on Linux, please use package installer. If you are on a debian based system (such as Ubuntu or Mint), simply use the apt install command :

Setting up SITLВ¶

In order to use GDB, you need to configure your SITL build with debug symbols. Use :

Raw GDBВ¶

This method use the command line gdb for debugging. There are 3 possible ways:

  • run SITL under gdb from the start.

Example: The following launches the default Copter SITL:

You can also attach MAVProxy if required

  • run gdb with SITL launch script sim_vehicle.py : simply add -D -G to build and launch SITL with debug symbols and in gdb directly :

The SITL launch script also get some other feature already provided like launch gdb stopped, put some breakpoints, etc.

  • attach to already running SITL process. You can get the SITL process id with pidof [vehicle type : arducopter, arduplane, ardurover] .

When gdb is launched you should be able to use it to debug ArduPilot like any other program. If you don’t know how to use gdb from commandline, please look on the net for some tutorial, a simple one can be found here. Don’t forget that you can crash you drone on SITL safely !

With IDEВ¶

For those that are not used to commandline, there are plenty ways to use gdb for debugging with GUI. Here are some.

For Ubuntu user, the default protections will prevent you to attach gdb to SITL from IDE : see here. This will lead to an error message ptrace: Operation not permitted on your first attempt to attach to a local process.

In this case, do one of the following:

  • To disable this restriction temporarily, enter the command:
  • To disable this restriction permanently, open the /etc/sysctl.d/10-ptrace.conf file for editing and change the line kernel.yama.ptrace_scope = 1 to kernel.yama.ptrace_scope = 0. To apply the changes immediately, enter the above command. Alternatively, run sudo service procps restart or simply restart your system.

VS CODEВ¶

Open ArduPilot directory. Go in debug menu and then Add a configuration, it should open a launch.json file for debugging configuration. You should have a big Add a configuration button.

Click and select C/C++ : (gdb) Attach option.

Fill the “program” line with

Or the other vehicle you want.

Launch SITL with launch script sim_vehicle.py : simply add -D to build and launch SITL with debug symbols :

And now start debugging with VSCode, it will ask you for a process name : type arducopter or the other vehicle name you want to debug.

Now you can put breakpoint in the code and start debugging !

CLIONВ¶

Jetbrains website Clion is a paid product, but free for student !

Open ArduPilot directory. Launch SITL with launch script sim_vehicle.py : simply add -D to build and launch SITL with debug symbols :

Читайте также:  Подключение сетевого диска роутера windows 10

In Run menu, select Attach to Local Process.

, and type arducopter or the other vehicle name you want to debug.

Now you can put breakpoint in the code and start debugging !

© Copyright 2021, ArduPilot Dev Team.

Источник

Краткий гайд по использованию GDB

В этом коротком туториале мы рассмотрим базовые приёмы работы с GDB, а также посмотрим как можно (и нужно) подготавливать файлы к отладке для GDB.

GDB — переносимый отладчик проекта GNU, который работает на многих UNIX-подобных системах и умеет производить отладку многих языков программирования, включая Си, C++, Free Pascal, FreeBASIC, Ada, Фортран, Python3, Swift, NASM и Rust.

Почему именно GDB? Всё легко, он уже установлен на многих UNIX-подобных системах, лёгок в использовании и поддерживает много языков. Работа с ним оказывается очень лёгкой, а также его можно подключить к VSCode и другим редакторам кода (Включая Vim, NeoVim (ясное дело), Emacs, Atom и далее)

Подготовка файлов

Для примера мы возьмём файлы .cpp и будем проходиться по ним вдоль и поперёк.

Для того чтобы нам пройтись по такому файлу нам нужно скомпилировать его с помощью G++ с использованием флага -g (это действительно важно, без этого флага, программа не будет корректно работать в GDB).

Python-файл вы можете продебажить с помощью этой команды:

Для Java вы просто можете использовать jdb, который уже идёт в комплекте c JDK.

Также, если вам не хочется компилировать всё ручками, вы можете просто использовать сайт OnlineGDB, там просто нужно вставить код и нажать debug, а затем внизу откроется консоль, где вы сможете писать команды.

Использование GDB

Как только мы зашли в GDB нам выводится следующее сообщение:

Последняя строка говорит о том, нормально ли запустился файл.

Теперь нужно посмотреть, где в нашем файле точка вхождения (строка, откуда наша программа начинает свою работу), в случае cpp это метод main() . Находим номер этой строки c помощью команды list и пишем её порядковый номер с буквой b (также можно просто указать имя функции b main тоже работает):

Далее запускаем программу с помощью комманды r :

Также вы можете включить TUI, с помощью комбинации клавиш

Для того, чтобы посмотреть на какой мы сейчас строке, нужно написать f :

Для того, чтобы сделать шаг, нужно нажать n (от слова next):

Как мы видим GDB сразу пропускает пустые строки (или строки с комментариями) и переходит к следующей строке.
Предположим, что у нас есть функция, при нажатии n наш отладчик быстро пройдет функцию, не заходя в неё, чтобы зайти в функцию нужно сделать «шаг внутрь» (step-in) или просто клавиша s :

(В примере нет функции, однако шаг step-in все равно будет работать и с обычными инициализациями, условиями и циклами)

Чтобы узнать какие переменные (локальные) сейчас инициализированны в программе нужно написать комманду info locals :

Чтобы вывести только одну переменную, нужно написать print имя_переменной :

Мы можем также изменить переменную с помощью set :

Мы можем также следить за переменными с помощью watch :

Также, если нужно можно посмотреть что в данный момент находится в регистрах ( info registers ):

Чтобы посмотреть какие в данный момент есть breakpoints (точки останова) нужно написать info breakpoints :

Чтобы удалить точку останова del breakpoint_num :

Чтобы прыгнуть к следующей точке останова нужно нажать c :

Мы можем вызывать функции из программы (локальные) с помощью call :

Чтобы продолжить выполнение функции и остановить программу когда она (функция) завершится нужно написать finish или fin :

Стоит уточнить, что нельзя использовать finish в главном методе.

Чтобы завершить выполнение программы, нужно написать kill :

Также можно написать help в любой момент и получить краткую справку, как пользоваться отладчиком

Источник

Удаленная отладка в Linux при помощи связки GDB-gdbserver

Как всем нам известно, процесс отладки это такая вещь, важность которой трудно переоценить. Причем, понимая важность таких методов как дебажное моргание светодиодами и вывод дебажных сообщений в порт, я остаюсь при мнении, что эффективнее пошаговой отладки пока ничего не придумано. Однако, задача пошаговой отладки становится не такой тривиальной в случае программирования под Linux на встраиваемых системах (таких как rasbery pi, virt2real или промышленные процессорные модули).

Данную задачу в Linux призвана решать стандартная связка программ GDB и gdbserver. Идея в том, что пишешь на компе программу (host в терминологии GDB), компилируешь её и заливаешь на целевое устройство (target). Далее запускаешь на целевом устройстве (target) отлаживаемый файл и gdbserver, а на хосте GDB и вперед.

Схему взаимодействия такой отладки кратко можно представить так:

Исполняемый файл — это та самая программа, которую мы хотим удаленно отлаживать. Для корректной работы, экземпляр программы должен находиться не только на целевом усройстве, но и на компе (host) с которого идет отладка.
GDB — программа, которая непосредственно выполняет процесс отладки. Обычно, входит в состав тулчейна GCC и находится там же где и компилятор.
gdbserver — ответная часть GDB, которая запускает исполняемый файл в режиме отладки. Поскольку gdbserver запускается на удаленной стороне (target), то он должен быть собран под целевое устройство, при помощи кросс-компилятора. Собственно, сборке gdbserver’а из исходников и посвящена в основном данная статья.

Читайте также:  Vmware tools для линукса

В моём распоряжении есть плата virt2real, а так же процессорный модуль на базе процессора от TI серии AM335x. Ниже будет показана последовательность действий на примере virt2real, однако, всё тоже самое мною было успешно (и что важно — аналогично) проделано с чипом AM335x.

Примечание: операционная система, установленная на host’e — Ubuntu.12.04.

Подготовка

Создаем в своей домашней директории папку gdb, в которой и будем производить все наши манипуляции. Внутри создаем подпапку downloads:

Скачиваем необходимые нам исходники и распаковываем их. Нам понадобится сам GDB, а так же библиотека termcap (её использует GDB).

Обычно собирают прямо в папке с исходниками, но мы так делать не будем, для того что бы оставить исходники нетронутыми. Это пригодится на случай, если у Вас есть не одна, а несколько разновидностей целевых платформ. Тогда одни и те же скаченные исходники можно будет использовать несколько раз.

Собираем библиотеку termcap

Соответственно, начинаем с библиотеки termcap, потому что она потребуется позднее при сборке самого gdbserver’a. Создаем папку builds, в которую будем собирать наши программы. Внутри создаем папку v2r, в неё поместим все результаты для платформы virt2real. Ну а там уже папку termcap для построения библиотеки termcap. Переходим в созданную директорию.

Указываем системе компилятор и ranlib которые будем использовать. В моем случае это:

Теперь конфигурируем. Потребуется указать 2 параметра: —host и —prefix.

  • Признаюсь, я так и не понял имеет ли значение, что указать в —host. У меня сложилось впечатление, что нет. В любом случае, я не сумел найти внятного объяснения, что именно нужно указывать в данном параметре, поэтому указал префикс компилятора. Т.е. мой компилятор называется arm-none-linux-gnueabi-gcc, поэтому в качестве —host я указал arm-none-linux-gnueabi.
  • В качестве параметра —prefix указываем папку, в которую мы хотим поместить результаты работа (конфигурирования), т.е. ту папку в которой мы сейчас и находимся.

Если все сделано правильно и прошло без ошибок, то в папке

/gdb/builds/v2r/termcap будет создан Makefile.

Далее собираем библиотеку:

Собираем gdbserver

Создаем папку в которой будем собирать сервер и переходим в неё:

Указываем где взять библиотеку termcap:

Конфигурируем аналогично termcap. Тут важно отметить, что мы собираем gdbserver (а не GDB), поэтому файл configure указываем именно из папки /gdb-7.8/gdb/gdbserver:

. Поэтому, тут потребуется имя своего пользователя вписать.

Если все верно, будет создан Makefile. Далее стандартно:

Пробуем

Что бы протестировать процесс отладки создадим короткий Hello world и скомпилируем его под целевую платформу.

Исходный код файла hello.cpp:

Заливаем исполняемый файл hello и наш gdbserver на целевую плату.
Я заливаю в папку /usr/ используя SCP:

Теперь запускаем второй экземпляр терминала и подключаемся к целевой плате по ssh и переходим в папку /usr/:

Запускаем на целевой плате gdbserver, и с его помощью наш исполняемый (отлаживаемый) файл hello. Затем открываем дебажную сессию на понравившемся нам порту:

Возвращаемся на host и запускаем отлаживаемый файл hello с помощью GDB

В ответ должны увидеть приглашение от GDB:

Подключаемся к удаленному gdbserver’у используя указанный выше порт:

Получаем ответ и приглашение для ввода следующей команды:

При этом удаленная сторона (gdbserver на target в лице virt2real) должна увидеть установку дебажной сессии:

Комментарий host target
Ставим breakpoint на main
Идем до Breakpoint’а
Переходим к следующей строке
Переходим к следующей строке
Переходим к следующей строке
Переходим к следующей строке (которой, впрочем нет)
Запускаем программу до конца, что приводит к её завершению

На этом пример пошаговой отладки закончен. Отмечу:

  • для получения полного списка команд можно воспользоваться командой help, а так же почитать книгу, посвященную отладке с помощью GDB (ссылку смотри в конце статьи)
  • «ручная» отладка с помощью GDB дело весьма утомительное, так что рекомендую использовать для этих целей, например, Eclipse. К сожалению, описание подобной отладки в рамках данной статьи, увеличило бы её до неприличных размеров. В конце статьи указана ссылка на очень хорошее англоязычное описание данной темы.

Установка sysroot

Для корректной работы GDB, ему нужны так называемые debugging symbols, которые могут быть считаны из библиотек удаленной операционки (target). Их отсутствие является, например, причиной подобных сообщений:

А потенциально вызывать и другие неприятные проблемы отладки.
Для устранения проблемы GDB на host’е необходимо указать где взять эти самые библиотеки с помощью команды:

Если у Вас на host’е где-то завалялся образ линукса Вашго target’а, то необходимо указать путь до папки с библиотеками.
Или предварительно эти библиотеки выкачать на host:

Возвращаемся в папку с проектом, снова запускаем GDB и указываем путь до библиотек:

Теперь, периодически будут появляться сообщения типа:

Посмотреть список используемых в текущий момент библиотек можно так:

Список используемой «литературы»

/gdb/builds/v2r/termcap
7) cd

/gdb/builds/v2r/termcap
8) export CC=/opt/virt2real-sdk/codesourcery/arm-2013.05/bin/arm-none-linux-gnueabi-gcc
9) export RANLIB=/opt/virt2real-sdk/codesourcery/arm-2013.05/bin/arm-none-linux-gnueabi-ranlib
10) ../../../downloads/termcap-1.3.1/configure —host=arm-none-linux-gnueabi —prefix=

/gdb/builds/v2r/termcap
11) make
12) make install
13) mkdir -p

/gdb/builds/v2r/gdbserver
14) cd

/gdb/builds/v2r/gdbserver
15) export LDFLAGS=»-static -L

/gdb/builds/v2r/termcap/lib»
16) export CFLAGS=»-g -O2 -I

/gdb/builds/v2r/termcap/include»
17) ../../../downloads/gdb-7.8/gdb/gdbserver/configure —host=arm-none-linux-gnueabi —prefix=/home/den1s/gdb/builds/v2r/gdbserver —disable-werror # &&
18) make
19) make install

Источник

Оцените статью