Spec-Zone.ru › GCC 14

3.12 Варианты инструментирования программ

GCC поддерживает ряд командно-строковых параметров, которые управляют добавлением инструментирования во время выполнения в генерируемый код. Например, одна из целей инструментирования — сбор статистики профилирования для поиска горячих точек программы, анализа охвата кода или профилирования оптимизаций. Другой класс инструментирования программ — добавление проверок во время выполнения для обнаружения ошибок программирования, таких как некорректная разыменование указателей или обращение к массивам за пределами допустимых границ, а также преднамеренно враждебных атак, таких как переполнение стека или перехват таблицы виртуальных функций C++. Также имеется общий обработчик, который можно использовать для реализации других форм отслеживания или инструментирования на уровне функций для отладки или анализа программы.

-p
-pg

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

Вы можете использовать атрибут функции no_instrument_function для подавления профилирования отдельных функций при компиляции с этими параметрами. См. Общие атрибуты функций.

-fprofile-arcs

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

Когда скомпилированная программа завершается, она сохраняет эти данные в файл с именем auxname.gcda для каждого исходного файла. Данные могут быть использованы для оптимизации, направленной на профиль (-fbranch-probabilities), или для анализа покрытия тестов (-ftest-coverage). Имя auxname для каждого объектного файла генерируется из имени выходного файла, если оно явно указано и это не окончательный исполняемый файл, иначе это имя базового исходного файла. В обоих случаях удаляется любой суффикс (например, foo.gcda для входного файла dir/foo.c или dir/foo.gcda для выходного файла, указанного как -o dir/foo.o).

Обратите внимание, что если команда непосредственно компонует исходные файлы, соответствующие файлы .gcda будут иметь префикс с именем выходного файла без суффикса. Например, gcc a.c b.c -o binary сгенерирует файлы binary-a.gcda и binary-b.gcda.

-fcondition-coverage

Добавляет код для инструментирования условий программы. Во время выполнения программа записывает, какие условия в условном операторе влияют на принятие решения, что может использоваться для проверки того, что все условия в булевой функции проверяются и оказывают независимое влияние на результат решения. Результат можно прочитать с помощью gcov --conditions.

См. Перемещение файлов данных для поддержки кросс-профилирования.

--coverage

Этот параметр используется для компиляции и компоновки кода, инструментированного для анализа покрытия. Параметр является синонимом для -fprofile-arcs -ftest-coverage (при компиляции) и -lgcov (при компоновке). Подробнее см. документацию по этим параметрам.

  • Скомпилируйте исходные файлы с -fprofile-arcs плюс параметры оптимизации и генерации кода. Для анализа покрытия тестов используйте дополнительный параметр -ftest-coverage. Вам не нужно профилировать каждый исходный файл в программе.
  • Скомпилируйте исходные файлы дополнительно с -fprofile-abs-path, чтобы создать абсолютные пути в файлах .gcno. Это позволяет gcov находить правильные исходные файлы в проектах, где компиляция происходит в различных рабочих каталогах.
  • Скомпонуйте ваши объектные файлы с -lgcov или -fprofile-arcs (последнее подразумевает первое).
  • Запустите программу с репрезентативной рабочей нагрузкой, чтобы сгенерировать информацию о профилировании дуг. Это можно повторить любое количество раз. Вы можете запускать несколько экземпляров своей программы, и при условии, что файловая система поддерживает блокировку, данные файлы будут правильно обновляться. Если не используется строгий вариант языка ISO C, вызовы fork обнаруживаются и обрабатываются правильно, без двойного подсчета.

    Кроме того, объектный файл можно перекомпилировать несколько раз, и соответствующий файл .gcda объединяется, пока исходный файл и параметры компилятора не изменятся.

  • Для оптимизации, направленной на профиль, снова скомпилируйте исходные файлы с теми же параметрами оптимизации и генерации кода плюс -fbranch-probabilities (см. Параметры, управляющие оптимизацией).
  • Для анализа покрытия тестов используйте gcov для получения удобочитаемой информации из файлов .gcno и .gcda. Дополнительную информацию см. в документации gcov.

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

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

-ftest-coverage

Создает файл заметок, который может использовать утилита анализа покрытия gcov (см. gcov—Программа анализа покрытия тестов), чтобы показать покрытие программы. Файл заметок для каждого исходного файла называется auxname.gcno. Ссылка на параметр -fprofile-arcs выше содержит описание auxname и инструкции по генерации данных анализа покрытия тестов. Данные покрытия соответствуют исходным файлам точнее, если вы не используете оптимизацию.

-fprofile-abs-path

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

-fprofile-dir=path

Устанавливает каталог для поиска файлов данных профиля в path. Этот параметр влияет только на данные профиля, сгенерированные с помощью -fprofile-generate, -ftest-coverage, -fprofile-arcs и используемые -fprofile-use и -fbranch-probabilities и их связанными параметрами. Можно использовать как абсолютные, так и относительные пути. По умолчанию GCC использует текущий каталог в качестве path, поэтому файл данных профиля появляется в той же директории, что и объектный файл. Чтобы избежать конфликта имен файлов, если имя объектного файла не является абсолютным путем, мы изменяем абсолютный путь к файлу sourcename.gcda и используем его в качестве имени файла .gcda. Подробности о именовании файлов см. в -fprofile-arcs. См. аналогичный параметр -fprofile-note.

При выполнении исполняемого файла в среде с массовым параллелизмом рекомендуется сохранять профиль в различных папках. Это можно сделать с помощью переменных в path, которые экспортируются во время выполнения:

%p

Идентификатор процесса.

%q{VAR}

Значение переменной среды VAR

-fprofile-generate
-fprofile-generate=path

Включает параметры, обычно используемые для инструментирования приложения, чтобы получить профиль, полезный для последующей перекомпиляции с оптимизацией на основе обратной связи профиля. Вы должны использовать -fprofile-generate как при компиляции, так и при компоновке вашей программы.

Включены следующие параметры: -fprofile-arcs, -fprofile-values, -finline-functions и -fipa-bit-cp.

