cygwin下的cygheap:从父历程到子历程的复制
Cygwin里的子历程在跳转到正确的位置之前要做一些特定的处理惩罚,这个处理惩罚由child_info_fork::handle_fork函数完成,在child_info_fork::handle_fork函数挪用的第一个函数就是cygheap_fixup_in_child:
cygheap_fixup_in_child (false);
看它的实现:
/* Called by fork or spawn to reallocate cygwin heap */
void __stdcall
cygheap_fixup_in_child (bool execed)
{
cygheap_max = child_proc_info->cygheap;
cygheap = (init_cygheap *) cygheap_max;
_csbrk ((char *) child_proc_info->cygheap_max - (char *) cygheap);
child_copy (child_proc_info->parent, false, "cygheap", cygheap, cygheap_max, NULL);
cygheap_init ();
debug_fixup_after_fork_exec ();
if (execed)
{
cygheap->hooks.next = NULL;
cygheap->user_heap.base = NULL; /* We can allocate the heap anywhere */
/* Walk the allocated memory chain looking for orphaned memory from
previous execs */
for (_cmalloc_entry *rvc = cygheap->chain; rvc; rvc = rvc->prev)
{
cygheap_entry *ce = (cygheap_entry *) rvc->data;
if (!rvc->ptr || rvc->b >= NBUCKETS || ce->type <= HEAP_1_START)
continue;
else if (ce->type < HEAP_1_MAX)
ce->type += HEAP_1_MAX; /* Mark for freeing after next exec */
else
_cfree (ce); /* Marked by parent for freeing in child */
}
}
}
在这里child_proc_info是父历程挪用CreateProcess时通报进来的参数,其cygheap和cygheap_max生存了父历程的cygheap的范畴,这个函数做的第一件事就是将父历程这一段空间的内容复制到子历程相内地点的空间中,这个成果由child_copy函数完成。
紧接着,又挪用了一个叫cygheap_init的函数:
extern "C" void __stdcall
cygheap_init ()
{
cygheap_protect.init ("cygheap_protect");
if (!cygheap)
{
cygheap = (init_cygheap *) memset (_cygheap_start, 0,
_cygheap_mid - _cygheap_start);
cygheap_max = cygheap;
_csbrk (sizeof (*cygheap));
}
if (!cygheap->fdtab)
cygheap->fdtab.init ();
if (!cygheap->sigs)
sigalloc ();
}
此时,由于cygheap的内容已经从父历程完整复制过来,这个函数相当于什么事没做。独一有结果的就是cygheap_protect.init函数挪用。
在cygheap_init之后,是一行空语句:
# define debug_fixup_after_fork_exec() do {} while (0)
由于从child_info_fork::handle_fork通报进来的execed为false,因此函数执行到此竣事。