Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
分叉过程中的确定性malloc_C_Linux_Gcc_X86 64 - Fatal编程技术网

分叉过程中的确定性malloc

分叉过程中的确定性malloc,c,linux,gcc,x86-64,C,Linux,Gcc,X86 64,我想要的是让forked进程(它是其父进程的副本)获得从每个malloc函数调用返回的与其父进程相同的地址。我怎样才能做到这一点 实际上,我试图实现的是有两个复制的进程,它们执行相同的事情。我这样做基本上是为了检测软错误,也就是说,如果有任何分歧,它一定是由于错误,而不是非确定性。现在,由于malloc是不确定的,它将使两个过程分开,这是我想要避免的 如果不可能,我可以为父进程记录malloc返回的地址,并为分叉进程使用相同的地址。这行吗?您可能想使用。您不能让malloc返回相同的值,因为一旦

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

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


如果不可能,我可以为父进程记录malloc返回的地址,并为分叉进程使用相同的地址。这行吗?

您可能想使用。您不能让malloc返回相同的值,因为一旦第一次调用执行,该内存就已分配,无法分配给另一个进程。

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


你能告诉我们你为什么要这样做的更多细节吗?也许还有另一种方法可以达到您想要的效果。

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

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

但是,这并不能保证父进程和子进程将获得相同的行为(因为它们之间有一个很小的区别:返回
fork()
和它们的pid)。你也不能确定他们的分配模式是否足够相似。想象一下,如果在fork之后(forked)程序执行如下操作

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

然后,您应该期望malloc在父级和子级中请求大不相同的大小,并使用不同的malloc返回地址。因此,这个虚构的例子表明您的需求是不现实的

您不能使用标准的
malloc
执行此操作。但您可以编写自己的自定义分配器,该分配器具有确定的分配方式。例如,作为分配池,使用足够大的
静态字符池[pool_SIZE]
fork()
中,
池的地址保持不变。所有指向
池的指针也都是
。瞧

这是一个奇怪的要求;你介意分享哪种设计需要这个吗?你是在试图自己构建共享内存吗?实际上,我正在尝试实现冗余执行以检测软错误,也就是说,如果有任何分歧,应该是由于错误,而不是由于非确定性。我能想到的获取不同地址的唯一解释是ASLR。在内核级别关闭它,您可能会得到相同的地址。但是依赖这个似乎是一个非常糟糕的主意。现在我知道你在做什么了,我认为这在大多数情况下仍然是被误导的。通常,一个过程的两个分叉副本会因其他原因而出现分歧,例如具有不同的PID、获取独占资源的不同成功顺序(这可能反过来导致不同的
malloc
模式)等。如果您的程序(几乎)纯粹是计算性的,这些差异可能无关紧要,但它看起来仍然非常脆弱,怎么会这样呢?不同的进程有完全独立的地址空间,用于各自独立的虚拟内存……嗯,地址空间是不同的,但动态获得的mallod指针可能具有相同的数值(但指向不同的空间)。@KerrekSB从字面意义上讲是非常正确的。我将OPs问题解释为想要指向相同的物理内存块,这显然是不正确的。我试图实现冗余执行,以便能够检测软错误,也就是说,如果有任何分歧,应该是由于错误,而不是由于非确定性。因此,我希望这两个进程,即父进程和它的副本(分叉进程)在没有错误的情况下以完全相同的方式执行。我不知道禁用ASR将如何使其工作。ASR影响虚拟地址空间布局(您显然知道),它是在fork()之后继承的。每个子级中的Malloc()只是在这个布局中分配堆上的空间,因此应该总是分散,或者至少可以这样做。也许我遗漏了什么。@gnometorule:虚拟地址布局与
malloc
相关,因为
malloc
使用虚拟内存。每个内存块(在Unix中)要么来自进程(
brk
空间),要么来自
mmap
块<代码>mmap
直接受ASLR影响。当然。但这如何适用于当前的问题?@gnometorule:对于大型分配,
glibc
中的
malloc()
使用
mmap()
获取新的内存块,而不是在当前堆中分配空间。如果启用了ASLR,内核将为这个新的匿名映射提供一个随机地址,该地址反映在
malloc()
返回的地址中。
 char *p = malloc (8192*(3 + (getpid() % 10) + time(NULL) % 100));