Программирование PC Опции GCC для поддержки отладки Tue, November 12 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Опции GCC для поддержки отладки Печать
Добавил(а) microsin   

У компилятора GCC есть различные специальные опции, которые используют для отладки либо вашей программы, либо самого GCC.

-g

Вставит в выходной файл отладочную информацию в традиционном (native) формате операционной системы (stabs, COFF, XCOFF, или DWARF). GDB может работать с этой отладочной информацией.

На большинстве систем используются формат stabs. Опция -g позволяет выдать дополнительную отладочную информацию, которую может использовать только GDB. Эта дополнительная информация улучшает отладку в GDB, однако может привести к краху или других отладчиков или к запрету чтения программы. Если вы хотите управлять генерируемой отладочной информацией, используйте опции -gstabs+, -gstabs, -gxcoff+, -gxcoff, -gdwarf-1+, -gdwarf-1 или -gvms (см. далее).

В отличие от большинства других компиляторов C, GCC позволяет использовать опцию -g вместе с опцией управления оптимизацией -O. Сокращения, которые принимает оптимизированный код, могут иногда давать результаты с сюрпризом: некоторые переменные, которые вы декларировали, могут просто исчезнуть; управление потоком может перейти туда, где вы его вообще не ожидали; некоторые операторы могут не выполняться, потому что они вычисляют постоянные результаты, или эти результаты не используются, или их значения уже были вычислены; некоторые операторы могут выполняться в разных местах, поскольку они были перемещены из циклов.

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

Следующие опции полезны, когда GCC генерирует код с добавлением более одно формата отладочной информации.

-ggdb

Генерирует отладочную информацию, предназначенную для использования отладчиком GDB. Это означает использование самого выразительного формата из доступных (DWARF 2, stabs, или native-формат, если ни один из них не поддерживается), включая расширения GDB, если это вообще возможно.

-gstabs

Создание отладочной информации в формате stabs (если он поддерживается), без расширений GDB. Это формат, используемый отладчиком DBX на большинстве систем BSD. На системах MIPS, Alpha и System V Release 4 эта опция создает вывод отладочной информации stabs, которую не понимает DBX или SDB. На системах System V Release 4 эта опция требует ассемблера GNU.

-gstabs+

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

-gcoff

Создание отладочной информации в формате COFF (если он поддерживается). Этот формат использует отладчик SDB на большинстве систем System V более ранних, чем System V Release 4.

-gxcoff

Создание отладочной информации в формате XCOFF (если он поддерживается). Этот формат использует отладчик DBX на системах IBM RS/6000.

-gxcoff+

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

-gdwarf

Создание отладочной информации в формате DWARF version 1 format (если он поддерживается). Этот формат используется отладчиком SDB на большинстве систем System V Release 4.

-gdwarf+

Создание отладочной информации в формате DWARF version 1 (если он поддерживается), с использованием расширений GNU, которые понимает только отладчик GNU (GDB). Использование этих расширений обычно приводит к падению других отладчиков или к невозможности чтения отлаживаемой программы.

-gdwarf-2

Создание отладочной информации в формате DWARF version 2 (если он поддерживается). Этот формат используется отладчиком DBX на IRIX 6.

-gvms

Создание отладочной информации в формате VMS debug (если он поддерживается). Этот формат используется отладчиком DEBUG на системах VMS.

-glevel
-ggdblevel
-gstabslevel
-gcofflevel
-gxcofflevel
-gvmslevel

Запрашивает создание отладочной информации, и также используют указание уровня level, сколько её должно быть. Уровень по умолчанию Level 2.

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

Level 3 включает дополнительную информацию, такую как определения макросов, присутствующих в программе. Некоторые отладчики поддерживают расширение макросов, когда вы используете -g3.

Обратите внимание,  что для того, чтобы избежать коллизии между DWARF1 debug level 2 и DWARF2, ни -gdwarf, ни -gdwarf-2 не поддерживают объединение уровней отладки. Вместо этого используйте дополнительную опцию -glevel, чтобы поменять уровень отладочной информации DWARF1 или DWARF2.