Если указан path, GCC ищет файлы данных обратной связи профиля в path. См. -fprofile-dir.

Чтобы оптимизировать программу на основе собранной информации о профиле, используйте -fprofile-use. Дополнительную информацию см. в Параметры, управляющие оптимизацией.

-fprofile-info-section
-fprofile-info-section=name

Зарегистрировать информацию о профиле в указанном разделе вместо использования конструктора/деструктора. Имя раздела — name, если оно указано, в противном случае имя раздела по умолчанию — .gcov_info. Указатель на информацию о профиле, сгенерированную с помощью -fprofile-arcs, размещается в указанном разделе для каждого трансляционного блока. Этот параметр отключает регистрацию информации о профиле через конструктор и отключает обработку информации о профиле через деструктор. Этот параметр не предназначен для использования в размещённых средах, таких как GNU/Linux. Он предназначен для автономных сред (например, встроенных систем) с ограниченными ресурсами, которые не поддерживают конструкторы/деструкторы или ввод/вывод файлов библиотеки C.

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

.gcov_info      :
{
  PROVIDE (__gcov_info_start = .);
  KEEP (*(.gcov_info))
  PROVIDE (__gcov_info_end = .);
}

Программа могла бы вывести информацию о профилировании, зарегистрированную в этом наборе компоновщика, например, так:

#include <gcov.h>
#include <stdio.h>
#include <stdlib.h>

extern const struct gcov_info *const __gcov_info_start[];
extern const struct gcov_info *const __gcov_info_end[];

static void
dump (const void *d, unsigned n, void *arg)
{
  const unsigned char *c = d;

  for (unsigned i = 0; i < n; ++i)
    printf ("%02x", c[i]);
}

static void
filename (const char *f, void *arg)
{
  __gcov_filename_to_gcfn (f, dump, arg );
}

static void *
allocate (unsigned length, void *arg)
{
  return malloc (length);
}

static void
dump_gcov_info (void)
{
  const struct gcov_info *const *info = __gcov_info_start;
  const struct gcov_info *const *end = __gcov_info_end;

  /* Obfuscate variable to prevent compiler optimizations.  */
  __asm__ ("" : "+r" (info));

  while (info != end)
  {
    void *arg = NULL;
    __gcov_info_to_gcda (*info, filename, dump, allocate, arg);
    putchar ('\n');
    ++info;
  }
}

int
main (void)
{
  dump_gcov_info ();
  return 0;
}

Подкоманда merge-stream утилиты gcov-tool может использоваться для десериализации потока данных, сгенерированного функциями __gcov_filename_to_gcfn и __gcov_info_to_gcda, и объединения информации о профилировании в файлы .gcda на файловой системе хоста.

-fprofile-note=path

Если указан path, GCC сохраняет файл .gcno в расположение path. Если вы используете этот параметр с несколькими исходными файлами, файл .gcno будет перезаписан.

-fprofile-prefix-path=path

Этот параметр можно использовать в сочетании с profile-generate=profile_dir и profile-use=profile_dir, чтобы указать GCC базовый каталог построенного дерева исходного кода. По умолчанию profile_dir будет содержать файлы с искажёнными абсолютными путями всех файлов объектов в построенном проекте. Это нежелательно, когда каталог, используемый для построения инструментированного двоичного файла, отличается от каталога, используемого для построения оптимизированного двоичного файла с обратной связью профиля, так как данные профиля не будут найдены во время оптимизированного построения. В таких настройках можно использовать -fprofile-prefix-path=path с path, указывающим на базовый каталог построения, чтобы удалить нерелевантную часть пути и сохранить все имена файлов относительно основного каталога построения.

-fprofile-prefix-map=old=new

При компиляции файлов, находящихся в каталоге old, записывать информацию о профилировании (с --coverage), описывая их так, как будто файлы находятся в каталоге new вместо этого. См. также -ffile-prefix-map и -fcanon-prefix-map.

-fprofile-update=method

Изменить метод обновления для приложения, инструментированного для оптимизации на основе обратной связи профиля. Аргумент method должен быть одним из ‘single’, ‘atomic’ или ‘prefer-atomic’. Первый полезен для однопоточных приложений, а второй предотвращает повреждение профиля, генерируя потокобезопасный код.

Предупреждение: Когда приложение не правильно объединяет все потоки (или создаёт откреплённый поток), файл профиля всё ещё может быть повреждён.

Использование ‘prefer-atomic’ будет преобразовано либо в ‘atomic’, если это поддерживается целевой платформой, или в ‘single’ в противном случае. Драйвер GCC автоматически выбирает ‘prefer-atomic’, когда -pthread присутствует в командной строке, в противном случае по умолчанию используется метод ‘single’.

Если выбран ‘atomic’, то информация о профиле обновляется с использованием атомных операций по возможности. В идеале, информация о профиле обновляется с помощью атомных операций в аппаратном обеспечении. Однако, если целевая платформа не поддерживает необходимые атомные операции в аппаратном обеспечении, но доступна libatomic, информация о профиле обновляется с помощью вызовов libatomic. Если целевая платформа не поддерживает ни необходимые атомные операции в аппаратном обеспечении, ни libatomic, то информация о профиле не обновляется атомарно, и выдаётся предупреждение. В этом случае полученная информация о профилировании может быть повреждена для многопоточных приложений.

По соображениям производительности, если для информации о профилировании используются 64-битные счётчики, а целевая платформа поддерживает только 32-битные атомные операции в аппаратном обеспечении, то критически важные для производительности обновления профиля выполняются с использованием двух 32-битных атомных операций для каждого обновления счётчика. Если сигнал прерывает эти две операции, обновляющие счётчик, то информация о профилировании может оказаться в несогласованном состоянии.

-fprofile-filter-files=regex

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

Например, -fprofile-filter-files=main\.c;module.*\.c будет инструментировать только main.c и все C-файлы, начинающиеся с ’module’.

-fprofile-exclude-files=regex

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

Например, -fprofile-exclude-files=/usr/.* предотвратит инструментирование всех файлов, которые находятся в папке /usr/.

-fprofile-reproducible=[multithreaded|parallel-runs|serial]

