안드로이드 Check failed: Thread::Current() != GetDebugThread() (Thread::Current()=0xacc0a400, GetDebugThread()=0xacc0a400) Expected event thread

안녕하세요. 개발자 드리머즈입니다.


문제현상

언제부터인가 안드로이드 스튜디오에서 Debug 'app'을 눌러 디버깅 상태로 앱을 실행시키면 동작 중에 앱의 특정 버튼을 누르면 계속 크래쉬가 발생했습니다.

RecyclerView, Adapter를 보여주는 화면에서 크래쉬가 발생했습니다.


에러 메세지는 엄청나게 긴데 위의 몇줄만 가져오면 아래와 같습니다.


1
2
3
4
5
6
7
8
9
A/art: art/runtime/jdwp/jdwp_event.cc:661] Check failed: Thread::Current() != GetDebugThread() (Thread::Current()=0xacc0a400, GetDebugThread()=0xacc0a400) Expected event thread
A/art: art/runtime/runtime.cc:422] Runtime aborting...
A/art: art/runtime/runtime.cc:422] Aborting thread:
A/art: art/runtime/runtime.cc:422] "JDWP" prio=5 tid=4 WaitingForDebuggerSend
A/art: art/runtime/runtime.cc:422]   | group="" sCount=0 dsCount=0 obj=0x12c40310 self=0xacc0a400
A/art: art/runtime/runtime.cc:422]   | sysTid=4278 nice=0 cgrp=default sched=0/0 handle=0xa81d2920
A/art: art/runtime/runtime.cc:422]   | state=R schedstat=( 0 0 0 ) utm=1 stm=1 core=1 HZ=100
A/art: art/runtime/runtime.cc:422]   | stack=0xa80d6000-0xa80d8000 stackSize=1014KB
A/art: art/runtime/runtime.cc:422]   | held mutexes= "abort lock"
cs

원인

이게 무슨 일인지 찾아봤습니다.


다행히 아래의 스택오버플로우에서 이미 토론?이 된 기록이 있습니다.

https://stackoverflow.com/questions/40618803/android-app-crashes-when-launched-in-debug-mode/40667569#40667569


그 중 아래의 comment가 정답에 가까운 설명인 것 같습니다.

The issue is a mix of breakpoints in other threads on 7.1.1 with instant run on. So change any of the above 3 and it will stop crashing. – Warpzit Apr 5 '17 at 11:40 

번역을 해보면 이 문제는 아래의 3가지 조합으로 인해 발생하는 구글의 버그입니다.

  1. main thread가 아닌 다른 thread에 설정된 breakpoint가 있음
  2. instant run으로 실행됨
  3. 테스트 단말의 안드로이드 버전이 7.1.1임

문제가 되는 3가지 조합 중에서 하나라도 제거를 하면 문제가 발생하지 않는다고 합니다. 

문제를 제거하기 전에 먼저 제 경우를 확인해봤습니다.


1.theard와 breakpoint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class FragmentTest extends Fragment {
    //필요없는 코드들 생략
    private Callback insertItemCallback= new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            //생략
        }
 
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //Breakpoint 잡은 위치!
        }
    };
}
cs

위의 코드에서 보듯이 제가 Breakpoint 잡은 위치는 Callback()의 onResponse() 내부입니다. Callback은 네트워크 동작과 관련되어 있으므로 네트워크 응답을 기다리는 동안 화면이 멈추는 것을 방지하기 위해 기본 thread?가 아닌 thread에서 돌아갑니다. 그래서 저는 main thread가 아닌 다른 thread에 break point를 잡은 상태였습니다.


2.instant run

안드로이드 스튜디오 File -> Settings -> Build, Execution, Deployment -> Instant Run에서 확인 가능합니다.

위 사진에서 볼 수 있듯이 Instant Run이 켜진 상태였습니다.


3. 테스트 단말의 안드로이드 OS버전

위 사진에서 보듯이 하필이면 테스트 단말(에뮬레이터)의 안드로이드 OS버전이 7.1.1이네요.


결국 저는 위에서 말한 조합 3가지에 모두 해당하여 문제가 발생하고 있었습니다.

해결방법

이 문제(구글의 버그)는 3가지 문제의 조합으로 발생하기에 3가지 중에 하나만 제거되어도 문제가 발생하지 않습니다. 특히 1번 문제의 경우 디버깅을 시작하기 전에 main thread가 아닌 다른 thread에 breakpoint가 설정되어 있을 때 발생하는 문제입니다. 그래서 Debug 'app' 버튼을 누르기 전에는 breakpoint를 제거한 다음에 디버깅으로 앱이 시작된 이후에 breakpoint를 설정하면 문제가 발생하지 않습니다. 신기하겠지만 디버깅으로 앱 시작되고 난 이후에 코드에서 breakpoint를 잡아도 브레이크포인트가 정상적으로 동작합니다!

다른 방법으로는 Instant Run을 비활성화(Disable)할 수도 있고, 테스트 단말의 안드로이드 OS버전을 7.1.1이 아닌 다른 버전으로 변경해도 될 것 같습니다.


왜 아직까지도 이런 구글 버그가 수정이 안된 것인지는 모르겠지만 포스팅은 이만 마무리합니다!



작성자

Posted by 드리머즈

관련 글

댓글 영역