相关疑难解决方法(0)

"POSIX"是什么意思?

什么是POSIX?我已阅读维基百科的文章,每次遇到这个词时我都会阅读它.事实是,我从来没有真正理解它是什么.

任何人都可以通过解释"对POSIX的需求"向我解释一下吗?

unix linux posix terminology

822
推荐指数
8
解决办法
29万
查看次数

在x86汇编中寄存器上使用的push/pop指令的功能是什么?

在阅读有关汇编程序的文章时,我经常遇到人们在写文件时他们推送处理器的某个寄存器并稍后再次弹出它以恢复它之前的状态.

  • 怎么能推一个寄存器?它在哪里推?为什么需要这个?
  • 这可归结为单处理器指令还是更复杂?

x86 assembly stack terminology

79
推荐指数
5
解决办法
26万
查看次数

x86分页如何工作?

这个问题旨在填补关于该主题的良好免费信息的真空.

我相信一个好的答案将适合一个大的答案或至少在几个答案.

主要目标是为完整的初学者提供足够的信息,以便他们可以自己学习手册,并能够理解与分页相关的基本操作系统概念.

建议的指导方针:

  • 答案应该是初学者友好的:
    • 具体但可能简化的例子非常重要
    • 欢迎使用所示概念的应用
  • 引用有用的资源是好的
  • 我们欢迎操作系统如何使用分页功能
  • PAE和PSE的解释是受欢迎的
  • 我们欢迎对x86_64进行小规模的讨论

相关问题以及为什么我认为它们不是愚蠢的:

paging x86 virtual-memory

78
推荐指数
2
解决办法
3万
查看次数

为什么两次调用sbrk(0)给出不同的值?

我正在努力理解这个sbrk()功能.

据我所知:
sbrk(0)返回中断的当前地址,不会增加它.
sbrk(size)size字节为单位递增中断的地址,并返回中断的先前地址.

所以我创建了一些东西来测试它:

#include <unistd.h>
#include <stdio.h>

int main(void)
{
    printf("sbrk(0) = %p\n", sbrk(0)); // should return value x
    printf("sbrk(0) = %p\n", sbrk(0)); // should return value x
    printf("sbrk(5) = %p\n", sbrk(5)); // should return value x
    printf("sbrk(0) = %p\n", sbrk(0)); // should return value x + 5
}
Run Code Online (Sandbox Code Playgroud)

所以我期待看到如下结果:

sbrk(0) = 0x1677000 // x value
sbrk(0) = 0x1677000 // x value
sbrk(5) = 0x1677000 // x value
sbrk(0) = 0x1677005 // …
Run Code Online (Sandbox Code Playgroud)

c memory sbrk brk

11
推荐指数
1
解决办法
379
查看次数

堆的边界是什么?

给定进程中堆的边界是什么?我理解这个问题可能没有简单的答案,所以我特别感兴趣的是以下答案:

  • 在AMD64上Linux下是否有64位进程的标准堆大小/位置?
  • 如果我正在实现一个语言运行库,我怎样才能找到我不允许放入堆的地方(同样,Linux/AMD64)
  • 应用程序是否有可移植的方式来查找它的开始/结束位置?

linux memory 64-bit heap-memory virtual-memory

10
推荐指数
2
解决办法
2078
查看次数

在malloc中,为什么要完全使用brk?为什么不只使用mmap?

malloc使用brk/ sbrk作为从OS声明内存的主要方式的典型实现。但是,它们还用于mmap获取大容量分配的块。使用brk代替确实有真正的好处mmap,还是仅仅是传统?将其与所有内容一起使用mmap是否会很好?

(注意:我在这里可以互换使用sbrkbrk因为它们是同一个Linux系统调用接口brk。)


作为参考,以下是一些描述glibc malloc的文档:

GNU C库参考手册:GNU分配器
https://www.gnu.org/software/libc/manual/html_node/The-GNU-Allocator.html

glibc Wiki:Malloc概述
https://sourceware.org/glibc/wiki/MallocInternals

这些文件所描述的是,它sbrk被用来声明一个小的分配的主要场所,mmap被用来声明一个次级的场所,mmap还被用来声明一个大对象(“比页面大得多”)的空间。

同时使用应用程序堆(带有sbrk),并mmap引入了一些其他不必要的复杂性:

分配的竞技场-主竞技场使用应用程序的堆。其他竞技场使用mmap堆。要将块映射到堆,您需要知道哪种情况适用。如果该位为0,则该块来自主区域和主堆。如果该位为1,则该块来自mmap的内存,并且可以从该块的地址计算出堆的位置。

