본문 바로가기
iOS/이슈

[iOS Issue] Multi thread 환경에서 Dangling Pointer Crash 이슈

by Sky Titan 2024. 5. 5.
728x90

앱의 Logging을 담당하는 모듈에서 multi thread 환경에서 동작 시 잦은 Crash가 발생하는 이슈가 생겼다.

 

결론만 말하자면 원인은 Singletone 클래스에 있는 Thread-safety 처리가 되어있지 않은 stored property에 여러 스레드가 동시에 setter에 접근을 하면서 Dangling pointer 크래시가 발생했다.

 

이슈 상황은 크게 2가지 였다.

 

Unknown Object Release

 이 경우는 Setter가 여러 스레드에서 동시에 불리면서 이미 Retain Count가 0임에도 불구하고 추가로 Release를 시도하면서 생기는 크래시였다.

 

다음과 같은 상황으로 보면 될 것 같다.

  1. stored property에 이미 instance가 존재하는 중 (retain count는 1)
  2. Concurrent Queue에 존재하는 A thread, B thread가 동시에 stored property의 값을 교체하려고 setter를 호출한다.
  3. A thread에서 원래 존재하던 instance의 retain count를 확인해보니 1이다. 그렇기에 값을 교체하면서 release() 함수를 호출시켰다.
  4. B thread에서도 동시에 원래 존재하던 instance의 retain count를 확인해보니 1이다. 그렇기에 값을 교체하면서 release() 함수를 호출시켰다.
  5. 즉 retain count는 1이지만 release() 함수는 2번이 호출이 되면서 Crash가 발생한다.

Unknown Object Release

 그림으로 표현하기가 쉽지 않은데, 2개 이상의 스레드에서 원래 있던 instance의 retain count를 체크하고 release함수를 호출하는 타이밍이 겹치면 발생하는 상황이라고 보면 될 것 같다.

 

Unknown Object Retain

 이 상황도 기본적으로 위에서 언급했던 상황처럼 이미 여러 스레드에서 동시에 release 함수를 호출하면서 release count가 0이 된 상황을 가정하면 된다.

 다만 이미 release count가 0인 상황에서 기존에 있던 instance를 retain 시키는 행동을 했을 때는 unknown object retain으로 스택 트레이스가 찍히고, release 시키는 행동을 했을 때는 unknown object release로 스택 트레이스가 찍히는 차이이다.

728x90

댓글