Управление уровнем воспроизводимости профиля, собранного -fprofile-generate. Это позволяет перестроить программу с тем же результатом, что полезно, например, для дистрибутивных пакетов.

С -fprofile-reproducible=serial собранный профиль -fprofile-generate воспроизводим, при условии, что обученная программа ведёт себя одинаково при каждом вызове обучения, она не многопоточна и потоковая передача данных профиля всегда происходит в том же порядке. Обратите внимание, что потоковая передача профиля происходит в конце выполнения программы, но также и до вызова функции fork.

Обратите внимание, что часто количество вызовов некоторых частей программы зависит, например, от длины имён временных файлов или рандомизации памяти (что может повлиять на частоту коллизий хеш-таблиц). Такая невоспроизводимая часть программы может быть аннотирована атрибутом функции no_instrument_function. gcov-dump с -l может быть использован для выгрузки собранных данных и проверки того, что они действительно воспроизводимы.

С -fprofile-reproducible=parallel-runs собранный профиль остаётся воспроизводимым независимо от порядка потоковой передачи данных в файлы gcda. Эта настройка позволяет запускать несколько экземпляров инструментированной программы параллельно (например, с make -j). Это снижает качество собранных данных, в частности профилирования косвенных вызовов.

-fsanitize=address

Включить AddressSanitizer, быстрый детектор ошибок памяти. Инструкции доступа к памяти инструментированы для обнаружения ошибок выхода за пределы границ и использования памяти после освобождения. Параметр включает -fsanitize-address-use-after-scope. См. https://github.com/google/sanitizers/wiki/AddressSanitizer для получения более подробной информации. Поведение во время выполнения может быть изменено с помощью переменной среды ASAN_OPTIONS. При установке значения help=1, доступные параметры отображаются при запуске инструментированной программы. См. https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags для списка поддерживаемых параметров. Параметр не может быть объединён с -fsanitize=thread или -fsanitize=hwaddress. Обратите внимание, что единственной целевой платформой для -fsanitize=hwaddress в настоящее время является AArch64.

Для получения более точных трассировок стека можно использовать такие параметры, как -O0, -O1 или -Og (которые, например, предотвращают большинство инлайнингов функций), -fno-optimize-sibling-calls (который предотвращает оптимизацию вызовов братьев и вызовов по хвосту; этот параметр неявно используется для -O0, -O1 или -Og) или -fno-ipa-icf (который отключает Identical Code Folding для функций). Поскольку несколько запусков программы могут приводить к трассировкам стека с различными адресами из-за ASLR (Address Space Layout Randomization), может потребоваться выключить ASLR. В Linux это можно сделать с помощью ‘setarch `uname -m` -R ./prog’.

-fsanitize=kernel-address

Включить AddressSanitizer для ядра Linux. См. https://github.com/google/kernel-sanitizers для получения более подробной информации.

-fsanitize=hwaddress

Включить AddressSanitizer с аппаратной поддержкой, который использует аппаратную возможность игнорировать старший байт указателя, чтобы позволить обнаружение ошибок памяти с низкой нагрузкой на память. Инструкции доступа к памяти инструментированы для обнаружения ошибок выхода за пределы границ и использования памяти после освобождения. Параметр включает -fsanitize-address-use-after-scope. См. https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html для получения более подробной информации. Поведение во время выполнения может быть изменено с помощью переменной среды HWASAN_OPTIONS. При установке значения help=1, доступные параметры отображаются при запуске инструментированной программы. Параметр не может быть объединён с -fsanitize=thread или -fsanitize=address, и в настоящее время доступен только для AArch64.

-fsanitize=kernel-hwaddress

Включить AddressSanitizer с аппаратной поддержкой для компиляции ядра Linux. Аналогично -fsanitize=kernel-address, но с использованием альтернативного метода инструментирования, и аналогично -fsanitize=hwaddress, но с отличиями в инструментировании, необходимыми для компиляции ядра Linux. Эти различия предназначены для избежания вызовов инициализации библиотеки hwasan и для учёта того, что указатель стека имеет другое значение в своём старшем байте.

Примечание: Этот параметр имеет другие значения по умолчанию по сравнению с -fsanitize=hwaddress. Инструментирование вызовов стека и alloca по умолчанию не включено, но всё ещё возможно с помощью указания опций командной строки --param hwasan-instrument-stack=1 и --param hwasan-instrument-allocas=1 соответственно. Использование случайной метки кадра не реализовано для инструментирования ядра.

-fsanitize=pointer-compare

Инструментировать операцию сравнения (<, <=, >, >=) с операндами-указателями. Параметр должен быть объединён с -fsanitize=kernel-address или -fsanitize=address. Параметр не может быть объединён с -fsanitize=thread. Примечание: по умолчанию проверка отключена во время выполнения. Чтобы включить её, добавьте detect_invalid_pointer_pairs=2 в переменную среды ASAN_OPTIONS. Использование detect_invalid_pointer_pairs=1 обнаруживает неверную операцию только когда оба указателя не равны нулю.

-fsanitize=pointer-subtract

Инструментировать вычитание с операндами-указателями. Параметр должен быть объединён с -fsanitize=kernel-address или -fsanitize=address. Параметр не может быть объединён с -fsanitize=thread. Примечание: по умолчанию проверка отключена во время выполнения. Чтобы включить её, добавьте detect_invalid_pointer_pairs=2 в переменную среды ASAN_OPTIONS. Использование detect_invalid_pointer_pairs=1 обнаруживает неверную операцию только когда оба указателя не равны нулю.

-fsanitize=shadow-call-stack

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

В настоящее время он поддерживает только платформу aarch64. Он специально разработан для ядра Linux, в котором включен параметр CONFIG_SHADOW_CALL_STACK. Для пользовательских программ поддержка в runtime в настоящее время не предоставляется в libc и libgcc. Пользователи, желающие использовать эту функцию в пользовательском пространстве, должны обеспечить собственную поддержку runtime. Следует отметить, что это может нарушить правила ABI.

