안전에 중요한 코드를 개발하기 위한 10가지 규칙

안전에 중요한 코드를 개발하기 위한 10가지 규칙

enter image description here

안전에 중요한 코드를 개발하기 위한 10가지 규칙

참조링크 : https://hardwareteams.com/docs/embedded/nasas-rules-for-software/

첨부된 링크의 번역을 기반으로 합니다.
제가 이해한 대로 작성하다 보니 오역이 많을 수 있습니다.

Power of 10 Rules

1. 모든 코드는 매우 간단한 제어 흐름 구조로 제한되어야 합니다.

  • goto 문장 사용 금지
  • setjmp 함수 사용 금지
  • longjmp 함수 사용 금지
  • 재귀 호출 사용 금지

2. 모든 루프는 고정된 상한값을 가져야 합니다.

  • 모든 루프는 정수로 된 상한값으로 제한되어야 합니다.(즉, null에 대한 논리적 확인으로 루프를 중단시키지 말아야 함)
#include <stdio.h>

void processArray(int array[], int size) {
    int i;
    for (i = 0; i < size; i++) {
        array[i] += 5;
    }
}

int main() {
    int array[] = {1, 2, 3, 4, 5};
    int size = sizeof(array) / sizeof(array[0]); // 항상 제한된 값을 가짐 
    int i;

    printf("Original Array: ");
    for (i = 0; i < size; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");

    processArray(array, size);

    printf("Modified Array: ");
    for (i = 0; i < size; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");

    return 0;
}

3. 초기화 이후에 동적 메모리 할당을 사용하면 안됩니다.

  • 힙(heap) 사용 금지
  • 스택(stack) 사용 - 프로그램이 사용할 메모리 양을 쉽게 예측 가능

4. 함수의 길이는 표준 형식의 한 장의 용지에 출력할 수 있는 길이로 제한되어야 합니다. 한 줄에 하나의 문장과 선언문이 있어야 합니다.

  • 테스트하기 쉽도록 함수를 충분히 작게 유지해야 합니다.

5. 코드의 어설션(assertion) 비율은 함수 당 최소 두 개의 어설션을 평균적으로 가져야 합니다.

#include <stdio.h>
#include <assert.h>

int add(int a, int b) {
    assert(a > 0 && b > 0);  // 어설션: a와 b는 양수여야 함
    return a + b;
}

int main() {
    int result = add(5, 10);
    printf("Result: %d\n", result);
    return 0;
}

6. 모든 데이터 객체는 가능한 한 작은 범위에서 선언되어야 합니다.

  • 변수에 접근할 수 있는 코드 양을 줄여서 잠재적인 오류 가능성을 감소시킵니다.

7. 호출하는 함수는 반환 값을 확인해야 하며, 호출되는 함수는 호출자가 제공한 모든 매개변수의 유효성을 확인해야 합니다.

#include <stdio.h>

int divide(int a, int b) {
    if (b == 0) {
        printf("Error: Division by zero!\n");  // 예외 처리
        return 0;
    }
    return a / b;
}

int main() {
    int result = divide(10, 2);
    printf("Result: %d\n", result);
    return 0;
}

8. 전처리기 사용은 헤더 파일의 포함과 간단한 매크로 정의에만 제한되어야 합니다.

  • 조건부 컴파일은 컴파일 대상의 수를 기하급수적으로 증가시킬 수 있습니다.

9. 포인터를 이용한 링크를 여러 번 연결해서 받지 않고, 함수 포인터는 사용하지 않습니다.

10. 모든 경고가 활성화된 성태로 컴파일 합니다. 그리고 모든 경고는 소프트웨어 릴리즈 전에 해결해야 합니다.

gcc -Wall -Werror -Wpedantic

결론

임베디드 시스템에서 실제로 위 10가지를 대부분 지켰던 것 같다. 5번 항목의 assertion 은 코드 작성할 때 사용하지 않았는데 이제부터라도 코드에 넣을 수 있도록 해야겠다. 위에 따로 10가지를 작성하기는 했지만 아마도 국내에서는 안전한 코드 작성 룰로 오토모티브쪽 코딩 룰인 MISRA-C 코딩 가이드라인을 주로 사용하는 것으로 알고 있다. 위 10 가지는 MISRA-C 코딩 가이드라인 참조한 요약본 정도로 보면 될 것 같다.

끝 :)

도움이 되셨다면 더 좋은 정보 공유를 위해 광고 클릭 부탁 드립니다 :)

댓글 쓰기

0 댓글