[Glibc malloc源自ptmalloc,而ptmalloc则源自dlmalloc,后者始于1987年。]


jemalloc手册页(http://jemalloc.net/jemalloc.3.html)有这样一段话:

传统上,分配器使用sbrk(2)获取内存,由于一些原因,该内存不是最佳的,原因包括竞争条件,增加的碎片以及人为限制最大可用内存。如果操作系统支持sbrk(2),则此分配器将按优先顺序使用mmap(2)和sbrk(2);否则,此分配器将使用mmap(2)和sbrk(2)。否则,仅使用mmap(2)。

因此,他们甚至在这里说这sbrk不是次优的,但是无论如何他们还是会使用它,即使他们已经为编写代码而烦恼,以至于没有它就可以工作。

[jemalloc的编写始于2005年。]

更新:更多地考虑这一点,关于“按优先顺序”的一点让我对询问保持了一致。为什么选择优先顺序?它们是否只是sbrkmmap不支持(或缺少必要功能)的情况下用作备用,还是该进程可能进入可以使用sbrk但不能使用的状态mmap?我看一下他们的代码,看看是否能弄清楚它在做什么。


我之所以问是因为我正在用C实现垃圾回收系统,到目前为止,我看不到除之外的任何用途mmap。我想知道是否还有什么我想念的。

(就我而言,我还有另一个避免使用的原因brk,那就是malloc在某些时候可能需要使用。)

c linux malloc mmap brk

8
推荐指数
5
解决办法
557
查看次数

关于brk / sbrk的不安全/遗留之处是什么?

我在很多地方(MUSL邮件列表,MACOS论坛等)听说brk()sbrk()不安全。这些地方中的许多要么根本不给出解释,要么给出非常模糊的解释。例如,链接指出“这些功能从根本上被破坏了”,并继续说mallocsbrk子系统被完全破坏了,它们破坏了堆,等等。

我的问题是:为什么会这样?如果malloc以这样的方式使用它来分配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;
}
Run Code Online (Sandbox Code Playgroud)

brk

#include <unistd.h>

intptr_t brk(void *ptr)
{
        if( (void *)syscall(SYS_brk, ptr) != ptr )
                return -1;
        else …
Run Code Online (Sandbox Code Playgroud)

c legacy malloc sbrk brk

6
推荐指数
1
解决办法
290
查看次数

从Linux进程分配的堆栈内存在哪里?

我们知道,当创建一个进程时,会为此进程分配一个堆栈.在linux中,堆栈的大小通常为8 Mb.我的问题是,从这个堆栈分配的位置?从用户空间还是从系统空间?

unix linux operating-system

3
推荐指数
2
解决办法
3908
查看次数

是否可以在堆栈上进行分配

malloc函数始终在堆上分配内存.然而,在研究维基百科上Escape Analylis文章时,我发现作为一种优化,编译器可以将堆分配转换为堆栈分配.例如,如果它看到只使用分配的内存然后在函数内释放.

现在我的问题是,程序员有没有办法自己这样做.那是在堆栈上分配内存?我知道C99允许变量作为数组声明的大小给出,但是说程序员想要调整它的大小.可以吗?

c compiler-construction optimization

1
推荐指数
1
解决办法
199
查看次数

理解和实现 malloc

malloc 是如何在内部实现的?如何在以下必要条件下实现 malloc

• Malloc 至少分配请求的字节数

• malloc 返回的指针指向一个已分配的空间(即程序可以成功读写的空间;)

• 对 malloc 的其他调用不会分配此空间或其任何部分,除非该指针之前已被释放。

• malloc 应该易于处理:malloc 必须尽快终止(它不应该是 NP-hard !;)

• Malloc 还应提供调整大小和释放功能。

该函数遵循以下签名: Void * malloc(size_t size);

c malloc realloc

1
推荐指数
1
解决办法
4820
查看次数

sbrk()如何运作?

我试图了解它是如何sbrk工作的.

这是我的小代码:

int  main()
{  
    printf("end of the break : %p\n", sbrk(0));
    printf("end of the break : %p\n", sbrk(10));
    printf("new end of the break : %p\n\n", sbrk(0));
}
Run Code Online (Sandbox Code Playgroud)

这输出:

end of break : 0xaa6000    
end of break : 0xac7000    
new end of the break : 0xac700a    
Run Code Online (Sandbox Code Playgroud)

为什么前2个地址0xac7000 - 0xaa6000 = 21000而不是10?

c unix sbrk brk

1
推荐指数
1
解决办法
1547
查看次数