상세 컨텐츠

본문 제목

malloc(): invalid size (unsorted)

🔫Trouble Shooting

by qkrtnals 2025. 7. 8. 17:12

본문

malloc(): invalid size (unsorted) 에러란?

: 할당된 버퍼보다 더 많은 데이터를 쓰거나, 메모리를 덮어씌울 때 발생

문제상황

  • 환경: Raspberry Pi 5 + Raspbian 12 (Bookworm) + PiCamera2 + aiortc (PyAV)
  • 증상: 웹페이지 처음 로드 시 스트리밍 OK, 페이지 새로고침 시 glibc 오류 발생

  • 원인 : 같은 카메라 인덱스(0)에 대해 CameraTrack 인스턴스가 두 번 생성되고 동시에 프레임 캡처 시도 → 메모리 충돌

WebRTC + Picamera2에서 이 에러가 발생하는 이유

  • NumPy 배열이 메모리 안전하지 않을 수 있음
    • capture_image("main")나 capture_array(...) 가 반환하는 데이터가 내부적으로 C 수준에서 공유된 버퍼인 경우
      ➡️ .copy()나 np.ascontiguousarray()없이 처리하면 av.VideoFrame.from_ndarray() 사용시 포인터 충돌이 발생할 수 있다.
  • 배열 shape 또는 dtype 오류로 속된 버퍼 오버플로우 가능
    ➡️ (480, 640, 4) 처럼 채널이 더 많다면 rgb24나 bgr24 포맷에 잘못 맞춰 내부 C 레벨에서 메모리 범위을 초과해 사용할 수 있음.
  • 동시 다발적 접근
    ➡️ malloc metadata 손상

코드 분석

⚪️ Picamera2 인스턴스를 여러 Track에서 공유하고 있음
        ➡️ get_camera_instance(index) 함수는 같은 카메라 index에 대해 하나의 객체만 생성해 공유

⚪️ recv() 메서드 안에서 .capture_array()가 병렬 호출됨
       ➡️ WebRTC에서 frame은 일정 간격으로 각 PeerConnection에 비동기 전달
       ➡️ 내부적으로 malloc 또는 free가 호출되며 상태가 꼬여서 발생

해결 방법 

1. 하나의 카메라 인스턴스만 허용

  • 새 연결 전 기존 WebRTC 연결 종료 및 camera.stop() 수행
  • MediaStreamTrack.stop()을 오버라이드하거나, aiortc의 연결 상태 변화를 감지해 정리

➡️ 여기서 현재 문제 발생
: 이제 메모리 문제는 발생하지 않지만 카메라 2개가 동시에 가동되지 않는 상태

if camera_index in track_registry:
    asyncio.create_task(track_registry[camera_index].stop())

 

 

2. 카메라 싱글턴 패턴 사용

  • 전역 카메라 인스턴스를 공유하여 중복 생성을 막고, 요청이 겹칠 경우 대기 처리
track_registry[camera_index] = self

3. 비동기 접근 동기화

  • 여러 클라이언트가 같은 카메라 스트림을 볼 경우에는 MediaRelay를 사용해 하나의 프레임을 복수 소비자에게 분배
async with frame_lock:
    frame = self.camera.capture_array()

4. 프레임 형식 검증

  • "rgb24" 포맷이 실제 RGB888 형식과 일치하는지 확인
  • NumPy 배열이 메모리상 연속적인지 .copy()로 확인 가능

결론 

어제부터 채널을 맞추기 위해 코드를 이렇게 저렇게 수정하면서 하루하고도 반나절 동안 malloc()을 봤더니 이제 저것만 봐도 토할 것 같다.. 😩 카메라 2개가 들어와서 처리하기 문제였다는거까지는 깨달아서 이제 트랙을 조절하면 되겠다 하고 조절했다. 근데 이제 문제는 로봇이 외눈박이가 되어버렸다.. 목요일에 출근해서 이 부분을 고쳐야겠다 🥹

관련글 더보기