Вы не можете "войти в" функции; Godbolt не отладчик, это дизассемблер. Ваша программа не запускается , она просто компилируется. (И если вы не выберете «двоичный» вариант вывода, он компилируется только в asm, а не в машинный код, и фактически не связывается.)
Но независимо от терминологии, нет, вам не удастся заставить Godbolt показать вам разборку для какой-либо версии библиотеки, которую он установил.
Одноступенчатая программа на рабочем столе. (Скомпилируйте с gcc -O3 -fno-plt
, чтобы избежать необходимости выполнять ленивую динамическую компоновку PLT.)
(Я так и сделал, и libstdc ++ 6.2.1 в Arch Linux запускает cpuid
в конструкторе для std::random_device
. Если rdrand
доступен, он использует его при вызовах _M_getval()
. Это можно понять из простой разборки было бы сложно, есть несколько уровней вызовов функций и ветвления, и без символов было бы трудно понять, что к чему. Мой Skylake имеет rdseed
доступный, но он не использовал его. Да, как вы прокомментировал, что это был бы лучший выбор.)
Разные компиляторы могут генерировать разные версии библиотечных функций из одного и того же источника, что является основным моментом существования проводника компилятора. И нет, у него нет отдельной версии libstdc ++, скомпилированной каждым компилятором в выпадающем списке.
Не будет никакой гарантии, что код библиотеки, который вы видели, будет соответствовать тому, что находится на вашем рабочем столе, или чему-либо еще.
На самом деле на нем установлены библиотеки Linux x86-64, хотя, теоретически, Godbolt мог бы дать вам возможность находить и разбирать определенные библиотечные функции, но эта функциональность в настоящее время не существует. И будет работать только для целей, где доступна опция «двоичный»; Я думаю, что для большинства целей кросс-компиляции у него есть только заголовки, а не библиотеки. Или, может быть, есть какая-то другая причина, по которой он не будет связывать и разбирать для ISA, отличных от x86.
Использование -static
и бинарный режим показывает вещи, но не то, что мы хотим.
Я попытался скомпилировать с -static -fno-plt -fno-exceptions -fno-rtti -nostartfiles -O3 -march=skylake
(поэтому rdrand и rdseed будут доступны в случае, если они будут встроены; они не будут). -fno-plt
избыточен с -static
, но полезно без , чтобы удалить этот беспорядок.
-static
приводит к тому, что код библиотеки фактически оказывается в связанном бинарном файле, который разбирает Godbolt . Но вывод ограничен 500 строками, и определение std::random_device::_M_getval()
оказывается не близко к началу файла.
-nostartfiles
позволяет избежать загромождения двоичного файла с помощью _start
и т. Д. Из файлов запуска CRT. Я думаю, что Godbolt уже отфильтровывает их из разборки, потому что вы не видите их в обычном двоичном выводе (без -static
). Вы не собираетесь запускать программу, поэтому не имеет значения, что компоновщик не смог найти символ _start
и просто по умолчанию установил точку входа ELF в начале раздела .text
.
Несмотря на компиляцию с -fno-exceptions -fno-rtti
(поэтому не включен обработчик развёртывания для вашей функции), функции libstdc ++ были скомпилированы с включенной обработкой исключений. Таким образом, связывание их приводит к загрузке кода исключения. Статический исполняемый файл начинается с определений таких функций, как std::__throw_bad_exception():
и std::__throw_bad_alloc():
Кстати, без -fno-exceptions
, есть также определение get_random_seed() [clone .cold]:
, которое я считаю обработчиком раскрутки. Это не определение вашей действительной функции. В начале статического двоичного файла находится operator new(unsigned long) [clone .cold]:
, который, как мне кажется, снова является кодом обработчика исключений libstdc ++.
Я думаю, к сожалению, сначала были связаны разделы .text.cold
или .init
, поэтому ни одна из интересных функций не будет видна в первых 500 строках.
Даже если это сработало, это только разборка в двоичном режиме, а не компилятор asm
Даже с символами отладки мы не знали бы, к какому элементу структуры обращались, только смещения чисел из регистров, потому что objdump не заполняет их.
И с большим количеством ветвлений трудно следовать за сложными логическими возможностями. Один шаг во время выполнения автоматически следует фактическому пути выполнения.