2P by neo 3일전 | favorite | 댓글 1개

Steam 클라이언트 안정성 개선

  • 배경: 11월 5일 Steam 클라이언트 업데이트에서 Linux에서의 일반적인 충돌을 수정함. 이 중 가장 큰 영향을 미친 것은 setenvgetenv 함수의 사용 방식 변경임.

  • 문제점: setenv는 Linux에서 안전하지 않은 API로, 멀티스레드 환경에서 사용 시 문제가 발생할 수 있음. getenv 호출 후 다른 스레드에서 SIGABRT와 같은 충돌이 발생할 수 있음.

  • 해결책:

    • 대부분의 setenv 호출을 제거하고, 프로세스 생성 시 execvpe를 사용하여 환경을 전달하도록 리팩토링함.
    • getenv 의존도를 줄이기 위해 호출을 캐싱함.
    • 남은 setenv 사용 사례에 대해 '환경 관리자'를 도입하여 시작 시 충분히 큰 값 버퍼를 미리 할당함.
  • 결과: 이러한 변경으로 SIGABRT 발생 빈도가 크게 감소함. 그러나 완벽한 해결책은 아니며, 외부 라이브러리가 setenv를 호출할 경우 여전히 충돌 위험이 있음.

  • 향후 계획: glibc에서 이 문제를 해결하기 위해 비동기 신호 안전성을 유지하면서 envp 사용과 동기화하는 방법을 연구 중임. 이 작업은 복잡하지만, 장기적으로 POSIX 사양에서 벗어나지 않는 범위 내에서 해결책을 제안할 계획임.

Hacker News 의견
  • Red Hat의 그래픽 스택 안정성 문제로 인해 패치가 검토 중임

    • getenv의 스레드 안전성 수정이 glibc 2.41에 포함될 가능성이 높음
    • setenv는 이미 환경 문자열을 해제하지 않기 때문에 처리하기 쉬움
    • unsetenv는 동시성 문제로 복잡함
    • getenv에 잠금을 도입하지 않으려는 이유는 비동기 신호 안전성을 유지하기 위함임
    • vfork+execve로 인해 메모리 누수를 피하기 어려워 환경 처리 수정이 논란이 있음
  • Linux에서 Steam이 잘 작동하는 것에 감사함

  • 환경 변수를 부팅 시 읽고 setenv를 사용하지 않는 것이 최선의 방법임

    • 새로운 프로세스를 생성할 때는 현재 환경을 복제하여 새로운 값을 업데이트해야 함
    • getenv/setenv를 IPC 메시징 메커니즘으로 사용하는 것은 문제가 될 수 있음
  • setenv가 Linux API인지에 대한 의문이 있음

    • setenv는 POSIX에 정의되어 있으며 Linux 커널이 아닌 사용자 공간에서 구현됨
  • 프로그램이 한 스레드에서 setenv를 호출하고 다른 스레드에서 효과를 원할 경우가 있는지에 대한 질문이 있음

    • GLIBC는 위험한 함수들을 잘 문서화하고 있어 잠금/복사를 추가할 수 있음
  • Steam이 연결이 없다고 불평하는 문제가 있음

    • '재시도' 버튼을 여러 번 누르면 작동하지만 불편함
  • Steam 클라이언트와 Linux 프로그래밍에 대한 통찰력이 흥미로움

    • 릴리스 노트가 자세하지 않은 이유를 이해하지만, "일반적인 충돌 수정"은 과소평가된 표현임
  • glibc에서 문제를 해결하려면 기능의 절충이 필요할 수 있음

    • 장기적으로 합리적인 제안을 할 수 있다면 추구할 수 있음
  • Steam 클라이언트의 렌더링 성능이 마우스가 창 안에 있을 때 좋지 않음

  • Linux Steam 클라이언트에 오랜 기간 지속된 버그가 있음

    • 하루 이상 Steam을 실행하면 창 핸들이 부족해져 새로운 그래픽 애플리케이션/창을 열 수 없음
    • Steam Chat을 사용하면 문제가 더 빨리 발생함
    • 이 문제는 GitHub에 문서화되어 있지만, 이유 없이 닫힘
    • 개인적으로 매일 Steam을 재시작함
    • KDE/Wayland와 X11에서도 이 문제를 관찰함