Android平台使用SFML触发SIGSEGV崩溃的解决方法
问题
我开发了一款基于SFML的游戏,PC端运行正常,现在计划移植到Android平台。编译构建都成功了,但把生成的APK安装到运行LineageOS 14.1的三星S5 Exynos设备上测试时,出现了如下报错:
12-02 13:20:51.953 24780 24780 E libEGL : validate_display:101 error 3001 (EGL_NOT_INITIALIZED) 12-02 13:20:51.954 24780 24780 E libEGL : validate_display:99 error 3008 (EGL_BAD_DISPLAY) 12-02 13:20:51.954 24780 24780 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x24 in tid 24780 (ames.cyberchess) 12-02 13:20:51.955 3600 3600 W : debuggerd: handling request: pid=24780 uid=10081 gid=10081 tid=24780 12-02 13:20:52.034 23099 24195 I Icing : Usage reports ok 1, Failed Usage reports 0, indexed 0, rejected 0 12-02 13:20:52.057 23099 23127 I Icing : IndexChimeraService.getServiceInterface callingPackage=com.google.android.gms componentName=null serviceId=30 12-02 13:20:52.074 24805 24805 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 12-02 13:20:52.074 24805 24805 F DEBUG : LineageOS Version: '14.1-20181109-NIGHTLY-k3gxx' 12-02 13:20:52.074 24805 24805 F DEBUG : Build fingerprint: 'samsung/k3gxx/k3g:6.0.1/MMB29K/G900HXXU1CPF2:user/release-keys' 12-02 13:20:52.074 24805 24805 F DEBUG : Revision: '0' 12-02 13:20:52.074 24805 24805 F DEBUG : ABI: 'arm' 12-02 13:20:52.075 24805 24805 F DEBUG : pid: 24780, tid: 24780, name: ames.cyberchess >>> com.cyberdaystudio.games.cyberchess <<< 12-02 13:20:52.075 24805 24805 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x24 12-02 13:20:52.075 24805 24805 F DEBUG : r0 00000024 r1 00000024 r2 00000000 r3 7ffffff8 12-02 13:20:52.075 24805 24805 F DEBUG : r4 bed4c3d8 r5 00000000 r6 00000000 r7 bed4c3d0 12-02 13:20:52.075 24805 24805 F DEBUG : r8 00000000 r9 b4284f38 sl b2d17950 fp bed4c6d8 12-02 13:20:52.075 24805 24805 F DEBUG : ip b2cf9888 sp bed4c3c8 lr b2c7f153 pc b2c7f1ae cpsr 60070030 12-02 13:20:52.094 24805 24805 F DEBUG : 12-02 13:20:52.094 24805 24805 F DEBUG : backtrace: 12-02 13:20:52.094 24805 24805 F DEBUG : #00 pc 000451ae /data/app/com.cyberdaystudio.games.cyberchess-1/lib/arm/libsfml-system.so (_ZN2sf5MutexD2Ev+21) 12-02 13:20:52.094 24805 24805 F DEBUG : #01 pc 0004514f /data/app/com.cyberdaystudio.games.cyberchess-1/lib/arm/libsfml-system.so (_ZN2sf4LockC2ERNS_5MutexE+10) 12-02 13:20:52.094 24805 24805 F DEBUG : #02 pc 0000c5f5 /data/app/com.cyberdaystudio.games.cyberchess-1/lib/arm/libsfml-window.so (_ZN2sf4priv10EglContextC1EPS1_+84) 12-02 13:20:52.094 24805 24805 F DEBUG : #03 pc 00006eff /data/app/com.cyberdaystudio.games.cyberchess-1/lib/arm/libsfml-window.so (_ZN2sf4priv9GlContext12initResourceEv+94) 12-02 13:20:52.094 24805 24805 F DEBUG : #04 pc 00008d17 /data/app/com.cyberdaystudio.games.cyberchess-1/lib/arm/libsfml-window.so (_ZN2sf10GlResourceC1Ev+6) 12-02 13:20:52.094 24805 24805 F DEBUG : #05 pc 00049a99 /data/app/com.cyberdaystudio.games.cyberchess-1/lib/arm/libsfml-graphics.so (_ZN2sf7TextureC2Ev+24) 12-02 13:20:52.094 24805 24805 F DEBUG : #06 pc 0000791c /data/app/com.cyberdaystudio.games.cyberchess-1/lib/arm/libcyberchess.so (offset 0xa000) 12-02 13:20:52.182 23099 24195 I Icing : Usage reports ok 0, Failed Usage reports 0, indexed 0, rejected 0 12-02 13:20:52.223 23099 24195 I Icing : Indexing com.google.android.gms-apps from com.google.android.gms 12-02 13:20:52.285 23099 24195 I Icing : Indexing done com.google.android.gms-apps 12-02 13:20:52.289 23099 24195 I Icing : Indexing com.google.android.gms-apps from com.google.android.gms 12-02 13:20:52.293 23099 24195 I Icing : Indexing done com.google.android.gms-apps 12-02 13:20:52.738 24780 24780 W ames.cyberchess: type=1701 audit(0.0:1358): auid=4294967295 uid=10081 gid=10081 ses=4294967295 subj=u:r:untrusted_app:s0:c512,c768 reason="memory violation" sig=11 12-02 13:20:52.747 3600 3600 W : debuggerd: resuming target 24780 12-02 13:20:52.749 4145 24815 W ActivityManager: Force finishing activity com.cyberdaystudio.games.cyberchess/.MainActivity
我写了简化的测试代码,还是出现同样错误:
main.cpp
#include "main_point.h" void ShowWindow() { sf::VideoMode screen(sf::VideoMode::getDesktopMode()); sf::RenderWindow window(screen, ""); window.setFramerateLimit(30); }
main_point.h
// SFML Library include #include <SFML/Window.hpp> #include <SFML/Graphics.hpp> #include <SFML/Audio.hpp> #include <SFML/Network.hpp> void ShowWindow();
jni.cpp
#include <jni.h> #include "main_point.h" extern "C" { void Java_com_cyberdaystudio_games_cyberchess_MainActivity_showWindow(JNIEnv *env, jclass clazz) { ShowWindow(); } }
AndroidManifest.xml
<?xml version='1.0'?> <manifest xmlns:a='http://schemas.android.com/apk/res/android' package='com.cyberdaystudio.games.cyberchess' a:versionCode='0' a:versionName='0'> <uses-sdk a:minSdkVersion="21" a:targetSdkVersion="34"/> <application a:label="CyberChess"> <activity a:name='com.cyberdaystudio.games.cyberchess.MainActivity' a:exported="true"> <intent-filter> <category a:name='android.intent.category.LAUNCHER'/> <action a:name='android.intent.action.MAIN'/> </intent-filter> </activity> </application> </manifest>
MainActivity.java
package com.cyberdaystudio.games.cyberchess; import android.app.Activity; import java.lang.System; import android.os.Bundle; public class MainActivity extends Activity { // do nothing, successfully String[] libs = { "c++_shared", "sfml-activity", "sfml-audio", "sfml-graphics", "sfml-network", "sfml-system", "sfml-window", "openal", "cyberchess" }; private static native void showWindow(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); for (String lib : libs) { System.loadLibrary(lib); } showWindow(); } }
我的主机环境:
# ANDROID BUILD_TOOLS=/mnt/Linux/build-tools/34.0.0 ANDROID_PLATFORM=/mnt/Linux/platforms/android-34 ANDROID_NDK=/mnt/Linux/ndk/26.1.10909125
主机系统:
Linux duythanh-VivoBook-ASUSLaptop-X409FA-X409FA 6.2.0-37-generic #38~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Thu Nov 2 18:01:13 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
从回溯信息看,崩溃发生在SFML销毁sf::Mutex对象时,我试过克隆SFML官方仓库切换到2.6.x分支重新构建,问题依旧。怎么让SFML在Android平台正常工作?
解决方案
1. 修正SFML Android初始化流程
Android平台下SFML不能直接像PC那样创建RenderWindow,必须依赖SFMLActivity提供的上下文,否则EGL无法正确初始化。修改MainActivity继承SFMLActivity而非普通Activity:
package com.cyberdaystudio.games.cyberchess; import org.sfml.graphics.RenderWindow; import org.sfml.system.Vector2i; import org.sfml.window.VideoMode; import org.sfml.window.WindowStyle; import android.os.Bundle; import com.sfml.android.SFMLActivity; public class MainActivity extends SFMLActivity { private RenderWindow mWindow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void onCreateView() { // 使用SFMLActivity提供的窗口上下文创建RenderWindow VideoMode mode = new VideoMode(getWindowManager().getDefaultDisplay().getWidth(), getWindowManager().getDefaultDisplay().getHeight()); mWindow = new RenderWindow(mode, "CyberChess", WindowStyle.DEFAULT, getContext()); mWindow.setFramerateLimit(30); } @Override protected void onRender() { if (mWindow != null) { mWindow.clear(); // 这里添加你的渲染逻辑 mWindow.display(); } } @Override protected void onDestroyView() { if (mWindow != null) { mWindow.close(); mWindow = null; } } }
2. 调整SFML库加载顺序
SFML的依赖库有严格加载顺序,当前的加载顺序错误,导致初始化时依赖缺失。修正libs数组顺序为:
String[] libs = { "c++_shared", "openal", "sfml-system", "sfml-window", "sfml-graphics", "sfml-audio", "sfml-network", "sfml-activity", "cyberchess" };
3. 适配Android API级别与NDK版本
你的设备运行Android 6.0(API 23),但编译用的是API 34和NDK 26,高版本NDK对旧Android版本兼容性差,建议:
- 将
ANDROID_PLATFORM改为android-23 - 使用NDK 21(LTS版本),对旧设备兼容性更好
4. 检查SFML构建配置
构建SFML for Android时,确保开启以下选项:
SFML_BUILD_ANDROID_ACTIVITY=ONSFML_USE_ANDROID_WINDOW=ON- 针对
armeabi-v7a架构构建(你的设备ABI是arm,对应armeabi-v7a)
5. 避免在JNI直接初始化SFML资源
不要在onCreate中直接调用JNI创建窗口,而是通过SFMLActivity的生命周期回调(onCreateView、onRender)来管理窗口和资源,确保EGL上下文正确绑定。
内容的提问来源于stack exchange,提问作者duckk404
相关产品推荐
相关产品推荐

