Русский
Русский
English
Статистика
Реклама

Команды GDB, о которых вы возможно не знали


Отладка кода это как охота. Охота на баги.
Amit Kalantri

Что такое GDB


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


Проще говоря GDB отладчик, который работает прямо из консоли.


В данной статье я опишу комманды, о которых раньше не знал, однако, они оказались очень полезными при отладке в GDB.


Рассматривать работу отладчика будем на одной из моих курсовых работ, её тема шифр Цезаря, так что не нужно удивляться названиям переменных или классов. Самого кода вы тут не увидите, ибо это будет лишним для понимания сути действия, однако стоит привести несколько замечаний для полного понимания:


Объект Что значит
Caesar::shift Свойство Caesar
Caesar::ChangeShift Метод Caesar
Caesar::Crypt Метод Caesar

Интерфейс в консоли (TUI)


Я всегда включаю TUI, как только зайду в GDB, он позволяет посмотреть где именно находится выполняемая строка, что идёт перед ней, что дальше. Включается TUI в GDB командой tui enable


С помощью колесика мыши (или стрелок) вы можете перемещаться по псевдо-интерфейсу вверху. С помощью комбинации клавиш Ctrl + p (previous), Ctrl + n (next), вы можете перемещаться между введёнными командами в терминале (окно внизу).


Тезис: Для включения псевдо-интерфейса используют команду tui enable, для выключения tui disable.


Точки останова


Точки останова можно ставить с помощью команды breakpoint (сокращение b).
Можно ставить точки останова исходя из следующих принципов:


  • Точкой останова может являться имя функции (метода) или переменной
  • Точкой останова может являться номер строки
  • Точкой останова может являться адрес памяти, в котором располагается инструкция
  • Точкой останова может являться условие

Если с тремя первыми всё понятно, то третий принцип достаточно интересный.


b Method if variable == value примерно такой синтаксис используется для задания точки останова исходя из выполнения условия.


Например:


(gdb) b Crypt if Caesar::shift == 1Note: breakpoint 2 also set at pc 0x4026e3.Breakpoint 4 at 0x4026e3: file Caesar.h, line 55.

Тут сказано поставить точку останова на методе Crypt(), если свойство класса Caesar под названием shift будет равно 1.


Дополнительно: точки останова можно удалять с помощью команды delete, или её сокращения d.


Тезис: Точки останова можно ставить четыремя способами: с помощью имени объекта, с помощью номера строки, с помощью адреса, с помощью условия.


Шаг с входом в Scope, шаг без входа


Различие между командами next и step (сокращения: n и s) состоит в том, что next выполняет код не входя в Scope (не входя внутрь функции или метода), тогда как step просто выполняет шаг и аналогичен команде Step In в обычных дебагерах.


Дополнительно: для выполнения программы до точки останова используют continue, для выхода из функции в которую вы вошли используют finish или fin.


Тезис: Для вхождения в функцию используется step, для обычного выполнения next.


Просмотр переменных разными способами


Одной из самых главных частей в процессе отладки является просмотр переменных в разных частях программы. Можно делать это с помощью команды print или p, однако есть и более удобные методы для просмотра переменных.


Команда display


Команда display будет показывать значение переменных каждый раз, когда терминал будет доступен для ввода


(gdb) display Caesar::shift1: Caesar::shift = <error: Cannot reference non-static field "shift">(gdb) nBreakpoint 2, Caesar::Crypt (this=0x7fffffffdc30, text="Crypt this text! Btw, xyz") at Caesar.h:551: Caesar::shift = 1(gdb) n1: Caesar::shift = 1(gdb)

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


(gdb) display *stringArrayForOutput@lengthOfArray1: *stringArrayForOutput@lengthOfArray = {"Etarv vjku vgzv! Dvy, zab", "Fubsw wklv whaw! Ewz, abc", "Gvctx xlmw xibx! Fxa, bcd"}(gdb) 

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


Команда explore


