Linux 7.2, strncpy API 제거
Linux 7.2는 공식적으로 Linux 커널에서 strncpy API를 제거했습니다. 이는 약 362개의 커밋을 포함한 6년간의 마이그레이션 작업을 마무리하여 해당 함수의 모든 남아 있는 내부 사용자를 제거한 것입니다.
strncpy가 제거된 이유
strncpy 함수는 커널 내에서 두 가지 주요 결함 때문에 지속적인 버그와 성능 저하의 원천으로 확인되었습니다:
- 직관에 반하는 의미론: NUL 종료에 관한 함수의 동작이 종종 오해되어 메모리 안전 문제를 일으킬 수 있습니다. 구체적으로, 원본 문자열이 지정된 크기보다 길거나 같을 경우
strncpy는 대상 문자열을 NUL로 종료하지 않습니다. - 성능 오버헤드: 원본 문자열이 지정된 크기보다 짧을 경우 대상 버퍼를 불필요하게 0으로 채워 CPU 사이클을 낭비합니다.
Walter Bright(베테랑 C 개발자)가 지적했듯이, 코드베이스에 strncpy가 존재한다는 것은 코드 리뷰 시 잠재적인 버그의 주요 지표가 되는 경우가 많습니다.
Linux 커널 코드에서 권장되는 대체 함수
strncpy가 여러 가지(때로는 상충되는) 목적을 수행했기 때문에, Linux 커널은 보다 명시적인 함수 집합으로 이를 대체했습니다. 개발자는 메모리 작업의 구체적인 요구 사항에 따라 아래 대체 함수 중 하나를 선택해야 합니다:
strscpy(): NUL 종료가 반드시 필요한 대상에 사용합니다.strscpy_pad(): NUL 종료가 필요하고 특히 0 패딩이 요구되는 대상에 사용합니다.strtomem_pad(): NUL 종료되지 않은 고정 길이 필드에 사용합니다. 이 함수는 C 문자열을 고정 길이 레거시 메모리 필드로 변환한다는 신호를 명시적으로 전달하며,sizeof(dest)와 관련된 버그를 방지하기 위해__nonstring속성을 활용합니다.memcpy_and_pad(): 명시적인 패딩이 필요한 제한된 복사에 사용합니다.memcpy(): 길이가 이미 알려진 메모리 복사에 사용합니다.
엔지니어링 배경 및 커뮤니티 인사이트
장기 시스템 엔지니어링 노력
strncpy의 제거는 커뮤니티가 시스템 엔지니어링의 "지루한 갈고리"의 전형적인 사례로 보는 작업입니다. 새로운 기능을 추가하는 것과 달리, 방대한 코드베이스에서 레거시 API를 제거하려면 안정성을 유지하면서 기능을 보존하기 위한 체계적이고 다년간에 걸친 접근이 필요합니다.
API의 역사적 배경
업계 베테랑들은 strncpy가 초기 UNIX에서 매우 특정한 사용 사례를 위해 설계되었다고 지적합니다: 2바이트 inode 번호와 14바이트의 0 패딩된, 종료되지 않은 이름 필드로 구성된 디렉터리 엔트리에 파일명을 복사하는 경우였습니다. 이를 일반적인 문자열 복사 함수로 사용하는 것은 수십 년 동안 지속된 API의 근본적인 오용이었습니다.
C 언어에 대한 광범위한 비판
이번 제거에 대한 논의는 문자열을 다루는 C 언어에 대한 지속적인 불만을 부각시킵니다. 커뮤니티 구성원들은 원시 문자열 타입(예: 팻 포인터, 슬라이스, 문자열 뷰)과 같은 네이티브 문자열 타입이 없기 때문에 개발자들이 복잡하고 오류가 발생하기 쉬운 수동 메모리 관리 함수에 의존하게 된다고 지적했습니다. 일부 기여자는 Pascal 스타일 문자열이나 std::string(C++와 유사)과 같은 포인터와 길이를 포함하는 struct를 채택했다면 이러한 문제를 완전히 방지할 수 있었을 것이라고 제안했습니다.