【发布时间】:2023-03-12 21:40:02
【问题描述】:
以下 C 程序调用 select() 以获取在套接字缓冲区中有数据的客户端套接字列表(使用 UNIX 域数据报套接字)。它在调用 NASM 程序时需要四个参数。参数 fds_array[] 是在 NASM 中创建并传递给程序的 3 元素整数数组。
int select_clientsockets(int nfds, fd_set rfds, int fds_array[], int fd_count){
int fds_ready;
int abc;
fd_count = 3;
FD_ZERO(&rfds);
FD_SET(0,&rfds);
fds_ready = select(3, &rfds, NULL, NULL, 0);
for (int i = 0; i < fd_count; i++){
fds_array[i] = 0;
if (FD_ISSET(i, &rfds)) {
fds_array[i] = 1; }
}
for (int i = 0; i < fd_count; i++){
abc = fds_array[i];
printf("Value of array at %d, is %d\n", i, abc );
}
return 0;
}
数据从 NASM 传入 rdi、rsi、rdx 和 rcx。 :
mov rdi,7 ; range of fd #s
lea rsi,[socket_client_fds]
lea rdx,[fds_ready]
mov rcx,3 ; number of open client sockets
call [rel select_clientsockets wrt ..got]
正如所写,程序挂起。当我使用 gdb 逐步完成它时,它会正确地进行计算,并且 fds_array 中的值与预期的一样。但是在返回行(返回 0),gdb 会报告这个:
0x00007ffff720cfed in select_clientsockets (
nfds=<error reading variable: Cannot access memory at address 0xfffffffffffffffc>, rfds=<error reading variable: Cannot access memory at address 0x10>,
fds_array=<error reading variable: Cannot access memory at address 0xfffffffffffffff0>,
fd_count=<error reading variable: Cannot access memory at address 0xffffffffffffffec>) at POSIX_Datagram_Socket.c:139
所以它说变量 nfds、rfds 和 fds_array 无法访问。但我刚刚完成了它,一切都是正确的。
我的研究发现了关于该 gdb 错误消息的许多 Stack Overflow 问题,但它们都是特定于事实的,我没有找到任何符合这些事实的问题。
感谢您提供有关如何在退出时修复此错误的任何想法。
【问题讨论】:
-
贴出调用
select_clientsockets的代码。但是 C 函数中有一些非常可疑的东西——nfds、rfds和fd_count参数甚至可以做什么?请记住,fs_set是一种结构类型,因此它在 x86_64 中进入堆栈,但其他参数进入寄存器。 -
我刚刚更新了上面的 NASM 代码以显示调用。这就是进行调用的所有 NASM 代码。 nfds 是文件描述符的数量 (3);它作为 7 传递,因为 fd 编号是 5、6 和 7,但我在代码中将其更改为 3; rfds 是 fd_set。 socket_client_fds 是一个 3 元素数组,其中包含每个客户端套接字的文件描述符。
-
看起来问题可能是我没有正确处理 fd_set - 文件描述符的 3 元素数组不是 select() 所要求的。