Kompilasi Lua lib untuk Android - sukses, tetapi segfault aneh

Aristarhys 09/06/2012. 3 answers, 7.098 views
android android c android-ndk android-ndk lua

Maaf untuk pertanyaan panjang. Jika Anda mau, lewati bagian tentang kompilasi Lua (yang hampir oke) dan langsung ke pertanyaan terakhir.

Mari kompilasi perpustakaan Lua seperti perpustakaan statis untuk Android.

Unduh sumber terbaru dan lihat doc / readme.html - Building Lua on other systems bagian Building Lua on other systems untuk daftar file yang akan dikompilasi.

Dan tentu saja melihat makefiles - lihatlah dengan cara biasa kita harus mengatur bendera platform seperti linux, bsd dll. Tetapi tentu saja tidak ada platform Android, jadi kita punya pilihan untuk mengatur platform ke ANSI, Linux, Posix atau Generic.

First question: itu membangun ok (dengan satu pengecualian tentang llex.c yang akan saya jelaskan di bawah) bahkan tanpa bendera platform, jadi mungkin ini tidak perlu?

Saya mengatur bendera ANSI.

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := lua
LOCAL_CFLAGS    := -DLUA_ANSI
LOCAL_SRC_FILES := lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c lundump.c lvm.c lzio.c lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c
include $(BUILD_STATIC_LIBRARY) 

Application.mk

APP_MODULES := lua
APP_PLATFORM := android-8
APP_OPTIM   := release
APP_ABI := armeabi 

Dan mendapat kesalahan tentu saja

Compile thumb  : lua <= llex.c
jni/llex.c: In function 'trydecpoint':
jni/llex.c:214:18: error: 'struct lconv' has no member named 'decimal_point'


#if !defined(getlocaledecpoint)
#define getlocaledecpoint() (localeconv()->decimal_point[0]) //Missing struct member
#endif 

Fixing it in the most cheap way

#if !defined(getlocaledecpoint)
#define getlocaledecpoint() ('.') //Code-monkey style
#endif 

Ada beberapa batasan tentang locale.h di Android NDK, jadi kesalahan ini bukan yang mengejutkan.

Juga mendapat kesalahan tentang size_t, UCHAR_MAX, INT_MAX - menambahkan llimits.h include ke llex.c dan semua kesalahan hilang sekarang.

Hanya peringatan sekarang ada tentang "missing break at the end of case" dan "tidak ada pengembalian fungsi kembali non-kekosongan" di static int llex , tapi kami tidak mengacaukan kode sumber Lua lagi karena itu bukan yang penting.

Second Question: apakah saya akan ke neraka programmer untuk perbaikan cepat seperti itu?

Ambil LuaLib yang baru dipanggang di direktori obj/armeabi dan mari kita uji. Tentu saja untuk memuat skrip dari sistem file android, kita perlu menulis beberapa file loader dengan menggunakan kelas AssetManager di Java, jadi mari kita lakukan jauh sederhana dengan mendorong dan membaca lua vars global.

TestLua - Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := lua
LOCAL_SRC_FILES := liblua.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lua-inc //Where .h files from lua src stored
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := LuaLibTest
LOCAL_STATIC_LIBRARIES:= lua
LOCAL_SRC_FILES := LuaLibTest.c
LOCAL_LDLIBS    := -llog
include $(BUILD_SHARED_LIBRARY) 

LuaLibTest.c

#include "LuaLibTest.h"
#include "lua-inc/lua.h"
#include "lua-inc/lauxlib.h"
#include #define INFO_TAG "[INFO]"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, INFO_TAG, __VA_ARGS__)

 JNIEXPORT void JNICALL Java_com_lualib_test_NativeLib_testLua(JNIEnv* env, jclass _class)
{
 LOGI("HI FROM C");
 lua_State* L = luaL_newstate();
 luaL_openlibs(L);
 lua_pushstring(L, "Some string from Android C" );
 lua_setglobal(L, "TEST" );
 lua_getglobal(L, "TEST" );
 const char* res = lua_tostring(L, lua_gettop(L));
 LOGI("LUA TEST VAL: %s", res);
 lua_pop(L, 1);
 lua_close(L);
} 

Result

Ini juga berfungsi jika kita membaca file skrip dengan AssetManager dan memasukkannya ke string yang dimasukkan ke lual_dostring() . Jadi ya, kami membangun lua untuk Android (kecuali fungsi lua i / o, yang tidak akan berfungsi, karena stdio seperti printf tidak berfungsi di Android NDK).

Namun, build ini memiliki kesalahan aneh, misalnya - fps skrip memperbarui setiap bingkai, tetapi dapat jatuh kapan saja dengan kesalahan berikutnya pada fungsi pembaruan fps dengan waktu delta bingkai

FPS.lua

FPS = {}

function initFPS()
FPS.fps = 0
FPS.last_fps = 0
FPS.frames_count = 0
FPS.frames_time = 0.0
local fps_msg = "FPS: " .. FPS.fps
c_set_fps(fps_msg);//Set some label in app - c function
end

