생명을 지키는 코드
우리가 흔히 “안전”이라고 하면 기계, 설비, 구조물 같은 하드웨어(Hardware)를 먼저 떠올린다. 예를 들어, 비행기의 날개가 부러질 위험, 자동차 브레이크가 작동하지 않는 위험이 바로 그런 경우다. 하드웨어의 안전은 주로 물리적 고장(Failure)과 관련되어 있다. 금속이 피로에 의해 깨지거나, 회로가 단선되는 식의 눈에 보이는 실패등이 있다.
하지만 소프트웨어(Software)는 다르다. 소프트웨어는 금속처럼 피로해져서 부러지지 않으나, 대신 논리적 오류(Logic Error) 나 요구사항 미비, 설계상 결함, 인간의 실수 때문에 문제가 발생한다. 소프트웨어의 안전은 ‘망가지지 않는 물체’를 지키는 게 아니라, 잘못된 명령이 실행되지 않도록 막는 것이 핵심이다. 그래서 소프트웨어 안전은 단순히 “신뢰성(Reliability)”의 문제로만 볼 수 없고, 요구사항과 설계, 검증 단계에서부터 철저히 다른 접근을 해야 한다.
몇 년 전, 유럽의 한 공항에서 착륙하던 항공기가 갑자기 강하게 하강했다가 가까스로 자세를 회복한 사건이 있었다. 원인은 기체 결함도, 조종사의 미숙도 아니었다. 문제는 고도계 센서 값이 소프트웨어에 잘못 입력된 것이었다. 하드웨어는 멀쩡했으나, 소프트웨어가 그 숫자를 해석하는 방식에 오류가 있었고, 자동 조종 장치는 잘못된 ‘명령’을 충실하게 따랐다.
이 사례가 우리에게 말해주는 것은 단순하다. 하드웨어는 부러지며 사고를 일으키지만, 소프트웨어는 잘못된 사고방식으로 사고를 부른다는 점이었다. 즉, 소프트웨어 안전은 고장이 아닌 논리와 설계의 오류에서 출발한다.
수많은 코드 줄 사이에서, 모두가 같은 위험을 품고 있진 않는다. 예를 들어 비행기의 좌석 스크린이 멈춘다고 해서 사고로 이어지진 않듯. 하지만 조종 시스템을 제어하는 소프트웨어 한 줄이 잘못되면, 수백 명의 생명이 위험해진다.
그래서 안전 엔지니어들은 Software Control Categories를 통하여 SWCI(Software Control Item)를 정한다. 즉, “이 기능은 안전에 직접 연결되므로 더 엄격하게 다뤄야 한다”는 구분이다. SWCI를 정한다는 건 단순한 분류 작업이 아니다. 한정된 시간과 자원을 어디에 집중해야 하는가를 결정하는 생존의 전략이다.
SWCI Level은 일반적으로 하드웨어의 “개별고장 영향 분석(FHA, Functional Hazard Assessment)” 이나 시스템 안전 분석(SSA) 결과에 따라 결정된다. 핵심 질문은 하나다:
“이 소프트웨어가 잘못 동작했을 때, 사람과 시스템에 어떤 영향이 있는가?”
이에 따라 Level은 보통 치명적(Catastrophic) → 심각(Major/Hazardous) → 중간(Minor) → 무시 가능(No Safety Effect)으로 5등급으로 구분된다.
SWCI Level 1: Catastrophic (치명적), 소프트웨어 실패가 직접적으로 대규모 사망, 기체 손실, 시스템 전체 붕괴를 초래. 가장 엄격한 보증 요구.
예시: 항공기 자동조종, 로켓 추진 제어, 원자로 긴급 정지 소프트웨어
SWCI Level 2: Hazardous/Severe-Major (심각) 심각한 부상, 시스템의 심각한 손상. 승무원/운용자가 즉각 대응하지 않으면 사고로 이어짐.
예시: 항공기 엔진 추력 제어, 열차 제동 제어
SWCI Level 3: Major (중간 수준) 안전성 저하, 승무원 업무량 증가, 임무 성능 크게 떨어짐. 그러나 직접적인 치명적 사고는 아님.
예시: 항공기 항법 보조, 자율주행 보조 기능
SWCI Level 4: Minor (경미) 단순 불편, 임무 효율 저하. 안전에 직접 영향 없음.
예시: 객실 조명, 일반적인 모니터링 기능
SWCI Level 5: No Safety Effect (영향 없음) 소프트웨어 실패가 안전에 전혀 영향 없음. 특별한 안전 검증 불필요.
예시: 기내 엔터테인먼트, 승객용 UI
Level 1 (가장 엄격) → 실패하면 대형 사고. 따라서 정형기법(Formal Method), MC/DC 테스트, 독립적 V&V 등 모든 안전 활동을 요구.
Level 5 (가장 낮음) → 안전 영향 없음. 기본적인 품질 관리만 있으면 되고, 별도의 안전 검증 프로세스는 필요하지 않음.
즉,
Level 1 = 생명을 직접 지키는 SWCI
Level 5 = 단순 편의를 위한 SWCI
모든 소프트웨어를 Level 5처럼 관리한다면, 시간과 비용은 천문학적으로 늘어나고 프로젝트는 진행될 수 없다.
따라서 리스크 기반 접근이 필요하다:
안전과 직결된 부분(SWCI Level 1과 2)은 아주 엄격하게 개발·검증→ 논리적 컨트롤(이중화, Fail-safe 알고리즘, 제한 조건 검증) + 절차적 컨트롤(독립적 검증, 정형기법) 적용
영향이 적은 부분(Level 3과 4)은 최소한의 안전 관리만 적용 → 일반적인 단위 테스트와 코드 리뷰 중심
영향이 없는 부분(Level 5)은 안전 분석에서 제외
SWCI Level은 ‘이 소프트웨어가 실패했을 때 안전에 미치는 영향’의 크기로 구분하며, Level이 올라갈수록 요구되는 개발·검증 강도가 기하급수적으로 늘어난다. 그렇기에 이렇게 해야 한정된 자원을 가장 중요한 곳에 집중시킬 수 있다.
소프트웨어 안전에서 우리가 마주치는 리스크들은 크게 몇 가지로 나눌 수 있다.
요구사항의 결함 애초에 잘못된 요구사항이 들어가면, 아무리 완벽한 코드도 안전하지 않습니다. 예: 자동차 제동 거리를 짧게 계산하도록 요구사항이 설정된다면, 그 뒤의 모든 소프트웨어는 그대로 위험을 따라간다.
설계 오류 복잡한 기능이 의도치 않게 충돌하거나, 예외 상황을 고려하지 못한 설계. 예: 두 개의 센서 신호를 동시에 받아야 하는데, 하나만 받아도 정상으로 판단하는 로직.
코딩 실수 논리 연산 오류, 메모리 누수, 변수 범위 초과 등 인간이 흔히 저지르는 작은 실수. 이런 실수가 모여 시스템 전체를 무너뜨린다.
인터페이스 위험 소프트웨어와 하드웨어, 또는 다른 소프트웨어 간의 연결에서 발생하는 문제. 예: 센서가 주는 값이 0.01초 단위인데, 소프트웨어는 1초 단위로만 읽을 때 생기는 미세한 불일치.
동시성 문제(Concurrency) 여러 기능이 동시에 실행될 때 예상치 못한 충돌이 발생. 예: 항공기 제어 루프가 두 개의 스레드에서 같은 데이터를 동시에 수정해 버리는 상황.
보안 위협 과거에는 ‘안전(Safety)’과 ‘보안(Security)’을 별개로 봤지만, 지금은 해킹이 직접 안전 문제로 이어진다. 예: 자율주행차의 제어 시스템에 침입해 가속 신호를 변조하는 경우.
환경적 요인 전자파, 전력 불안정, 외부 환경 때문에 소프트웨어가 예상치 못한 동작을 할 수 있다. 예: 우주 환경의 방사선이 메모리 비트를 뒤집는 문제(SEU, Single Event Upset).
하드웨어 안전에서의 컨트롤(Control) 은 주로 물리적 장치나 설계 보강을 뜻한다. 예를 들어, 압력 용기에는 안전밸브를 설치하고, 회로에는 퓨즈를 다는 식이다. 즉, 고장이 나더라도 피해가 줄어들도록 “장치”를 두는 것이다.
소프트웨어 안전에서의 컨트롤은 조금 다르다. 여기서는 논리적 제어(Logical Control) 나 절차적 통제(Process Control)가 더 중요하다.
논리적 제어: 예를 들어, 소프트웨어가 엔진 추력을 높이는 명령을 내릴 때, 한 번 더 확인하는 루틴을 넣는다든지, 허용 범위를 벗어나면 자동으로 차단하는 알고리즘을 추가하는 것.
절차적 통제: 코드 리뷰, 독립적인 검증(V&V), 테스트 케이스 작성, 표준 준수(예: DO-178C) 같은 개발 과정의 안전장치.
즉, 하드웨어는 “물리적 컨트롤”, 소프트웨어는 “논리적·절차적 컨트롤”이 핵심 차이다.
Note:
하드웨어 안전: 고장 확률(Failure rate) → 물리적 장치로 제어
소프트웨어 안전: 논리적 오류와 요구사항 결함 → SWCI로 핵심 기능 선별 + 프로세스와 알고리즘으로 제어
소프트웨어는 절대 금속처럼 부러지지 않는다. 하지만 그 속의 한 줄 잘못된 명령이 사람의 생명을 앗아갈 수 있다.
따라서 소프트웨어 안전은 단순히 “버그를 잡는 것”이 아니라, 리스크를 예측하고, 치명적인 부분을 SWCI로 구분하며, 그 기능에 다층적인 컨트롤을 더하는 것이다.
그리고 이 과정에서 중요한 건 기술뿐 아니라 상상력이다.
“만약 이 코드가 다른 방식으로 작동한다면, 어떤 일이 벌어질까?”
그 질문이 바로 소프트웨어 안전의 출발점이다.