[TIL/크래프톤 정글9기] 52일차 (C/명시적 가용 리스트 구현 시 오류 해결)

blueprint·2025년 7월 2일

크래프톤정글9기

목록 보기
43/55

malloc-lab "lies outside heap" 에러 해결

32비트 → 64비트 환경에서 발생한 문제


문제

  • 환경: AWS 환경 EC2 Ubuntu 22.04 64비트에서 malloc-lab 실행
  • 에러: Payload (0x149007000:0x1490073ef) lies outside heap (0x149000000:0x14900700f)
  • 블록이 힙 바깥 주소를 침범
  • 원인:
    • 32비트용 코드를 64비트 환경에서 실행
    • makefile에서 CFLAGS = -Wall -O2 -g #-m32 로컬 컴퓨터에서 돌려보려 -m32 옵션 비활성화

문제점

1. 포인터 크기 차이

// 32비트: 포인터 = 4바이트
// 64비트: 포인터 = 8바이트
#define WSIZE 4        /* 워드 및 헤더/푸터 크기 (바이트) */
#define DSIZE 8        /* 더블 워드 크기 (바이트) */

#define NEXT_FREEP(bp) (*(void **)((char *)(bp) + WSIZE))  // WSIZE = 4바이트

2. 명시적 가용 리스트 매크로 오류

// 문제: 64비트에서 포인터는 8바이트인데 4바이트 사용
#define PRED_FREEP(bp) (*(void **)((char *)(bp)))
#define NEXT_FREEP(bp) (*(void **)((char *)(bp) + WSIZE))  // 64bit 환경에서 오류 발생

해결 방법

1. 매크로 수정

// 수정 전
#define NEXT_FREEP(bp) (*(void **)((char *)(bp) + WSIZE))

// 수정 후  
#define NEXT_FREEP(bp) (*(void **)((char *)(bp) + DSIZE))

2. 최소 블록 크기 조정 mm_malloc(), place()

// 32비트에서는 두 개의 포인터(8바이트) + 헤더/푸터(8바이트) = 16바이트
if (size <= DSIZE)
    asize = 2*DSIZE;  // 16바이트로 증가

// 64비트에서는 두 개의 포인터(16바이트) + 헤더/푸터(8바이트) = 24바이트
if (size <= DSIZE)
    asize = 3*DSIZE;  // 24바이트로 증가
// 수정 전 남은 공간이 최소 블록 크기(16바이트) 이상이면 분할 수행
if ((csize - asize) >= (2*DSIZE)) {
}
    
// 수정 후 남은 공간이 최소 블록 크기(24바이트) 이상이면 분할 수행
if ((csize - asize) >= (3*DSIZE)) {
}

교훈

  • 환경 차이 인식: 32비트 ↔ 64비트 이식 시 포인터 크기 고려 필수
  • 철저한 테스트: 환경 변경 후 충분한 테스트 필요

핵심: "작은 차이가 큰 문제를 만든다"

0개의 댓글