Visual c++ for linux development: практика использования для windows разработчиков

Введение

Откровенно говоря, программа GNU GDB довольно многофункциональная.
Пошаговая отладка — лишь одна из ее возможностей. В этой статье я
попытался описать те лишь команды GDB, которые позволяют проводить
удобную пошаговую отладку программ, написанных на Free Pascal.

Чтобы программу можно было отлаживать, она должна быть откомпилирована
с ключом -g.

Поскольку GDB ориентирован не на Pascal, а на C и C++, то
использование GDB для отладки Pascal программ иногда сопряжено с
неудобствами.

Приведу список подводных камней, обнаруженных мною и разработчиками
Free Pascal (перечисленных в user’s manual).

  1. Отладочная информация в Free Pascal генерируется в верхнем
    регистре. Поэтому имена всех переменных, процедур, функций при
    использовании GDB должны указываться БОЛЬШИМИ БУКВАМИ.

  2. GDB не воспринимает тип extended (ведь в C такого типа нет).
    Обойти эту неприятность можно, если, например, включить в код
    такие строки

    ...
    type
    {$IFDEF DEBUG}
      dbl = double;
    {$ELSE}
      dbl = extended;
    {$ENDIF}
    ...
    var x : dbl;
    ...
    
  3. К элементам многомерных массивов нужно обращаться в C-шной манере,
    а именно, команда

    	    (gdb) print A
    

    выдаст первую строку массива A. Для просмотра требуемого элемента
    следует писать

    	    (gdb) print A
    
  4. GDB не воспринимает множества.

  5. Есть трудности с поддержкой объектов (см. user’s manual за
    подробностями).

  6. Есть трудности с глобально переопределенными функциями. (за
    подробностями см. user’s manual).

  7. При отладке процедур, функций, расположенных в разных файлах,
    часто возникает несоответствие — смещение строк. Та строка,
    которую GDB показывает текущей, таковой не является, а текущая
    расположена строк эдак на двадцать выше. Это приводит к большим
    неудобствам при пошаговой отладке. Я для себя сделал из этого
    такую мораль — хоть GDB и позволяет отлаживать процедуры,
    описанные в разных файлах, но лучше этой возможностью не
    пользоваться, а на время отладки все вызываемые процедуры, работа
    которых вас заинтересует, помещать в одном файле.

1 Configuring the Linux kernel[edit]

To get debug symbols and add the GDB script (i.e. Linux awareness), the Linux kernel configuration must activate CONFIG_DEBUG_INFO and CONFIG_GDB_SCRIPTS using the Linux kernel Menuconfig tool (Menuconfig or how to configure kernel):

Symbol: DEBUG_INFO 
Location:
  Kernel Hacking --->
    Tracers -->
       -> Compile time checks and compiler options

Symbol: GDB_SCRIPTS 
Location:
  Kernel Hacking --->
    Tracers -->
       -> Compile-time checks and compiler options
         Provide GDB scripts for kernel debugging

CONFIG_DEBUG_INFO and CONFIG_GDB_SCRIPTS are enabled by default in all STM32MPU software Packages, so you have nothing to do.

Where can I learn more about debugging and debuggers?

  • LessTif or Open Motif.
    A window library needed to compile DDD.
  • HP Wildebeest (WDB).
    A port of GDB to PA-RISC/HP-UX, by HP.
  • Insight.
    A very nice GUI for GDB from
    Redhat, the GDB maintainers.
  • KDbg.
    A KDE-based GDB Interface with inspection of variable values in a tree structure.
  • xxgdb.
    The oldest and simplest X interface for GDB and DBX.
  • tgdb.
    A Tcl/Tk GDB interface (similar to Turbo Debugger or
    CodeView).
  • deet.
    A simple and extensible graphical debugger.
  • A list of available Perl debuggers.
    The ultimate Perl reference.
  • A GUI for the Perl Debugger.
    Written in Perl.
  • GNU Nana.
    Improved support for assertions and logging in C and C++.
  • GNU Checker.
    A tool to find memory errors at runtime
  • xwpe.
    A programming environment integrating a program editor with an external debugger.
  • Valgrind.
    No-one developing C or C++ code under Linux/x86 or Linux/PPC should be without it.

Current Maintainer:

Shaunak Saha <shaunak at gnu.org>

Former Maintainers:

Peter Wainwright
<peter dot wainwright at ieee dot org>

Andreas Zeller
<zeller at gnu.org>

Andrew Gaylard <apg at users dot sf dot net>

Jose María Gómez Vergara
<josemaria at jmgv dot org>

GNU’s home page

Please send FSF & GNU inquiries & questions to

gnu at gnu.org.
There are also other ways to contact the FSF.

