1

I have Status Bar Cocoa App that provides GUI with general information and preferences windows for my background running server. This server is implemented in C programming language and the only work it is doing now is simple echo to client.

Application has button that starts this server. When I press this button server starts and listens on randomly selected port. It works correctly, I can even restart server etc.

I start server using this code:

- (void) startServerInBackground: (server_t) serverFunc {

    dispatch_queue_t server_dispatch_queue = dispatch_queue_create("click.remotely.Server", DISPATCH_QUEUE_CONCURRENT);

    dispatch_async(server_dispatch_queue, ^(void){

        start_server(serverFunc, serverInfo);

        /***
         *   dispatch_async(dispatch_get_main_queue(), ^(void){
         *   //Run UI Updates
         *   });
         */
    });
}

The problem begins only when some client connects to the server. I can connect using telnet 192.168.8.101 <PORT_NUMBER>. I can even talk to server and it replays correctly. Here the odd things happens!

When I try to open Status Bar Cocoa App I can get crashes like this: 1. No crash for very long time (client talking to server, restarting, switching windows and panes) 2. Get crash immediately after connecting client and selecting Status Bar Icon of App 3. Get crash some time later when I connect client, open Status Bar Icon, select some Menu Item and try to Open window. 4. The app can also crash a little later ex. not on first window opening but third, fourth or n-th window opening, button clicking.

Below screenshot shows how this nondeterministic looks enter image description here

What causes the app to crash? How can I resolve this issue?

Here is my server loop in C

/**
 * Function is looping infinitely and waiting
 * for new incoming client connections.
 * It handles connections one by one on the same thread.
 */
result_t iterative_stream_server_loop(server_info_t *server_info, connection_handler_t handle_connection) {

    sock_fd_t cs_fd, ps_fd;

    // get passive server socket
    ps_fd = server_info_sock(server_info);

    while(1) {

        if(server_info_should_shut_down(server_info)) {
            return CLOSED;
        }
        if(server_info_force_shut_down(server_info)) {
            return FORCE_CLOSED;
        }

        // check to accept new connection on the main thread...
        cs_fd = accept_new_connection(ps_fd);

        if(cs_fd == FAILURE) {
            fprintf(stderr, "accept_new_connection: failed!\n");
            server_info_connection_error_event(server_info, cs_fd, CONN_ERROR_ACCEPT, "accept_new_connection: failed!");
            return FAILURE;
        } else if(cs_fd == CONTINUE) {
            continue;
        }

        // publish client connected event
        server_info_client_connected_event(server_info, cs_fd);

        printf("Handle connection on the main thread...\n");

        switch (handle_connection(server_info, cs_fd)) {
            case FAILURE:
                fprintf(stderr, "handle_connection: failed!\n");
                // publish connection error event
                server_info_connection_error_event(server_info, cs_fd, CONN_ERROR_HANDLER, "handle_connection: failed!");
                break;
            case CLOSED:
                printf("handle_connection: closed!\n");
                // publish client disconnecting event
                server_info_client_disconnecting_event(server_info, cs_fd);
                break;
            default:
                break;
        }

        if(close(cs_fd) < 0){
            fprintf(stderr, "close: %s\n", strerror(errno));
            server_info_connection_error_event(server_info, cs_fd, CONN_ERROR_CLOSE, strerror(errno));
            return FAILURE;
        }
    }
}

And here is the client connection handling (echo service)

result_t echo_service_connection_handler(server_info_t *server_info, sock_fd_t sock_fd) {

    char buf[MAX_BUF_SIZE];
    int n_recv; // number of bytes received
    int n_sent; // number of bytes sent

    fcntl(sock_fd, F_SETFL, O_NONBLOCK);

    while(1) {

        if(server_info_should_shut_down(server_info))
            return CLOSED;

        if ((n_recv = recv(sock_fd, buf, sizeof(buf) - 1, 0)) <= 0) {
            if(n_recv == 0) {
                printf("echo connection is closing...\n");
                return CLOSED;
            }
            if( (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
                // call to recv() on non-blocking socket result with nothing to receive
                continue;
            }
            perror("recv");
            // publish connection error event
            server_info_connection_error_event(server_info, sock_fd, CONN_ERROR_RECV, strerror(errno));
            return FAILURE;
        }

        buf[n_recv] = '\0';

        printf(ANSI_COLOR_BLUE "server: received '%s'" ANSI_COLOR_RESET "\n", buf);

        if ((n_sent = send(sock_fd, buf, strlen(buf), 0)) < 0) {
            perror("send");
            // publish connection error event
            server_info_connection_error_event(server_info, sock_fd, CONN_ERROR_SEND, strerror(errno));
            return FAILURE;
        }
    }

    return SUCCESS;
}
Michał Ziobro
  • 10,759
  • 11
  • 88
  • 143
  • 1
    The error tells you what you need to do, and what the problem is... "`invalid pointer dequeued`"... – l'L'l Jun 17 '17 at 23:23
  • But what does it mean, where the error is? It something wrong with GUI Cocoa app? some bug in Cocoa framework? why server if alone app work correctly and if client is connected it crashes in unpredicatble fashion! Not in certain place but in random situations? – Michał Ziobro Jun 18 '17 at 08:00
  • 1
    The error tells you what to do: [Set a breakpoint in malloc_error_break to debug](https://stackoverflow.com/q/14045208/4244136). – Willeke Jun 18 '17 at 10:25

0 Answers0