我正在尝试让学生代码不再使用分配,并拖延我的测试机器。我试过了
setrlimit(RLIMIT_DATA, r);
其中r
是一个持有限制的结构。但遗憾的是,尽管此限制会使brk
和sbrk
停止分配,但C库只会故障转移到mmap
并继续分配。
我也试过
setrlimit(RLIMIT_AS, r)
这会使进程停止运行,但是这个补救措施太严重了 - 进程无法从ENOMEM
错误中恢复,因为代码在遇到{时所做的调用没有堆栈空间从NULL
返回的{1}}值。
我对二进制文件的控制有限,所以如果可以使用系统调用,我宁愿这样做。但我需要一些方法来限制分配,而不会破坏流程的恢复能力。有没有人有建议?
更新:我找到了一个名为failmalloc的东西,但它不是很复杂,虽然我可能会导致它失败,但我总是得到gdb无法诊断的段错误。
进一步更新:我发现malloc()
似乎完成了我想要的工作,至少在某些情况下 - 之后发生的段错误是由不相关模块中的故障引起的。除非有人想出一些有趣的东西(或保留问题的理由),否则我可能会删除这个问题。
答案 0 :(得分:5)
基于failmalloc使用的构思,您可以使用LD_PRELOAD *
环境变量和函数插入来构建malloc()
的包装并在那里施加任何限制。
您需要使用dlsym()
动态加载指向原始malloc()
的指针。您无法直接从包装器调用原始malloc()
,因为它将被解释为对包装器本身的递归调用。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
void * malloc(size_t size)
{
static void * (*func)(size_t) = NULL;
void * ret;
if (!func)
{
/* get reference to original (libc provided) malloc */
func = (void *(*)(size_t)) dlsym(RTLD_NEXT, "malloc");
}
/* impose any necessary restrictions before calling malloc */
...
/* call original malloc */
ret = func(size);
/* impose any necessary restrictions after calling malloc */
...
return ret;
}
*请注意LD_PRELOAD
必须指定插入器库的完整路径,并且为setuid程序禁用该库插入以防止出现安全问题。
使用alternative的dlsym()
将使用GNU链接器--wrap symbol
选项。
答案 1 :(得分:3)
你可以强迫毫无戒心的学生使用宏吗? : - )
#define malloc(bytes) limited_malloc(bytes)
以及limited_malloc
的定义,限制了可以做的事情。