-p

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

-pg

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

-a

Генерирует дополнительный код, чтобы записать информацию профиля для базовых блоков, где записано, сколько раз был выполнен каждый базовый блок, начальный адрес базового блока и имя функции, содержащей этот базовый блок. Если используется -g, то также будет записаны номер строки и имя файла начала базового блока. Если это не переопределено описанием машины, то действие по умолчанию заключается в добавлении к текстовому файлу bb.out.

Эти данные предназначены для анализа программой наподобие tcov [3]. Однако имейте в виду, что формат этих данных не тот, который ожидает tcov. Так или иначе должен быть расширен GNU gprof [4] для обработки этих данных.

-Q

Заставляет компилятор печатать каждое имя компилируемой функции, и печатать некоторую статистику по каждому завершаемому проходу.

-ftime-report

Заставляет компилятор печатать некоторую статистику о времени, затраченном на завершение каждого прохода.

-fmem-report

Заставляет компилятор печатать некоторую статистику о постоянном выделении памяти при завершении.

-fprofile-arcs

Специальная обработка во время компиляции (instrument arc) для генерации данных покрытия или упорядочивания блоков, предназначенных для профайлинга. Во время выполнения программа записывает, сколько раз была выполнена каждая ветвь, и сколько было затрачено на это процессорного времени. Когда скомпилированная программа завершается, она записывает эти данные в файл имяисходногофайла.da для имени каждого файла исходного кола.

Для упорядочивания блоков профайлинга (profile-directed block ordering) компилируйте программу с опцией -fprofile-arcs плюс с опциями оптимизации и генерации кода, сгенерируйте информацию arc profile путем запуска программы на выбранной нагрузке, и затем скомпилируйте программу снова с теми же опциями оптимизации и опциями генерации кода плюс опция -fbranch-probabilities (см. документацию по опциям, управляющим оптимизацией [5]).

Другое применение -fprofile-arcs это использование её вместе с gcov, когда применена опция -ftest-coverage. GCC поддерживает 2 метода определения покрытия кода (code coverage): опции, которые поддерживает gcov, а также опции -a и -ax, которые записывают информацию в текстовые файлы. Опциям, поддерживающим gcov не нужно делать инструментальную обработку для каждой arc в программе, поэтому программа, скомпилированная с ними, работает быстрее, чем программа, скомпилированная с помощью -a, которая добавляет код инструментальной обработки к каждому базовому блоку программы. Однако это приводит к компромиссу: поскольку у gcov нет счетчиков выполнения всех ветвей программы, он должен запускаться со счетчиками выполнения для инструментально обработанных ветвей, и затем провести итерации по графу выполнения кода программы, пока не будет разрешен граф полностью. Таким образом, gcov работает несколько медленнее, чем программа, которая использует информацию из -a и -ax.

С опцией -fprofile-arcs для каждой функции вашей программы компилятор GCC создаст граф выполнения кода (program flow graph), затем находит связующее дерево для этого графа. Только те arc-и, которые не входят в связующее дерево, должны быть подвергнуты инструментальной обработке: компилятор добавляет код для подсчета количества раз, сколько выполняется каждая arc. Когда у arc только одна точка выхода или единственный вход в блок, код инструментальной обработки может быть добавлен в блок; иначе должен быть создан новый базовый блок, который должен содержать код инструментальной обработки.

Эта опция позволяет оценить вероятности ветвления и вычислить счетчики выполнения базовых блоков. Как правило, счетчики выполнения базовых блоков предоставляемые -a, не дают достаточно информации для оценки всех вероятностей ветвления.

-ftest-coverage

Создает файлы данных для утилиты покрытия кода gcov (code-coverage, см. [6]). Имена файлов начинаются с имени вашего файла исходного кода программы:

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

