Почему программа зависает в WSL? - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть следующий код в моей программе.

Thread* t = arg->thread;
//at this point, the new thread is being executed.
t->myId = TGetId();
void* (*functor)(void*) = t->functor;
void* fArg = arg->arg;
nfree(arg);
_INFO_PRINTF(1, "Launching thread with ID: %d", t->myId);
sigset_t mask;
sigfillset(&mask);         //fill mask with all signals
sigdelset(&mask, SIGUSR1); // allow SIGUSR1 to get to the thread.
sigdelset(&mask, SIGUSR2); // allow SIGUSR2 to get to the thread.
pthread_sigmask(SIG_SETMASK, &mask, NULL); //block some sigs

struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = TSignalHandler;
act.sa_mask = mask;
if(sigaction(SIGUSR1, &act, NULL))
{
    _ERROR_PRINT(1, "Could not set signal action.");
    return NULL;
}
if(sigaction(SIGUSR2, &act, NULL))
{
    _ERROR_PRINT(1, "Could not set signal action.");
    return NULL;
}
void* ret = functor(fArg);
t->hasReturned = true;
return ret;

Поток, который выполняет этот код, будет правильно вызывать обработчик сигнала при работе в native linux.Проблема в том, что в подсистеме Windows для Linux программа зависает, когда SIGUSR1 или SIGUSR2 отправляются через pthread_kill, который отправляет сигналы потоку.Почему это работает на нативной Ubuntu (через VMWARE WORKSTATION 14) и на Debian и Fedora, но НЕ на WSL?

1 Ответ

0 голосов
/ 25 февраля 2019

Если у вас есть зависание, которое вы не можете воспроизвести во время работы в отладчике, вы можете присоединить отладчик к запущенному процессу после воспроизведения зависания.Это не позволит вам наблюдать за изменяющимися переменными по мере того, как вы ведете к зависанию, но, по крайней мере, вы получите трассировку стека точно, где происходит зависание.

Как только вы узнаете идентификатор процесса зависшего процесса (предположим, что это 12345), вы можете использовать:

$ gdb -p 12345

Или вы можете завершить процесс с помощью сигнала, который вызовет генерацию ядра.Мне нравится использовать SIGTRAP, поскольку его легко отличить от SIGSEGV.

$ kill -SIGTRAP 12345

А затем вы можете использовать gdb, чтобы узнать, что зависло в процессеon.

Преимущество присоединения к запущенному процессу состоит в том, что процесс все еще активен.Это позволяет вам вызывать функции из отладчика, что может облегчить доступ к диагностике, встроенной в вашу программу.Файл core сохраняет ошибку, что полезно, если трудно воспроизвести зависшую ошибку.

...