做共享库使用同一个堆的应用程序? [英] Do shared libraries use the same heap as the application?

查看:258
本文介绍了做共享库使用同一个堆的应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有在Linux中使用共享库(的.so 文件)的应用程序。我的问题是在这些库中的code是否会在同一个堆中分配内存作为主应用程序或者他们用自己的堆?

因此​​,例如,在的.so 文件的调用一些功能的malloc ,将它使用相同的堆管理器作为应用程序或另一个呢?另外,怎么样在那些共同的记忆全局数据。它在哪里在哪里?我知道它位于BSS和数据段的应用程序,但不知道它是为那些共享的目标文件。


解决方案

  

我的问题是,在这些库中的code是否会在同一个堆中分配内存作为主应用程序或做他们用自己的堆?


如果库中使用相同的的malloc /免费作为应用程序(例如,从的glibc ) - 然后是,程序和所有库将采用单堆。

如果库使用 MMAP 直接,它可以分配内存,是不是程序本身使用的内存。


  

因此​​,例如,在.so文件的一些功能调用malloc,那会使用相同的堆管理器和应用软件或另一个呢?


如果从的.so调用malloc功能,这malloc的是相同的malloc从程序调用。你可以看到符号在Linux中绑定日志/ glibc的(> 2.1)与

  LD_DEBUG =绑定./your_program

是的,堆管理器的多个实例(使用默认配置)不能共存,不知道对方(问题是保持实例之间的同步BRK-分配的堆大小)。但是有一个配置可能当几个实例可以并存的。

最经典的malloc实现(ptmalloc *,dlmalloc等),可以使用从系统获取内存的方法有两种: BRK MMAP 。 BRK是经典的堆,其是直链,并且可以扩大或缩小。 MMAP可以得到很多的内存的任何地方;你可以返回这个内存给系统(释放它)以任意顺序。

当的malloc被建造时,BRK方法可以被禁用。然后将的malloc只使用 MMAP 取值模拟线性堆甚至将禁用经典的线性堆和所有的分配将不连续mmaped片段(fragments)进行。

所以,有些图书馆可以有自己的内存管理器,例如的malloc 编译 BRK 禁用或不malloc存储器管理。该经理应该比的malloc 免费,例如 malloc1 free1 或不应该显示/这名导出到动态连接器。


  

另外,怎么样在那些共同的记忆全局数据。它在哪里在哪里?我知道它位于BSS和数据段的应用程序,但不知道它是为那些共享的目标文件。


您应该考虑两个有关规划和.so就像ELF文件。每个ELF文件都有程序标题( readelf -l elf_file )。数据如何从ELF加载到内存的方式取决于程序头的类型。如果类型是 LOAD 文件的相应部分将是私人 MMAP ED(原文如此)内存。通常情况下,有2个负载分段;第一个为code与R + X(读+执行)的标志和第二个是与R + W(读+写)标志的数据。无论的.bss 。数据(全局数据)节放在类型的负载与写启用标志的段。

这两个可执行文件和共享库具有负载分段。有些段有memory_size> FILE_SIZE。这意味着段将在存储器进行扩展;它的第一部分将与ELF文件,大小(memory_size-FILE_SIZE)的第二部分的数据填充将填充为零(用于 * BSS 章节),利用的mmap(的/ dev /零) memset的(0)

在内核或动态链接程序加载ELF文件到内存中,他们不会去想共享。例如,要启动两次相同的程序。第一个进程将加载只读与MMAP ELF文件的一部分;第二个进程会做同样的mmap(如果ASLR是活动 - 第二MMAP会到不同的虚拟地址)。这是页面缓存(VFS子系统)的任务,以保持数据的单一副本在物理内存(与写入时复制又名COW);和MMAP将从虚拟地址只是建立映射在每一个加工成单一的物理位置。如果任何进程将改变一个内存页;它会写上独特的专用的物理内存被复制。

加载code为的glibc /精灵/ DL-load.c _dl_map_object_from_fd )的LD的.so和 Linux内核/ FS / binfmt_elf.c 为内核的ELF装载程序( elf_map load_elf_binary )。做一个搜索 PT_LOAD