имяисходногофайла.bbg
Список всех arc в графе выполнения кода программы. Это позволит gcov сделать реконструкцию графа потока выполнения кода в программе, так что он может просчитать счетчики выполнения всех базовых блоков и arc из  информации в файле имяисходногофайла.da.

Используйте опцию -ftest-coverage вместе с опцией -fprofile-arcs; последняя добавит информацию инструментальной обработки в программу, которая запишет счетчики выполнения в другой файл данных:

имяисходногофайла.da
Runtime-счетчики выполнения arc, используемые совместно с arc-информацией в файле имяисходногофайла.bbg.

Данные покрытия (coverage data) будут лучше отображены на файлы исходного кода, если опция -ftest-coverage использовалась без оптимизации.

-dletters

Создает дампы отладки при компиляции в моменты, указанные letters. Это используется для отладки компилятора. Имена файлов для большинства дампов создаются путем добавления номера прохода и слова для имени файла исходного кода (например foo.c.00.rtl или foo.c.01.sibling). Ниже перечислены варианты для letters и их назначение:

A Снабжает вывод ассемблера различной отладочной информацией.

b Дамп в файл file.14.bp после вычисления вероятностей ветвления.

B Дамп в файл file.29.bbro после переупорядочивания блоков.

c Дамп в файл file.16.combine после комбинирования инструкции.

C Дамп в файл file file.17.ce после первого преобразования условного ветвления (if conversion).

d Дамп в файл file.31.dbr после отложенного планирования ветвления.

D Дамп в обычный вывод всех макроопределений по окончании работы препроцессора.

e Дамп в файлы file.04.ssa и file.07.ussa после SSA-оптимизаций.

E Дамп в файл file.26.ce2 после второго if conversion.

f Дамп в файл file.15.life после анализа времени жизни (life analysis).

F Дамп после очистки кодов ADDRESSOF, в файл file.09.addressof.

g Дамп после глобального выделения регистров, в файл file.21.greg.

h Дамп после финализации кода обработки EH, в файл file.02.eh.

k Дамп после преобразования reg-to-stack, в файл file.28.stack.

o Дамп после post-reload оптимизаций, в файл file.22.postreload.

G Дамп после GCSE, в файл file.10.gcse.

i Дамп после оптимизаций вызова одноуровневого узла (sibling call) в файл file.01.sibling.

j Дампо после оптимизации первого jump, в файл file.03.jump.

k Дамп после преобразования из регистров в стек, в файл file.32.stack.

l Дамп после локального выделения регистров, в файл file.20.lreg.

L Дамп после оптимизации цикла, файл file.11.loop.

M Дамп после выполнения зависящего от машины прохода реорганизации, в файл file.30.mach.

n Дамп после изменения нумерации регистров, в файл file.25.rnreg.

N Дамп после прохода перемещения регистров, в файл file.18.regmove.

r Дамп после генерации RTL, в файл file.00.rtl.

R Дамп после второго прохода планирования (second scheduling), в файл file.27.sched2.

s Дамп после CSE (включая jump-оптимизацию, которая иногда следует за CSE), в файл file.08.cse.

S Дамп после первого прохода планирования (first scheduling), в файл file.19.sched.

t Дамп после второго прохода CSE (включая jump-оптимизацию, которая иногда следует за CSE), в файл file.12.cse2.

w Дамп после второго прохода (second flow pass), в файл file.23.flow2.

X Дамп после удаления мертвого кода (SSA dead code elimination), в файл file.06.ssadce.

z Дамп после peephole-прохода, в файл file.24.peephole2.

a Генерирует все перечисленные выше дампы.

m Печатает статистику по использованию памяти в конце запуска. Печать осуществляется в стандартный поток ошибок.

p Снабжает вывод ассемблера аннотацией с комментарием, который указывает, какой использовался шаблон и альтернатива. Также печатается длина каждой инструкции.

P Дамп RTL в вывод ассемблера в виде комментария перед каждой инструкцией. Также включает аннотацию -dp.

v Для каждого другого указанного файла дампа (кроме file.00.rtl), делает дамп представления представления графа потока управления, подходящего для просмотра с помощью VCG, в файл file.pass.vcg.