На платформе aarch64 для инструментации используется регистр x18. Это означает, что любой код, который может выполняться на том же потоке, что и код, скомпилированный с ShadowCallStack, должен быть скомпилирован со флагом -ffixed-x18, в противном случае функции, скомпилированные без -ffixed-x18, могут повредить x18 и, таким образом, испортить указатель на теневой стек.

Кроме того, поскольку поддержка runtime в пользовательском пространстве отсутствует, код, скомпилированный с ShadowCallStack, не может использовать обработку исключений. Используйте -fno-exceptions для отключения исключений.

Более подробную информацию см. на странице https://clang.llvm.org/docs/ShadowCallStack.html.

-fsanitize=thread

Включить ThreadSanitizer, быстрый детектор гонок данных. Инструкции доступа к памяти инструментируются для обнаружения ошибок гонок данных. Более подробную информацию см. на странице https://github.com/google/sanitizers/wiki#threadsanitizer. Поведение во время выполнения можно изменить с помощью переменной среды TSAN_OPTIONS; список поддерживаемых параметров см. на странице https://github.com/google/sanitizers/wiki/ThreadSanitizerFlags. Параметр нельзя комбинировать с -fsanitize=address, -fsanitize=leak.

Обратите внимание, что санизированные атомные встроенные функции не могут генерировать исключения при работе с недопустимыми адресами памяти с исключениями, не связанными с вызовами (-fnon-call-exceptions).

-fsanitize=leak

Включить LeakSanitizer, детектор утечек памяти. Этот параметр важен только для компоновки исполняемых файлов. Исполняемый файл компонуется с библиотекой, которая переопределяет malloc и другие функции-аллокаторы. Более подробную информацию см. на странице https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer. Поведение во время выполнения можно изменить с помощью переменной среды LSAN_OPTIONS. Параметр нельзя комбинировать с -fsanitize=thread.

-fsanitize=undefined

Включить UndefinedBehaviorSanitizer, быстрый детектор неопределённого поведения. Различные вычисления инструментируются для обнаружения неопределённого поведения во время выполнения. Более подробную информацию см. на странице https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html. Поведение во время выполнения можно изменить с помощью переменной среды UBSAN_OPTIONS. Текущие подпараметры:

-fsanitize=shift

Этот параметр включает проверку того, что результат операции сдвига не является неопределённым. Обратите внимание, что то, что считается неопределённым, несколько отличается между C и C++, а также между ISO C90 и C99 и т.д. Этот параметр имеет два подпараметра: -fsanitize=shift-base и -fsanitize=shift-exponent.

-fsanitize=shift-exponent

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

-fsanitize=shift-base

Если второй аргумент операции сдвига находится в пределах допустимого диапазона, проверяется, что результат операции сдвига не является неопределённым. Обратите внимание, что то, что считается неопределённым, несколько отличается между C и C++, а также между ISO C90 и C99 и т.д.

-fsanitize=integer-divide-by-zero

Обнаружение целочисленного деления на ноль.

-fsanitize=unreachable

С этим параметром компилятор преобразует вызов __builtin_unreachable в вызов сообщения об ошибке вместо этого. При достижении вызова __builtin_unreachable поведение является неопределённым.

-fsanitize=vla-bound

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

-fsanitize=null

Этот параметр включает проверку указателей. В частности, приложение, скомпилированное с включённым этим параметром, выведет сообщение об ошибке, когда попытается выполнить разыменование нулевого указателя или если ссылка (возможно, ссылка на rvalue) привязана к нулевому указателю или если метод вызывается на объекте, на который указывает нулевой указатель.

-fsanitize=return

Этот параметр включает проверку операторов возврата. Программы, скомпилированные с включённым этим параметром, выдадут сообщение об ошибке, когда будет достигнут конец функции, не возвращающей значение void, без фактического возвращения значения. Этот параметр работает только в C++.

-fsanitize=signed-integer-overflow

Этот параметр включает проверку переполнения знакового целого. Проверяется, что результат +, *, а также унарных и бинарных - не выходит за пределы диапазона в знаковом арифметике. Это также обнаруживает INT_MIN / -1 знаковое деление. Обратите внимание, что необходимо учитывать правила повышения точности целых чисел. Например, следующее не является переполнением:

signed char a = SCHAR_MAX;
a++;
-fsanitize=bounds

Этот параметр включает инструментацию границ массивов. Обнаружение различных обращений за пределы границ. Члены массивов с гибкой длиной, массивы, похожие на члены массивов с гибкой длиной, и инициализаторы переменных со статической областью хранения не инструментируются, за исключением массивов, похожих на члены массивов с гибкой длиной, для которых параметры -fstrict-flex-arrays или -fstrict-flex-arrays= или атрибуты strict_flex_array указывают, что их не следует обрабатывать как массивы с гибкой длиной.

-fsanitize=bounds-strict

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

-fsanitize=alignment

Этот параметр включает проверку выравнивания указателей при их разыменовании или когда ссылка привязана к недостаточно выровненному целевому объекту или когда метод или конструктор вызывается на недостаточно выровненном объекте.

-fsanitize=object-size

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

-fsanitize=float-divide-by-zero

Обнаружение деления на ноль с плавающей запятой. В отличие от других подобных параметров, -fsanitize=float-divide-by-zero не включено с помощью -fsanitize=undefined, так как деление на ноль с плавающей запятой может быть законным способом получения бесконечностей и NaN.

-fsanitize=float-cast-overflow

Этот параметр включает проверку преобразования типа с плавающей запятой в целочисленный тип. Проверка того, что результат преобразования не выходит за пределы диапазона. В отличие от других подобных параметров, -fsanitize=float-cast-overflow не включено с помощью -fsanitize=undefined. Этот параметр не работает хорошо с включёнными исключениями FE_INVALID.

-fsanitize=nonnull-attribute

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

-fsanitize=returns-nonnull-attribute

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

-fsanitize=bool

Этот параметр включает инструментацию загрузки из bool. Если загружается значение отличное от 0/1, выдаётся ошибка во время выполнения.

-fsanitize=enum

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

-fsanitize=vptr

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

-fsanitize=pointer-overflow

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

-fsanitize=builtin