Please send comments on these web pages to
bug-ddd at gnu.org.

Copyright 2000-2011 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA

Verbatim copying and distribution of this entire article is
permitted in any medium, provided this notice is preserved.

Updated:

$Date: 2018/03/23 14:46:06 $ $Author: th_g $

Исходный текст и машинный код

Вы можете использовать команду , чтобы отобразить cтроки
исходного текста в программные адреса (и наоборот), и
команду , чтобы вывести диапазон адресов в виде
машинных инструкций. При запуске в режиме GNU Emacs, команда
выводит стрелку, указывающую на заданную строку.
Также выводит адреса как в символьной форме, так и в
шестнадцатеричной.

Выводит начальный и конечный адреса скомпилированного кода,
соответствующего строке исходного текста указ-стр. Вы можете
определить строки исходного текста любым способом, воспринимаемым
командой (see section ).

Например, мы можем использовать для определения
положения объектного кода первой строки функции
:

(gdb) info line m4_changequote
Line 895 of "builtin.c" starts at pc 0x634c and ends at 0x6350.

Мы также можем запросить (используя как форму
задания указ-стр), какая строка исходного текста соответствует
определенному адресу:

(gdb) info line *0x63ff
Line 926 of "builtin.c" starts at pc 0x63e4 and ends at 0x6404.

После , адрес, используемый по умолчанию для команды
, меняется на начальный адрес строки, так что `x/i’
достаточно для начала исследования машинного кода (see section ). Этот адрес также сохраняется как значение
вспомогательной переменной (see section ).

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

Следующий пример показывает результат дисассемблирования диапазона
адресов кода HP PA-RISC 2.0:

(gdb) disas 0x32c4 0x32e4
Dump of assembler code from 0x32c4 to 0x32e4:
0x32c4 <main+204>:      addil 0,dp
0x32c8 <main+208>:      ldw 0x22c(sr0,r1),r26
0x32cc <main+212>:      ldil 0x3000,r31
0x32d0 <main+216>:      ble 0x3f8(sr4,r31)
0x32d4 <main+220>:      ldo 0(r31),rp
0x32d8 <main+224>:      addil -0x800,dp
0x32dc <main+228>:      ldo 0x588(r1),r26
0x32e0 <main+232>:      ldil 0x3000,r31
End of assembler dump.

Некоторые архитектуры имеют несколько широко используемых наборов мнемоник
инструкций или другой синтаксис.

Выбрать набор инструкций для использования при дисассемблировании программы
командами и .

В настоящее время, эта команда определена только для Intel x86. Вы
можете установить набор-инструкций в или .
По умолчанию установлено , диалект AT&T используется по
умолчанию ассемблерами Unix на архитектурах, базирующихся на x86.

Go to the first, previous, next, last section, table of contents.

Спонсоры:

Хостинг:

Maxim ChirkovДобавить, Поддержать, Вебмастеру

Командные файлы

Командный файл для GDB—это файл, состоящий из строк с
командами GDB. Такие файлы могут также включать комментарии
(строки, начинающиеся с #). Пустая строка в командном файле
ничего не делает; она не означает повторение последней команды, как это
было бы при вводе с терминала.

Когда вы вызываете GDB, он автоматически выполняет команды из
своих файлов инициализации. Это файлы, называющиеся
`.gdbinit' в Unix и `gdb.ini' в DOS/Windows. Во время старта,
GDB делает следующее:

  1. считывает файл инициализации (если он существует) в вашем
    домашнем каталоге.

  2. Обрабатывает ключи и операнды командной строки.

  3. Считывает файл инициализации (если он существует) в текущем рабочем
    каталоге.

  4. Считывает командные файлы, заданные с помощью ключа `-x’.

Файл инициализации в вашем домашнем каталоге может
устанавливать параметры (такие как `set complaints’), которые влияют на
последующую обработку ключей и операндов командной строки. Файлы
инициализации не выполняются, если вы используете ключ `-nx’
see section .

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

  • VxWorks (ОС реального времени Wind River Systems): `.vxgdbinit'

  • OS68K (ОС реального времени Enea Data Systems): `.os68gdbinit'

  • ES-1800 (эмулятор Ericsson Telecom AB M68000): `.esgdbinit'

Вы также можете запросить выполнение командного файла с помощью команды
:

Выполнить командный файл имя-файла.

Строки командного файла выполняются последовательно, при этом они
не выводятся. Ошибка в любой команде завершает выполнение всего
командного файла.

Команды, запрашивающие подтверждение в интерактивном режиме, при
выполнении в командном файле выполняются без запросов. Многие
команды GDB, обычно выводящие сообщения о своих действиях,
опускают эти сообщения при вызове из командных файлов.

