Como encontrar porque um bash sai com sinal 11, falha de segmentação

4

No meu servidor de produção rodando o Red Hat Linux (V6) eu recebi frequentemente core dumps do bash. Isso ocorre de um par de vezes por dia a dezenas de vezes por dia.

TLTR

Resolução : instale o bash-debuginfo para obter mais detalhes do núcleo e localize a instrução que causa a falha.

Causa : neste caso, foi por causa de um bug não corrigido na minha versão antiga do bash lists.gnu.org/archive/html/bug-bash/2010-04/msg00038.html relatado em abril de 2010 contra 4.1 e corrigido em 4.2 (lançado no início de 2011)

Detalhes
Este servidor executa uma única aplicação web (apache + cgi-bin) e muitos lotes. O webapp cgi (programa C) executa chamadas do sistema com mais frequência.

Não há muita interação com o shell, portanto, o dump principal provavelmente é causado por algum serviço ou pelo aplicativo da Web e eu preciso saber o que está causando esse erro.

O backtrace coredump é um pouco seco (veja abaixo).

Como posso ter mais detalhes sobre o erro? Eu gostaria de saber qual é a cadeia de processos pai (totalmente detalhada), as variáveis atuais e o env, qual foi o script executado e / ou comando ...

Eu tenho o sistema de auditoria ativado, mas as linhas de auditoria sobre isso estão um pouco secas também. Aqui está um exemplo:

type=ANOM_ABEND msg=audit(1516626710.805:413350): auid=1313 uid=1313 gid=22107 ses=64579 pid=8655 comm="bash" sig=11

E este é o principal rastreio:

    Core was generated by 'bash'.
Program terminated with signal 11, Segmentation fault.
#0  0x000000370487b8ec in free () from /lib64/libc.so.6
#0  0x000000370487b8ec in free () from /lib64/libc.so.6
#1  0x000000000044f0b0 in hash_flush ()
#2  0x0000000000458870 in assoc_dispose ()
#3  0x0000000000434f55 in dispose_variable ()
#4  0x000000000044f0a7 in hash_flush ()
#5  0x0000000000433ef3 in pop_var_context ()
#6  0x0000000000434375 in pop_context ()
#7  0x0000000000451fb1 in ?? ()
#8  0x0000000000451c84 in run_unwind_frame ()
#9  0x000000000043200f in ?? ()
#10 0x000000000042fa18 in ?? ()
#11 0x0000000000430463 in execute_command_internal ()
#12 0x000000000046b86b in parse_and_execute ()
#13 0x0000000000444a01 in command_substitute ()
#14 0x000000000044e38e in ?? ()
#15 0x0000000000448d4e in ?? ()
#16 0x000000000044a1b7 in ?? ()
#17 0x0000000000457ac8 in expand_compound_array_assignment ()
#18 0x0000000000445e79 in ?? ()
#19 0x000000000044a264 in ?? ()
#20 0x000000000042ee9f in ?? ()
#21 0x0000000000430463 in execute_command_internal ()
#22 0x000000000043110e in execute_command ()
#23 0x000000000043357e in ?? ()
#24 0x00000000004303bd in execute_command_internal ()
#25 0x0000000000430362 in execute_command_internal ()
#26 0x0000000000432169 in ?? ()
#27 0x000000000042fa18 in ?? ()
#28 0x0000000000430463 in execute_command_internal ()
#29 0x000000000043110e in execute_command ()
#30 0x000000000041d6d6 in reader_loop ()
#31 0x000000000041cebc in main ()
~

Atualizar : O sistema está sendo executado em uma máquina virtual manipulada pela VMWare.

  • Qual versão do bash? GNU bash, versão 4.1.2 (1) -release (x86_64-redhat-linux-gnu)

  • Qual versão do libc e outras libs ligadas ao bash?

ldd (GNU libc) 2.12

(quais são as outras libs ligadas ao bash? Existe um comando para obter os detalhes seguidos?

  • isso acontece ao executar um script ou um shell interativo ou ambos? se script, isso só acontece em um script ou em vários ou em algum? O que, em termos gerais, tipo de tarefa é o seu script bash fazendo? Você recebe falhas de seg de outros processos? Você executou um teste de memória no seu servidor? Possui RAM ECC?

como afirmado na minha pergunta: Eu não sei, mas deve ser causado por alguns scripts agendados ou por alguma chamada do sistema dentro da aplicação web interativa. Também pode ser um 'script em um script' como neste tipo de construção:

myVar=$($(some command here ($and here too))

No entanto, sinto que o problema provavelmente não é físico com a RAM, já que não há outro acidente aleatório, apenas este, e também o temos em 2 separações da VM em execução em duas máquinas físicas separadas.

Atualização 2:

Da pilha, tenho a impressão de que talvez o problema possa estar relacionado a matrizes associativas:

#1  0x000000000044f0b0 in hash_flush ()
#2  0x0000000000458870 in assoc_dispose ()
#3  0x0000000000434f55 in dispose_variable ()
#4  0x000000000044f0a7 in hash_flush ()

E esse tipo de variável está em quase todos os nossos scripts personalizados: há um script principal usado em uma biblioteca que contém variáveis e funções comuns para o nosso sistema.

Este script é originado em quase todos os nossos scripts.

    
por Guillaume 23.01.2018 / 16:39

2 respostas

2

Eu instalei as ferramentas debuginfo, conforme sugerido pelo gdb, e depois obtive a expressão responsável pela falha:

#20 0x0000000000457ac8 in expand_compound_array_assignment (
    var=<value optimized out>, 
    value=0x150c660 "$(logPath \"$@\")", flags=<value optimized out>
)

Então, agora eu sei o que e onde está o problema. No meu caso, estava em uma função originada no .bashrc e a causa raiz era essa redefinição errada das variáveis do mapa no Bash:

declare -A myMap
local myMap=""

...
for key in "${!myMap[@]}"; do 
  echo ${myMap[$key]}
done    

Esta função foi chamada dentro de um sub-shell que causou a saída do erro 'segmentation fault'.

    
por 24.01.2018 / 16:12
1

É um problema típico de double free . hash_flush() é chamado uma vez no segmento de memória 0x000000000044f0a7 , em seguida, novamente em 0x000000000044f0b0 .

Você deve pesquisar todas as chamadas para hash_flush() e inspecionar os valores da matriz associativa antes deles.

Se você ativar uma combinação ao registrar e usar o argumento -x em sua linha shebang, verá o problema.

Embora eu não tenha 100% de certeza sobre o bash e sua memória esteja limpa (pensando em GC como Perl, Python, PHP & Java ou free (), dealloc () etc de C / C ++).

Desculpe, não é uma solução definitiva, mas eu teria que examinar seu código, etc.

    
por 23.01.2018 / 19:04