function updateFPS(frameDeltaTime)
FPS.frames_count = FPS.frames_count + 1
FPS.frames_time = FPS.frames_time + frameDeltaTime
if FPS.frames_time >= 1000.0
then
    FPS.frames_time = 0.0;
    FPS.fps = FPS.frames_count;
    FPS.frames_count = 0;
    if FPS.last_fps ~= FPS.fps
    then
        local fps_msg = "FPS: " .. FPS.fps
        c_set_fps(fps_msg);
        FPS.last_fps = FPS.fps
    end
end
end 

FPS.c

void update_fps(const double* frame_delta_time) //SEGFAULT at this, at random time
 {
  lua_State* l = get_lua();
  lua_getglobal(l, "updateFPS");
  lua_pushnumber(l, *frame_delta_time);
  lua_call(l, 1, 0);
 } 

Dan dapatkan pesan kesalahan berikutnya dengan seluruh aplikasi macet secara acak (1 menit - 3 menit)
Pesan kesalahan

Pertanyaan terakhir (yay, Anda berhasil / melewati bagian membosankan)
Mengapa saya mendapatkan segfault, mengapa pada waktu acak? Skrip FPS hanyalah contoh, paling-paling setiap skrip lua saya memiliki kesempatan untuk menabrak seluruh aplikasi (lebih banyak panggilan == kesempatan lebih baik). Jadi beberapa skrip pemain yang mengubah dirnya pada crash pos baru kadang-kadang juga.

Saya pikir itu karena konflik pembersih sampah Android / Java dan pembersih sampah Lua, jadi ada yang mencoba untuk membebaskan memori yang sudah bebas.

EDIT - DARI SANA POINTER GANDA DATANG DAN MENGAPA:

#define MS_1_SEC 1000.0

 typedef struct time_manager
 {
   double _time;
   double delta_time;
 }time_manager;

 static double get_ms(s_time* time)//get time in ms
 {
  return MS_1_SEC * time->tv_sec + (double) time->tv_nsec / NS_1_SEC;
 }

 double get_time_now()
 {
 s_time time_now;
 clock_gettime(CLOCK_REALTIME, &time_now);
 return get_ms(&time_now);
 }

 void init_time_manager(time_manager* tm)
 {
 tm->_time = get_time_now();
 tm->delta_time = 0.0;
}

void update_time_manager(time_manager* tm)
{
 double time_now = get_time_now();
 tm->delta_time = time_now - tm->_time;
 tm->_time = time_now;
}


static time_manager TM;//Global static var for whole render module 

In onInit() function

init_time_manager(&TM); 

In onDraw() function

double* frame_time = &TM.delta_time;//get pointer to delta time
 update_ui(frame_time);//Pass it every function
 update_sprites(frame_time);
 update_fps(frame_time);
 ...
 draw_fps();
 update_time_manager(&TM); 

Mengapa saya menggunakan pointer untuk menggandakan bukan hanya dua kali lipat? Yah itu menghemat 4 byte menyalin (setiap pointer memiliki ukuran 4, ganda memiliki ukuran 8) param frame_delta_time untuk setiap fungsi seperti update_ui (), saya melakukan hal yang sama untuk setiap struct / jenis lebih besar dari 4 byte, const pointer bukan hanya struct x untuk akses read-only. Apakah ini buruk?

4 Comments
Michal Kottman 09/06/2012
Lebih dari masalah Lua, sepertinya Anda melewatkan sesuatu yang aneh dalam penunjuk frame_delta_time . Bagaimana Anda memanggil fungsi ini? Dari mana datangnya pointer?
Aristarhys 09/07/2012
Ditambahkan suntingan baru tentang hal itu pada akhirnya.
Michal Kottman 09/07/2012
Satu hal lagi - dari mana TM berasal? Apakah ini variabel global? Apakah itu variabel lokal di onInit ? (nah, itu tidak akan berhasil di onDraw )
Aristarhys 09/07/2012
Global static in render.c, sama di mana onInit () dan onDraw ()

3 Answers


Michael Anderson 09/06/2012.