Installing and using Insight (GDB User Interface) for remote debugging

Many people, don’t like to use the command line and prefer to use a graphical interface, especially since it makes it easy to add breakpoints and see both the assembly and source code.

There is no binary packages for Insight in Debian/Ubuntu, so it has to be cross-compiled.

First, download and extract the source code:

Shell

ftp://sourceware.org/pub/insight/releases/insight-6.8-1a.tar.bz2
tar xjvf insight-6.8-1a.tar.bz2

1
2

ftp//sourceware.org/pub/insight/releases/insight-6.8-1a.tar.bz2

tar xjvf insight-6.8-1a.tar.bz2

Then configure, build and install it to run on Intel x86 and support ARM targets:

Shell

cd insight-6.8-1
./configure —host=i686-linux-gnu —target=arm-linux-gnueabi —disable-werror  —prefix=/usr
make
sudo make install

1
2
3
4

cdinsight-6.8-1

./configure—host=i686-linux-gnu —target=arm-linux-gnueabi—disable-werror —prefix=/usr

make

sudo makeinstall

Now run arm-linux-gnueabi-insight without arguments.

Set the path where your ARM library are located. Click on View->Console to start the gdb console and type:

Shell

set sysroot=/usr/arm-linux-gnueabi

1 set sysroot=/usr/arm-linux-gnueabi

where /usr/arm-linux-gnueabi is the sysroot path. The arm libraries are in /usr/arm-linux-gnueabi/lib directory in my case. This path depends on the cross-toolchain you use. I’m using EmDebian.

If you don’t set the sysroot, you’ll end up with dynamic library errors as you run the program. For example:

Click load your debug program by clicking File->Open, it will automatically load the source files and set a breakpoint in the main. You can also set your own breakpoints in the source (Red square in the screenshot below).

Insight Source & Assembler Windows

Click on Run->Connect to target and the Target Selection Windows should pop-up. Select GDBserver/TCP in the Target drop-down menu and enter the IP and port to connect to your board.

Insight Target Selection Window

Click on OK. That’s it. You can now browse the code to add breakpoints, monitor variable…. To run the program, select Run->Run or Click on the “blue running man” icon.

Support CNX Software — Donate via PayPal, become a Patron on Patreon, or buy review samples

Setting breakpoints to stop the execution of a program

You can debug your C++ program more efficiently if you use breakpoints. Breakpoints refer to instructions that stop the execution at specific moments. For instance, you should set breakpoints in places you suspect to be problematic.

It is possible to set breakpoints in two ways:

  • Setting a line at which execution stops.
  • Setting a function name to stop execution at.

The following example sets a breakpoint at the start of the function:

This example sets a breakpoint at a specific line (20):

This example adds a breakpoint at the beginning of a class member function:

This example lists all of the breakpoints:

The following example deletes a breakpoint at line 20:

I have found a bug! How do I report it?

bug tracker

  • Please try to see whether your bug has already been reported. You can
    browse or
    search
    the bug tracker.
  • Please read the section «Bugs and How to Report Them» toward
    the end of the DDD Manual.
  • Be sure to include a copy of your ~/.ddd/log file
    which tells your DDD configuration as well as the interaction between
    DDD and the underlying command-line debugger.
  • Remember, the more (relevant) information you put in your bug report,
    the more likely it is to be fixed rapidly.

The purpose of reporting a bug is to enable the bug to be fixed for
the sake of the whole community of users. You may or may not receive a
response; the maintainers will send one if that helps them find or
verify a fix. Most GNU maintainers are volunteers and all are
overworked; they don’t have time to help individuals and still fix the
bugs and make the improvements that everyone wants. If you want help
for yourself in particular, you may have to hire someone for technical support.

If you are willing to help fixing DDD bugs, you can
subscribe
to the bug-ddd mailing list or access its archives.

6 Debugging Linux kernel decompression[edit]

  • Configure the GDB and the OpenOCD to be attached on the running target in .
  • Add a breakpoint in the boot_jump_linux function from U-Boot source file, arch/arm/lib/bootm.c.
The U-Boot function jumps to the Linux kernel module previously loaded.
Breakpoints have to be set at a specific line in the function:
...
   kernel_entry(0, machid, r2); -> please check the line number in the arch/arm/lib/bootm.c file, i.e. line 400 
...
# Insert a breakpoint in the load_module function:
(gdb) b arch/arm/lib/bootm.c:400
Breakpoint 1 at 0xc0100c70: arch/arm/lib/bootm.c:400. (2 locations)
(gdb) continue

From the UART console, run the command to boot the Linux kernel image:

Board $> run bootcmd

