2 pontos por GN⁺ 2024-11-12 | 1 comentários | Compartilhar no WhatsApp

Melhorias na estabilidade do cliente Steam

  • Contexto: na atualização do cliente Steam de 5 de novembro, foram corrigidos travamentos comuns no Linux. Entre eles, o de maior impacto foi a mudança na forma de uso das funções setenv e getenv.

  • Problema: setenv é uma API insegura no Linux, e seu uso em ambientes multithread pode causar problemas. Após uma chamada de getenv, pode ocorrer um travamento como SIGABRT em outra thread.

  • Solução:

    • A maior parte das chamadas de setenv foi removida, e o código foi refatorado para passar o ambiente ao criar processos usando execvpe.
    • As chamadas foram colocadas em cache para reduzir a dependência de getenv.
    • Para os casos restantes de uso de setenv, foi introduzido um “gerenciador de ambiente” que pré-aloca na inicialização um buffer de valores suficientemente grande.
  • Resultado: com essas mudanças, a frequência de ocorrência de SIGABRT caiu significativamente. No entanto, isso não é uma solução perfeita, e ainda há risco de travamentos caso bibliotecas externas chamem setenv.

  • Próximos planos: no glibc, está sendo estudada uma forma de resolver esse problema sincronizando o uso de envp sem perder a segurança assíncrona de sinais. Esse trabalho é complexo, mas a proposta é apresentar uma solução de longo prazo que não fuja da especificação POSIX.

1 comentários

 
GN⁺ 2024-11-12
Comentários no Hacker News
  • Um patch está sendo avaliado por causa de problemas de estabilidade na stack gráfica da Red Hat

    • É bem provável que uma correção de segurança de thread para getenv entre no glibc 2.41
    • setenv já é mais fácil de lidar porque não libera as strings de ambiente
    • unsetenv é complicado por causa de problemas de concorrência
    • O motivo para não querer introduzir travas em getenv é preservar a segurança para sinais assíncronos
    • Por causa de vfork+execve, é difícil evitar vazamentos de memória, então mudanças no tratamento do ambiente são controversas
  • Agradecimento pelo Steam funcionar bem no Linux

  • O melhor é ler as variáveis de ambiente na inicialização e não usar setenv

    • Ao criar um novo processo, deve-se copiar o ambiente atual e atualizar os novos valores
    • Usar getenv/setenv como mecanismo de troca de mensagens IPC pode causar problemas
  • Há dúvidas sobre setenv ser uma API do Linux

    • setenv é definido pelo POSIX e implementado em espaço de usuário, não no kernel Linux
  • Há uma pergunta sobre se existe caso em que um programa chama setenv em uma thread e espera o efeito em outra thread

    • A glibc documenta bem funções perigosas, então seria possível adicionar travas/cópias
  • Há um problema em que o Steam reclama que não há conexão

    • Clicar várias vezes no botão “tentar novamente” faz funcionar, mas é incômodo
  • Os insights sobre o cliente Steam e programação no Linux são interessantes

    • Dá para entender por que as notas de versão não são detalhadas, mas “correções gerais de travamentos” é uma descrição modesta demais
  • Para resolver o problema na glibc, talvez seja necessário aceitar alguns compromissos de funcionalidade

    • Se surgir uma proposta razoável de longo prazo, ela pode ser levada adiante
  • O desempenho de renderização do cliente Steam no Linux é ruim quando o mouse está dentro da janela

  • Existe um bug antigo e persistente no cliente Steam para Linux

    • Se o Steam ficar aberto por mais de um dia, os handles de janela se esgotam e não é possível abrir novos aplicativos/janelas gráficas
    • Usar o Steam Chat faz o problema acontecer mais rápido
    • Esse problema está documentado no GitHub, mas foi fechado sem motivo aparente
    • Pessoalmente, a pessoa reinicia o Steam todos os dias
    • Esse problema também foi observado em KDE/Wayland e no X11