Этот параметр включает инструментацию аргументов для выбранных встроенных функций. Если некорректное значение передаётся в такие аргументы, выдаётся ошибка во время выполнения. Например, передача 0 в качестве аргумента в __builtin_ctz или __builtin_clz вызывает неопределённое поведение и диагностируется этим параметром.

Обратите внимание, что санитайзеры, как правило, увеличивают частоту ложных срабатываний, особенно в отношении -Wmaybe-uninitialized. Мы не рекомендуем сочетать -Werror и санитайзеры.

В то время как -ftrapv вызывает генерацию ловушек для знаковых переполнений, -fsanitize=undefined даёт сообщение об ошибке. В настоящее время это работает только для языков семейства C.

-fno-sanitize=all

Этот параметр отключает все ранее включённые санитайзеры. -fsanitize=all не допускается, поскольку некоторые санитайзеры нельзя использовать вместе.

-fasan-shadow-offset=number

Этот параметр заставляет GCC использовать пользовательский смещение тени в проверках AddressSanitizer. Он полезен для экспериментов с различными макетами теневой памяти в ядре AddressSanitizer.

-fsanitize-sections=s1,s2,...

Санизировать глобальные переменные в выбранных пользовательских секциях. si может содержать подстановочные знаки.

-fsanitize-recover[=opts]

-fsanitize-recover= управляет режимом восстановления ошибок для санлайзеров, перечисленных в списке, разделенном запятыми, opts. Включение этого параметра для компонента санлайзера заставляет его пытаться продолжить выполнение программы, как если бы никакой ошибки не произошло. Это означает, что несколько ошибок во время выполнения могут быть сообщены в одной сессии работы программы, и код завершения программы может указывать на успех, даже если ошибки были сообщены. Параметр -fno-sanitize-recover= может использоваться для изменения этого поведения: только первая обнаруженная ошибка сообщается, и программа завершается с ненулевым кодом выхода.

В настоящее время эта функция работает только для -fsanitize=undefined (и его подвариантов, кроме -fsanitize=unreachable и -fsanitize=return), -fsanitize=float-cast-overflow, -fsanitize=float-divide-by-zero, -fsanitize=bounds-strict, -fsanitize=kernel-address и -fsanitize=address. Для этих санлайзеров восстановление ошибок включено по умолчанию, за исключением -fsanitize=address, для которого эта функция является экспериментальной. -fsanitize-recover=all и -fno-sanitize-recover=all также принимаются, первое включает восстановление для всех санлайзеров, которые его поддерживают, а второе — отключает восстановление для всех санлайзеров, которые его поддерживают.

Даже если режим восстановления включен со стороны компилятора, он должен быть также включен со стороны библиотеки времени выполнения, иначе ошибки остаются фатальными. Библиотека времени выполнения по умолчанию имеет значение halt_on_error=0 для ThreadSanitizer и UndefinedBehaviorSanitizer, а значение по умолчанию для AddressSanitizer — halt_on_error=1. Это можно переопределить, установив флаг halt_on_error в соответствующей переменной среды.

Синтаксис без явного параметра opts устарел. Он эквивалентен указанию списка opts:

undefined,float-cast-overflow,float-divide-by-zero,bounds-strict
-fsanitize-address-use-after-scope

Включить проверку локальных переменных для обнаружения ошибок использования после области действия. Параметр устанавливает -fstack-reuse в ‘none’.

-fsanitize-trap[=opts]

Параметр -fsanitize-trap= инструктирует компилятор сообщать об ошибках поведения, перечисленных в списке, разделённом запятыми, opts санлайзеров, используя __builtin_trap вместо стандартной libubsan библиотеки. Если этот параметр включён для определенного санлайзера, он имеет приоритет над -fsanitizer-recover= для данного санлайзера, __builtin_trap будет выведено и будет фатальным независимо от того, включено ли восстановление или выключено с помощью -fsanitize-recover=.

Преимущество этого заключается в том, что libubsan библиотека не требуется и не подключается, поэтому это может быть использовано даже в средах без библиотеки.

В настоящее время эта функция работает с -fsanitize=undefined (и его подвариантами, кроме -fsanitize=vptr), -fsanitize=float-cast-overflow, -fsanitize=float-divide-by-zero и -fsanitize=bounds-strict. -fsanitize-trap=all также может быть указан, что включает его для undefined подвариантов, -fsanitize=float-cast-overflow, -fsanitize=float-divide-by-zero и -fsanitize=bounds-strict. Если -fsanitize-trap=undefined или -fsanitize-trap=all используются и -fsanitize=vptr включено в командной строке, инструментация будет проигнорирована, так как инструментация всегда требует libubsan поддержки, -fsanitize-trap=vptr не разрешено.

-fsanitize-undefined-trap-on-error

Параметр -fsanitize-undefined-trap-on-error устарел, эквивалентен -fsanitize-trap=all.

-fsanitize-coverage=trace-pc

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

-fsanitize-coverage=trace-cmp

Включить инструментацию кода, управляемую потоком данных, для мутаций. Вставляет вызов __sanitizer_cov_trace_cmp1, __sanitizer_cov_trace_cmp2, __sanitizer_cov_trace_cmp4 или __sanitizer_cov_trace_cmp8 для целочисленного сравнения с обеими операндами переменными или __sanitizer_cov_trace_const_cmp1, __sanitizer_cov_trace_const_cmp2, __sanitizer_cov_trace_const_cmp4 или __sanitizer_cov_trace_const_cmp8 для целочисленного сравнения с одним константным операндом, __sanitizer_cov_trace_cmpf или __sanitizer_cov_trace_cmpd для сравнения чисел с плавающей точкой или двойной точности и __sanitizer_cov_trace_switch для операторов switch.

-fcf-protection=[full|branch|return|none|check]

Включить инструментацию кода для передачи управления, чтобы повысить безопасность программы, проверяя, что целевые адреса инструкций передачи управления (например, косвенный вызов функции, возврат функции, косвенный переход) действительны. Это предотвращает перенаправление потока управления на неожиданную цель. Это призвано защитить от таких угроз, как Return-Oriented Programming (ROP), и аналогичных методов программирования, ориентированных на вызов/переход (COP/JOP).

