검색/저수준 시스템 패치에서 스타일 지적보다 진짜 버그를 먼저 찾기

저수준 시스템 패치에서 스타일 지적보다 진짜 버그를 먼저 찾기

드라이버나 네트워크 라이브러리 같은 저수준 시스템 코드의 패치를 검토할 때 씁니다. 메모리, 락, 오류 경로를 따라가고, 정수 폭, 스레드, 암호화, API 변경을 확인하며, 고칠 수 있는 문제만 알리고 스타일 지적은 아주 확실할 때만 합니다.

이 AI 규칙을 사용하려면
## 버그일 가능성은 조금 불확실해도 알리고, 스타일은 아주 확실할 때만 알리기 정확성 결함을 가장 가치 높은 지적으로 취급한다. 신뢰도가 50퍼센트 이상인 타당한 정확성 버그는 보고하고, 증거가 불완전하면 불확실성을 명시한다. 추가 확인이 필요하더라도 해제 후 사용, 리소스 누수, 경쟁 상태 또는 경계 위반 가능성은 드러낼 가치가 있다. 스타일, 서식 및 절차에 관한 지적에는 다른 임계값을 적용한다. - 신뢰도가 80퍼센트를 초과할 때만 보고한다. - 최종적으로 올바르거나, 허용 가능하거나, 무해하다고 판단한 것은 모두 생략한다. - 같은 지적 안에서 우려를 제시한 뒤 스스로 이를 뒤집지 않는다. - 가능하면 의견마다 실행 가능한 문장 하나를 우선한다. 각 패치는 그 자체의 동작을 기준으로 검토한다. 단일 변경 내역만 보고 패치 묶음의 순서, 패치 간 컴파일 의존성 또는 기여자의 사정을 추론하지 않는다. 묶음에서는 문제가 없는 패치를 이상 없음으로 요약하지 말고 생략한다. ## 할당과 오류 경로를 끝까지 따라가 누수와 잘못된 사용 찾기 모든 할당, 열린 핸들, 획득한 잠금 또는 부분적으로 초기화된 객체에 대해 이후의 모든 분기를 추적한다. 조기 반환과 정리 레이블에서 해제가 균형을 이루는지, 순서가 올바른지, 오류 코드가 보존되는지 확인한다. 다음을 우선한다. - 해제 후 접근, 이중 해제, 널 역참조 및 도달 가능한 초기화되지 않은 읽기. - 메모리, 디스크립터, 소켓, 잠금 또는 부분적으로 구성된 멤버의 누수. - 실제로 실패할 수 있는 연산에서 실패 확인이 빠진 경우. - 잘못된 반환값, 버려진 오류 상태, 반전된 조건 및 한 칸 어긋난 경계. - 처음 읽히기 전에 무조건 덮어쓰이는 값. - 중첩 반복문에서 반복 카운터 하나를 재사용하는 경우. - 표본을 더하지 않고 대입하는 카운터 누적. 증분 카운터를 게이지 및 초기 대입과 구분한다. 지원 플랫폼 문서에서 유효한 인수에 대한 해당 호출은 실패하지 않는다고 명시한다면, 함수의 반환형이 정수라는 이유만으로 확인하지 않은 반환값을 지적하지 않는다. ## 정수 폭과 패킷 크기 확인하기 산술은 목적지 너비뿐 아니라 피연산자 너비에서도 검토한다. - 결과에 더 넓은 형이 필요하다면 곱셈 전에 적어도 한 피연산자의 너비를 넓힌다. - 넓은 비트 마스크로 이동시키기 전에 목적지와 같은 너비의 리터럴이나 피연산자를 사용한다. - 포인터 산술이나 넓은 결과에 쓰이는 시프트 전에 좁은 부호 없는 값의 너비를 넓힌다. - 좁은 결과의 전체 범위가 들어맞고 더 넓은 문맥이 없다면 해당 시프트는 그대로 둔다. - 게스트, 패킷, 장치 또는 API 입력이 제어하는 모든 연결 구조나 인덱스 순회에 경계를 둔다. 패킷 또는 디스크립터 객체 묶음을 해제할 때 소유권을 존중한다. 할당자나 풀 하나를 전제로 하는 일괄 기본 연산은 요소의 출처가 서로 다를 수 있는 배열에 안전하지 않다. 고속 경로 계약에서 소유권이 균일하다고 입증하지 않는 한 풀을 인식하는 해제 경로를 사용한다. 프로토콜 페이로드 크기와 전체 프레임 크기를 구분한다. 프레이밍 오버헤드는 보편 상수가 아니라 장치 기능에서 도출하고, 설정 후에는 오래된 요청 필드가 아니라 정본인 현재 구성을 읽는다. 프레임 하나가 수신 버퍼 하나에 들어맞지 않으면 구현은 지원되는 다중 세그먼트 경로를 활성화하거나 구성을 거부해야 한다. 초기 구성, 큐 설정 및 실행 중 크기 변경 시 이를 다시 확인하고, 구성된 모드와 실제 크기 요구 사항을 모두 기준으로 수신 함수를 선택한다. ## 공유 데이터에 volatile 대신 원자적 연산이나 락을 쓰는지 확인하기 `volatile`을 스레드 간 동기화로 인정하지 않는다. 공유 가변 상태에는 원자적 연산이나 적절한 잠금이 필요하다. `volatile`은 컴파일러의 접근만 제한하며 원자성도 메모리 순서도 제공하지 않는다. 정확성을 보장하는 가장 약한 순서를 선택한다. - 관련 데이터를 게시하지 않는 독립 통계와 플래그에는 완화된 순서를 사용한다. - 게시하고 소비하는 관계에는 릴리스 저장과 획득 로드를 사용한다. - 상태를 소비하는 동시에 게시하는 읽기-수정-쓰기 연산에는 획득-릴리스 순서를 사용한다. - 독립된 원자적 연산에 단일 전역 순서가 필요할 때만 순차적 일관성을 사용한다. 독립형 펜스보다 원자적 연산 자체에 순서를 지정하는 방식을 우선한다. 펜스는 원자적이지 않은 더 큰 접근 묶음의 순서를 정해야 할 때만 적절하다. 하드웨어 레지스터 및 그 밖의 실제 장치 대상 접근에는 `volatile`을 허용한다. 프로세스 간 공유 메모리에 놓인 뮤텍스, 조건 변수, 배리어 또는 읽기-쓰기 잠금에는 프로세스 공유 초기화를 요구하되, 프로세스 전용 메모리에는 이를 요구하지 않는다. 대기 동작이 사용 사례에 맞는다면 공유 메모리용으로 설계된 동기화 기본 요소를 우선한다. ## 패치가 키나 비밀 값을 다룰 때만 암호화 검토하기 패치가 키, 논스, 인증 자료 또는 보안 프로토콜 코드를 다룰 때만 암호화 검사를 적용한다. - 공격자의 영향을 받는 인증 태그, 다이제스트, MAC 또는 무결성 값을 상수 시간 동등성 기본 연산으로 비교한다. - 일반 바이트 비교를 대체할 때 동등성의 의미를 보존한다. - 키, 확장된 키 스케줄, 세션 비밀 및 유사한 자료는 해제 전에 생략될 수 없는 연산으로 지운다. - 키, 초기화 벡터 및 논스는 암호학적으로 안전한 난수원으로 생성한다. 알고리즘 식별자, 길이, 기능 또는 조회 키의 일반적인 비교를 지적하지 않는다. 재사용 여부가 변경 내역으로 확정할 수 없는 실행 시점 속성이라면 정적인 패치만 보고 논스 재사용을 주장하지 않는다. ## 라이브러리 API는 단순하게 하고, 호환되지 않는 ABI 변경에는 버전 붙이기 재사용 가능한 라이브러리는 컴파일러와 같은 서비스로 설계한다. 핸들을 만들고, 입력을 제공하고, 구조화된 출력을 받은 뒤, 다음 동작은 호출자가 결정하게 한다. 호출자를 라이브러리의 백엔드로 만들도록 강제하는 싱글턴 상태와 콜백 테이블은 피한다. 공개 콜백과 데이터 모델에는 다음을 적용한다. - 큰 연산 테이블보다 콜백 매개변수 하나를 우선한다. - 콜백이 다섯 개를 넘으면 재설계 경고로, 스무 개를 넘으면 API 설계 오류로 취급한다. - 콜백의 소유권, 수명, 반환값 및 실패 동작을 문서화한다. - 실패할 수 있는 연산에는 반환값이 없는 콜백을 사용하지 않는다. - 커지는 열거형과 커지는 공용체의 조합보다 확장 가능한 태그 레코드를 우선한다. 레이블과 관계없이 헤더로 설치되는 것은 모두 공개 API다. 특히 내부 정적 저장소의 버퍼 소유권과 수명을 명시한다. 새 코드는 사용 중단된 인터페이스를 도입해서는 안 된다. 사용 중단에는 트리 내부에 남은 사용자가 없어야 하고, 릴리스 문서, 마이그레이션 경로 및 컴파일러에 보이는 주석이 필요하다. 공개, 실험적 및 내부 주석은 도구 체인이 기대하는 정확한 위치에 두고, 소스 정의에서 심볼을 내보내며, 호환되지 않는 안정 시그니처 변경에는 ABI 버전 관리를 사용한다. 생성된 심볼 맵의 수동 편집을 절대 요청하지 않는다. ## 기계적인 스타일은 도구에 맡기고 도구가 못 잡는 부분 검토하기 기계적인 치환은 포매터, 의미 기반 패치 도구 및 저장소 검증 스크립트가 처리하게 한다. 이런 도구가 이해할 수 없는 경우에 사람 또는 AI 검토를 사용한다. 들여쓰기, 줄 끝, 포함 파일 그룹, 중괄호, 함수 배치, 식별자 및 이름공간 접두사에 관한 프로젝트의 기존 규칙을 확인한다. 정적 링크 충돌을 피하기 위해 외부에 보이는 라이브러리 또는 드라이버 심볼에는 고유한 접두사를 요구한다. 포용적인 용어를 사용한다. 참 또는 거짓 상태에는 실제 불리언 형을 우선하되, 오류 코드나 다중 상태 값에는 정수를 유지하고 기존 코드에서 관련 없는 형식 변경을 피한다. 실행 중 등록이나 기능 탐색이 변경하지 않는 한 컴파일 시점 함수 디스패치 테이블은 상수로 유지한다. 할당 및 복사 기본 연산을 데이터 경로에 맞춘다. - 일반 제어 데이터에는 보통의 힙 할당을 사용한다. - DMA, 큐 또는 프로세스 간 데이터에는 장치에서 보이고 NUMA를 인식하며 영으로 초기화되는 할당을 사용한다. - 고속 경로가 이점을 얻고 계약이 충족될 때만 최적화된 일괄 복사를 사용한다. 주석은 코드를 되풀이하지 말고 제약과 의도를 설명해야 한다. ## 코드를 바꾸면 테스트와 문서도 함께 고치기 모든 커밋은 독립적으로 빌드할 수 있어야 하지만, 패치만 보는 검토자는 묶음의 순서를 추측해서는 안 된다. 프로젝트가 지원하는 컴파일러, 대상, 옵션 및 빌드 스크립트로 검증한다. 새 동작과 공개 API에는 초점을 맞춘 테스트를 추가한다. 저장소의 기능 테스트 단언문과 테스트 모음 실행기를 사용하고, 환경 요구 사항을 정확히 기록하며, 새 장치 대상 API에는 적어도 하나의 구현을 제공한다. 코드와 문서를 한 단위로 갱신한다. - 공개 API와 중요한 사용자 노출 변경 사항을 문서화한다. - 기능 표와 연산 문서가 구현과 일치하게 유지한다. - 공개 API, 새 드라이버 또는 중요한 동작 변경에 대해서만 현재 릴리스 노트를 갱신한다. - 테스트 전용 또는 내부 구현 변경에는 릴리스 노트를 요구하지 않는다. - 각 항목이 충분한 설명을 갖춘 용어라면 구조화된 문서에서 정의 목록을 우선하고, 짧은 항목과 절차에는 단순 목록을 유지한다. 저장소에서 사용하는 빌드 언어 포매터와 정렬 규칙을 적용한다. 지정된 포매터와 줄 길이 정책으로 Python을 검증한다. ## 대상이 안정판일 때만 안정 브랜치 규칙 적용하기 대상 브랜치나 릴리스가 안정판이라고 명시되었을 때만 엄격한 안정판 릴리스 규칙을 사용한다. 그때는 버그 수정만 허용하며 새 기능, 공개 API, ABI 변경, 심볼, 구성 옵션 또는 관련 없는 리팩터링은 허용하지 않는다. 백포트는 원래 수정 사항을 참조하고 프로젝트의 안정판 알림 관례를 따라야 한다. 작은 수정 주변의 대규모 정리는 백포트 위험을 높이므로 경고로 취급한다. 릴리스가 지정되지 않았다면 새 기능과 API가 유효할 수 있는 주 개발 브랜치로 가정한다. 저장소가 안정 브랜치도 유지한다는 이유만으로 안정판 전용 금지를 적용하지 않는다. ## 구체적인 수정 방법을 쓰고 제출 전에 지적을 두 번 다시 보기 확인된 메모리 안전성, 동기화, 경계, 정리, 암호화, ABI 및 컴파일 결함은 오류로 분류한다. 테스트나 문서 누락, 부적절한 API 형태, 사용 중단 항목 추가, 할당 오용 및 신뢰도 높은 유지보수성 문제에는 경고를 사용한다. 다음은 보고하지 않는다. - 검증 도구가 이미 담당하는 생성 맵 누락, 저작권 세부 사항 또는 커밋 서식. - 하드웨어 `volatile`, 프로세스 전용 잠금, 다중 세그먼트 수신 또는 현재 테스트 매크로의 올바른 사용. - 잘못되었다는 증거 없이 무언가를 확인하라고 하는 모호한 요청. - 문제가 없는 패치, 추측성 패치 간 실패 또는 수정 조치가 없는 관찰. 실제 문제마다 먼저 문제를 밝히고, 영향이 명확하지 않을 때만 이를 설명하며, 구체적인 수정 사항이나 코드 방향을 제시한다. 제출하기 전에 별도로 두 차례 점검한다. 1. 정확성 점검: 증명 없이 기각된 타당한 정확성 지적을 복원하고, 리소스 경로, 수명, 경계 및 오류 전파를 추적했는지 확인한다. 2. 거짓 양성 점검: 분석 자체에서 허용 가능하거나, 올바르거나, 무해하다고 판단한 모든 스타일 또는 절차 항목을 제거한다. 이 점검 후 지적 목록이 비어 있어도 유효하다. 목록을 채우려고 의견을 꾸며내지 않는다.