Para responder a essa pergunta, você precisa entender como os sinais são enviados para um processo e como um processo existe no kernel.
Cada processo é representado como task_struct dentro do kernel (a definição está no arquivo de cabeçalho sched.h e beginns aqui . Essa estrutura contém informações sobre o processo; por exemplo o pid. As informações importantes estão na linha 1566 onde o sinal associado é armazenado. Isso é definido apenas se um sinal for enviado ao processo.
Um processo morto ou um processo zumbi ainda tem task_struct . A estrutura permanece, até que o processo pai (natural ou por adoção) tenha chamado wait() depois de receber SIGCHLD para colher seu processo filho. Quando um sinal é enviado, o signal_struct é definido. Não importa se o sinal é acessível ou não, neste caso.
Os sinais são avaliados sempre que o processo é executado. Ou, para ser exato, antes o processo seria executado. O processo está, então, no estado TASK_RUNNING . O kernel executa a rotina schedule() , que determina o próximo processo em execução de acordo com seu algoritmo de agendamento. Assumindo que este processo é o próximo processo em execução. Então o valor do signal_struct é avaliado, se existe um sinal de espera a ser tratado ou não. Se um manipulador de sinal é definido manualmente (via signal() ou sigaction() ), a função registrada é executada, se não o signal é executada. A ação padrão depende do sinal que está sendo enviado.
Por exemplo, o manipulador padrão do sinal SIGSTOP alterará o estado do processo atual para TASK_STOPPED e, em seguida, executará schedule() para selecionar um novo processo a ser executado. Observe que SIGSTOP não pode ser acessado (como SIGKILL ), portanto, não há possibilidade de registrar um manipulador de sinal manual. No caso de um sinal não detectável, a ação padrão será sempre executada.
Para sua pergunta:
Um processo extinto ou morto nunca será determinado pelo agendador para estar novamente no estado TASK_RUNNING . Assim, o kernel nunca executará o manipulador de sinais (padrão ou definido) para o sinal correspondente, qualquer que seja o sinal. Portanto, o exit_signal nunca será definido novamente. O sinal é "delievered" para o processo, definindo o signal_struct em task_struct do processo, mas nada mais acontecerá, porque o processo nunca será executado novamente. Não há código para rodar, tudo o que resta do processo é aquele struct do processo.
Se o processo pai, no entanto, colhe seus filhos por wait() , o código de saída que recebe, é aquele em que o processo "inicialmente" morreu. Não importa se há um sinal aguardando para ser tratado.