Значение branch сообщает компилятору о реализации проверки валидности передачи управления в точке инструкций косвенного перехода, т.е. инструкций вызова/перехода. Значение return реализует проверку валидности в точке возврата из функции. Значение full является псевдонимом для указания как branch, так и return. Значение none отключает инструментацию.

Для переопределения -fcf-protection необходимо добавить -fcf-protection=none, а затем -fcf-protection=xxx.

Значение check используется для окончательной связи с оптимизацией на этапе компоновки (LTO). Возникает ошибка, если файлы объектов LTO скомпилированы с разными значениями -fcf-protection. Значение check игнорируется на этапе компиляции.

Макрос __CET__ определён при использовании -fcf-protection. Первый бит __CET__ установлен в 1 для значения branch, а второй бит __CET__ установлен в 1 для return.

Вы также можете использовать атрибут nocf_check для идентификации функций и вызовов, которые следует пропускать из инструментации (см. Объявление атрибутов функций).

В настоящее время целевая платформа x86 GNU/Linux предоставляет реализацию, основанную на технологии Intel Control-flow Enforcement Technology (CET), которая работает для процессоров i686 и более новых.

-fharden-compares

Для каждого логического теста, который проходит оптимизации gimple и не является условием в условном ветвлении (например, условия, проверенные для условных перемещений или для хранения в булевых переменных), генерируется дополнительный код для вычисления и проверки обратного условия и вызова __builtin_trap , если результаты не совпадают. Используйте с ‘-fharden-conditional-branches’ для охвата всех условных выражений.

-fharden-conditional-branches

Для каждого не векторного условного ветвления, которое проходит оптимизации gimple, генерируется дополнительный код для вычисления и проверки обратного условия и вызова __builtin_trap , если результат неожиданный. Используйте с ‘-fharden-compares’ для охвата всех условных выражений.

-fharden-control-flow-redundancy

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

Проверка выполняется перед возвратами, перед обязательными вызовами хвоста (см. ниже) и, необязательно, перед обработкой исключений с -fhardcfr-check-exceptions, перед возвращающими вызовами с -fhardcfr-check-returning-calls и перед вызовами noreturn с -fhardcfr-check-noreturn-calls). Доступны параметры настройки --param hardcfr-max-blocks и --param hardcfr-max-inline-blocks.

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

-fhardcfr-skip-leaf

Отключить -fharden-control-flow-redundancy в функциях-листьях.

-fhardcfr-check-exceptions

Когда -fharden-control-flow-redundancy активен, проверять записанный путь выполнения относительно графа потока управления в точках выхода из исключений, как если бы тело функции было обернуто обработчиком очистки, который выполнял проверку и повторно поднимал исключение. Этот параметр включён по умолчанию; используйте -fno-hardcfr-check-exceptions для его отключения.

-fhardcfr-check-returning-calls

Когда -fharden-control-flow-redundancy активен, проверять записанный путь выполнения по отношению к графику потока управления перед любым вызовом функции, сразу за которым следует возврат результата, если таковой имеется, чтобы не препятствовать оптимизации вызовов хвоста, является ли он в конечном итоге оптимизированным в вызов хвоста или нет.

Этот параметр включён по умолчанию, когда включены оптимизации вызовов-братьев (см. -foptimize-sibling-calls), но он может быть включён (или выключен, используя его отрицание) явно, независимо от оптимизаций.

-fhardcfr-check-noreturn-calls=[always|no-xthrow|nothrow|never]

Когда активен параметр -fharden-control-flow-redundancy, проверяется записанный путь выполнения относительно графа потока управления перед noreturn вызовами, либо все из них (always), те, которые не ожидается вернут управление вызывающей стороне через исключение (no-xthrow, по умолчанию), те, которые могут не вернуть управление вызывающей стороне через исключение (nothrow) или ни один из них (never).

Проверка перед noreturn функцией, которая может вернуть управление вызывающей стороне через исключение, может привести к тому, что проверка будет выполнена более одного раза, если исключение перехвачено в вызывающей стороне, будь то обработчиком или очисткой. Когда -fhardcfr-check-exceptions также включен, компилятор избежит ассоциации noreturn вызова с неявным обработчиком очистки, поскольку это было бы избыточным по отношению к проверке, выполненной перед вызовом, но другие обработчики или очистка в функции, если они активированы, изменят записанный путь выполнения и проверят его снова, когда будет достигнута другая контрольная точка. Контрольная точка может даже быть другим noreturn вызовом, поэтому проверка может быть выполнена несколько раз.

Различные оптимизаторы могут привести к тому, что вызовы будут помечены как noreturn и/или nothrow, даже в отсутствие соответствующих атрибутов, что может повлиять на размещение проверок перед вызовами, а также на добавление неявных обработчиков очистки для них. Эта непредсказуемость и тот факт, что поднятие и повторное поднятие исключений часто сводится к неявным вызовам noreturn функций, сделали no-xthrow значением по умолчанию для этого параметра: из процесса noreturn исключаются только внутренние функции, используемые для (повторного) поднятия исключений, которые не затронуты этими оптимизациями.

-fhardened

Включить набор флагов для C и C++, которые улучшают безопасность сгенерированного кода без влияния на его ABI. Точные включенные флаги могут меняться между основными версиями GCC, но в настоящее время это:

-D_FORTIFY_SOURCE=3
-D_GLIBCXX_ASSERTIONS
-ftrivial-auto-var-init=zero
-fPIE  -pie  -Wl,-z,relro,-z,now
-fstack-protector-strong
-fstack-clash-protection
-fcf-protection=full (x86 GNU/Linux only)

Список параметров, включенных с помощью -fhardened, можно получить, используя параметр --help=hardened.

Когда система glibc старше 2.35, вместо этого используется -D_FORTIFY_SOURCE=2.

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

В настоящее время -fhardened поддерживается только для целевых платформ GNU/Linux.

-fhardened включает конкретный параметр только в том случае, если он не был указан где-либо в командной строке. Например, -fhardened -fstack-protector включит только -fstack-protector, но не -fstack-protector-strong.