In the GDB, check that the software execution stopped at the expected breakpoint. You can then check the kernel_entry address (address of the Linux kernel compressed image that will be executed, i.e. zImage)

(gdb) p kernel_entry
$1 = (void (*)(int, int, uint)) 0xc2000040

Load the compressed Linux kernel symbol file (see symadd_vmlinux_compressed variable define in the path_env.gdb configuration file used in the GDB).

(gdb) symadd_vmlinux_compressed

Set a breakpoint in the decompress_kernel function from Linux kernel:

(gdb) b decompress_kernel
Breakpoint 2 at 0xc2000ae4: file <your_linux_kernel_source_dir>/arch/arm/boot/compressed/misc.c, line 150

Proceed with software execution. It then stops at the breakpoint set in the decompress_kernel function:

(gdb) continue

From this point, you can start a debugging session.

Installing and running gdbserver on the target board

First of all you need to install gdbserver on the target board. Assuming you use a Debian based distribution:

Shell

apt-get install gdbserver

1 apt-getinstall gdbserver

If you distribution, does not have binary repository, you can download gdb source code and cross-compile gdbserver.

Once gdbserver is installed, (cross-)compile your application in debug mode and start gdbserver as follows:

Shell

gdbserver target_ip:target_port prog_dbg

1 gdbserver target_iptarget_port prog_dbg

Where target_ip and target_port are respectively the IP address of the board and the chosen TCP port, and prog_dbg, the program under test compile in debug mode (CFLAGS=-g).

Определяемые пользователем команды-ловушки

Вы можете определять ловушки, которые являются специальным
видом определяемых пользователем команд. Всякий раз, когда вы выполняете
команду `foo’, перед ней выполняется определенная пользователем команда
`hook-foo’ (без параметров), если она существует.

Кроме того, существует псевдокоманда `stop’. Определение
(`hook-stop’) велит выполняться связанным с ней командам при каждом
останове вашей программы: перед выполнением команд точек останова, перед
выводом на экран сообщений или кадров стека.

Например, чтобы игнорировать сигналы во время выполнения
в пошаговом режиме, но обрабатывать их при нормальном выполнении, вы
можете определить:

define hook-stop
handle SIGALRM nopass
end

define hook-run
handle SIGALRM pass
end

define hook-continue
handle SIGLARM pass
end

Вы можете определить ловушку для любой однословной команды
GDB, но не для синонимов команды; вам следует определить
ловушку для базового имени команды, например, , но не
. Если во время выполнения вашей ловушки возникает ошибка,
выполнение команд GDB останавливается, и
он выдает приглашение (до того, как введенная вами
команда начнет выполняться).

Если вы попытаетесь определить ловушку, не соответствующую никакой
известной команде, вы получите предупреждение от команды .

21.4 Ключи configure

Здесь приводится обзор ключей и параметров , которые
наиболее часто используются для построения GDB.
также имеет несколько других ключей, не представленных
здесь. См. Info-файл файл `configure.info’, нода `What Configure Does’, для полного
объяснения .

configure 
          [--prefix=каталог]
          [--exec-prefix=каталог]
          [--srcdir=имя-каталога]
           
          [--target=цель]
          платформа

Если хотите, можете вводить ключи с одним `-‘, а не с `—‘;
но вы можете сокращать имена ключей, если используете `—‘.

Отображает быстрый обзор, как вызывать .

Конфигурировать источник, чтобы устанавливать программы и файлы в
подкаталогах `каталога'.

Конфигурировать источник, чтобы устанавливать программы в каталог
`каталог'.

Предупреждение: использование этого ключа требует GNU
или другой программы , реализующей возможности
.
Используйте этот ключ для создания конфигураций в каталогах,
отдельных от исходного каталога GDB. Кроме всего прочего, вы
можете использовать его для построения (или поддержки)
нескольких конфигураций одновременно в отдельных каталогах.
записывает файлы, относящиеся к конфигурации, в текущий
каталог, но принимает меры, чтобы можно было использовать источники в
каталоге имя-каталога. создает каталоги внутри
рабочего каталога параллельно с исходными каталогами внутри имя-каталога.

Конфигурировать только тот уровень каталогов, где выполняется
; не распространять конфигурацию на подкаталоги.

Конфигурировать GDB для кросс-отладки программ, выполняемых на
указанной цели. Без этого ключа GDB конфигурируется для
отладки программ, выполняемых на той же машине (платформе), что и сам
GDB.

Нет никакого удобного способа сгенерировать список всех доступных
целей.

Конфигуровать GDB для выполнения на указанной платформе.

Нет никакого удобного способа сгенерировать список всех допустимых
платформ.

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

НазадПредВверхСледВперед

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector