unbit / uwsgi

uWSGI application server container
http://projects.unbit.it/uwsgi
Other
3.45k stars 688 forks source link

Sigmask cause some commands segmentfault #2599

Open echoechoin opened 8 months ago

echoechoin commented 8 months ago

In this function, uwsgi mask all signals:


void uwsgi_setup_thread_req(long core_id, struct wsgi_request *wsgi_req) {
    int i;
    sigset_t smask;

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &i);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &i);
    pthread_setspecific(uwsgi.tur_key, (void *) wsgi_req);

    if (core_id > 0) {
        // block all signals on new threads
        sigfillset(&smask);
#ifdef UWSGI_DEBUG
        sigdelset(&smask, SIGSEGV);
#endif
        pthread_sigmask(SIG_BLOCK, &smask, NULL);

        // run per-thread socket hook
        struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
        while (uwsgi_sock) {
            if (uwsgi_sock->proto_thread_fixup) {
                uwsgi_sock->proto_thread_fixup(uwsgi_sock, core_id);
            }
            uwsgi_sock = uwsgi_sock->next;
        }

        for (i = 0; i < 256; i++) {
            if (uwsgi.p[i]->init_thread) {
                uwsgi.p[i]->init_thread(core_id);
            }
        }
    }

}

Meanwhile we use Subprocess.run to run lscpu:

Subprocess.run("lscpu")

It will cause segmentation fault because of signal handlers of the lscpu is masked.

// lscpu code:
memset(&act, 0, sizeof(act));
act.sa_sigaction = segv_handler;
act.sa_flags = SA_SIGINFO;

if (sigaction(SIGSEGV, &act, &oact))
    err(EXIT_FAILURE, _("cannot set signal handler"));

// Cause segmentfault if not vmware env.
vmware_bdoor(&eax, &ebx, &ecx, &edx);

if (sigaction(SIGSEGV, &oact, NULL))
    err(EXIT_FAILURE, _("cannot restore signal handler"));

Why uwsgi mask all signal? does there has other elegant implement instead of masking all signal?