-v
,它也会失败并显示错误信息gcc: virtual memory exhausted
。我已经使用2.6.24内核重新启动我的开发系统,并且编译器可以正常工作(使用2.6.25重新启动则失败)。我们有一个系统保持在2.6.24版本,只是为了构建该芯片的程序,但是如果Linux世界继续向前发展,我们将无法再重建一个能够运行编译器的系统(例如,我们的2.6.24系统停止使用,而我们无法在新系统上安装和运行2.6.24,因为某些软件部分不再可用),这让我们感到有些不安。
有没有人有什么想法可以让我们在更现代的安装中运行这个遗留编译器?
好的,更多信息:
看起来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”)启动新的shell
我已经尝试过它们,它们似乎确实有影响,因为brk()返回值与没有它们时不同(在内核2.6.25和2.6.26上都试过),但是brk()仍然失败,所以旧版gcc仍然失败:-(。
此外,我设置了vm.legacy_va_layout=1
和vm.overcommit_memory=2
,但没有改变,并且我重新启动了保存在/ etc / sysctl.conf中的vm.legacy_va_layout=1
和kernel.randomize_va_space=0
。仍然没有变化。
编辑:
在内核2.6.26(和2.6.25)上使用kernel.randomize_va_space=0
会导致strace legacy-gcc
报告以下brk()调用:
brk(0x80556d4) = 0x8056000
这表明brk()失败了,但看起来它失败是因为数据段已经超出了所请求的范围。使用objdump,我可以看到数据段应该以0x805518c结束,而失败的brk()指示数据段当前以0x8056000结束:
章节: Idx 名称 大小 VMA LMA 文件偏移 对齐 0 .interp 00000013 080480d4 080480d4 000000d4 2**0 内容,分配,加载,只读,数据 1 .hash 000001a0 080480e8 080480e8 000000e8 2**2 内容,分配,加载,只读,数据 2 .dynsym 00000410 08048288 08048288 00000288 2**2 内容,分配,加载,只读,数据 3 .dynstr 0000020e 08048698 08048698 00000698 2**0 内容,分配,加载,只读,数据 4 .rel.bss 00000038 080488a8 080488a8 000008a8 2**2 内容,分配,加载,只读,数据 5 .rel.plt 00000158 080488e0 080488e0 000008e0 2**2 内容,分配,加载,只读,数据 6 .init 00000008 08048a40 08048a40 00000a40 2**4 内容,分配,加载,只读,代码 7 .plt 000002c0 08048a48 08048a48 00000a48 2**2 内容,分配,加载,只读,代码 8 .text 000086cc 08048d10 08048d10 00000d10 2**4 内容,分配,加载,只读,代码 9 .fini 00000008 080513e0 080513e0 000093e0 2**4 内容,分配,加载,只读,代码 10 .rodata 000027d0 080513e8 080513e8 000093e8 2**0 内容,分配,加载,只读,数据 11 .data 000005d4 08054bb8 08054bb8 0000bbb8 2**2 内容,分配,加载,数据 12 .ctors 00000008 0805518c 0805518c 0000c18c 2**2 内容,分配,加载,数据 13 .dtors 00000008 08055194 08055194 0000c194 2**2 内容,分配,加载,数据 14 .got 000000b8 0805519c 0805519c 0000c19c 2**2 内容,分配,加载,数据 15 .dynamic 00000088 08055254 08055254 0000c254 2**2 内容,分配,加载,数据 16 .bss 000003b8 080552dc 080552dc 0000c2dc 2**3 分配 17 .note 00000064 00000000 00000000 0000c2dc 2**0 内容,只读 18 .comment 00000062 00000000 00000000 0000c340 2**0 内容,只读 符号表: 没有符号编辑:
回应下面ephemient的评论:“如此奇怪地将GCC视为没有源代码的二进制文件”!
因此,我使用strace、objdump、gdb和有限的386汇编语言和体系结构理解,已经追踪到遗留代码中第一个malloc调用的问题。遗留gcc调用malloc,它返回NULL,导致stderr上出现“虚拟内存耗尽”的消息。这个malloc在libc.so.5中,它调用getenv多次,并最终调用brk()...我猜是为了增加堆...但失败了。
由此我只能推测问题不仅仅是brk随机化,或者我尽管设置了randomize_va_space=0和legacy_va_layout=1 sysctl设置,但并没有完全禁用brk随机化。
libc.so.5
,问题出在这里?这是一个可怕的hack,但是glibc应该足够兼容,如果你做一个ln -s libc.so.6 libc.so.5
,你的代码可能仍然可以运行。 - ephemient