gpt4 book ai didi

c - printf 使用 sbrk,与自定义内存分配器冲突

转载 作者:行者123 更新时间:2023-11-30 16:05:51 27 4
gpt4 key购买 nike

嗨,我写了一个内存分配器,并且工作得很好。我使用 sbrk/brk 进行页面分配和释放。但当我开始使用 printfs 打印信息时,这一切都中断了。谷歌搜索显示 - printf 内部也使用 sbrk。因此,另一个 glibc 函数 (printf) 意外地使用 sbrk 修改了堆段 - 破坏了内存分配器正在执行的簿记操作。

引用:sbrk(0) value getting increased after calling printf基本上,任何其他使用 sbrk 的 glibc 函数都会破坏我的内存分配器。您能建议可能的解决方案吗?

粘贴下面的回溯显示 printf 最终调用 sbrk。即使打印完成后,我发现中断指针也永远不会恢复到其原始点。 printf 不应该将中断指针恢复到原来在堆段中的位置吗?在这方面有 printf 的替代方案吗?

(gdb) bt
0 __GI___sbrk (increment=135168) at sbrk.c:40
1 0x00007ffff7e68a99 in __GI___default_morecore (increment=<optimized out>) at morecore.c:47
2 0x00007ffff7e64297 in sysmalloc (nb=nb@entry=592, av=av@entry=0x7ffff7fb2c40 <main_arena>) at malloc.c:2480
3 0x00007ffff7e657b3 in _int_malloc (av=av@entry=0x7ffff7fb2c40 <main_arena>, bytes=bytes@entry=576) at malloc.c:4149
4 0x00007ffff7e65f25 in tcache_init () at malloc.c:2995
5 0x00007ffff7e66ba6 in tcache_init () at malloc.c:3050
6 __GI___libc_malloc (bytes=1024) at malloc.c:3050
7 0x00007ffff7e4f85c in __GI__IO_file_doallocate (fp=0x7ffff7fb3760 <_IO_2_1_stdout_>) at filedoalloc.c:101
8 0x00007ffff7e5f0b2 in __GI__IO_doallocbuf (fp=fp@entry=0x7ffff7fb3760 <_IO_2_1_stdout_>) at libioP.h:904
9 0x00007ffff7e5e198 in _IO_new_file_overflow (f=0x7ffff7fb3760 <_IO_2_1_stdout_>, ch=-1) at fileops.c:752
10 0x00007ffff7e5cbd5 in _IO_new_file_xsputn (n=13, data=<optimized out>, f=0x7ffff7fb3760 <_IO_2_1_stdout_>) at libioP.h:904
11 _IO_new_file_xsputn (f=0x7ffff7fb3760 <_IO_2_1_stdout_>, data=<optimized out>, n=13) at fileops.c:1204
12 0x00007ffff7e44e10 in __vfprintf_internal (s=0x7ffff7fb3760 <_IO_2_1_stdout_>, format=0x555555557334 "\nPage Size = %zu Bytes\n", ap=ap@entry=0x7fffffffdcc0,
mode_flags=mode_flags@entry=0) at ../libio/libioP.h:904
13 0x00007ffff7e308d8 in __printf (format=<optimized out>) at printf.c:33
14 0x000055555555677d in mm_print_memory_usage () at mm.c:613
15 0x00005555555552a9 in main (argc=1, argv=0x7fffffffdf18) at testapp.c:64

最佳答案

Ctx 的评论:

This is not possible; sbrk() is used by the libc memory allocator internally, so many libc functions use it implicitly. Either do not use libc at all, or do your memory allocations with malloc() or mmap().

是正确的。如果不使用 malloc,则只能使用 sbrk,并且您无法知道是否使用 malloc,因为除非另有说明实现,libc 中的任何内容都可能这样做。

如果您的 libc 支持替换 malloc(注意:大多数都支持),那么您可以编写完整的 malloc 替换(这包括所有 malloc-系列函数,而不仅仅是 malloc 本身),它们要么不使用 sbrk,要么配合您使用它,然后您就可以自由使用它。然而,否则,您根本无法使用sbrk

另请注意,在某些环境中,包括经常使用与位置无关的可执行文件 (PIE),sbrk 将几乎没有内存可使用,并且在仅进行几次分配或没有分配后经常会失败根本没有,因为遇到了为其他东西映射的内存。 sbrk 的整个概念是向后的,根本不应该在现代代码中使用。对于某些分配器策略,它可能是有意义的后端选择之一,同时使用 mmap 或其他东西。但它不应该是分配器获取新内存的唯一方式,而且在我看来,支持它根本没有什么用处。 mmap 几乎在所有方面都更好。

关于c - printf 使用 sbrk,与自定义内存分配器冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60147776/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com