- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在很多地方(musl 邮件列表、macOS 论坛等)听说 brk()
和 sbrk()
是不安全的。这些地方很多要么根本不解释,要么解释的很模糊。例如,this链接指出“这些功能从根本上被破坏了”,并继续说 malloc
和 sbrk
子系统完全被破坏,它们破坏了堆,等等。
我的问题是:为什么会这样?如果 malloc
以这样的方式使用,即它分配了一 block 内存,其中 sbrk
足够大以平息或大大减少进一步分配的需要,那么 sbrk
和 brk
使用起来绝对安全吗?
这是我对 sbrk
和 brk
的实现:
sbrk
:
#include <unistd.h>
#include <stddef.h>
void *sbrk(intptr_t inc)
{
intptr_t curbrk = syscall(SYS_brk, NULL);
if( inc == 0 ) goto ret;
if( curbrk < 0 ) return (void *)-1;
curbrk((void *)(curbrk+inc));
ret:
return (void *)curbrk;
}
brk
:
#include <unistd.h>
intptr_t brk(void *ptr)
{
if( (void *)syscall(SYS_brk, ptr) != ptr )
return -1;
else
return 0;
}
最佳答案
现实在很大程度上取决于实现,但这里有一些要素:
brk
/sbrk
的发明是为了允许进程从系统请求更多内存,并在单个连续段中释放它。因此,它们被许多 malloc
和 free
实现使用。问题是,当它返回一个唯一的段时,当多个模块(同一进程的)直接使用它时,事情会出错。由于竞争条件,它在多线程进程中变得更糟。假设有 2 个线程要添加新内存。他们将使用 sbrk(0)
查看当前的顶部地址,查看相同的地址,使用 brk
或 sbrk
请求新内存,并且由于竞争条件,两者将使用相同的内存。
即使在单线程进程中,某些malloc
和free
实现也假设它们只被允许使用低级s/brk
接口(interface),并且任何其他代码都应该使用它们。在那种情况下,如果他们内部维护的中断段的图像不再是假定值,事情就会出错。他们必须猜测该段的某些部分是“保留”供其他用途使用的,这可能会破坏释放任何内存的能力。
因此,用户代码不应直接使用brk
/sbrk
,而应仅依赖于malloc
/free
。当且仅当您正在编写标准库的实现,包括 malloc
/realloc
/calloc
/free
,你可以安全地使用brk
/sbrk
在现代系统上,mmap
可以更好地使用虚拟内存管理。您可以根据需要使用任意数量的动态内存段,它们之间没有交互。因此,在现代系统上,除非您有使用 brk
/sbrk
进行内存分配的特定需求,否则您应该使用 mmap
。
brk
和 sbrk
的 FreeBSD 引用指出:
The brk() and sbrk() functions are legacy interfaces from before the advent of modern virtual memory management.
及以后:
BUGS: Mixing brk() or sbrk() with malloc(3), free(3), or similar functions will result in non-portable program behavior.
关于c - brk/sbrk 的不安全/遗留问题是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55367809/
自从升级 NodeJs 以来,我从 Visual Studio 2017 运行 Nodejs 时遇到此错误。 断点也不起作用。有任何解决这个问题的方法吗? 注意:VS版本是15.5.6NodeJS 版
我已经使用 VS 2015 在我的计算机上安装了 nodeJs 并进行了设置。当我尝试运行示例 hello world 应用程序时,它抛出以下错误: verb(node:14096) [DEP0062
当我在 Visual Studio 中运行 Node.js 应用程序时,我收到以下消息:DeprecationWarning: 'node --debug' 和 'node --debug-brk'
根据Linux程序员手册: brk() and sbrk() change the location of the program break, whichdefines the end of the
据我所知,在 brk() 系统调用之后,额外的虚拟内存尚未分配(即页表尚未增长以容纳新的虚拟地址)。我的印象是这些页表被添加为 那么...为什么您需要 brk() 系统调用?为什么内核不能在内存访问进
这是 strace -T -ttt -ff -x -y -o pid.trace -p 2145 的输出。跟踪如下。 1503431273.934716 semop(1204093022, {{0,
我写了一个基本的自定义内存管理分配器,它会获取一 block 内存,预先创建 X 对象,这样每当我需要“创建”一个对象时,我就可以获取一个预先创建的对象并简单地分配数据成员(内存已经分配)。 我使用了
我正在尝试将内存动态分配到堆中,然后在这些内存地址中分配值。我了解如何分配内存,但我如何将例如寄存器中的值分配给第一个动态内存地址? 这是我到目前为止: push rbp mov rb
我正在尝试将内存动态分配到堆中,然后在这些内存地址中分配值。我了解如何分配内存,但我如何将寄存器中的值分配给第一个动态内存地址?这是我目前所拥有的: push rbp mov rbp,
我想知道在内核源代码版本 >= 2.6 中定义了 brk。那是哪个c文件包含它的定义? grep 并没有透露太多。另外 sbrk 是在 glibc 中实现的吗? 最佳答案 它在 mmap.c 中。寻找
我正在尝试在 NASM/x86 程序集中使用 sys_brk 分配一些内存。 sys_break返回break的新地址,这是数据段的末尾,对吧?那么我新分配的内存驻留在哪里?我假设它位于旧中断值和新中
不使用brk是否可以实现malloc库函数?我可以使用 sbrk(0) 找出程序中断的当前位置,然后使用 sbrk(size) 对其进行递增吗? 如果是,那么为什么首先要添加 brk? 最佳答案 br
有人可以解释为什么这个“无休止的”循环会很快出现段错误吗?例如,假设我们有这个功能: #!/bin/bash foo() { foo }; foo 8-10 秒后出现段错误。通过 strace 检
我在很多地方(musl 邮件列表、macOS 论坛等)听说 brk() 和 sbrk() 是不安全的。这些地方很多要么根本不解释,要么解释的很模糊。例如,this链接指出“这些功能从根本上被破坏了”,
虽然我知道 Unix 系统调用 brk 和函数 sbrk 的作用,但我不知道它们代表什么。谁能赐教一下? 最佳答案 它来自于“破值”。 我引用:“更改是通过重置进程的中断值并分配适当的空间量来进行的。
我是新手,任何人都可以通过一个简短的例子说出 brk 和 sbrk 之间的确切区别吗?有没有效率因素可以从两者中选择任何一个?malloc 和 new 内部调用 brk 或 sbrk。 最佳答案 in
我编写了一个小的 hello world 程序,并在其二进制文件上运行 strace,它列出了所有在我的 Hello_world 程序执行过程中调用的系统调用。 strace ./a.out exec
我发现并研究了x86 memory access segmentation fault它在我的代码中不起作用。区别可能在于我不使用单独的 .text 和 .data 段,而是通过创建自定义 ELF h
我正在尝试通过简单的脚本使用 Node 检查器。我有一些控制台日志,因此我可以判断它是否正在运行。我尝试了两种方法: Node 调试 test.js 通过这种方法,调试器在 Chrome 中打开,但不
我正在使用 Node v6.10.0 并试图弄清楚为什么我的 --debug-brk 如此缓慢。如果没有此标志(仅使用 --inspect 或 --debug),它几乎是瞬时的,尽管调试器仍然需要很长
我是一名优秀的程序员,十分优秀!