вторник, 22 мая 2018 г.

профилируем программы, не умы

Раз уж потратил изрядное количество времени на проблемку, так постараюсь минут за 10 это описать...
Задача: получить читаемый лог вызовов функций программы.
Решение "по учебнику" — профилировщик, в GCC это gprof. Не сработало!


По-простому, по мануалу:
gcc -pg 1.c
порождает исполнимый a.out, который содержит в себе код профилировщика, выдающий профиль программы. Окей, попробуем:
cmake $PROJECT_DIR \
-DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS=-pg
make

./$PROJECT_EXE
gprof -b ./$PROJECT_EXE
получаем на выходе:
Each sample counts as 0.01 seconds.
 no time accumulated
воссааа? впрочем, интернет даёт объяснение:
 >>  no time accumulated
This can happen if the clock never ticks while the program has the CPU, such as if all execution takes place for very short times (less than 1/512 second) immediately after the clock ticks and the kernel schedules processes, which might happen to a simple GUI or other process whose execution is strongly correlated with scheduling.
ааа! так gprof не собирает точную, всю информацию, а только "время от времени". Ладно. чем его заменить? Оказывается, можно заменить valgrind-ом:
valgrind --tool=callgrind ./$PROJECT_EXE
gprof2dot.py -n0 -e0 -p nfc -f callgrind callgrind.out.* > /tmp/1.dot
(nfc тут для фильтрации вызовов функций)
посмотрим...
Эмм.. как-то тут всё разрозненно. Почему? а!
gprof2dot.py -n0 -e0 -p nfc -p ld-2 -f callgrind callgrind.out.* > /tmp/1.dot
так-то лучше. Но что этот ld тут мешается?
В исходниках функции nfc_init() вызывается прямо из main(). Не сразу до меня дошло, что это последствия динамического связывания (линковки) nfc-anticol с библиотекой libnfc. Быстренько поправим:
-ADD_LIBRARY(nfc SHARED ${LIBRARY_SOURCES})
+ADD_LIBRARY(nfc STATIC ${LIBRARY_SOURCES})
о! ну вот! красота!!! Как на ладони: что откуда приходит и что куда уходит :)

Bonus:
оказалось, что если линковать библиотеку статически, то gprof тоже что-то показывает:
gprof -b ./nfc-anticol > gmon.out.txt
gprof2dot.py -n0 -e0 gmon.out.txt > /tmp/1.dot
так, посмотрим.

Чёёё? А где main() ? И некоторых вызовов не хватает. Ладно, gprof "в печку", вместе с перепиской Энгельса "с этим... Как его — дьявола — с Каутским.":
—Зина! — кричал Борменталь.
—Зина! — орал испуганный Шариков.
Зина прибежала бледная.
—Зина, там в приемной... Она в приемной?
—В приемной, — покорно ответил Шариков, — зеленая, как купорос.
—Зеленая книжка...
—Ну, сейчас палить, — отчаянно воскликнул Шариков, — она казенная, из библиотеки!
—Переписка — называется, как его... Энгельса с этим чертом... В печку ее!
Зина улетела.
P.S. за 10 минут, разумеется, не получилось. А получилось как всегда...

Комментариев нет:

Отправить комментарий