在公司有同事用这个小程序RunLim来调试程序的内存问题。刚开始以为是我们上海的一个同事写的,就弄来看了看。后来发现是公司一个早期同事Armin Biere写的,还开源了,debian 的源里有这个东西。我在公司维护的一部分代码是这个人写的,据说厉害的程序员,他现在在学术圈里。
用这个小程序来测试程序跑的时间和内存,用法很简单:
./runlim prog.exe
比如:
kang@ubuntu:~/download/runlim-1.7$ ./runlim sleep 1
[runlim] version: 1.7
[runlim] time limit: 311040000 seconds
[runlim] real time limit: 311040000 seconds
[runlim] space limit: 4294966090 MB
[runlim] argv[0]: sleep
[runlim] argv[1]: 1
[runlim] start: Tue Oct 30 00:02:52 2012
[runlim] main pid: 22546
[runlim] end: Tue Oct 30 00:02:53 2012
[runlim] status: ok
[runlim] result: 0
[runlim] children: 0
[runlim] real: 1.63 seconds
[runlim] time: 0.00 seconds
[runlim] space: 0.5 MB
[runlim] samples: 10
查看 help,这个工具还可以指定 time limit 和 space limit,在指定的时间和内存限制内强制退出程序,其功能很像那些Online Judge,只是没有检测结果输出是否正确。
发现代码里有一个小小的 Bug,根据源代码如果没有指定 space limit,space limit 那栏应该是当前的空闲内存大小,但是看我上面运行的命令,显示的 4294966090 MB 明显偏大,是其中的一个获取系统内存大小的函数溢出了。这里应该是这样:
static unsigned
get_physical_mb ()
{
unsigned long long mem;
mem = (unsigned long long)sysconf(_SC_PAGE_SIZE)*
(unsigned long long)sysconf(_SC_PHYS_PAGES);
return mem >>= 20;
}
sysconf 获取页大小和页数目,具体看这里How to get information about the memory subsystem?。
这个小工具还是查询/proc 下的进程统计信息的,根据 fork 出来的子进程 pid,递归地查询统计信息。
时间的统计可能会稍显粗略,如果需要更精确的时间统计该如何实现。