在公司有同事用这个小程序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,递归地查询统计信息。
时间的统计可能会稍显粗略,如果需要更精确的时间统计该如何实现。