Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

The following C program calls select() to get a list of client sockets that have data in the socket buffer (using UNIX domain datagram sockets). It takes four parameters on call from a NASM program. The parameter fds_array[] is a 3-element integer array created in NASM and passed into the program.

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;

The data are passed in from NASM in rdi, rsi, rdx and 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]

As written, the program hangs. When I step through it with gdb, it does its calculations correctly and the values in fds_array are as expected. But at the return line (return 0), gdb reports this:

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

So it says the variables nfds, rfds and fds_array cannot be accessed. But I just finished stepping through it and everything was correct.

My research turned up a number of Stack Overflow questions on that gdb error message, but they're all fact-specific and I didn't find any that fit these facts.

Thanks for any ideas on how to fix this error on exit.

Post the code that calls select_clientsockets. But there is some really suspicious stuff in the C function—what do the nfds, rfds, and fd_count parameters even do? Keep in mind that fs_set is a structure type, so it goes on the stack in x86_64, but the other arguments go in registers. – Dietrich Epp May 21, 2020 at 16:15 I just updated the NASM code above to show the call. That's all the NASM code that makes the call. nfds is number of file descriptors (3); it's passed as 7 because the fd numbers are 5, 6 and 7 but I changed it in code to 3; rfds is the fd_set. socket_client_fds is a 3-element array with the file descriptors of each of the client sockets. – RTC222 May 21, 2020 at 16:25 It looks like the problem may be that I am not handling fd_set correctly -- a 3-element array of file descriptors is not what select() calls for. – RTC222 May 21, 2020 at 16:29 lea rdx,[fds_ready] mov rcx,3 ; number of open client sockets call [rel select_clientsockets wrt ..got]

In the System V AMD64 ABI, the arguments would be passed in:

  • rdi - ndfs
  • rsi - fds_array
  • rsp..rsp+127 - rfds
  • rdx - fd_count
  • It looks like you’re passing rfds as if it were a pointer. It’s not. It goes on the stack.

    If this were Windows, it would be passed as a pointer. However, it sounds like you’re not using Windows, since you mention Unix domain sockets (although AF_UNIX is actually available on Windows).

    If you ever need help calling a C function from assembly, just use Godbolt.

    Yes, Linux. I can see now that rdfs is a struct so it would be passed differently. It can also be created as a struc in NASM and passed by pointer (I've done that in other cases). Thanks for your answer. – RTC222 May 21, 2020 at 17:04 One other question -- if I pass the struct on the stack, wouldn't it be better to drop some stack space for the struct and unwind after the call, instead of using rsp+127? I ask because this prorgram stores other vars on the stack. – RTC222 May 21, 2020 at 17:06

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.