Почему моя переменная stati c не работает при запуске? - PullRequest
1 голос
/ 15 января 2020

Я пишу тесты для кода для обработки памяти на границах степеней двух, и мне понадобился блок памяти объемом 1 МБ на границе 1 МБ для тестов. Код работал для маленьких блоков, но не для больших. В конце концов, я решил, что это потому, что мои предположительно выровненные данные не были выровнены по границе 1 МБ.

(я, конечно, могу обойти это, но я хочу знать, что происходит.)

Этот код компилируется без предупреждений, objdump говорит, что переменная находится по разумному адресу, но когда я запускаю ее, она выравнивается по границе 4 КБ, а не 1 М.

cat x.c ; gcc --version ; uname -a ; gcc -Wall x.c && ( objdump -x a.out | grep test_data  ; ./a.out )
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct data {
  char memory[1024*1024];
};

static struct data __attribute__(( aligned( 0x100000 ) )) test_data = { 0 };

int main( int argc, const char **argv )
{
  printf( "test_data is actually here: %p\n", &test_data );
  return 0;
}


gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Linux Lubuntutu 4.15.0-72-generic #81-Ubuntu SMP Tue Nov 26 12:20:02 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
0000000000400000 l     O .bss   0000000000100000              test_data
test_data is actually here: 0x5600cb9fe000

Интересным является запуск под GDB:

Reading symbols from ./a.out...done.
(gdb) display &test_data
1: &test_data = (struct data *) 0x400000 <test_data>
(gdb) start
Temporary breakpoint 1 at 0x659: file x.c, line 13.
Starting program: /tmp/a.out 

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe038) at x.c:13
13    printf( "test_data is actually here: %p\n", &test_data );
1: &test_data = (struct data *) 0x555555954000 <test_data>
(gdb) print &test_data.memory[16]
$1 = 0x555555954010 <test_data+16> ""
(gdb) c
Continuing.
test_data is actually here: 0x555555954000

1 Ответ

1 голос
/ 15 января 2020

Это функция загрузчика или, возможно, модуля безопасности.

Код был перемещен в память на такое же количество, предположительно как часть рандомизации макета адресного пространства, но это случайное число из 4 тыс. страниц, что нарушит любое более грубое выравнивание, запрошенное программами.

Связывание программы статически останавливает это, по крайней мере, на данный момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...