Linux内核对堆溢出或栈溢出的行为

3

我正试图理解一些重要的操作系统概念(为了简单起见,让我们只考虑Linux内核)。假设我以内核模式运行此代码,并将以下行(仅选择A或B中的一种)添加到某个系统调用的源代码中。

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

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

案例A:上述代码在循环中消耗堆内存。一开始,我会开始消耗内存,然后事情会变得正常。在消耗足够多的内存之后,在崩溃之前会发生什么?我知道内核空间位于进程地址空间中的保留块内。当我穿过内核使用的堆栈部分时,我会在哪个点崩溃?或者这会扩大那个保留空间(甚至占用整个虚拟内存)吗?

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

案例 B: 我知道内核为其保留了一定的(且较小的)栈空间。因此,当我提供的值足够大时,我可能会用尽该预定义的栈空间。这种情况下会发生什么样的崩溃?我会跨越内核的堆部分吗?

1个回答

0
在您的A示例中,应用程序将永远循环。在某些时候, malloc将无法将页面映射到逻辑地址空间,并返回0。
在您的B示例中:每个进程都有自己的内核模式堆栈(通常有一个共享的中断堆栈)。
您最终可能会在堆栈末尾命中守卫页并收到访问冲突通知。您不会超过内核的内存池。

对于情况A,当我循环时,会扩展我的内核空间吗?也就是说,假设最初内核在虚拟地址4GB中占用1GB,现在它会进一步扩展吗? - visweshn92
在内核模式下调用malloc将不会扩展系统区域。如果它工作,它只会扩展用户区域。 - user3344003
我指的是进一步扩展到“用户区域”而已。因为它会在这个过程中扩展到用户区域。每个其他的进程都能看到相同扩展的内核空间吗?因为内核空间通常在进程之间是相同的。在一个进程中进行扩展应该也会使其在其他进程中扩展,对吧? - visweshn92
如果malloc在内核模式下实际起作用,其效果只会被执行的进程看到。它不会扩展共享的系统空间。 - user3344003
谢谢!你为我澄清了重要的观点。请考虑使用这些细节更新答案。再次感谢! - visweshn92

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接