Вопрос

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

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

Мои вопросы:

  1. Как эта оптимизация происходит через Лаутербаха?
  2. Это выгодно??
Это было полезно?

Решение

Есть пара вещей:

  1. По поводу заявления Я обнаружил, что некоторые функции не указаны в исходном коде, пытаясь найти их, чтобы поставить точки останова.", просто проверьте файл сопоставления/файл карты, который состоит из различных функций, которые использовались при сборке, их расположения в памяти и т. д., и если вы не найдете там свою функцию, просто посмотрите на оптимизацию [Только это может быть проблема].

  2. Как справедливо отмечено, оптимизация выполняется не Лаутербахом, а компилятором.Обычно существуют разные уровни оптимизации [в ARM у нас есть O0-O2], где O0 — это максимально возможная оптимизация, но его следует использовать только при выпуске версии для клиента, иначе уровень оптимизации O2 следует использовать для отладки.

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

  4. Другой момент, который может быть [напрямую] не связан с этим, но может помочь, - это знать, «В какой области памяти находится ваш файл», поскольку во многих случаях, когда вы хотите что-то отладить, а эта страница все еще не находится в ОЗУ, вы не сможете поставить точки останова до тех пор, пока эта страница не будет взята в ОЗУ [по сути, что-то вроде пейджинга по требованию, если оно присутствует в вашей системе]

Надеюсь это поможет.

-hjsblogger

Другие советы

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

Чтобы переопределить эти оптимизации в целях тестирования, вы можете использовать флаг компилятора --no_inline.

Компилятор может выполнить встраивание функции, которая вызывается только один раз.

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

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

W.r.t.поведение вашего инструмента трассировки, ваш вопрос довольно неясен.

Если вызывается функция, которую вы не можете найти в исходном коде, это вряд ли связано со встроенными функциями по двум причинам:

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

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

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

Как называются «загадочные функции»?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top