Spec-Zone.ru › GCC 9

3.11 Варианты программно-аппаратной отладки

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). См. Взаимопрофилирование.

--coverage

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

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

При использовании -fprofile-arcs для каждой функции вашей программы 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.

Когда исполняемый файл выполняется в среде с высокой параллельностью, рекомендуется сохранять профиль в различных папках. Это можно сделать с помощью переменных в 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-update=method

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

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

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

-fprofile-filter-files=regex

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

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

-fprofile-exclude-files=regex

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

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

-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=kernel-address

Включает AddressSanitizer для ядра Linux. Подробнее см. https://github.com/google/kasan/wiki.

-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=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

Обнаружить целочисленное деление на ноль, а также INT_MIN / -1 деление.

-fsanitize=unreachable

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

-fsanitize=vla-bound

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

-fsanitize=null

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

-fsanitize=return

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

-fsanitize=signed-integer-overflow

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

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

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

-fsanitize=bounds-strict

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

-fsanitize=alignment

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

-fsanitize=object-size

Этот параметр включает инструментирование ссылок на память с использованием функции __builtin_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 вызывает неопределённое поведение и диагностируется этим параметром.

В то время как -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

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

-fsanitize-undefined-trap-on-error

Опция -fsanitize-undefined-trap-on-error инструктирует компилятор сообщать об неопределённом поведении с помощью __builtin_trap вместо функции библиотеки libubsan. Преимущество в том, что библиотека libubsan не нужна и не подключается, поэтому это можно использовать даже в автономных средах.

-fsanitize-coverage=trace-pc

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

-fsanitize-coverage=trace-cmp

Включить инструментацию кода для fuzzing с руководством по потоку данных. Вставляет вызов __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]

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

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

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

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

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

-fstack-protector

Выполнять дополнительный код для проверки переполнения буфера, таких как атаки stack smashing. Это делается путем добавления переменной-защитника к функциям с уязвимыми объектами. Это включает функции, которые вызывают 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. Он не является достаточным для защиты от атак 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 linker.

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

-fsplit-stack

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

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

-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-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 back-end gen_nop. Это поведение зависит от целевой платформы и также может зависеть от варианта архитектуры и/или других параметров компиляции.

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

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

Инструкции NOP вставляются в — и возможно до, в зависимости от M — адрес входа в функцию, даже перед прологом.

Далее: Параметры препроцессора, Предыдущее: Параметры оптимизации, Наверх: Вызов GCC [Содержание][Индекс]

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

Spec-Zone.ru

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