임베디드 면접 용어 사전
디버깅·신뢰성

coredump

장애 시점의 메모리·레지스터 상태를 남기는 덤프. 재현되지 않는 필드 버그 분석에 쓰인다.

크래시 시점의 메모리와 레지스터 상태를 저장해 나중에 분석하는 것.

왜 임베디드에서 필요한가

현장에 배포된 기기가 가끔 재부팅된다
→ 디버거를 붙일 수 없다
→ 재현이 안 된다
→ 로그만으로는 원인을 모른다

"그 순간에 무슨 일이 있었는지"를 남기는 유일한 방법이다.

무엇을 저장하나 — 우선순위 순

① 폴트 정보    : CFSR, HFSR, BFAR, MMFAR       (16바이트)
② 스택 프레임  : R0-R3, R12, LR, PC, xPSR      (32바이트)
③ 나머지 레지스터: R4-R11, SP                   (36바이트)
④ 메타데이터   : 펌웨어 버전, 리셋 원인, 업타임  (수십 바이트)
⑤ 스택 일부    : 콜 스택 복원용 (256~1024바이트)
⑥ 주요 전역 변수: 시스템 상태
⑦ 최근 로그    : 링 버퍼 내용

①②만으로도 대부분의 원인을 좁힐 수 있다. 저장 공간이 부족하면 여기까지만 해도 큰 도움이 된다.

어디에 저장하나

위치장점단점
.noinit RAM빠르다(폴트 중에도 안전)전원이 끊기면 사라짐
RTC 백업 레지스터VBAT로 유지매우 작다(수십 바이트)
백업 SRAMVBAT로 유지용량 제한
내부 플래시영구 보존폴트 중 쓰기가 위험
외부 플래시/EEPROM용량 충분통신이 필요 → 폴트 중 불안정

실무 조합 — 폴트 핸들러에서는 .noinit RAM에 빠르게 기록하고 리셋한 뒤, 정상 부팅한 상태에서 플래시나 서버로 옮긴다.

폴트 핸들러 안에서 플래시 쓰기나 통신을 시도하면 안 된다 — 이미 시스템이 불안정한 상태라 또 죽을 수 있다.

구현

typedef struct {
    uint32_t magic;
    uint32_t pc, lr, psr;
    uint32_t r0, r1, r2, r3, r12;
    uint32_t cfsr, hfsr, bfar, mmfar;
    uint32_t uptime_ms;
    char     fw_version[16];
    uint32_t stack_snapshot[64];
} CoreDump;

__attribute__((section(".noinit"))) volatile CoreDump g_dump;

void hard_fault_c(uint32_t *sp) {
    g_dump.pc    = sp[6];
    g_dump.lr    = sp[5];
    g_dump.psr   = sp[7];
    g_dump.cfsr  = SCB->CFSR;
    g_dump.bfar  = SCB->BFAR;
    g_dump.uptime_ms = HAL_GetTick();
    for (int i = 0; i < 64; i++) g_dump.stack_snapshot[i] = sp[i];
    g_dump.magic = 0xC0DEDEAD;      // ★ 마지막에 쓴다

    __DSB();
    NVIC_SystemReset();
}

★ magic을 마지막에 쓰는 이유 — 기록 도중에 또 죽으면 불완전한 덤프가 유효한 것처럼 보인다. 매직을 마지막에 써야 "완전히 기록됐다"는 표시가 된다.

부팅 시 회수

int main(void) {
    if (g_dump.magic == 0xC0DEDEAD) {
        save_to_flash(&g_dump);       // 또는 서버 전송
        g_dump.magic = 0;             // 중복 보고 방지
    }
    …
}

분석 — PC를 소스 줄로

arm-none-eabi-addr2line -e firmware.elf -f -C 0x08001234
# process_data
# /src/main.c:142

해당 버전의 .elf 파일을 반드시 보관해야 한다. 버전이 다르면 주소가 전혀 다른 함수를 가리킨다.

릴리스마다 elf + map 파일을 아카이브에 저장 덤프의 fw_version 으로 어느 elf 를 쓸지 결정

이 절차가 없으면 덤프를 모아도 분석할 수 없다.

콜 스택 복원

  • 스택 스냅샷에서 플래시 영역(0x08xxxxxx)에 해당하는 값들을 찾는다
  • 그것들이 반환 주소일 가능성이 높다
  • addr2line 으로 각각을 해석하면 대략적인 호출 경로가 나온다

정확하지는 않지만(데이터가 우연히 그 범위일 수 있다) 실무에서 상당히 유용하다.

리셋 원인도 함께

uint32_t csr = RCC->CSR;
if (csr & RCC_CSR_IWDGRSTF) reason = WATCHDOG;
if (csr & RCC_CSR_SFTRSTF)  reason = SOFTWARE;    // 우리가 낸 리셋
if (csr & RCC_CSR_PORRSTF)  reason = POWER_ON;
if (csr & RCC_CSR_PINRSTF)  reason = RESET_PIN;
RCC->CSR |= RCC_CSR_RMVF;

덤프가 없는데 워치독 리셋이 기록됐다면 폴트가 아니라 무한 루프나 데드락이다. 원인 분류의 첫 갈래가 된다.

통계로 활용

같은 PC 값이 반복되면 → 특정 버그 다양한 PC 값이 흩어지면 → 메모리 손상, 스택 오버플로, 하드웨어 문제 특정 기기에서만 발생 → 하드웨어 불량 여러 기기의 덤프를 모아 패턴을 보는 것이 현장 문제 해결의 핵심이다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 디버깅·신뢰성 — JTAG/SWD·HardFault(fault 레지스터)·트레이스·watchdog·EMC