macOS Cocoa应用程序:崩溃时出现未指定的错误

时间:2017-06-17 22:33:36

标签: objective-c c xcode macos cocoa

我有 Status Bar Cocoa App ,它为我的后台运行服务器提供GUI以及常规信息和首选项窗口。这个服务器是用C编程语言实现的,它现在唯一的工作就是对客户端进行简单的回显。

应用程序具有启动此服务器的按钮。当我按下此按钮时,服务器启动并侦听随机选择的端口。它工作正常,我甚至可以重启服务器等。

我使用此代码启动服务器:

- (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
         *   });
         */
    });
}

只有当某个客户端连接到服务器时,问题才会开始。 我可以使用telnet 192.168.8.101 <PORT_NUMBER>进行连接。我甚至可以与服务器通话,它可以正确重放。这里奇怪的事情发生了!

当我尝试打开Status Bar Cocoa App时,我可能会遇到如下崩溃: 1.很长时间没有崩溃(客户端与服务器通信,重启,切换窗口和窗格) 2.连接客户端并选择App的状态栏图标后立即崩溃 3.稍后当我连接客户端,打开状态栏图标,选择一些菜单项并尝试打开窗口时崩溃。 该应用程序也会在稍后崩溃。不是在第一个窗口打开,而是第三,第四或第n个窗口打开,按钮单击。

下面的屏幕截图显示了这种不确定性的外观 enter image description here

导致应用崩溃的原因是什么?我该如何解决这个问题?

这是我在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;
        }
    }
}

这是客户端连接处理(回显服务)

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;
}

0 个答案:

没有答案