x Просто генерирует RTL для функции вместо её компиляции. Обычно используется вместе с r.

y Дамп в стандартный вывод ошибок информации отладки во время парсинга.

-fdump-unnumbered

При выполнении дампов отладки (см. выше описание опции -d) подавляет в выводе номера инструкций и номера строк. Это делает более целесообразным использование diff на дампах отладки для вызовов компилятора с различными опциями, в частности с опцией -g и без опции -g.

-fdump-translation-unit (только C и C++)
-fdump-translation-unit-options (только C и C++)

Дамп в файл представления древовидной структуры для всей единицы трансляции. Имя файла формируется путем добавления .tu к имени файла исходного кода. Если используется форма -options, то опции управляют подробности дампа, как описано опциями -fdump-tree.

-fdump-class-hierarchy (только C++)
-fdump-class-hierarchy-options (только C++)

Дамп в файл представления каждой иерархии класса и таблицы виртуальных функций. Имя файла формируется путем добавления .class к имени файла исходного кода. Если используется форма -options, то опции управляют подробностями дампа, как описано опциями -fdump-tree.

-fdump-tree-switch (только C++)
-fdump-tree-switch-options (только C++)

Управляет дампом в файл различных стадий обработки дерева промежуточного языка. Имя файла формируется путем добавления специфичного суффикса переключателя к имени файла исходного кода. Если используется форма -options, то опции это список отделенных через - опций, которые управляют деталями дампа. Не все опции применимы для всех дампов, так что опции, которые не имеют смысла, игнорируются. Доступны следующие опции:

address Печатает адрес для каждого узла. Обычно это не имеет смысла так как меняется в зависимости от среды и исходного файла. Его основное использование заключается в связывании файла дампа со средой отладки.

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

all Включает все опции.

Доступны следующие 3 дампа:

original Дамп перед любой оптимизацией, основанной на дереве, в файл file.original.

optimized Дамп после любой оптимизации, основанной на дереве, в файл file.optimized.

inlined Дамп после вставки inline-функции, в файл file.inlined.

-fpretend-float

При работе кросс-компилятора делает вид, что целевая машина использует тот же формат плавающей точки, что и машина хоста. Это приводит к некорректному выводу фактических констант плавающей точки, однако реальная последовательность инструкций будет вероятно такой же, как и с GCC, запущенном на целевой машине.

-save-temps

Постоянно хранить обычные "временные" промежуточные файлы; размещать их в текущей директории, и давать имена на основе файла исходного кода. Таким образом, компиляция foo.c с опциями -c-save-temps сгенерирует файлы foo.i и foo.s, а также foo.o. Это создаст выходной файл препроцессора foo.i, хотя компилятор теперь обычно использует встроенный препроцессор.

-time

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

          # cc1 0.12 0.01
          # as 0.00 0.01

Первое число на каждой строке это "user time", которое потрачено на выполнение самой программы. Второе число это "system time", потраченное время на выполнение подпрограмм операционной системы от имени программы. Оба числа в секундах.

-print-file-name=library

Печатает полное абсолютное имя библиотечного файла library, которая будет использоваться при линковке, и ничего другого не делает. С этой опцией GCC ничего не компилирует и не линкует; он просто печатает имя файла.

-print-multi-directory

Печатает имя директории, соответствующее multilib, выбранной любыми другими ключами командной строки. Предполагается, что эта директория присутствует в GCC_EXEC_PREFIX.

-print-multi-lib

Печатает сопоставление имен каталогов multilib с ключами компилятора, которые из включают. Имя директории отделяется от ключей точкой с запятой (;), и каждый ключ начинается @ вместо -, без пробелов между несколькими ключами. Предполагается, что это упростит шелл-обработку.

-print-prog-name=program

Наподобие -print-file-name, однако ищет такую программу, как cpp.

-print-libgcc-file-name

То же самое, что и -print-file-name=libgcc.a.

