我想在100 X 100阵列上进行DFS.(假设数组的元素代表图形节点)因此,假设最坏的情况,递归函数调用的深度可以达到10000,每个调用占用20个字节.那么可行的方法是否存在stackoverflow的可能性?
C/C++中堆栈的最大大小是多少?
请指定gcc for
1)cygwin on Windows
2)Unix
一般限制是什么?
我最近使用/FAsuVisual C++编译器选项输出特别长的成员函数定义的源+汇编.在汇编输出中,在设置堆栈帧之后,只需调用一个神秘的_chkstk()函数.
MSDN页面上_chkstk()没有解释调用此函数的原因.我也看到了Stack Overflow问题在堆栈上分配更多页面大小的缓冲区会破坏内存吗?,但我不明白OP和接受的答案是在谈论什么.
_chkstk()CRT功能的目的是什么?它有什么作用?
Linux上的clone()系统调用接受一个指向堆栈的参数,以供新创建的线程使用.显而易见的方法是简单地malloc一些空间并传递它,但是你必须确保你已经使用了大量的堆栈空间,因为该线程将使用(很难预测).
我记得在使用pthreads时我不必这样做,所以我很好奇它做了什么.我遇到了这个网站,它解释说,"Linux pthreads实现使用的最佳解决方案是使用mmap来分配内存,标志指定在使用时分配的内存区域.这样,内存分配给根据需要使用堆栈,如果系统无法分配额外的内存,则会发生分段违规."
我曾经听过mmap使用的唯一上下文是将文件映射到内存,实际上读取mmap手册页需要一个文件描述符.如何使用它来分配一堆动态长度来给clone()?这个网站真的很疯狂吗?;)
在任何一种情况下,内核都不需要知道如何为新堆栈找到一堆免费内存,因为在用户启动新进程时,它必须始终做什么?如果内核已经能够解决这个问题,为什么首先需要首先指定堆栈指针?
在堆栈的末尾,有一个保护页被映射为不可访问的内存——如果程序访问它(因为它试图使用比当前映射更多的堆栈),就会出现访问冲突。
_chkstk() 是一个特殊的编译器辅助函数,它
确保局部变量有足够的空间
即它正在做一些堆栈探测(这是一个LLVM 示例)。
这种情况是特定于 Windows 的。所以Windows有一些解决问题的方法。
让我们考虑 Linux(或其他一些类 Unix)下的类似情况:我们有很多函数的局部变量。第一个堆栈变量访问在堆栈段后面(例如mov eax, [esp-LARGE_NUMBER],这里 esp-LARGE_NUMBER 是堆栈段后面的内容)。是否有任何功能可以防止可能的页面错误或 Linux(可能是其他类 Unix)或开发工具(如gcc、clang等)中的任何功能?-fstack-check(GCC 堆栈检查)是否以某种方式解决了这个问题?这个答案表明它与_chkstk().
PPS 一般来说,问题是关于操作系统(最重要的Linux与 Windows)之间的实现差异,这些方法与大量堆栈变量作斗争,爬到堆栈段后面。添加 C++ 和 C 标记是因为它是关于 Linux 本地二进制生成的,但汇编代码与编译器相关。
我正在学习amd64汇编程序,并尝试实现一个简单的Unix过滤器。由于未知的原因,甚至简化为最低版本(下面的代码),它也会随机崩溃。
我试图在GNU调试器(gdb)中调试该程序。在gdb的默认配置中,该程序运行良好,但是如果启用地址随机化(set disable-randomization off),该程序将开始崩溃(SIGSEGV)。清单中标记了有问题的说明:
format ELF64 executable
sys_read = 0
sys_write = 1
sys_exit = 60
entry $
foo:
label .inbuf at rbp - 65536
label .outbuf at .inbuf - 65536
label .endvars at .outbuf
mov rbp, rsp
mov rax, sys_read
mov rdi, 0
lea rsi, [.inbuf]
mov rdx, 65536
syscall
xor ebx, ebx
cmp eax, ebx
jl .read_error
jz .exit
mov r8, rax ; r8 - count of valid bytes in input buffer
xor r9, r9 ; …Run Code Online (Sandbox Code Playgroud) 当我们运行代码时,编译器在编译后“检测”必要的堆栈内存量?这样,每个程序都有自己的堆栈内存“块”。
或者每个程序的堆栈内存是由操作系统定义的?
谁定义了每个运行的应用程序的堆栈内存量?
或者我们没有这个,每个程序都可以根据需要使用所有堆栈内存?
下图显示了进程的各个部分在进程的虚拟地址空间中的布局(在Linux中):
您会看到只有一个堆栈部分(因为我假设该进程只有一个线程)。
但是,如果该进程有另一个线程,该第二个线程的堆栈将位于哪里呢?它会位于第一个堆栈的正下方吗?
I'm trying to understand how stack works in Linux. I read AMD64 ABI sections about stack and process initialization and it is not clear how the stack should be mapped. Here is the relevant quote (3.4.1):
Stack State
This section describes the machine state that
exec(BA_OS) creates for new processes.
and
It is unspecified whether the data and stack segments are initially mapped with execute permissions or not. Applications which need to execute code on the stack or data …