Я демонтирую исполняемый файл:
(gdb) disas main
Dump of assembler code for function main:
0x004012d0 <main+0>: push %ebp
0x004012d1 <main+1>: mov %esp,%ebp
...
Каждый раз адрес памяти является тем же:0x004012d0
.
Разве адрес памяти не должен быть динамично присвоен ОС?
ОБНОВЛЕНИЕ
Теперь я вижу, что это - виртуальное пространство, и это может быть рандомизировано на некоторых платформах.
Кто-то может отправить дамп gdb, который изменяется?
Почему ОС выбирает другой адрес?
Когда ОС выполняет процесс, она загружает исполняемый файл в пространство виртуальной памяти. По пути он разрешит любые относительные и/ или символические ссылки. Предполагая, что у вас один и тот же исполняемый файл и те же разделяемые библиотеки, и вы запускаете его так же, как и в предыдущий раз, было бы очень странно, если бы ОС решила загрузить исполняемый файл другим способом.
Я думаю, что проблема здесь (по крайней мере, в Linux) может быть в том, что gdb пытается помочь, из документации:
set disable-randomization
set disable-randomization on
Эта опция (включена по умолчанию в gdb) отключает встроенную рандомизацию в виртуальном адресном пространстве запущенной программы. виртуального адресного пространства запущенной программы. Эта опция полезна для нескольких отладочных чтобы сделать выполнение более воспроизводимым, а адреса памяти - многократно используемыми в разных сеансах отладки. сеансах отладки.
Эта возможность реализована только в gnu/Linux. Вы можете получить такое же поведение, используя
(gdb) set exec-wrapper setarch `uname -m` -R
http://sourceware.org/gdb/current/onlinedocs/gdb/Starting.html
UPDATE: Я проверил это и, похоже, это действительно так для меня (под управлением Linux 2.6.28). Составьте простую программу Hello World и запустите gdb без args командной строки (мы не хотим загружать программу до переопределения настройки disable-randomization), а затем введите:
(gdb) set disable-randomization off
(gdb) file ./a.out
(gdb) break main
(gdb) run
(gdb) disas printf
Адрес printf отличается при каждом запуске программы.
Это зависит от ОС. Чаще всего адрес двоичного файла остается неизменным. Это важно для эксплуатации ошибок манипулирования памятью, таких как переполнения буфера. Адрес слинкованных библиотек в Linux всегда будет отличаться из-за ASLR. В Windows Vista и Windows 7 пространство виртуальной памяти двоичного файла также рандомизируется при каждом его выполнении, поэтому адрес функции будет отличаться при каждом запуске.
Некоторые исполняемые файлы настроены так, что они всегда загружаются по одному и тому же адресу. Некоторые установлены таким образом, что их можно "перемещать". Параметр, управляющий этим в компоновщике Visual Studio, называется / FIXED. Даже такие исполняемые файлы чаще всего загружаются по предпочтительному адресу. Более новые ОС (Win7, Vista) рандомизируют адрес загрузки для некоторых исполняемых файлов для повышения безопасности (процесс атаки, загруженный по неизвестному адресу, сложнее) - это называется ASLR . Примечание. Даже исполняемый файл, помеченный как / FIXED: NO, не считается подходящим для ASLR. Разработчик должен явно разрешить ASLR для исполняемого файла.
Примечание: важно понимать, что процесс владеет всем адресным пространством. У нескольких процессов есть собственное адресное пространство, поэтому, если вы запускаете один и тот же исполняемый файл несколько раз, нет причин, по которым он не может загружаться по одному и тому же адресу каждый раз.
И да, и нет. Физическая память выделяется ОС, и только ОС знает, где находится ваша программа в физической оперативной памяти. Ваша программа видит только виртуальный адрес, который всегда будет одним и тем же, если все загружается в одном и том же порядке.
Это зависит от операционных систем. В большинстве современных операционных систем с виртуальной памятью нет необходимости в перемещаемом исполняемом коде, но в старых операционных системах и в некоторых специализированных операционных системах (например, в реальном времени, встроенные) наложения кода могут использоваться в сочетании с позиционно-независимыми. код и таблицы переходов. В этом случае адрес функции может измениться, например если его кодовый сегмент заменен, а затем заменен обратно по другому адресу.
Это виртуальный адрес. Физический адрес известен ОС, но каждый процесс имеет собственное виртуальное адресное пространство. Перемещаемый образ, вероятно, будет каждый раз получать одно и то же сопоставление, особенно основной исполняемый файл. Но это не гарантируется. Примером являются библиотеки DLL. Библиотеки DLL могут загружаться в разном порядке, что приводит к разным виртуальным адресам между запусками, потому что по мере загрузки DLL 1 DLL 2 не может быть загружена в этот виртуальный адрес и должна получить свой собственный адрес.