cygwin fork子进程对父进程数据的复制

快乐虾

http://blog.csdn.net/lights_joy/

[email protected]

 

本文适用于

Cygwin checkout-2008-09-28

vs2008

 

欢迎转载,但请保留作者信息

 

fork出来的子进程里,首先复制的就是cygheap的内容,接着又连续从父进程中复制了下面两块内容:

  child_copy (parent, false,

           "dll data", dll_data_start, dll_data_end,

           "dll bss", dll_bss_start, dll_bss_end,

           "user heap", cygheap->user_heap.base, cygheap->user_heap.ptr,

           NULL);

  /* step 2 now that the dll has its heap filled in, we can fill in the

     user's data and bss since user_data is now filled out. */

  child_copy (parent, false,

           "data", user_data->data_start, user_data->data_end,

           "bss", user_data->bss_start, user_data->bss_end,

           NULL);

第一块复制的是cygwin.dll的数据段,第二块复制的是user_data的内容。

1.1    复制数据段

在这里定义了几个全局变量dll_data_start, dll_data_end, dll_bss_start, dll_bss_end。这是几个宏定义:

#define dll_data_start &_data_start__

#define dll_data_end &_data_end__

#define dll_bss_start &_bss_start__

#define dll_bss_end &_bss_end__

这几个全局变量并不在c/cpp文件里面定义,而是由链接器计算而得:

  .data ALIGN(__section_alignment__) :

  {

    __data_start__ = .;

    *(.data)

    *(.data2)

    *(SORT(.data$*))

    __data_end__ = .;

    *(.data_cygwin_nocopy)

  }

  .bss ALIGN(__section_alignment__) :

  {

    __bss_start__ = .;

    *(.bss)

    *(COMMON)

    __bss_end__ = .;

  }

它们指明了cygwin.dll里的数据段的起始地址和结束地址。

vs2008下编译的时候,由于vs将这些数据都放在.data段中,因此我们直接复制.data这个段的内容:

     GetModuleInformation( hProcess, hCygwinDll, &modinfo, sizeof(MODULEINFO) );

 

     // 根据lpBaseOfDll得到其它的数据

     lpbuf = (BYTE*)modinfo.lpBaseOfDll;

 

     //取得节数目

     pfh   =   (PIMAGE_FILE_HEADER)   ((LPVOID)((BYTE *)(lpbuf)+((PIMAGE_DOS_HEADER)(lpbuf))-> e_lfanew+sizeof(DWORD)));

     int nSectionCount   =   pfh-> NumberOfSections;

 

     poh = (PIMAGE_OPTIONAL_HEADER)(pfh + 1);

     psh   =   (PIMAGE_SECTION_HEADER)   ((LPVOID)((BYTE   *)pfh + sizeof(IMAGE_FILE_HEADER) + pfh->SizeOfOptionalHeader));

    

     dwBase = 0;

     for(int i = 0; i < nSectionCount; i++)

     {

         if(strcmp( ".data",   (char *)psh->Name) == 0)

         {

              dwBase = (DWORD)modinfo.lpBaseOfDll + psh->VirtualAddress;

         }

         else if(dwBase > 0)

         {

              child_copy (parent, false,

                   "dll data", dwBase, (BYTE*)modinfo.lpBaseOfDll + psh->VirtualAddress,

                   NULL);

              break;

         }

         psh++;

     }

感谢Tr0j4n提供的代码。

1.2    复制user_data的内容

cygwinuser_data里的data_start等几个成员可以用于指示malloc / free等的heap范围,但由于我们并没有将malloc / freeheap放在user_data里,因此这个复制相当于空操作。

 

 

 

1       参考资料

cygwin下的共享内存区(2009-9-8)

cygwin下的user heap(2009-9-8)

cygwin下的cygheap:从父进程到子进程的复制(2009-9-7)

cygwin下的/etc/fstab(2009-9-7)

cygwin关键技术:fork(2009-9-4)

cygwin关键技术:设备模拟(2009-9-4)

cygwin关键技术cygheap(2009-9-2)

cygwin关键技术:tls(2009-8-24)

vs2008下使用cygwin23):stdinstdoutstderr(2008-10-21)

 

 

 

 

你可能感兴趣的:(user,header,null,dll,byte,alignment)