Open xxxxxliil opened 2 months ago
看上去只是数字比较大而已,你认为错误fd的依据是什么?
看上去只是数字比较大而已,你认为错误fd的依据是什么?
我用 sysdig 检查 curl 的 syscall,发现没有 syscall 返回过如此大的 fd,且 ulimit -n
的输出是 4096
4096
只是同时打开的FD的总数,并不是FD这个数字最大值的限制。
如果再有这种现场,你可以配合lsof等命令,确认FD是不是正确的值。
4096
只是同时打开的FD的总数,并不是FD这个数字最大值的限制。如果再有这种现场,你可以配合lsof等命令,确认FD是不是正确的值。
怎么保持对应的 fd 为打开状态呢?
4096
只是同时打开的FD的总数,并不是FD这个数字最大值的限制。 如果再有这种现场,你可以配合lsof等命令,确认FD是不是正确的值。怎么保持对应的 fd 为打开状态呢?
单线程下个大文件
curl 在下载文件时暂停后截的图
补图:
接下来也许还要怀疑发起请求的和传输下载内容的 tcp fd 不是同一个?虽然昨天我说过已经用 sysdig 看过没有任何 syscall 返回过那么大的文件描述符
这是码
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
system("echo $(($(ulimit -n) - 1)) is max fd");
int udfd = atoi(argv[1]);
int o_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("open socket fd: %i, errno: %i, strerr: %s\n", o_fd, errno, strerror(errno));
int n_fd = dup2(o_fd, udfd);
printf("dup2 origin fd: %i, user define fd: %i, new fd: %i, errno: %i, strerr: %s\n",
o_fd, udfd, n_fd, errno, strerror(errno));
getchar();
return 0;
}
最大 fd 数量就是 fd 最大值
$ gcc t.c; ./a.out 4095
4095 is max fd
open socket fd: 3, errno: 0, strerr: Success
dup2 origin fd: 3, user define fd: 4095, new fd: 4095, errno: 0, strerr: Success
如果尝试更高的值就会
$ gcc t.c; ./a.out 4096
4095 is max fd
open socket fd: 3, errno: 0, strerr: Success
dup2 origin fd: 3, user define fd: 4096, new fd: -1, errno: 9, strerr: Bad file descriptor
偶尔close一些fd啊。否则都持有着,肯定超过不了4096
偶尔close一些fd啊。否则都持有着,肯定超过不了4096
在上面的示例中只有 5 个 fd,但是 fd 号仍然不能超过 ulimit 中同时打开的 fd 上限
man 2 dup:
ERRORS
EBADF oldfd isn't an open file descriptor.
EBADF newfd is out of the allowed range for file descriptors (see the discussion of RLIMIT_NOFILE in getrlimit(2)).
man 3p dup:
The dup2() function shall fail if:
EBADF The fildes argument is not a valid open file descriptor or the argument fildes2 is negative or greater than or equal to {OPEN_MAX}.
man 3p getrlimit:
RLIMIT_NOFILE
This is a number one greater than the maximum value that the system may assign to a newly-created descriptor.
If this limit is exceeded, functions that allocate a file descriptor shall fail with errno set to [EMFILE].
This limit constrains the number of file descriptors that a process may allocate.
我是真的想见识一下如何分配值大于 RLIMIT_NOFILE 的 fd。网上搜不行,自己测试不行,文档说不行。但你一直说这是可以随意做到的,请讲解一下如何做到
不好意思,工作日比较忙,我周末验证一下,再回复。
@cfc4n 我已经知道问题出在哪里了,但是因为个人原因(我承认是在赌气),请你先演示一下如何在主线内核中取得一个比 ulimit 中比 fd 上限更高数值的 fd
我找了点资料看了一下,是我对linux内核的fd回收机制理解不对,close的fd会被内核复用,做不到fd的值大于ulimit的情况。
看得出来,你还在赌气。 对我来说,个人精力有限,不能及时挨个回答用户问题,更何况是特定场景下的小众问题。你说你在赌气,我完全无法理解,换位思考一下,我是做开源软件的,你用我写的软件,没收你钱,还在持续帮你解决问题,凭什么要承诺解决方案的准确性、可靠性?
其次,我不是所有领域的专家,对个别知识点理解不对,给出错误结论是很正常的事情。 任何人在成长的过程中,都是伴随着错误知识不断迭代修正。
友好交流,有问题就互相纠正吧,情绪化不可取。
我找了点资料看了一下,是我对linux内核的fd回收机制理解不对,close的fd会被内核复用,做不到fd的值大于ulimit的情况。
看得出来,你还在赌气。 对我来说,个人精力有限,不能及时挨个回答用户问题,更何况是特定场景下的小众问题。你说你在赌气,我完全无法理解,换位思考一下,我是做开源软件的,你用我写的软件,没收你钱,还在持续帮你解决问题,凭什么要承诺解决方案的准确性、可靠性?
我没有要求承诺可用性,是有点难以接受在你第二次回复时提出的问题。在第一次的提问中我已经使用 syadig 检查过 curl 执行过程中调用的 syscall,curl 从未有过 ecapture 报告的那么巨大的 fd。但第二次回复中只是觉得它有点大,并希望我在下一次发现问题的现场用 lsof 看一看 fd 是不是正确的。
其次,我不是所有领域的专家,对个别知识点理解不对,给出错误结论是很正常的事情。 任何人在成长的过程中,都是伴随着错误知识不断迭代修正。
友好交流,有问题就互相纠正吧,情绪化不可取。
理解,但是交 pr 很可能因为前几天时不时用 codespace 看 commit 记录并且没及时停止导致免费市场用完,等下个月才能了。
这个问题本质上是 openssl 3 以上的 libssl.so .rodata 段中不再存在版本信息,且开 issue 时对于检查不到版本且根据文件后缀回退到默认的 3.0.0 时的日志输出时 info,导致使用时很难注意到是版本没有正确匹配导致的输出信息有误,同时发生的现象还有 keylog 和 pcap 都不能进行抓取解密的 tls 流量。
Describe the bug 使用 ecapture 捕获时,日志展示夸张的 FD 和不能获得的访问地址 且在
/sys/kernel/debug/tracing/trace_pipe
中发现以下内容:To Reproduce Steps to reproduce the behavior:
# ecapture --debug tls
Expected behavior 显示正确的 fd 和正确的地址
Screenshots
Linux Server/Android (please complete the following information):
make env
to get the environment variables]Additional context 每个程序的每个实例都有独立且固定的错误 fd