在堆栈的末尾,有一个保护页被映射为不可访问的内存——如果程序访问它(因为它试图使用比当前映射更多的堆栈),就会出现访问冲突。
_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 本地二进制生成的,但汇编代码与编译器相关。
我阅读了一些文章,并检查了inet_listen()-> inet_csk_listen_start()等Linux内核代码,看来syscall的backlog参数listen()只影响接受的队列,而不影响 SYN接收的队列:
sk->sk_max_ack_backlog = backlog;
Run Code Online (Sandbox Code Playgroud)
即象征意义accept-queue + syn-received-queue != backlog。我不知道发生了什么事。本文指出:
接受和SYN队列的最大允许长度取自应用程序传递给listen(2)syscall的backlog参数。
但是MAN页中没有类似的东西。
此外,在Linux的情况下:是backlog的提示,提到这里也确实限制了队列?
c ×2
assembly ×1
gcc ×1
linux ×1
linux-kernel ×1
networking ×1
sockets ×1
stack-memory ×1
tcp ×1