Это полезно, когда вы используете -nostdlib или -nodefaultlibs но вы хотите сделать линковку с libgcc.a. Вы можете сделать:

         gcc -nostdlib files... `gcc -print-libgcc-file-name`

-print-search-dirs

Печатает имя сконфигурированной директории инсталляции и список директорий программы и библиотечных директорий gcc вместе с search, и ничего больше не делает.

Это полезно, когда gcc печатает сообщение о проблеме инсталляции, cannot exec cpp0: No such file or directory. Чтобы решить эту проблему, вам либо нужно поместить cpp0 и другие компоненты компилятора туда, где gcc ожидает их найти, или вы можете установить переменную окружения GCC_EXEC_PREFIX в каталог, куда вы их установили. Не забудьте про завершающий символ '/'. См. документацию по использование переменных окружения вместе с GCC [7].

-dumpmachine

Печатает целевую машину компилятора (например, i686-pc-linux-gnu), и ничего больше не делает.

-dumpversion

Печатает версию компилятора (например, 3.0), и ничего больше не делает.

-dumpspecs

Печатает встроенные спецификации компилятора, и ничего больше не делает (это используется, когда GCC собирает самого себя). См. Spec Files [8].

[Примеры использования опций gcc для поддержки отладки]

Ниже во врезках показаны реальные примеры использования опций отладки -g и -fsanitize=address, с помощью которых я отловил ошибки доступа мимо буфера и утечки памяти.

При компиляции без отладки я использовал следующий makefile (очистка запускалась командой make clean, а компиляция make linux):

CFLAGS_LINUX   := -D LINUX

INCLUDE := -Imcu/vsp/common INCLUDE += -Imcu/vsp/hook INCLUDE += другие пути поиска подключаемых файлов

SRC := main.c SRC += blupdater.c SRC += crc.c SRC += другие модули программы

linux: gcc $(CFLAGS_LINUX) -pthread -o acmutil $(SRC) -lm $(INCLUDE) -L./lib -no-pie
clean: rm *.o acmutil -f

Эта командная строка для gcc не включала в себя поддержку отладочной информации, и в случае ошибки вывод программы был мало информативным:

acmutil[2840851]: segfault at 0 ip 000000000040307d sp 00007fffffffb750 error 4
 in acmutil[402000+6000] likely on CPU 1 (core 1, socket 0)
Mar 27 07:11:13 0001NBB0203LZB4 kernel: [1693851.888321] Code: 00 48 8b 45 e8
 48 89 c7 e8 90 29 00 00 8b 45 e4 89 c7 e8 15 f9 ff ff 89 45 fc 81 7d fc 00 01
 00 00 75 17 48 8b 05 33 82 10 00 < 0f> b7 00 66 3d ff 05 75 07 c7 45 fc 04 01
 00 00 8b 45 fc c9 c3 f3

Но если в командную строку добавить опции отладки -g -fsanitize=address:

gcc $(CFLAGS_LINUX) -pthread -o acmutil $(SRC) -lm $(INCLUDE) -L./lib -no-pie -O0 \
 -g -fsanitize=address

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

