A mensagem `Falha na segmentação` é apresentada em STDERR?

17

Eu executei um executável em bash

./code > log

Ele mostra mensagens de erro ocasionais no terminal, enquanto todas as instruções printf entram no arquivo de log. Volto a executá-lo como abaixo

./code >& log

Agora, as mensagens de erro ocasionais também entram no log. Mas se houver uma falha de segmentação, ela ainda será mostrada no terminal. Por quê? Como fazer com que a mensagem Segmentation fault (core dumped)entre no arquivo de log?


usuário $ bash --version

Lançamento do GNU bash, versão 4.2.24 (1) (i686-pc-linux-gnu)

user13107
fonte

Respostas:

14

Uma falha de segmentação é um sinal, se você não estiver capturando isso, seu programa será encerrado e seu shell imprimirá isso no stderr (em vez do stderr do seu programa).

É possível que o seu programa ou o shell execute ações específicas quando isso ocorrer, seja pelo programa captando o sinal ou por seu shell capturando o sinal SIGCHILD e depois verificando o status de saída do seu filho.

cjh
fonte
1
@ user13107help trap
Carlos Campderrós
2
Sim. Entendi. se alguém estiver interessado, aqui está o que eu fiz pastebin.com/QyeJYYHC
user13107 30/10/12
1
O trapcomando shell intercepta os sinais enviados para o shell . Portanto, não funcionará para capturar o que está sendo enviado ao seu programa.
Derobert 31/10/12
1
@ warl0ck é possível capturar um segfault da mesma maneira que você captura qualquer sinal, no entanto, isso pode levar a um comportamento indefinido, mas se você souber o que está fazendo, poderá pelo menos morrer de uma maneira sensata. O OP queria imprimir em stderr, nesse caso capturar o segfault e imprimir é seguro.
Cjh 31/10/12
1
@ warl0ck: você pode, é apenas uma péssima idéia fazer qualquer coisa no manipulador, exceto logar e sair. Existem alguns casos de uso especializados.
Linuxios 5/11/12
19

A mensagem "falha de segmentação" é impressa no stderr, mas é o erro padrão do shell, não o erro padrão do programa. O shell imprime esta mensagem quando detecta que o programa foi finalizado devido a um sinal.

Você pode silenciar a mensagem redirecionando stderr ao redor da parte do script de shell que executa o programa:

{ ./code; } >&log
Gilles 'SO- parar de ser mau'
fonte