我正在使用 Sun Studio 12.5 在 Solaris 11 下测试 C++ 库。该库在 Sun Studio 12.2 至 12.4 下没有问题,但在 12.5 下有问题。
在 12.5 版本中,编译时出现痛点非优化和调试构建文件bench.cpp
。工具抱怨空间不足。编译失败的输出如下。
我以前见过这种症状,但它通常是内存较小且没有交换文件的 ARM 设备。
该机器有双 Xeon、8 GB RAM 和两个 136 GB 磁盘驱动器,配置为 RAID 1。已使用的磁盘空间似乎约为 20 GB。我担心安装系统时可能配置错误,但我无法发现错误所在。配置信息如下。
我的问题很简单:我是否有足够的内存和存储空间来编译一个会给工具带来负担的文件?是不是配置有误?
$ prtconf | grep -i memory
Memory size: 8190 Megabytes
$ zpool list
NAME SIZE ALLOC FREE CAP DEDUP HEALTH ALTROOT
rpool 136G 19.6G 116G 14% 1.00x ONLINE -
$ df -h
Filesystem Size Used Available Capacity Mounted on
rpool/ROOT/solaris 134G 11G 113G 10% /
/devices 0K 0K 0K 0% /devices
/dev 0K 0K 0K 0% /dev
ctfs 0K 0K 0K 0% /system/contract
proc 0K 0K 0K 0% /proc
mnttab 0K 0K 0K 0% /etc/mnttab
swap 6.7G 1.6M 6.7G 1% /system/volatile
objfs 0K 0K 0K 0% /system/object
sharefs 0K 0K 0K 0% /etc/dfs/sharetab
/usr/lib/libc/libc_hwcap1.so.1
124G 11G 113G 10% /lib/libc.so.1
fd 0K 0K 0K 0% /dev/fd
rpool/ROOT/solaris/var
134G 346M 113G 1% /var
swap 6.8G 114M 6.7G 2% /tmp
rpool/VARSHARE 134G 164K 113G 1% /var/share
rpool/export 134G 32K 113G 1% /export
rpool/export/home 134G 36K 113G 1% /export/home
rpool/export/home/apolyakov
134G 38K 113G 1% /export/home/apolyakov
rpool/export/home/jwalton
134G 2.6G 113G 3% /export/home/jwalton
rpool/export/home/mcaswell
134G 38K 113G 1% /export/home/mcaswell
rpool/export/home/pgutmann
134G 38K 113G 1% /export/home/pgutmann
rpool 134G 4.9M 113G 1% /rpool
rpool/VARSHARE/zones 134G 31K 113G 1% /system/zones
rpool/VARSHARE/pkg 134G 32K 113G 1% /var/share/pkg
rpool/VARSHARE/pkg/repositories
134G 31K 113G 1% /var/share/pkg/repositories
和:
# format
Searching for disks...done
AVAILABLE DISK SELECTIONS:
0. c1t0d0 <HP-LOGICAL VOLUME-5.26-136.70GB>
/pci@0,0/pci8086,25e3@3/pci103c,3235@0/sd@0,0
Specify disk (enter its number): 0
selecting c1t0d0
[disk formatted]
/dev/dsk/c1t0d0s1 is part of active ZFS pool rpool. Please see zpool(1M).
FORMAT MENU:
disk - select a disk
type - select (define) a disk type
partition - select (define) a partition table
...
format> partition
PARTITION MENU:
0 - change `0' partition
1 - change `1' partition
2 - change `2' partition
3 - change `3' partition
4 - change `4' partition
5 - change `5' partition
6 - change `6' partition
select - select a predefined table
modify - modify a predefined partition table
name - name the current table
print - display the current table
...
partition> print
Current partition table (original):
Total disk sectors available: 286660669 + 16384 (reserved sectors)
Part Tag Flag First Sector Size Last Sector
0 BIOS_boot wm 256 256.00MB 524543
1 usr wm 524544 136.44GB 286660702
2 unassigned wm 0 0 0
3 unassigned wm 0 0 0
4 unassigned wm 0 0 0
5 unassigned wm 0 0 0
6 unassigned wm 0 0 0
8 reserved wm 286660703 8.00MB 286677086
$ cat bench-compile.txt
...
/opt/developerstudio12.5/bin/CC -DDEBUG -g3 -xO0 -native -m64 -KPIC -template=no%extdef -c bench2.cpp
DBG_GEN FATAL ERROR: dbg_tables.c:171 - fwrite() failed to write required bytes [DBG_GEN 5.6.3]
CC: Fatal error in /opt/developerstudio12.5/lib/compilers/bin/previse
CC: Status 134
gmake: *** [test.o] Error 134
gmake: *** Waiting for unfinished jobs....
Assembler: bench2.cpp
"<null>", line 821548 : Trouble writing; probably out of temporary file space
/opt/developerstudio12.5/lib/compilers/sys/amd64/libsunir.so'ir_proc_write+0x5d [0xffff80ffbb0eeffd]
/opt/developerstudio12.5/lib/compilers/sys/amd64/libsunir.so'ir_mod_write_and_close+0x2f [0xffff80ffbb10633f]
/opt/developerstudio12.5/lib/compilers/bin/iropt'0x3fee3f [0x7fee3f]
/opt/developerstudio12.5/lib/compilers/bin/iropt'main+0x567 [0x8058f7]
/opt/developerstudio12.5/lib/compilers/bin/iropt'0x12d324 [0x52d324]
compiler(iropt) error: libsunir File IO (read / write IR) error using /tmp/iropt.1468062981.23519.05.ir (No space left on device).
CC: cannot copy temporaries: /tmp/previse.1468062981.23519.07.err
CC: Fatal error in /opt/developerstudio12.5/lib/compilers/bin/previse
CC: Status 134
gmake: *** [bench2.o] Error 134
ERROR: failed to make cryptest.exe
$
答案1
根据错误信息,您的系统缺少虚拟内存。即使有足够的磁盘空间和足够的 RAM,也可能会发生这种情况。
我将首先创建第二个 zvol,比如说 8 GB 的 zvol,然后将其添加为交换设备。例如:
zfs create -V 8gb rpool/swap1
swap -a /dev/zvol/dsk/rpool/swap1
echo "/dev/zvol/dsk/rpool/swap1 - - swap - no -" >> /etc/vfstab
可以使用swap -s
命令监控虚拟内存的使用情况。
答案2
使用 Studio 编译器在 Solaris 上构建程序时可能会发生两个类似的问题。
1)/tmp 空间耗尽
上述症状表明您确实遇到了这种情况。由于 /tmp 目录是在虚拟内存(基于内存的文件系统)之外分配的,因此解决方法是添加交换空间,如上所示。
2)malloc 返回失败代码
如果系统无法在正在运行的进程中找到堆空间 (malloc),则常见的错误模式之一就是出现“fork failed”消息,这种情况发生在操作系统无法分配足够的虚拟内存来创建新进程映像时。此消息来自操作系统,而不是编译器。
即使系统分配了足够的交换空间,Solaris 内核有时也会向用户程序返回 malloc() 失败。当内存请求超时时,就会发生这种情况。如果内核在合理的时间内找不到可用空间(例如通过将内存交换到磁盘),它将返回失败。
这会令人困惑,因为看起来好像没有更多的交换,但这只是一个时间问题。
总之:
通过 /tmp 目录耗尽 VM 的症状和行为与通过 malloc() 调用耗尽 VM 的症状和行为不同。因此请记住这一点。