Кажется, что-то подобное должно существовать, но я не использовал ничего подобного. Я могу рассказать вам, как бы я написал сценарий вместе. Вероятно, есть более быстрые и / или более сексуальные способы сделать это.
Сначала некоторые вещи, которые вы, возможно, уже знаете:
Команда addr2line принимает адрес и может сказать вам, где находится исходный код, который реализует машинный код. Исполняемый файл должен быть собран с отладочными символами, и вы, вероятно, не захотите много его оптимизировать (-O0, -O1 или -Os, вероятно, так же высоки, как вы бы хотели сначала). У addr2line есть несколько флагов, и вы захотите прочитать его страницу руководства, но вам определенно нужно будет использовать -C или --demangle, если вы хотите видеть имена функций C ++, которые имеют смысл в выводе.
Команда objdump может распечатать все виды интересных вещей о материале во многих типах объектных файлов. Одна из вещей, которую он может сделать, это распечатать таблицу, представляющую символы в объектном файле или на которые они ссылаются (включая исполняемые файлы).
Теперь, что вы хотите сделать с этим:
Вам нужно, чтобы objdump сообщал вам адрес и размер секции .text. Вот где живет настоящий исполняемый машинный код. Есть несколько способов сделать это, но самый простой (для этого, во всяком случае), вероятно, для вас, чтобы сделать:
objdump -h my_exe | grep text
Это должно привести к чему-то вроде:
12 .text 0000049 000000f000 0000000f000 00000400 2**4
Если бы вы не взяли его, он бы выглядел как:
Idx Name Size VMA LMA File off Algn
Я думаю, что для исполняемых файлов VMA и LMA должны быть одинаковыми, поэтому не имеет значения, какой вы используете, но я думаю, что LMA - лучший. Вы также захотите размер.
С LMA и размером вы можете многократно вызывать addr2line с запросом происхождения исходного кода машинного кода. Я не уверен, как это будет работать, если вы передадите адрес, который был в пределах одной инструкции, но я думаю, что это должно сработать.
addr2line -e my_exe <address>
Выходными данными будут путь / имя файла, двоеточие и номер строки.
Если бы вы должны были подсчитать вхождение каждого уникального пути / файла: num, вы сможете посмотреть те, которые имеют наибольшее количество.
Perl хэширует, используя путь / файл: num в качестве ключа и счетчик в качестве значения, это будет простой способ реализовать это, хотя есть более быстрые способы, если вы обнаружите, что работает слишком медленно.
Вы также можете отфильтровать вещи, которые, как вы можете определить, не нужно включать заранее.
Для отображения выходных данных вы можете отфильтровать разные строки из одной и той же функции, но вы можете заметить, что разные строки в одной функции имеют различное число, что может быть интересно. В любом случае, это может быть сделано либо с помощью addr2line, сообщающей вам имя функции, либо с помощью objdump -t на первом шаге и работающего по одной функции за раз.
Если вы видите, что некоторый код шаблона или другие строки кода появляются в ваших исполняемых файлах чаще, чем вы думаете, то вы можете легко найти их и присмотреться. Макросы и встроенные функции могут в конечном итоге проявить себя не так, как вы ожидаете.
Если вы не знали, objdump и addr2line из пакета GNU binutils , который включает в себя несколько других полезных инструментов.