- 안영기의 개발실 -: Android 카테고리 글 목록http://smgal.ismine.net/tc_191/blog1/게임 개발을 기반으로 한, 잡다한 개발 기록 저장소2019-07-14T09:03:47+09:00Textcube 1.9.164-bit NDK에서, <dlopen failed: cannot locate symbol "__register_atfork"> 문제안영기http://smgal.ismine.net/tc_191/blog1/532019-06-27T07:10:07+09:002019-06-27T07:09:35+09:00<div style="-en-clipboard: true;">[문제의 발단]</div>
<div style="margin-left: 40px;">2019년 8월부터 구글 플레이에 올라가는 앱은 64비트를 대응해야 한다고 한다.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">지금 서비스 하고 있는 앱의 경우, 핵심 모듈은 C++로 되어 있는데 모두 몇 년 전에 만들었던 32비트 so 를 사용하고 있었다.</div>
<div style="margin-left: 40px;">그래서 예전의 C++ 소스 코드를 꺼내서 다시 64비트 so로 만드는 과정이 필요했다.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">예전에는 Eclipse에서 ndkBuild로 만들었다면, 지금은 최신 Android Studio에서 새로운 NDK 빌드 방식으로 만들어야 하는 점이 달랐는데,</div>
<div style="margin-left: 40px;">새로 NDK Makefile을 만드는 것도 우여곡절이 많았지만 그건 어쨌든 과정의 일부였고, 최종적으로는 NDK 빌드를 성공하고 64비트 so를 적용하여 테스트를 거친 뒤 public release를 했다.</div>
<div> </div>
<div>[문제의 발생]</div>
<div style="margin-left: 40px;">그런데 릴리즈가 되자마자 며칠만에 에러 보고가 날아오기 시작했는데, 다음과 같은 메시지였다.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">Fatal Exception: java.lang.UnsatisfiedLinkError</div>
<div style="margin-left: 40px;">dlopen failed: cannot locate symbol "__register_atfork" referenced by "lib*****.so"...</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">java.lang.Runtime.loadLibrary (Runtime.java:372)</div>
<div style="margin-left: 40px;">java.lang.System.loadLibrary (System.java:988)</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">JNI 연결을 위해 so를 읽는 과정에서 특정 내부 함수를 찾을 수 없다는 에러이다.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">한국의 메이저 안드로이드 제조사 것은 문제가 없어서 자체 테스트에서는 발견이 안 되었던 것이고, 화웨이, OPPO, HTC, ZET 등의 기기에서도 OS 5 버전에서만 문제가 발생했다.</div>
<div> </div>
<div>[문제의 원인]</div>
<div style="margin-left: 40px;">위의 에러 상황으로 검색을 해보니, 이런 버그 레포트가 올라왔고</div>
<div style="margin-left: 40px;"><a href="https://android-review.googlesource.com/c/platform/bionic/+/948880">https://android-review.googlesource.com/c/platform/bionic/+/948880</a></div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">최종 review confirm된 코드의 diff를 보면 다음과 같은 내용의 추가로 문제를 해결을 하였다.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">## `__register_atfork` (Available in API level >= 23)</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">To allow `atfork` and `pthread_atfork` handlers to be unregistered on</div>
<div style="margin-left: 40px;">`dlclose`, the implementation changed in API level 23. Unfortunately this</div>
<div style="margin-left: 40px;">requires a new libc function `__register_atfork`. Code using these functions</div>
<div style="margin-left: 40px;">that is built with a target API level >= 23 therefore will not load on earlier</div>
<div style="margin-left: 40px;">versions of Android, with an error referencing `__register_atfork`.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">*Resolution*: build your code with an NDK target API level that matches your</div>
<div style="margin-left: 40px;">app's minimum API level, or avoid using `atfork`/`pthread_atfork`.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">위의 패치의 결과로, 공식 매뉴얼에서 다음과 같이 추가되었으며 (글 중간에 있음)</div>
<div style="margin-left: 40px;"><a href="https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md">https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md</a></div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">
<div>결론적으로는, 앱의 minSDK API level과 NDK의 minSDK API level이 다른 것이 문제로 보였다.</div>
<div>API level 23 이후로 내부 standard so에 저러한 것들이 많이 추가가 된 모양이다.</div>
</div>
<div> </div>
<div>[문제의 해결]</div>
<div style="margin-left: 40px;">앱은 원래부터 minSDK를 19로 지정하고 있었지만, NDK는 이번에 발드를 위해 새로 프로젝트를 만드는 바람에 minSDK 는 현재 가장 높은 버전인 28로 맞춰져 있었다,'</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">그래서 NDK 빌드를 위한 프로젝트에서 app/build.gradle 를 android:defaultConfig:minSdkVersion : 28 -> 19 로 수정하여 빌드를 하였고 문제가 해결된 것을 nm으로 확인할 수 있었다.</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;"><minSdkVersion 28일 때></div>
<div style="margin-left: 40px;">00000000001285f8 A __end__</div>
<div style="margin-left: 40px;"> U __errno</div>
<div style="margin-left: 40px;"> U __register_atfork <- 여기</div>
<div style="margin-left: 40px;"> U __stack_chk_fail</div>
<div style="margin-left: 40px;">00000000001285f8 A _bss_end__</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;"><minSdkVersion 19일 때></div>
<div style="margin-left: 40px;">00000000001295f8 A __end__</div>
<div style="margin-left: 40px;"> U __errno</div>
<div style="margin-left: 40px;"> U __sF</div>
<div style="margin-left: 40px;"> U __stack_chk_fail</div>
<div style="margin-left: 40px;">00000000001295f8 A _bss_end__</div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;"> </div>
<div style="margin-left: 40px;">arm64와 x64 모두 동일하게 문제의 심볼인 '_register_atfork' 의 dynamic refrence가 사라진 것을 확인 하였다.</div><p><strong><a href="http://smgal.ismine.net/tc_191/blog1/53?commentInput=true#entry53WriteComment">댓글 쓰기</a></strong></p>동급생2 맵출력 샘플 (android ver.)안영기http://smgal.ismine.net/tc_191/blog1/442012-11-18T07:01:57+09:002012-11-18T06:56:37+09:00<div>이전에 bada로 만든 것을 동일한 소스를 이용해 Android에서 구동하게 만들었다.</div><div><br></div><div>android-ndk-r8b 에서 테스트 되었으며 일반적인 NDK 샘플인 것처럼 import 를 하면 된다.</div><div><br></div><div><br></div><div><font color="#009966">- 게임은 1995~6년도의 원작의 resource를 그대로 사용</font></div><div><font color="#ff3399"><b> (ELF사에 저작권이 있는 부분입임)</b></font></div><div><font color="#009966">- 당시 4-bit용 게임이었으므로 GetCanvasN()의 포맷인 ARGB8888로 리소스를 변경</font></div><div><font color="#009966">- 터치 입력을 추가, 스크린의 4 방향의 가장자리를 누르면 유이가 움직임</font><br></div><div><br></div><div><div style="text-align: center;"><div class="imageblock center" style="text-align: center; clear: both;"><a class="extensionIcon" href="http://smgal.ismine.net/tc_191/blog1/attachment/1504862495.zip"><img src="http://smgal.ismine.net/tc_191/resources/image/extension/zip.gif" alt="" /> com.avej.dokyusei2.Dokyusei2.zip</a></div></div><div style="text-align: center;">Android용 동급생 2 맵 출력 샘플 (182K)</div></div><p><strong><a href="http://smgal.ismine.net/tc_191/blog1/44?commentInput=true#entry44WriteComment">댓글 쓰기</a></strong></p>OpenGL ES 2.0 샘플 (Android ver.)안영기http://smgal.ismine.net/tc_191/blog1/372011-12-01T23:17:16+09:002011-12-01T23:04:34+09:00원래는 Android용 게임을 만들어 보려고 OpenGL Es 2.0을 이용하여 3D 및 스프라이트 등을 출력하는 기본 라이브러리를 만들고 있었다. 그렇게 시작한 것이 벌써 1년이 지났다.<div><br></div><div>하지만 시간에 쫓기다 보니 우선 순위에서 계속 밀리게 되었고 자칫하다가는 영원히 Android용 게임은 완성되지 않은 채로 프로젝트가 끝나지 않을까 하는 우려까지 하고 있다. 여전히 Android용 게임 제작은 전체 우선 순위에서 밀리고 있고<font color="#c1c1c1">(Java에 익숙하지 않은 탓과 Java로는 개인 라이브러리가 구축된 것이 없다는 것이 가장 큰 걸림돌이다)</font> 끝까지 성공해낼 확률은 꽤 낮은 편이다.</div><div><br></div><div>이것은 가장 초기에 만들었던 출력 테스트 샘플이다. Cube가 제대로 도는지 확인 해본 것이고 shader로 vertex, diffuse color, texture 출력까지 만들어 본 것이다. 간단한 터치도 테스트 해보기 위해 터치를 한 위치에 cube가 돈다.</div><div><br></div><div><div class="imageblock center" style="text-align: center; clear: both;"><img src="http://smgal.ismine.net/tc_191/attach/1/2143616241.png" alt="사용자 삽입 이미지" height="422" width="450" /></div><div class="imageblock center" style="text-align: center; clear: both;"><a class="extensionIcon" href="http://avej.com/tc_191/blog1/attachment/1706623564.zip"><img src="http://smgal.ismine.net/tc_191/resources/image/extension/zip.gif" alt="" /> CubeSampleViewActivity.zip</a></div><div style="text-align: center;">Android용 OpenGL ES 2.0 출력 샘플 (44K)</div></div><div><br></div><div><font color="#008000">프로젝트가 1.5 이상용인데, 너무 구형 프로젝트인지 실제로 import를 해보면 프로젝트 파일 관련 에러가 난다. 에러가 난 메시지로 구글에 검색해보면 프로젝트 파일 고치는 법이 나오는데, 그 방법을 써서 수정하면 된다.</font></div><p><strong><a href="http://smgal.ismine.net/tc_191/blog1/37?commentInput=true#entry37WriteComment">댓글 쓰기</a></strong></p>