-fstack-protector

Вывести дополнительный код для проверки переполнения буфера, например, атак переполнения стека. Это делается путем добавления защитной переменной к функциям с уязвимыми объектами. Это включает функции, которые вызывают alloca, и функции с буферами размером не менее 8 байтов. Защитные переменные инициализируются при входе в функцию и затем проверяются при выходе из функции. Если проверка защитной переменной завершается неудачей, выводится сообщение об ошибке, и программа завершается. Учитываются только переменные, которые фактически выделены в стеке, оптимизированные переменные или переменные, выделенные в регистрах, не учитываются.

-fstack-protector-all

Как -fstack-protector, за исключением того, что все функции защищены.

-fstack-protector-strong

Как -fstack-protector, но включает дополнительные защищаемые функции — те, которые имеют локальные определения массивов или имеют ссылки на адреса локальных кадров. Учитываются только переменные, которые фактически выделены в стеке, оптимизированные переменные или переменные, выделенные в регистрах, не учитываются.

-fstack-protector-explicit

Как -fstack-protector, но защищает только те функции, которые имеют атрибут stack_protect.

-fstack-check

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

Обратите внимание, что этот переключатель фактически не выполняет проверки; операционная система или среда выполнения языка должны это сделать. Переключатель генерирует код, гарантирующий, что они видят расширение стека.

Вы также можете указать строковый параметр: ‘no’ — значит без проверки, ‘generic’ — значит принудительно использовать проверку старого стиля, ‘specific’ — значит использовать наилучший метод проверки и эквивалентно простому -fstack-check.

Проверка стека старого стиля — это универсальный механизм, не требующий специальной поддержки целевой платформы в компиляторе, но со следующими недостатками:

  1. Измененная стратегия выделения для больших объектов: они всегда выделяются динамически, если их размер превышает определенный порог. Обратите внимание, что это может изменить семантику некоторого кода.
  2. Ограничение размера статического кадра функций: когда он заполняется конкретной функцией, проверка стека ненадежна, и компилятор выдает предупреждение.
  3. Неэффективность: из-за модифицированной стратегии выделения и универсальной реализации производительность кода снижается.

Обратите внимание, что проверка стека старого стиля также является резервным методом для ‘specific’, если в компиляторе не добавлена поддержка целевой платформы.

‘-fstack-check=’ предназначен для потребностей Ada в обнаружении бесконечной рекурсии и переполнения стека. ‘specific’ — отличный выбор при компиляции кода Ada. Его обычно недостаточно для защиты от атак с переполнением стека. Для защиты от них нужен параметр ‘-fstack-clash-protection’.

-fstack-clash-protection

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

Большинство платформ не полностью поддерживают защиту от столкновения стека. Однако на тех платформах -fstack-clash-protection защитит динамическое выделение памяти стека. -fstack-clash-protection также может обеспечить ограниченную защиту для статических выделений памяти стека, если платформа поддерживает -fstack-check=specific.

-fstack-limit-register=reg
-fstack-limit-symbol=sym
-fno-stack-limit

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

Например, если стек начинается с абсолютного адреса ‘0x80000000’ и растет вниз, можно использовать флаги -fstack-limit-symbol=__stack_limit и -Wl,--defsym,__stack_limit=0x7ffe0000 для принудительного ограничения стека 128 КБ. Обратите внимание, что это может работать только с линковщиком GNU.

Вы можете локально переопределить проверку ограничения стека, используя атрибут функции no_stack_limit (см. Объявление атрибутов функций).

-fsplit-stack

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

Когда код, скомпилированный с -fsplit-stack, вызывает код, скомпилированный без -fsplit-stack, для последнего кода может быть мало места в стеке. Если компиляция всего кода, включая код библиотеки, с -fsplit-stack невозможна, то линковщик может исправить эти вызовы так, чтобы у кода, скомпилированного без -fsplit-stack, всегда был большой стек. Поддержка этого реализована в линковщике gold в релизе GNU binutils 2.21 и более поздних.

-fstrub=disable

Полностью отключить очистку стека, игнорируя все атрибуты strub. См. Общие атрибуты типов.

-fstrub=strict

Функции по умолчанию работают в режиме strub disabled, и применяют строго ограничение, что только функции, связанные с режимами strub-callable (at-calls, callable и always_inline internal), могут быть вызваны функциями с включенными режимами strub (at-calls и internal).

-fstrub=relaxed

Восстановить значение по умолчанию очистки стека (strub), а именно, strub включается только по необходимости в соответствии с атрибутами strub функций и типов данных. Relaxed означает, что контексты очистки предотвращаются от вызова функций, явно связанных с режимом strub disabled. Этот параметр полезен только для переопределения других параметров -fstrub=*, которые идут перед ним в командной строке.

-fstrub=at-calls

Включить at-calls strub режим, если возможно. Основное использование этого параметра — для тестирования. Он использует механизм strub в сценариях, строго локальных для единицы трансляции. Этот режим strub изменяет интерфейсы функций, поэтому любая функция, видимая для других единиц трансляции или адрес которой взят, не будет затронута этим параметром. Параметры оптимизации также могут повлиять на возможность использования. См. документацию атрибута strub для получения подробной информации о требованиях к жизнеспособности и соответствию.

-fstrub=internal

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

-fstrub=all

Включить режим strub там, где это возможно. Если оба режима strub доступны, предпочтение отдаётся at-calls. -fdump-ipa-strubm добавляет атрибуты функций, указывающие, какой режим был выбран для каждой функции. Основное использование этого параметра — для тестирования, чтобы тщательно проверить механизм strub.

-fvtable-verify=[std|preinit|none]

Этот параметр доступен только при компиляции кода C++. Он включает (или выключает, если используется -fvtable-verify=none) функцию безопасности, которая во время выполнения проверяет для каждого виртуального вызова, что указатель vtable, через который выполняется вызов, является допустимым для типа объекта и не был повреждён или перезаписан. Если в ходе выполнения обнаруживается недействительный указатель vtable, выводится ошибка, и выполнение программы немедленно прерывается.