因此​​,全局数据和bss数据总是私下mmaped在每个过程中,和它们与COW保护

堆和栈在运行时用BRK + MMAP(堆),并在BRK般的进程(主线程堆栈)操作系统内核自动地分配。其他线程的堆栈在在pthread_create MMAP 分配的。

Say I have an application in Linux that uses shared libraries (.so files). My question is whether the code in those libraries will allocate memory in the same heap as the main application or do they use their own heap?

So for example, some function in the .so file calls malloc, would it use the same heap manager as the application or another one? Also, what about the global data in those shared memories. Where does it lie? I know for the application it lies in the bss and data segment, but don't know where it is for those shared object files.

解决方案

My question is whether the code in those libraries will allocate memory in the same heap as the main application or do they use their own heap?

If the library uses the same malloc/free as the application (e.g. from glibc) - then yes, program and all libraries will use the single heap.

If library uses mmap directly, it can allocate memory which is not the memory used by program itself.

So for example, some function in the .so file calls malloc, would it use the same heap manager as the application or another one?

If function from .so calls malloc, this malloc is the same as malloc called from program. You can see symbol binding log in Linux/glibc (>2.1) with

 LD_DEBUG=bindings ./your_program

Yes, several instances of heap managers (with default configuration) can't co-exist without knowing about each other (the problem is with keeping brk-allocated heap size synchronized between instances). But there is a configuration possible when several instances can co-exist.

Most classic malloc implementations (ptmalloc*, dlmalloc, etc) can use two methods of getting memory from the system: brk and mmap. Brk is the classic heap, which is linear and can grow or shrink. Mmap allows to get lot of memory in anywhere; and you can return this memory back to the system (free it) in any order.

When malloc is builded, the brk method can be disabled. Then malloc will emulate linear heap using only mmaps or even will disable classic linear heap and all allocations will be made from discontiguous mmaped fragmens.

So, some library can have own memory manager, e.g. malloc compiled with brk disabled or with non-malloc memory manager. This manager should have function names other than malloc and free, for example malloc1 and free1 or should not to show/export this names to dynamic linker.

Also, what about the global data in those shared memories. Where does it lie? I know for the application it lies in the bss and data segment, but don't know where it is for those shared object files.

You should think both about program and .so just as ELF files. Every ELF file has "program headers" (readelf -l elf_file). The way how data is loaded from ELF into memory depends on program header's type. If the type is "LOAD", corresponding part of file will be privately mmaped (Sic!) to memory. Usually, there are 2 LOAD segments; first one for code with R+X (read+execute) flags and second is for data with R+W (read+write) flags. Both .bss and .data (global data) sections are placed in the segment of type LOAD with Write enabled flag.

Both executable and shared library has LOAD segments. Some of segments has memory_size > file_size. It means that segment will be expanded in memory; first part of it will be filled with data from ELF file, and the second part of size (memory_size-file_size) will be filled with zero (for *bss sections), using mmap(/dev/zero) and memset(0)

When Kernel or Dynamic linker loads ELF file into memory, they will not think about sharing. For example, you want to start same program twice. First process will load read-only part of ELF file with mmap; second process will do the same mmap (if aslr is active - second mmap will be into different virtual address). It is task of Page cache (VFS subsystem) to keep single copy of data in physical memory (with COPY-on-WRITE aka COW); and mmap will just setup mappings from virtual address in each process into single physical location. If any process will change a memory page; it will be copied on write to unique private physical memory.

Loading code is in glibc/elf/dl-load.c (_dl_map_object_from_fd) for ld.so and linux-kernel/fs/binfmt_elf.c for kernel's ELF loader (elf_map, load_elf_binary). Do a search for PT_LOAD.

So, global data and bss data is always privately mmaped in each process, and they are protected with COW.

Heap and stack are allocated in run-time with brk+mmap (heap) and by OS kernel automagically in brk-like process (for stack of main thread). Additional thread's stacks are allocated with mmap in pthread_create.

这篇关于做共享库使用同一个堆的应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