Мы используем устаревший компилятор, основанный на gcc 2.6.0, для кросс-компиляции для старого встроенного процессора, который мы все еще используем (да, он все еще используется с 1994 года!). Инженер, создавший порт gcc для этого чипа, давно ушел. Хотя мы могли бы восстановить исходный код gcc 2.6.0 откуда-нибудь из Интернета, изменения, внесенные для этого чипа, исчезли в залах корпоративной истории. Мы путались до недавнего времени, так как компилятор все еще запускал и создавал работоспособные исполняемые файлы, но, начиная с ядра Linux 2.6.25 (а также 2.6.26), он не работает с сообщением _1 _... даже при запуске без параметров или только с -v
. Я перезагрузил свою систему разработки (с версии 2.6.26), используя ядро 2.6.24, и компилятор снова работает (перезагрузка с 2.6.25 не работает).
У нас есть одна система, которую мы сохраняем в версии 2.6.24 только для целей сборки для этого чипа, но мы чувствуем себя немного незащищенными на случай, если мир Linux дойдет до такой степени, что мы больше не сможем перестроить систему, которая будет работать. компилятор (т.е. наша система 2.6.24 умирает, и мы не можем заставить 2.6.24 установить и запустить в новой системе, потому что некоторые части программного обеспечения больше не доступны).
Есть ли у кого-нибудь идеи, что мы могли бы сделать с более современной установкой, чтобы запустить этот устаревший компилятор?
Изменить:
Чтобы ответить на некоторые комментарии ...
К сожалению, потеряны изменения исходного кода, характерные для нашего чипа. Эта потеря произошла из-за двух крупных реорганизаций компании и нескольких системных администраторов (пара из которых действительно оставила беспорядок). Теперь мы используем контроль конфигурации, но это закрывает дверь сарая слишком поздно для решения этой проблемы.
Использование виртуальной машины - хорошая идея, и, возможно, именно этим мы и займемся. Спасибо за идею.
Наконец, я попробовал strace, как было предложено ephemient, и обнаружил, что последним системным вызовом был brk (), который возвращал ошибку в новой системе (ядро 2.6.26) и возвращал успех в старой системе (ядро 2.6.24). Это будет означать, что у меня действительно заканчивается виртуальная память, за исключением того, что tcsh "limit" возвращает те же значения в старых и новых системах, а / proc / meminfo показывает, что в новых системах немного больше памяти и немного больше места для подкачки. Может это проблема фрагментации или где программа загружается?
Я провел дополнительное исследование, и в ядре 2.6.25 была добавлена «рандомизация brk», однако CONFIG_COMPAT_BRK
предположительно включен по умолчанию (что отключает рандомизацию brk).
Изменить:
Хорошо, больше информации: действительно похоже, что в этом виновата рандомизация brk, устаревший gcc вызывает brk (), чтобы изменить конец сегмента данных, и теперь он не работает, в результате чего устаревший gcc сообщает «виртуальная память исчерпана». Есть несколько задокументированных способов отключить рандомизацию brk:
sudo echo 0 > /proc/sys/kernel/randomize_va_space
sudo sysctl -w kernel.randomize_va_space=0
запуск новой оболочки с
setarch i386 -R tcsh
(или "-R -L")
Я пробовал их, и они, кажется, имеют эффект в том, что возвращаемое значение brk () отличается (и всегда то же самое), чем без них (пробовалось как на ядре 2.6.25, так и на 2.6.26), но brk () по-прежнему не работает, поэтому устаревший gcc по-прежнему не работает :-(.
Кроме того, я установил vm.legacy_va_layout=1
и vm.overcommit_memory=2
без изменений, и я перезагрузился с настройками vm.legacy_va_layout=1
и kernel.randomize_va_space=0
, сохраненными в /etc/sysctl.conf. По-прежнему без изменений.
Изменить:
Использование kernel.randomize_va_space=0
в ядре 2.6.26 (и 2.6.25) приводит к тому, что strace legacy-gcc
сообщает о следующем вызове brk ():
brk(0x80556d4) = 0x8056000
Это указывает на сбой brk (), но похоже, что он не удался, потому что сегмент данных уже заканчивается сверх того, что было запрошено. Используя objdump, я вижу, что сегмент данных должен заканчиваться на 0x805518c, тогда как неудачный brk () указывает, что сегмент данных в настоящее время заканчивается на 0x8056000:
Sections: Idx Name Size VMA LMA File off Algn 0 .interp 00000013 080480d4 080480d4 000000d4 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .hash 000001a0 080480e8 080480e8 000000e8 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .dynsym 00000410 08048288 08048288 00000288 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .dynstr 0000020e 08048698 08048698 00000698 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .rel.bss 00000038 080488a8 080488a8 000008a8 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .rel.plt 00000158 080488e0 080488e0 000008e0 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .init 00000008 08048a40 08048a40 00000a40 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 7 .plt 000002c0 08048a48 08048a48 00000a48 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 8 .text 000086cc 08048d10 08048d10 00000d10 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 9 .fini 00000008 080513e0 080513e0 000093e0 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 10 .rodata 000027d0 080513e8 080513e8 000093e8 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 11 .data 000005d4 08054bb8 08054bb8 0000bbb8 2**2 CONTENTS, ALLOC, LOAD, DATA 12 .ctors 00000008 0805518c 0805518c 0000c18c 2**2 CONTENTS, ALLOC, LOAD, DATA 13 .dtors 00000008 08055194 08055194 0000c194 2**2 CONTENTS, ALLOC, LOAD, DATA 14 .got 000000b8 0805519c 0805519c 0000c19c 2**2 CONTENTS, ALLOC, LOAD, DATA 15 .dynamic 00000088 08055254 08055254 0000c254 2**2 CONTENTS, ALLOC, LOAD, DATA 16 .bss 000003b8 080552dc 080552dc 0000c2dc 2**3 ALLOC 17 .note 00000064 00000000 00000000 0000c2dc 2**0 CONTENTS, READONLY 18 .comment 00000062 00000000 00000000 0000c340 2**0 CONTENTS, READONLY SYMBOL TABLE: no symbols
Изменить:
Чтобы повторить комментарий ephemient ниже: «Так странно рассматривать GCC как двоичный файл без исходного кода»!
Итак, используя strace, objdump, gdb и мое ограниченное понимание 386 ассемблера и архитектуры, я проследил проблему до первого вызова malloc в устаревшем коде. Устаревший gcc вызывает malloc, который возвращает NULL, что приводит к сообщению «виртуальная память исчерпана» на stderr. Этот malloc находится в libc.so.5, он несколько раз вызывает getenv и в конечном итоге вызывает brk () ... Я думаю, чтобы увеличить кучу ... что не удается.
Исходя из этого, я могу только предположить, что проблема заключается не только в рандомизации brk, или я не полностью отключил рандомизацию brk, несмотря на настройки sysctl randomize_va_space = 0 и legacy_va_layout = 1.
libc.so.5
, где проблема? Ужасный взлом, но glibc должна быть достаточно совместимой, чтобы, если вы сделаетеln -s libc.so.6 libc.so.5
, ваш код, вероятно, все равно будет работать. - person ephemient   schedule 27.04.2009