gprof: как создать граф вызовов для функций в разделяемой библиотеке, связанной с основной программой

Я работаю в среде Linux. У меня есть два исходных пакета 'C' train и test_train.

  1. пакет train при компиляции генерирует libtrain.so
  2. test_train ссылается на libtrain.so и генерирует исполняемый train-test

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

Я компилирую и связываю оба пакета с опцией -pg, а уровень отладки равен o0. После того, как я сделаю./train-test, генерируется gmon.out. Тогда я делаю:

$ gprof -q ./train-test gmon.out

Здесь вывод показывает график вызова функций в train-test, но не в libtrain.so

В чем может быть проблема?

3 ответа

gprof не сработает, нужно использовать sprof вместо. Я нашел эти ссылки полезными:

Резюме со 2-й ссылки:

  1. Скомпилируйте свою общую библиотеку (libmylib.so) в режиме отладки (-g). Нет-JP.
  2. export LD_PROFILE_OUTPUT = `pwd`
  3. экспорт LD_PROFILE = libmylib.so
  4. rm -f $ LD_PROFILE.profile
  5. выполнить вашу программу, которая загружает libmylib.so
  6. sprof PATH-TO-LIB / $ LD_PROFILE $ LD_PROFILE.profile -p> log
  7. Смотрите журнал.

Я обнаружил, что на шаге 2 это должен быть существующий каталог - в противном случае вы получите полезное предупреждение. И на шаге 3 может потребоваться указать библиотеку как libmylib.so.X (может быть даже .X.Y, не уверен) - иначе вы не получите никакого предупреждения.

Я загружаю свою библиотеку из Python и мне не повезло с sprof, Вместо этого я использовал oprofile, который был в репозиториях Fedora, по крайней мере:

operf --callgraph /path/to/mybinary

Подождите, пока ваше приложение не завершится или выполните Ctl-c, чтобы прекратить профилирование. Теперь давайте сгенерируем резюме профиля:

opreport --callgraph --symbols

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

Если вы не в Linux (как я в Solaris), вам просто не повезло, так как нет sprof там. Если у вас есть источники вашей библиотеки, вы можете решить свою проблему, связав статическую библиотеку и сделав вместо нее свой бинарный файл профилирования. Еще один способ, которым мне удается отследить вызовы к общим библиотекам, заключается в использовании truss, С возможностью -u [!]lib,...:[:][!]func, ... можно получить хорошее представление об истории вызовов бега. Это не совсем то же самое, что профилирование, но может быть очень полезным в некоторых сценариях.

Другие вопросы по тегам