Этот параметр вызывает создание структур данных во время запуска программы, которые используются для проверки указателей vtable. Параметры ‘std’ и ‘preinit’ управляют временем создания этих структур данных. В обоих случаях структуры данных создаются до достижения main. Использование -fvtable-verify=std вызывает создание структур данных после загрузки и инициализации общих библиотек. -fvtable-verify=preinit вызывает их создание до загрузки и инициализации общих библиотек.

Если этот параметр указан в командной строке несколько раз с различными значениями, ‘none’ имеет наивысший приоритет по сравнению с ‘std’ и ‘preinit’; ‘preinit’ имеет приоритет над ‘std’.

-fvtv-debug

При использовании совместно с -fvtable-verify=std или -fvtable-verify=preinit вызывает вызов отладочных версий функций времени выполнения для функции проверки vtable. Этот флаг также заставляет компилятор регистрировать информацию о том, какие указатели vtable он находит для каждого класса. Эта информация записывается в файл с именем vtv_set_ptr_data.log в каталоге, указанном переменной среды VTV_LOGS_DIR, если она определена, или в текущем каталоге в противном случае.

Примечание: эта функция добавляет данные в файл журнала. Если вам нужен новый файл журнала, убедитесь, что вы удалили любой существующий.

-fvtv-counts

Это флаг отладки. При использовании совместно с -fvtable-verify=std или -fvtable-verify=preinit он заставляет компилятор отслеживать общее количество виртуальных вызовов, которые он обнаруживает, и количество вставляемых им проверок. Он также подсчитывает количество вызовов определённых функций библиотеки времени выполнения, которые он вставляет, и регистрирует эту информацию для каждого модуля компиляции. Компилятор записывает эту информацию в файл с именем vtv_count_data.log в каталоге, указанном переменной среды VTV_LOGS_DIR, если она определена, или в текущем каталоге в противном случае. Он также подсчитывает размер наборов указателей vtable для каждого класса и записывает эту информацию в vtv_class_set_sizes.log в том же каталоге.

Примечание: эта функция добавляет данные в файлы журналов. Чтобы получить новые файлы журналов, убедитесь, что вы удалили все существующие.

-finstrument-functions

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

void __cyg_profile_func_enter (void *this_fn,
                               void *call_site);
void __cyg_profile_func_exit  (void *this_fn,
                               void *call_site);

Первый аргумент — адрес начала текущей функции, который можно точно найти в таблице символов.

Это инструментирование также выполняется для функций, расширенных встраиванием в другие функции. Вызовы профилирования указывают, где концептуально встраиваемая функция вводится и выходит. Это означает, что должны быть доступны адресованные версии таких функций. Если все ваши использования функции встроены, это может означать дополнительное увеличение размера кода. Если вы используете extern inline в своём коде C, должна быть предоставлена адресованная версия таких функций. (Обычно это так или иначе, но если вам повезёт, и оптимизатор всегда будет встраивать функции, возможно, вам не придётся предоставлять статические копии.)

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

-finstrument-functions-once

Это аналогично -finstrument-functions, но функции профилирования вызываются только один раз на функцию, т. е. первая функция профилирования вызывается после первого входа в функцию, а вторая — перед выходом, соответствующим этому первому входу.

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

-finstrument-functions-exclude-file-list=file,file,…

Устанавливает список функций, исключённых из инструментирования (см. описание -finstrument-functions). Если файл, содержащий определение функции, соответствует одному из file, то эта функция не инструментируется. Сопоставление выполняется по подстрокам: если параметр file является подстрокой имени файла, он считается совпадением.

Например:

-finstrument-functions-exclude-file-list=/bits/stl,include/sys

исключает любые встраиваемые функции, определённые в файлах, пути к которым содержат /bits/stl или include/sys.

Если по какой-либо причине вам нужно включить символ ‘,’ в одном из sym, напишите ‘\,’. Например, -finstrument-functions-exclude-file-list='\,\,tmp' (обратите внимание на одинарные кавычки вокруг параметра).

-finstrument-functions-exclude-function-list=sym,sym,…

Это аналогично -finstrument-functions-exclude-file-list, но этот параметр устанавливает список имён функций, которые нужно исключить из инструментирования. Функция, с которой будет выполняться сопоставление, — это её видимое пользователю имя, например vector<int> blah(const vector<int> &), а не внутреннее именованное имя (например, _Z4blahRSt6vectorIiSaIiEE). Сопоставление выполняется по подстрокам: если параметр sym является подстрокой имени функции, он считается совпадением. Для идентификаторов C99 и расширенных идентификаторов C++ имя функции должно быть указано в UTF-8, а не с использованием универсальных символьных имен.

-fpatchable-function-entry=N[,M]

Генерирует N команд NOP непосредственно в начале каждой функции, причём точка входа в функцию находится перед M-й командой NOP. Если M опущено, оно по умолчанию равно 0, так что точка входа в функцию соответствует адресу непосредственно после первой команды NOP. Команды NOP резервируют дополнительное пространство, которое можно использовать для вставки любой желаемой информации во время выполнения, при условии, что сегмент кода является изменяемым. Размер пространства можно контролировать косвенно через количество команд NOP; команда NOP, используемая, соответствует команде, выводимой внутренним интерфейсом GCC gen_nop. Это поведение зависит от целевой архитектуры и может также зависеть от варианта архитектуры и/или других параметров компиляции.

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

Обратите внимание, что значение __attribute__ ((patchable_function_entry (N,M))) имеет приоритет над параметром командной строки -fpatchable-function-entry=N,M. Это можно использовать для увеличения размера области или её полного удаления для одной функции. Если N=0, местоположение заполнения не записывается.

Команды NOP вставляются в — и, возможно, перед, в зависимости от M — адрес входа в функцию, даже перед прологом. На PowerPC с ABI ELFv2 для функции с двумя точками входа локальная точка входа — это адрес входа в функцию.

Максимальное значение N и M — 65535. На PowerPC с ABI ELFv2 для функции с двумя точками входа поддерживаемые значения для M — 0, 2, 6 и 14.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Instrumentation-Options.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API