Ответ 1
Кажется, что-то вроде этого должно существовать, но я не использовал ничего подобного. Я могу рассказать вам, как я буду писать об этом вместе. Вероятно, есть более быстрые и/или более сексуальные способы сделать это.
Прежде всего, некоторые вещи, которые вы уже знаете:
Команда addr2line принимает адрес и может сообщать вам, где исходный код, который там используется машинный код. Исполняемый файл должен быть построен с помощью отладочных символов, и вы, вероятно, не захотите его оптимизировать (-O0, -O1 или -Os, вероятно, так высок, как вы хотели бы пойти сначала в любом случае). addr2line имеет несколько флагов, и вы захотите прочитать его страницу руководства, но вам обязательно нужно использовать -C или --demangle, если вы хотите видеть имена функций С++, которые имеют смысл в выходе.
Команда 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, который включает в себя несколько других полезных инструментов.