cygwin下的共享内存区

快乐虾

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

[email protected]

本文适用于

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_hNULL,因此这个函数将调用CreateFileMapping创建一个共享内存区,而对于fork出来的子进程,其传递进来的句柄是从父进程复制而来,因此不为NULL,上述函数将直接用OpenFileMapping打开已经存在的共享内存区。

这些共享内存区的名称并不直接由name决定,而是由namen两个参数共同决定:

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一共打开了下面几块共享内存区:

1.1 shared

这块内存区的名称为“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

1.2 S-1-5-21-1390067357-839522115-1343024091-1011

这块内存区的名称为“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

1.3 cygpid

这块内存区的名称为“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

1.4 NULL

这块内存区的名称为空,创建时的调用栈如下:

> 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

1 参考资料

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)

你可能感兴趣的:(C++,c,C#,Security,Access)