Bash brk() 上的脚本段错误
Bash script segfaults on brk()
有人可以解释为什么这个 "endless" 循环会很快出现段错误吗?
例如,假设我们有这个函数:
#!/bin/bash
foo() {
foo
}; foo
这会在 8-10 秒后出现段错误。通过 strace 检查,我们可以看到很多 brk() 调用:
brk(0x2e11000) = 0x2e11000
brk(0x2e12000) = 0x2e12000
brk(0x2e13000) = 0x2e13000
brk(0x2e14000) = 0x2e14000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x7ffcddf5ff68} ---
+++ killed by SIGSEGV +++
Segmentation fault
我的问题是:
- 这是段错误,因为它试图访问内存中未映射的区域 space(通过 brk)吗?
- 如果是,为什么要尝试访问它?
- 这里 malloc() 是更好的选择吗?
- 如果您有任何关于此的 extra/trivia 信息,我们将不胜感激。
看起来您看到的是堆栈不断增长,直到资源耗尽。简而言之,这是一个递归问题。
看看 brk() 调用,您会发现它正在更改进程数据段的末尾。增加程序中断是为进程分配内存,但您没有取之不尽用之不竭的供应。当你 运行 退出时,它会崩溃。
但是关于你的第三个问题,即使文档中的注释部分也表明 malloc() 是更好的选择。
brk
没有关系。它会出现段错误,因为它用完了堆栈 space。如果使用 ulimit -s 512; ./yourscript
减少可用堆栈,您会发现它崩溃得更快。
它吞噬了所有堆栈 space 因为你有一个无限递归函数并且 bash 不做尾调用优化。
它已经使用了 malloc
(或 bash 的特定版本)。由于 malloc
是 C 库函数而不是系统调用,因此它不会出现在 strace
中。分配的内存没有问题,它 运行 出栈 space.
brk
s 用于存储一些与无限递归相关的无限元数据,但这还不够重要。
无限递归函数的崩溃在所有语言中以各种形式发生,当你有未优化的无限递归时。在 Java 中尝试 void foo() { foo(); }
,或在 Python 中尝试 def foo(): foo()
。
有人可以解释为什么这个 "endless" 循环会很快出现段错误吗? 例如,假设我们有这个函数:
#!/bin/bash
foo() {
foo
}; foo
这会在 8-10 秒后出现段错误。通过 strace 检查,我们可以看到很多 brk() 调用:
brk(0x2e11000) = 0x2e11000
brk(0x2e12000) = 0x2e12000
brk(0x2e13000) = 0x2e13000
brk(0x2e14000) = 0x2e14000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x7ffcddf5ff68} ---
+++ killed by SIGSEGV +++
Segmentation fault
我的问题是:
- 这是段错误,因为它试图访问内存中未映射的区域 space(通过 brk)吗?
- 如果是,为什么要尝试访问它?
- 这里 malloc() 是更好的选择吗?
- 如果您有任何关于此的 extra/trivia 信息,我们将不胜感激。
看起来您看到的是堆栈不断增长,直到资源耗尽。简而言之,这是一个递归问题。
看看 brk() 调用,您会发现它正在更改进程数据段的末尾。增加程序中断是为进程分配内存,但您没有取之不尽用之不竭的供应。当你 运行 退出时,它会崩溃。
但是关于你的第三个问题,即使文档中的注释部分也表明 malloc() 是更好的选择。
brk
没有关系。它会出现段错误,因为它用完了堆栈 space。如果使用ulimit -s 512; ./yourscript
减少可用堆栈,您会发现它崩溃得更快。它吞噬了所有堆栈 space 因为你有一个无限递归函数并且 bash 不做尾调用优化。
它已经使用了
malloc
(或 bash 的特定版本)。由于malloc
是 C 库函数而不是系统调用,因此它不会出现在strace
中。分配的内存没有问题,它 运行 出栈 space.brk
s 用于存储一些与无限递归相关的无限元数据,但这还不够重要。无限递归函数的崩溃在所有语言中以各种形式发生,当你有未优化的无限递归时。在 Java 中尝试
void foo() { foo(); }
,或在 Python 中尝试def foo(): foo()
。