快乐虾
http://blog.csdn.net/lights_joy/
本文适用于
Cygwin checkout-2008-09-28
vs2008
欢迎转载,但请保留作者信息
Cygwin使用了多块共享内存区,创建这些内存区的功能由open_shared函数完成:
void * __stdcall
open_shared (const char *name, int n, HANDLE& shared_h, DWORD size,
shared_locations& m, PSECURITY_ATTRIBUTES psa, DWORD access)
{
void *shared;
void *addr;
if (m == SH_JUSTCREATE || m == SH_JUSTOPEN)
addr = NULL;
else
{
addr = off_addr (m);
VirtualFree (addr, 0, MEM_RELEASE);
}
char map_buf[MAX_PATH];
char *mapname = NULL;
if (shared_h)
m = SH_JUSTOPEN;
else
{
if (name)
mapname = shared_name (map_buf, name, n);
if (m == SH_JUSTOPEN)
shared_h = OpenFileMapping (access, FALSE, mapname);
else
{
shared_h = CreateFileMapping (INVALID_HANDLE_VALUE, psa,
PAGE_READWRITE, 0, size, mapname);
if (GetLastError () == ERROR_ALREADY_EXISTS)
m = SH_JUSTOPEN;
}
if (shared_h)
/* ok! */;
else if (m != SH_JUSTOPEN)
api_fatal ("CreateFileMapping %s, %E. Terminating.", mapname);
else
return NULL;
}
shared = (shared_info *)
MapViewOfFileEx (shared_h, access, 0, 0, 0, addr);
if (!shared && addr)
{
shared = (shared_info *) MapViewOfFileEx (shared_h,
FILE_MAP_READ|FILE_MAP_WRITE,
0, 0, 0, NULL);
#ifdef DEBUGGING
system_printf ("relocating shared object %s(%d) from %p to %p", name, n, addr, shared);
#endif
offsets[0] = 0;
}
if (!shared)
api_fatal ("MapViewOfFileEx '%s'(%p), %E. Terminating.", mapname, shared_h);
if (m == SH_CYGWIN_SHARED && offsets[0])
{
ptrdiff_t delta = (caddr_t) shared - (caddr_t) off_addr (0);
offsets[0] = (caddr_t) shared - (caddr_t) cygwin_hmodule;
for (int i = SH_USER_SHARED + 1; i < SH_TOTAL_SIZE; i++)
{
unsigned size = offsets[i + 1] - offsets[i];
offsets[i] += delta;
if (!VirtualAlloc (off_addr (i), size, MEM_RESERVE, PAGE_NOACCESS))
continue; /* oh well */
}
offsets[SH_TOTAL_SIZE] += delta;
}
debug_printf ("name %s, n %d, shared %p (wanted %p), h %p", mapname, n, shared, addr, shared_h);
return shared;
}
对于父进程而言,其传递进来的句柄shared_h为NULL,因此这个函数将调用CreateFileMapping创建一个共享内存区,而对于fork出来的子进程,其传递进来的句柄是从父进程复制而来,因此不为NULL,上述函数将直接用OpenFileMapping打开已经存在的共享内存区。
这些共享内存区的名称并不直接由name决定,而是由name和n两个参数共同决定:
char * __stdcall
shared_name (char *ret_buf, const char *str, int num)
{
__small_sprintf (ret_buf, "%s.%d", str, num);
return ret_buf;
}
比如对于“shared”这块内存区,实际的名称将转换为“shared.5”。
在open_shared函数中断下来,可以发现cygwin一共打开了下面几块共享内存区:
这块内存区的名称为“shared”,创建时的调用栈如下
> cygwin.dll!open_shared(const char * name=0x100efb80, int n=0x00000005, void * & shared_h=0x00000000, unsigned long size=0x000081a0, shared_locations & m=SH_CYGWIN_SHARED, _SECURITY_ATTRIBUTES * psa=0x101407bc, unsigned long access=0x00000006) 行142 C++
cygwin.dll!memory_init() 行387 + 0x28 字节 C++
cygwin.dll!dll_crt0_0() 行847 C++
cygwin.dll!dll_entry(void * h=0x10000000, unsigned long reason=0x00000001, void * static_load=0x0021fd30) 行186 C++
cygwin.dll!DllMain(HINSTANCE__ * h=0x10000000, unsigned long reason=0x00000001, void * ptr=0x0021fd30) 行79 C++
cygwin.dll!__DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30) 行543 + 0x11 字节 C
cygwin.dll!_DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30) 行507 + 0x11 字节 C
这块内存区的名称为“S-1-5-21-1390067357-839522115-1343024091-1011”,创建时的调用栈如下:
> cygwin.dll!open_shared(const char * name=0x0021f50c, int n=0x00000001, void * & shared_h=0x00000000, unsigned long size=0x00004068, shared_locations & m=SH_USER_SHARED, _SECURITY_ATTRIBUTES * psa=0x101407a4, unsigned long access=0x00000006) 行142 C++
cygwin.dll!user_shared_create(bool reinit=false) 行261 + 0x26 字节 C++
cygwin.dll!memory_init() 行389 + 0x7 字节 C++
cygwin.dll!dll_crt0_0() 行847 C++
cygwin.dll!dll_entry(void * h=0x10000000, unsigned long reason=0x00000001, void * static_load=0x0021fd30) 行186 C++
cygwin.dll!DllMain(HINSTANCE__ * h=0x10000000, unsigned long reason=0x00000001, void * ptr=0x0021fd30) 行79 C++
cygwin.dll!__DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30) 行543 + 0x11 字节 C
cygwin.dll!_DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0x00000001, void * lpreserved=0x0021fd30) 行507 + 0x11 字节 C
这块内存区的名称为“cygpid”,创建时的调用栈如下:
> cygwin.dll!open_shared(const char * name=0x100ee364, int n=0x00000180, void * & shared_h=0x00000000, unsigned long size=0x00008108, shared_locations & m=SH_MYSELF, _SECURITY_ATTRIBUTES * psa=0x00215da0, unsigned long access=0x00000006) 行142 C++
cygwin.dll!pinfo::init(int n=0x00000180, unsigned long flag=0x00000001, void * h0=0x00000000) 行223 + 0x22 字节 C++
cygwin.dll!set_myself(void * h=0x00000000) 行53 C++
cygwin.dll!pinfo_init(char * * envp=0x00000000, int envc=0x00000000) 行94 C++
cygwin.dll!dll_crt0_1(void * __formal=0x00000000) 行952 C++
cygwin.dll!_cygtls::call2(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000, void * buf=0x00216fb8) 行72 + 0xd 字节 C++
cygwin.dll!_cygtls::call(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000) 行66 C++
cygwin.dll!_dll_crt0() 行1082 + 0xc 字节 C++
cygwin.dll!cygwin_dll_init() 行1121 C++
bash.exe!main(int argc=0x00000003, char * * argv=0x00c567f0) 行769 + 0x8 字节 C
这块内存区的名称为空,创建时的调用栈如下:
> cygwin.dll!open_shared(const char * name=0x00000000, int n=0x00000000, void * & shared_h=0x00000000, unsigned long size=0x00000514, shared_locations & m=SH_SHARED_CONSOLE, _SECURITY_ATTRIBUTES * psa=0x101407bc, unsigned long access=0x00000006) 行142 C++
cygwin.dll!fhandler_console::get_tty_stuff(int flags=0x00010002) 行76 + 0x26 字节 C++
cygwin.dll!fhandler_console::cyg_open(int flags=0x00010002, unsigned int __formal=0x00000000) 行594 + 0xb 字节 C++
cygwin.dll!fhandler_console::init(void * f=0x00000003, unsigned long a=0xc0000000, unsigned int bin=0x00010000) 行1812 + 0x1a 字节 C++
cygwin.dll!dtable::init_std_file_from_handle(int fd=0x00000000, void * handle=0x00000003) 行358 + 0x2a 字节 C++
cygwin.dll!dtable::stdio_init() 行170 C++
cygwin.dll!dll_crt0_1(void * __formal=0x00000000) 行1001 C++
cygwin.dll!_cygtls::call2(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000, void * buf=0x00216fb8) 行72 + 0xd 字节 C++
cygwin.dll!_cygtls::call(unsigned long (void *, void *)* func=0x10011ff0, void * arg=0x00000000) 行66 C++
cygwin.dll!_dll_crt0() 行1082 + 0xc 字节 C++
cygwin.dll!cygwin_dll_init() 行1121 C++
bash.exe!main(int argc=0x00000003, char * * argv=0x00c567f0) 行769 + 0x8 字节 C
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下使用cygwin(23):stdin,stdout和stderr(2008-10-21)