Perubahan Anda terlihat baik dan sesuai untuk sistem Anda. Milis lua menunjukkan bahwa Anda membuat perubahan ke luaconf.h daripada llex.c ( http://lua-users.org/lists/lua-l/2012-08/msg00100.html ) tetapi seharusnya tidak masalah. banyak. (Jadi singkatnya Anda tidak akan masuk neraka untuk perubahan ini ...).

Saya menduga bahwa segfault terjadi karena beberapa jembatan C-lua Anda melakukan sesuatu yang "buruk". Tebakan saya akan menjadi semacam lua stack over / under flow, atau mengakses di luar lua stack dengan menggunakan indeks yang tidak valid. Anda mungkin dapat melacak ini jika Anda dapat membangun bagian jembatan di linux / os x dan menggunakan valgrind. (Alat serupa juga ada untuk windows, tapi saya tidak yakin tentang native to android)

3 comments
Jonas Wielicki 09/06/2012
valgrind untuk windows terdengar menarik, karena beberapa orang cenderung bertanya kepada saya apa yang harus digunakan untuk itu. Bisakah Anda memberikan tautan, bahkan jika OT?
Michael Anderson 09/07/2012
AFAIK tidak ada "valgrind for windows" - maka "alat-alat serupa ada" komentar. Alat-alat serupa adalah hal-hal seperti rational purify dan parasoft insure++ , tetapi keduanya komersial dan saya gaven't digunakan baik dalam beberapa tahun.
Jonas Wielicki 09/07/2012
Itu yang saya maksud, terima kasih.

Suge 09/05/2013.

Lihatlah ini: http://comments.gmane.org/gmane.comp.security.nmap.devel/14966

static void trydecpoint (LexState *ls, SemInfo *seminfo) {
  char old = ls->decpoint;
  ls->decpoint = '.';   //ls->decpoint = getlocaledecpoint();  // try to fix error: 'struct lconv' has no member named 'decimal_point'   -------- look at here
  buffreplace(ls, old, ls->decpoint);  /* try new decimal separator */
  if (!buff2d(ls->buff, &seminfo->r)) {
    /* format error with correct decimal point: no more options */
    buffreplace(ls, ls->decpoint, '.');  /* undo change (for error message) */
    lexerror(ls, "malformed number", TK_NUMBER);
  }
} 

Martin Gerhardy 08/05/2015.

Terkadang membantu mengkompilasi lua dengan -DLUA_USE_APICHECK . Ini akan menghasilkan beberapa pesan kesalahan, bukan segfault.


HighResolutionMusic.com - Download Hi-Res Songs

1 Martin Garrix

Yottabyte flac

Martin Garrix. 2018. Writer: Martin Garrix.
2 Dyro

Latency flac

Dyro. 2018. Writer: Martin Garrix;Dyro.
3 Martin Garrix

Access flac

Martin Garrix. 2018. Writer: Martin Garrix.
4 Alan Walker

Diamond Heart flac

Alan Walker. 2018. Writer: Alan Walker;Sophia Somajo;Mood Melodies;James Njie;Thomas Troelsen;Kristoffer Haugan;Edvard Normann;Anders Froen;Gunnar Greve;Yann Bargain;Victor Verpillat;Fredrik Borch Olsen.
5 Sia

I'm Still Here flac

Sia. 2018. Writer: Sia.
6 Bradley Cooper

Shallow flac

Bradley Cooper. 2018. Writer: Andrew Wyatt;Anthony Rossomando;Mark Ronson;Lady Gaga.
7 Cardi B

Taki Taki flac

Cardi B. 2018. Writer: Bava;Juan Vasquez;Vicente Saavedra;Jordan Thorpe;DJ Snake;Ozuna;Cardi B;Selena Gomez.
8 Blinders

Breach (Walk Alone) flac

Blinders. 2018. Writer: Dewain Whitmore;Ilsey Juber;Blinders;Martin Garrix.
9 Halsey

Without Me flac

Halsey. 2018. Writer: Halsey;Delacey;Louis Bell;Amy Allen;Justin Timberlake;Timbaland;Scott Storch.
10 Lady Gaga

I'll Never Love Again flac

Lady Gaga. 2018. Writer: Benjamin Rice;Lady Gaga.
11 Mako

Rise flac

Mako. 2018. Writer: Riot Music Team;Mako;Justin Tranter.
12 Kelsea Ballerini

This Feeling flac

Kelsea Ballerini. 2018. Writer: Andrew Taggart;Alex Pall;Emily Warren.
13 Dewain Whitmore

Burn Out flac

Dewain Whitmore. 2018. Writer: Dewain Whitmore;Ilsey Juber;Emilio Behr;Martijn Garritsen.
14 Avril Lavigne

Head Above Water flac

Avril Lavigne. 2018. Writer: Stephan Moccio;Travis Clark;Avril Lavigne.
15 Lady Gaga

Look What I Found flac

Lady Gaga. 2018. Writer: DJ White Shadow;Nick Monson;Mark Nilan Jr;Lady Gaga.
16 Billie Eilish

When The Party's Over flac

Billie Eilish. 2018. Writer: Billie Eilish;FINNEAS.
17 Bradley Cooper

Always Remember Us This Way flac

Bradley Cooper. 2018. Writer: Lady Gaga;Dave Cobb.
18 Rita Ora

Let You Love Me flac

Rita Ora. 2018. Writer: Rita Ora.
19 Diplo

Electricity flac

Diplo. 2018. Writer: Diplo;Mark Ronson;Picard Brothers;Wynter Gordon;Romy Madley Croft;Florence Welch.
20 Charli XCX

1999 flac

Charli XCX. 2018. Writer: Charli XCX;Troye Sivan;Leland;Oscar Holter;Noonie Bao.

Related questions

Hot questions

Language

Popular Tags