Имеется такой псевдокод:
func1()
func2()
func3()
...
fincN()
он на выходе даёт граф, содержащий только func1 и func2 (ну и внутрь их), а дальше нету.
Это происходит потому, что func1 и func2 являются твоими собственными функциями или функциями, исходный код которых находится в подключаемых хедерах (в том числе и Qt), в то время как func3() и т.д. являются функциями, которые вызываются из разделяемых библиотек, прилинкованных к приложению, но при этом они собирались без включенного профилирования.
Я собрал свой Qt в debug с дополнительными ключами -pg. К сожалению это особо не помогло. Профилирование для основного приложения теперь выдает:
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 513092 0.00 0.00 etext
Вместо вызова статических функций, при этом gmon.out файл стал весить 2Мб. Я попробовал вот так:
gprof -q debug\QtCored4.dll >profiling.txt
Это сгенерело файл размером в 1Мб. Граф вызовов совпадает с тем, что происходит в моей программе. Количество функций 1739.
Затем
gprof -q debug\QtGuid4.dll >profiling.txt
Он оказался поменьше, но было в нем интересно найти вызовы функций которых я не ожидал. Функций больше 500.
Попытка сделать так:
gprof -q debug\QtGuid4.dll debug\QtCored4.dll debug\main.exe >profiling.txt
Привела к ошибке:
gprof: out of memory allocating 4294967280 bytes
То есть вариант с gprof отпал.
Затем я начал искать другие средства и наткнулся на такую статью:
http://www.ibm.com/developerworks/library/l-graphvisИз нее могу сказать, что метод действительно работает причем как в linux, так и в mingw. Но я не знаю как она будет работать с динамическими библиотеками. Про утилиту
pvtrace могу сказать, что с помощью mingw собирается хорошо. Ужимается до 10Кб. Работоспособность с файлом не проверял.
Искал также информацию по gdb. Кроме простеньких вариантов макросов ничего не нашел. backtrace не подходит хотябы потому, что нужно четко знать глубину на каторой остановится, чтобы "оглянуться" на стек вызовов.
Пробовал также gcov, задача которой вывести "покрытие" кода. Конечно она не работает с динамическими библиотеками, пока их не соберешь со спец ключами. Для неё нашел "front-end" -
lcov, который генерит отчеты в html формате. Написан на Perl, но в Windows не работает, так как использует Linux специфичные команды. Зато нашел замену gcov -
trucov. Написана на C++, умеет генерить графики. Front-end на Qt. Использует boost, в связи с чем у меня возникла накладка с компиляцией под MinGW. Может позже все-таки дособираю.
А это ссылки, который могут пригодится как мне, в будущем, если буду искать, так и другим:
http://www.graphviz.org/About.php - бесплатная кроссплатформенная программа генерации и визуализации графиков
http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Download - скрипт на питоне, позволяющий преобразовать вывод gprof'a в формат
dot, который можно скормить GraphViz для построения графика.
Вызывать например так:
gprof -q main.exe >profiling.txt
c:\Python25\python gprof2dot.py -n0 -e0 -o dots.txt profiling.txt
dot -Tpng -o output.png dots.txt
Параметры
n и
e контролируют глубину графа, нули означают выводить всё.
Наглядное представление:
http://img707.imageshack.us/img707/2495/qtcoregraph.pnghttp://img707.imageshack.us/img707/7091/qtcoregraphchunk.pngZGRViewer - программа для просмотра графов, в основном сконверченные GraphViz'ом в формат SVG, нежели PNG или другие. Довольно шустро работает на больших графах, но не без лагов. Написана на Java, SWIG интерфейс.
Tau - профайлер, который "кушает" вывод gprof'a и выводит статистику, графики и т.п. На больших объемах тормозит. Написана на Java, SWIG интерфейс.