09:18:39(3914): UnRegisterMessagesV2 0
Запуск ROM-загрузчика на скорости 230400
Отправка RAM-загрузчика stage1
scenario/grus.boot
100%
Переход на скорость 1M
Отправка RAM-загрузчика stage2
scenario/grus.boot
99%===================================================================
3433800==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62d00000995c at pc 0x7ffff743fe57 bp 0x7fffffffd0e0 sp 0x7fffffffc898
READ of size 256 at 0x62d00000995c thread T0 #0 0x7ffff743fe56 in __interceptor_write src/libsanitizer/sanitizer_common/
sanitizer_common_interceptors.inc:1146 #1 0x40e733 in StreamWrite ~/National/vsp_sdk/tools/acmutil/linux_port.c:124 #2 0x40b5de in MessageSend ~/National/vsp_sdk/tools/acmutil/message.c:200 #3 0x4036ae in SendAndReceive ~/National/vsp_sdk/tools/acmutil/main.c:225 #4 0x408c94 in GX8002_upload_RAM_bootloader ~/National/vsp_sdk/tools/acmutil/gxupdater.c:86 #5 0x404187 in RunCommand ~/National/vsp_sdk/tools/acmutil/main.c:369 #6 0x404dcc in RunScenario ~/National/vsp_sdk/tools/acmutil/main.c:612 #7 0x4052ec in Execute ~/National/vsp_sdk/tools/acmutil/main.c:683 #8 0x405d2a in main ~/National/vsp_sdk/tools/acmutil/main.c:830 #9 0x7ffff7029d8f in __libc_start_call_main sysdeps/nptl/libc_start_call_main.h:58 #10 0x7ffff7029e3f in __libc_start_main_impl csu/libc-start.c:392 #11 0x402bb4 in _start (~/National/vsp_sdk/tools/acmutil/acmutil+0x402bb4)

0x62d00000995c is located 0 bytes to the right of 38236-byte region [0x62d000000400,0x62d00000995c)
allocated by thread T0 here: #0 0x7ffff74b4887 in __interceptor_malloc src/libsanitizer/asan/asan_malloc_linux.cpp:145 #1 0x40c9a4 in ReadFile ~/National/vsp_sdk/tools/acmutil/misc.c:247 #2 0x403c1b in RunCommand ~/National/vsp_sdk/tools/acmutil/main.c:307 #3 0x404dcc in RunScenario ~/National/vsp_sdk/tools/acmutil/main.c:612 #4 0x4052ec in Execute ~/National/vsp_sdk/tools/acmutil/main.c:683 #5 0x405d2a in main ~/National/vsp_sdk/tools/acmutil/main.c:830 #6 0x7ffff7029d8f in __libc_start_call_main sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow src/libsanitizer/sanitizer_common/
sanitizer_common_interceptors.inc:1146 in __interceptor_write Shadow bytes around the buggy address: 0x0c5a7fff92d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a7fff92e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a7fff92f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a7fff9300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c5a7fff9310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c5a7fff9320: 00 00 00 00 00 00 00 00 00 00 00[04]fa fa fa fa 0x0c5a7fff9330: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a7fff9340: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a7fff9350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a7fff9360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c5a7fff9370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==3433800==ABORTING

Добавление опций -g -fsanitize=address также позволило легко обнаружить места в программе, где происходило несколько раз выделение памяти с помощью malloc, и эта память после использования не освобождалась. Следующее сообщение выводилось в консоль после завершения программы:

==3443387==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 186224 byte(s) in 1 object(s) allocated from:
#0 0x7ffff74b4887 in __interceptor_malloc src/libsanitizer/asan/asan_malloc_linux.cpp:145 #1 0x40ca92 in ReadFile ~/National/vsp_sdk/tools/acmutil/misc.c:247 #2 0x4042e1 in RunCommand ~/National/vsp_sdk/tools/acmutil/main.c:385 #3 0x404eba in RunScenario ~/National/vsp_sdk/tools/acmutil/main.c:617 #4 0x4053da in Execute ~/National/vsp_sdk/tools/acmutil/main.c:688 #5 0x405e18 in main ~/National/vsp_sdk/tools/acmutil/main.c:835 #6 0x7ffff7029d8f in __libc_start_call_main sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: 186224 byte(s) leaked in 1 allocation(s).

[Ссылки]

1. Options for Debugging Your Program or GCC site:gcc.gnu.org.
2. Отладка консольных приложений Linux.
3. The tcov Profiling Command site:docs.oracle.com.
4. The GNU Profiler site:gnu.org.
5. Options That Control Optimization site:gcc.gnu.org.
6. gcov: a Test Coverage Program site:gcc.gnu.org.
7. Environment Variables Affecting GCC site:gcc.gnu.org.
8. Specifying subprocesses and the switches to pass to them site:gcc.gnu.org.

 

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


Защитный код
Обновить

Top of Page