Иногда бывает такое, что информации до того много, что путаешься какой объект за что отвечает, для этого создали explore.


explore помогает найти что за объект мелькает перед вашими глазами и рассказывает о нём всё, что может


(gdb) explore Caesar::shift'Caesar::shift' is a scalar value of type 'int'.Caesar::shift = 6(gdb) explore Caesar'Caesar' is a struct/class with the following fields:letters = <Enter 0 to explore this field of type 'std::string'>shift = <Enter 1 to explore this field of type 'int'>

Тезис: Кроме команды print можно использовать команды explore и display.


Запись логов работы программы


Иногда нужно "перемотать вспять" момент, где случилась ошибка, для этого придумана команда record, которая может полностью записывать логи программы в файл или просто в память, дабы перемотать некоторые моменты вспять или посмотреть что именно вызвало ошибку


(gdb) target record-full(gdb) p Caesar::shift$1 = 6(gdb) n(gdb) p Caesar::shift$2 = 7(gdb) reverse-nextNo more reverse-execution history.(gdb) p Caesar::shift$3 = 6

Для того, чтобы остановить запись и удалить все логи нужно ввести record stop, для того, чтобы сохранить все логи в файл нужно ввести record save <имя файла>.


Тезис: GDB имеет возможность создать лог работы программы, с помощью которого, мы можем перемещаться по программе вспять.


Просмотр информации


Просмотреть сразу все локальные переменные можно с помощью info local:


(gdb) info localmainObj = {letters = "abcdefghijklmnopqrstuvwxyz", shift = 1}textForC = "Crypt this text! Btw, xyz"cryptedText = "Dszqu uijt ufyu! Cux, yza"outputVariants = 0x402280 <_start>

Просмотреть все переменные, которые инициализированы можно с помощью info variables:


(gdb) info variablesAll defined variables:File /usr/include/c++/10/bits/basic_string.h:101:    const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::size_type std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::npos;File /usr/include/c++/10/bits/stl_pair.h:83:     static const std::piecewise_construct_t std::piecewise_construct;File /usr/include/c++/10/iostream:74:     static std::ios_base::Init std::__ioinit;Non-debugging symbols:0x00000000004002e8  __abi_tag0x0000000000403000  _IO_stdin_used0x00000000004031b8  typeinfo for std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >0x00000000004031e0  typeinfo name for std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >--Type <RET> for more, q to quit, c to continue without paging--

Чтобы посмотреть все точки останова можно ввести info b:


(gdb) info b   Num     Type           Disp Enb Address            What1       breakpoint     keep y   0x0000000000402633 in Caesar::ChangeShift() at Caesar.h:31        breakpoint already hit 1 time2       breakpoint     keep y   0x00000000004026e3 in Caesar::Crypt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) at Caesar.h:55        breakpoint already hit 1 time

Вы также можете посмотреть тип переменной с помощью команды whatis:


(gdb) whatis Caesar::shifttype = int(gdb) whatis Caesartype = Caesar

Чтобы посмотреть адрес функции, вы можете использовать info address:


(gdb) info address Caesar::CryptSymbol "Caesar::Crypt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)" is a function at address 0x4026be.

Заключение


Есть ещё куча комманд, которые я не привёл в данной статье, однако, на мой взгляд они являются столь полезными, как те, что я перечислил выше. Вы можете почитать больше о разработке на Linux в моём телеграм-канале, если вам это нужно. Я периодически пишу о фулл-стак разработке, а также о Unix-подобных системах.


В данной статье не указаны некоторые комманды, которые легки для понимания, например: run, stop, quit, и т.д. Не указал я их специально, так как статья пытается нести информацию, о которой пользователи GDB возможно могли не знать. Если у вас есть предложения чем можно дополнить статью, с радостью почитаю комментарии.

Источник: habr.com
К списку статей
Опубликовано: 19.03.2021 00:20:03
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

*nix

Отладка

Разработка под linux

Gdb

Полезные команды

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru