分叉过程中的确定性malloc

时间:2011-11-18 16:15:14

标签: c linux gcc x86-64

我想要的是让forked进程(它是其父进程的副本)获取从每个malloc函数调用返回的相同地址作为其父进程。我怎样才能做到这一点?

实际上我想要实现的是拥有两个复制进程,它们执行相同的操作。我基本上这样做是为了检测软错误,也就是说,如果存在任何分歧,那一定是由于错误而不是非确定性。现在,由于malloc是非确定性的,它会使两个过程发生分歧,我想避免这种过程。

如果无法做到这一点,我是否可以记录malloc为父进程返回的地址,并为分叉进程使用相同的地址。这会有用吗?

4 个答案:

答案 0 :(得分:3)

如果您的系统是Linux,那么您可以通过禁用地址空间随机化来获得更多可重现的地址。您可以使用此命令(以root身份运行)来实现此目的

echo 0 > /proc/sys/kernel/randomize_va_space

(但地址空间随机化是一项可以提高系统安全性的功能)

但是,这并不能保证父子进程会得到相同的行为(因为它们之间存在细微差别:fork()及其pid的返回)。而你无法确定他们的分配模式是否足够相似。想象一下,如果在fork之后(forked)程序执行类似

的操作
 char *p = malloc (8192*(3 + (getpid() % 10) + time(NULL) % 100));

那么你应该期望malloc在父级和子级中请求大小不同的大小,并且具有不同的malloc返回地址。因此,这个有条件的例子表明您的要求是不现实的。

答案 1 :(得分:2)

malloc根本无法做到这一点。 malloc的返回地址未定义为任何确定性的(尤其是便携式地址)。尝试在进程之间,即使是孩子和父进程之间同步,也可能是徒劳无功的努力。

您能否详细介绍一下您为什么要这样做?也许还有另一种方法可以达到你想要的效果。

答案 2 :(得分:0)

您无法使用标准malloc执行此操作。但是你可以编写自己的自定义分配器,它具有确定的分配方式。例如。作为分配池,使用足够大小的static char pool[POOL_SIZE]; pool的地址在fork()内保持不变。所有指针也都指向pool。瞧!

答案 3 :(得分:-2)

您可能想要使用shared memory。你不能让malloc返回相同的值,因为一旦第一次调用执行,该内存已被分配,不能被提供给另一个进程。