Linux 内核在堆溢出或堆栈溢出时的行为

标签 linux linux-kernel operating-system

我试图理解几个重要的操作系统概念(为简单起见,让我们坚持使用 Linux 内核)。假设我在内核模式 中运行它,可能将这些行(caseA 或 caseB,而不是两者)添加到某些系统调用的源代码中。

# Assume __malloc() here is a simple heap memory manager
void consume_heap_forever(void)
    {

      for (;;)
        (void) __malloc(PAGE_SIZE);         
    }

案例A:上面的循环消耗堆。我将首先开始消耗内存,一切都会正常进行。在足够高的消耗之后,什么开始发生(在崩溃之前)?我知道内核空间在进程地址空间的保留 block 内。当我越过内核使用的堆栈部分时,我会崩溃吗?还是这会扩大保留范围(并可能消耗整个虚拟内存)?

# Vanilla Factorial logic
int factorial(int value)
    {
        if (value == 0)
           return 1;
         return value * factorial(value-1)
    }

案例 B: 我知道内核为它保留了固定的(和少量的)堆栈。所以也许当我给出一个足够大的值时——我会用完预定义的堆栈空间。这里发生了什么样的崩溃?我会进入内核的堆部分吗?

最佳答案

在您的示例 A 中,您的应用程序将永远循环。在某些时候,malloc 将无法将页面映射到逻辑地址空间并将返回 0。

在您的示例 B 中:每个进程都有自己的内核模式堆栈(通常有一个共享的中断堆栈)。

很可能您最终会访问堆栈末尾的保护页并遇到访问冲突。您不会超出内核的内存池。

关于Linux 内核在堆溢出或堆栈溢出时的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42217778/

相关文章:

linux - 从 csv 文件中删除特定列,在输出中保持相同的结构

c++ - 非 root 用户运行程序时的 Ubuntu、libftdi 权限、段错误

c++ - 使用 const char* 会导致内存错误?

linux - 如何检查 Linux 的 32 位/64 位内核

linux - Centos kernel-devel 安装后不可用

operating-system - 确定分区所属的文件系统

linux - 如何使用 cgroup v2 从容器内获取 docker 容器 ID

linux-kernel - 启动期间Linux内核空间中的页表

java - Eclipse 在哪个操作系统下最健壮?

c++ - 将 void 指针转换为结构时无法获取值