3.12 Параметры инструментирования программы
GCC поддерживает ряд параметров командной строки, управляющих добавлением инструментирования времени выполнения в генерируемый им код. Например, одна из целей инструментирования — сбор статистики профилирования для поиска узких мест программы, анализа покрытия кода или оптимизаций на основе профиля. Другой класс инструментирования программ — добавление проверок во время выполнения для обнаружения ошибок программирования, таких как разыменование недопустимых указателей или выход за границы массива, а также преднамеренных атак, например перезаписи стека или перехвата vtable 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. Описание auxname и инструкции по созданию данных о покрытии тестами см. выше в описании параметра -fprofile-arcs. Данные о покрытии точнее соответствуют исходным файлам, если не выполнять оптимизацию. -
-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 поддерживается только на x86-64 (только с параметрами-mlam=u48или-mlam=u57) и AArch64; в обоих случаях — только в ABI с 64-разрядными указателями.Чтобы получить более точные трассировки стека, можно использовать такие параметры, как -O0, -O1 или -Og (которые, например, предотвращают встраивание большинства функций), -fno-optimize-sibling-calls (который предотвращает оптимизацию вызовов функций-соседей и хвостовых рекурсивных вызовов; этот параметр неявно включен для -O0, -O1 и -Og) или -fno-ipa-icf (который отключает объединение идентичного кода функций). Поскольку при разных запусках программы адреса в трассировках могут различаться из-за ASLR (рандомизации адресного пространства), может быть полезно отключить ASLR. В Linux это можно сделать командой ‘setarch `uname -m` -R ./prog’.
-
-fsanitize=kernel-address -
Включить AddressSanitizer для ядра Linux. Дополнительные сведения см. на странице https://github.com/google/kernel-sanitizers.
-
-fsanitize=hwaddress -
Включить Hardware-assisted 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 -
Включить Hardware-assisted 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обнаруживает недопустимую операцию, только если оба указателя не равны null. -
-fsanitize=pointer-subtract -
Инструментировать вычитание указателей. Этот параметр необходимо использовать вместе с -fsanitize=kernel-address или -fsanitize=address. Его нельзя использовать вместе с -fsanitize=thread. Примечание: по умолчанию проверка отключена во время выполнения. Чтобы включить ее, добавьте
detect_invalid_pointer_pairs=2в переменную окруженияASAN_OPTIONS. Использованиеdetect_invalid_pointer_pairs=1обнаруживает недопустимую операцию, только если оба указателя не равны null. -
-fsanitize=shadow-call-stack -
Включить ShadowCallStack — механизм повышения безопасности, защищающий программы от перезаписи адреса возврата (например, при переполнении буфера стека). В прологе функции адрес возврата сохраняется в отдельно выделенном теневом стеке вызовов, а в эпилоге функции восстанавливается оттуда. Инструментируются только функции, которым необходимо сохранять адрес возврата в стеке.
В настоящее время поддерживается только платформа aarch64. Эта функция предназначена специально для ядер Linux, в которых включен параметр CONFIG_SHADOW_CALL_STACK. Для пользовательских программ поддержка во время выполнения в libc и libgcc пока не предоставляется. Пользователям, желающим применять эту функцию в пользовательском пространстве, необходимо самостоятельно обеспечить поддержку во время выполнения. Следует учитывать, что это может привести к нарушению правил ABI.
На aarch64 инструментирование использует регистр платформы
x18. Это обычно означает, что любой код, который может выполняться в одном потоке с кодом, скомпилированным с ShadowCallStack, необходимо компилировать с флагом -ffixed-x18; в противном случае функции, скомпилированные без -ffixed-x18, могут повредитьx18и тем самым испортить указатель теневого стека.Кроме того, поскольку поддержка пользовательской среды выполнения отсутствует, код, скомпилированный с 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 -
Эта опция включает проверку указателей. В частности, приложение, собранное с этой опцией, выдаст сообщение об ошибке при попытке разыменовать указатель NULL, при привязке ссылки (возможно, rvalue-ссылки) к указателю NULL или при вызове метода для объекта, на который указывает указатель NULL.
-
-fsanitize=return -
Эта опция включает проверку операторов 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 -
Эта опция включает инструментирование операторов return в функциях с атрибутом функции
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. Она полезна для экспериментов с различными схемами размещения теневой памяти в Kernel 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; для сравнения чисел типа float или double —__sanitizer_cov_trace_cmpfили__sanitizer_cov_trace_cmpd; для операторов switch —__sanitizer_cov_trace_switch. -
-fcf-protection=[full|branch|return|none|check] -
Включить инструментирование передач управления для повышения безопасности программы путём проверки допустимости целевых адресов инструкций передачи управления (например, косвенного вызова функции, возврата из функции или косвенного перехода). Это предотвращает перенаправление потока управления к неожиданной цели. Эта возможность предназначена для защиты от таких угроз, как программирование, ориентированное на возврат (ROP), а также программирование, ориентированное на вызовы и переходы (COP/JOP).
Значение
branchпредписывает компилятору проверять допустимость передачи управления в точке выполнения инструкций косвенного перехода, то есть инструкций call/jmp. Значениеreturnвключает проверку допустимости в точке возврата из функции. Значениеfullявляется псевдонимом для одновременного указанияbranchиreturn. Значениеnoneотключает инструментирование.Чтобы переопределить -fcf-protection, необходимо добавить -fcf-protection=none, а затем указать -fcf-protection=xxx.
Значение
checkиспользуется при финальной компоновке с оптимизацией во время компоновки (LTO). Если объектные файлы LTO скомпилированы с разными значениями -fcf-protection, выдаётся ошибка. Значениеcheckигнорируется во время компиляции.При использовании -fcf-protection определяется макрос
__CET__. Для значенияbranchпервый бит__CET__устанавливается в 1, а дляreturnвторой бит__CET__устанавливается в 1.Также можно использовать атрибут
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 без параметра.
Проверка старого типа — это универсальный механизм, для которого не требуется специальная поддержка цели в компиляторе, но у него есть следующие недостатки:
- Изменённая стратегия выделения для крупных объектов: они всегда выделяются динамически, если их размер превышает фиксированный порог. Обратите внимание: это может изменить семантику некоторого кода.
- Фиксированный предел размера статического кадра функций: если он превышен конкретной функцией, проверка стека становится ненадёжной, а компилятор выдаёт предупреждение.
- Низкая эффективность: производительность кода снижается из-за изменённой стратегии выделения и универсальной реализации.
Обратите внимание: проверка стека старого типа также используется как резервный метод для ‘specific’, если в компиляторе не реализована поддержка цели.
Параметр ‘-fstack-check=’ предназначен для нужд Ada — обнаружения бесконечной рекурсии и переполнения стека. Значение ‘specific’ отлично подходит при компиляции кода Ada. Как правило, этого недостаточно для защиты от атак типа stack clash. Для защиты от них следует использовать ‘-fstack-clash-protection’.
-
-fstack-clash-protection -
Сгенерировать код для предотвращения атак типа stack clash. При включении этой опции компилятор будет выделять за один раз не более одной страницы стека и сразу обращаться к каждой странице после её выделения. Это предотвращает перескакивание выделяемой области через любую защитную страницу стека, предоставленную операционной системой.
Большинство целей не поддерживают защиту от stack clash в полном объёме. Однако на таких целях -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 -
Для функций по умолчанию устанавливается режим
strubdisabled, а ограничение применяется строго: функции с режимамиstrub-callable(at-calls,callableиalways_inlineinternal) могутcallableтолько функциями с режимами, в которых включёнstrub(at-callsиinternal). -
-fstrub=relaxed -
Восстановить настройку очистки стека по умолчанию (
strub), то естьstrubвключается только в случаях, предусмотренных атрибутамиstrub, связанными с типами функций и данных.Relaxedозначает, что контекстам strub запрещено вызывать только функции, явно связанные с режимомstrubdisabled. Эта опция полезна только для переопределения других опций -fstrub=*, указанных перед ней в командной строке. -
-fstrub=at-calls -
Включить режим
at-callsstrubтам, где это возможно. Эта опция предназначена главным образом для тестирования. Она проверяет работу механизмаstrubв сценариях, ограниченных одной единицей трансляции. Этот режимstrubизменяет интерфейсы функций, поэтому опция не влияет на функции, видимые из других единиц трансляции или адрес которых используется. На возможность применения также могут влиять параметры оптимизации. Подробные сведения о требованиях к возможности применения и соответствию критериям см. в документации к атрибутуstrub. -
-fstrub=internal -
Включить режим
internalstrubтам, где это возможно. Эта опция предназначена главным образом для тестирования. Она позволяет тщательно проверить части механизма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);Первый аргумент — это адрес начала текущей функции, который можно точно найти в таблице символов.
Это инструментирование также выполняется для функций, встроенных в другие функции. Вызовы профилирования указывают, где, концептуально, начинается и заканчивается выполнение встроенной функции. Это означает, что должны быть доступны адресуемые версии таких функций. Если все вызовы функции встраиваются, это может привести к дополнительному увеличению размера кода. Если в коде C используется
extern inline, необходимо предоставить адресуемую версию таких функций. (Обычно это необходимо и в любом случае, но если оптимизатор всегда встраивает функции, возможно, можно обойтись без предоставления статических копий.)Функции можно назначить атрибут
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 соответствует инструкции, генерируемой внутренним интерфейсом GCCgen_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.4.0/gcc/Instrumentation-Options.html