在上一次的方案中,我用setrlimit来限制子进程对资源的使用量,用非阻塞的wait4函数来进行进程状态的连续监控,还有WIFEXIT, WTERMMSG等一组宏,可以做到对子进程的精确监视与限制,可是内存使用峰值却不能准确测出来。原方案是这样的,在每一轮wait4的时候查看/proc/$pid/statm或者/proc/$pid/status文件,其中保存有进程的内存使用情况。这样做有一个弊端,就是当进程运行时间相当短的话,是测不到有用的值的,因为我用vfork来产生子进程,此时父进程和子进程是并行的,这样一来,一旦两者相差的时间片比较多,便会有很大误差了,这就好比对连续信号的采样,肯定会有信息丢失的,原方案于是被否决了。那怎么样才能真正正确的监视呢?除非能够对子进程进行逐指令的监控,一旦发现有内存分配相关的syscall,便作统计,显然,当前进程内存占用 = 累计分配内存 - 累计释放内存。
linux下有一个系统函数能够做到这一点:ptrace,功能非常强大,可以对进程进行调试。在网上的资料是非常稀少,这里是一篇相当经典的文章:
Playing with ptrace Part I
Playing with ptrace Part II
同时在sourceforge上有个很好的应用ptrace的开源项目: libsandbox
为了避免重复发明轮子的错误,我借鉴了这个项目~
感谢项目作者Liu Yu (pineapple.liu@gmail.com), 在我为怎么调用sandbox困惑时而向他求助时,马上回复了我,邮件中的sample code让我开始搞懂sandbox的机制。
同时为了让这个库适用于online judge,我正在对源代码作一些修改,比如一开始调用这个库总是失败,后来才发现sandbox.c中有chroot的调用,这是需要super user权限的!chroot的目的就是防止子进程危害系统,可是在online judge上应该用不着,因为contestant是不允许在代码中出现系统函数的调用的,输入输出都是使用standard I/O,所以可以去掉这一机制,这样还避免了用root权限来运行sandbox,反倒是对安全有利的。同时sandbox的实时监控功能比较完善,而online judge中可能不会用到,所以准备作一些精简,以提高运行效率。
linux下有一个系统函数能够做到这一点:ptrace,功能非常强大,可以对进程进行调试。在网上的资料是非常稀少,这里是一篇相当经典的文章:
Playing with ptrace Part I
Playing with ptrace Part II
同时在sourceforge上有个很好的应用ptrace的开源项目: libsandbox
为了避免重复发明轮子的错误,我借鉴了这个项目~
![](/Editor/FCKeditor/editor/images/smiley/msn/tounge_smile.gif)
感谢项目作者Liu Yu (pineapple.liu@gmail.com), 在我为怎么调用sandbox困惑时而向他求助时,马上回复了我,邮件中的sample code让我开始搞懂sandbox的机制。
同时为了让这个库适用于online judge,我正在对源代码作一些修改,比如一开始调用这个库总是失败,后来才发现sandbox.c中有chroot的调用,这是需要super user权限的!chroot的目的就是防止子进程危害系统,可是在online judge上应该用不着,因为contestant是不允许在代码中出现系统函数的调用的,输入输出都是使用standard I/O,所以可以去掉这一机制,这样还避免了用root权限来运行sandbox,反倒是对安全有利的。同时sandbox的实时监控功能比较完善,而online judge中可能不会用到,所以准备作一些精简,以提高运行效率。