bugly崩溃排查2:luajit编译调试

简介: bugly崩溃排查2:luajit编译调试

luajit是什么

简单说,是lua语言的另一个实现版本,唯一区别的是,加入了jit功能。

JIT是just in time的缩写,也就是即时编译。

编译luajit

前置说明

luac文件是加密后的代码,并不是luac的代码才会在luajit模式下运行,加密和luajit是2个任何不相关的东西,不要混淆,这是一个理解的误区。

如果使用了luajit的库,那么lua代码才会在luajit模式下运行,因为luajit编译出来的是lua51.dll,和lua官方编译出来的文件名是一致的。

代码是在luajit的情况下崩溃的,所以必须让项目的lua代码运行在luajit模式下,为了方便测试,我选择了使用win32进行编译测试。

win32编译

luajit的win32编译非常简单,作者已经帮我们写好了bat编译脚本,切换到Visual Studio Command Prompt


image.png



输入msvcbuild.bat很顺利就在当前目录下生成了lua51.lib

msvcbuild.bat的解读

不使用msvcbuid.bat,自己搭建luajit的vs项目,这篇文章可以参考,编译脚本我们还是需要好好理解下,有助于我们了解更多的细节。

  1. 先编译了minilua.c,链接生成了minilua.exe


cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE 
    /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline 
    host\minilua.c
link /nologo /out:minilua.exe minilua.obj
  1. 生成src/host/buildvm_arch.h,host/.gitignore里面忽略了这个文件,也印证了这个文件是需要动态生成的
  2. 复制代码
minilua ..\dynasm\dynasm.lua -LN -D WIN -D JIT -D FFI -o host\buildvm_arch.h vm_x86.dasc

image.png

  1. 编译buildVM相关的源码,生成buildVM.exe,这里用到了上一步生成的buildvm_arch.h文件,不过对于cmake来说,它只关心c文件,不会影响cmake的编写


cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline /arch:SSE2 /I "." /I ..\dynasm host\buildvm*.c
link /nologo /out:buildvm.exe buildvm*.obj
  1. 使用buldVM.exe,生成了一些中间文件有obj.h.lua,也就是-o参数后边的文件
buildvm -m peobj   -o lj_vm.obj
buildvm -m bcdef   -o lj_bcdef.h    lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
buildvm -m ffdef   -o lj_ffdef.h    lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
buildvm -m libdef  -o lj_libdef.h   lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
buildvm -m recdef  -o lj_recdef.h   lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
buildvm -m vmdef   -o jit\vmdef.lua lib_base.c lib_math.c lib_bit.c lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c lib_jit.c lib_ffi.c lib_buffer.c
buildvm -m folddef -o lj_folddef.h  lj_opt_fold.c
  1. 编译lj_\*.clib_\*.c,链接生成lua51.dll,最关键的一步之前的所有准备都是为这一步准备的
cl  /nologo /c /O2 /W3 
    /D_CRT_SECURE_NO_DEPRECATE 
    /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline 
    /arch:SSE2 /MD /DLUA_BUILD_AS_DLL 
    lj_*.c 
    lib_*.c
link /nologo /release /DLL /out:lua51.dll lj_*.obj lib_*.obj
1. 编译luajit.c,链接生成luajit.exe
2. bash
3. 复制代码
cl /nologo /c /O2 /W3 /D_CRT_SECURE_NO_DEPRECATE /D_CRT_STDIO_INLINE=__declspec(dllexport)__inline /arch:SSE2 luajit.c
link /nologo /release /out:luajit.exe luajit.obj lua51.lib
  1. 最后就是一些清理工作了,至此生成的文件为lua51.lib lua51.dll luajit.exe

编译luajit可能遇到的报错

手动搭建vs项目编译luajit时,你一定会遇到这个问题:


2>lib_jit.obj : error LNK2019: 无法解析的外部符号 _lj_vm_cpuid,函数 _jit_cpudetect 中引用了该符号
2>lib_math.obj : error LNK2019: 无法解析的外部符号 _lj_vm_floor,函数 _random_seed 中引用了该符号
2>lj_vmmath.obj : error LNK2001: 无法解析的外部符号 _lj_vm_floor

lj_vm_xx好多函数都是在lj_vm.h中定义的,发现的确是没有lj_vm_cpuid的实现,luajit快的一个原因就是lj_vm_xx之类的函数都是用反汇编实现的,这也导致你就没有办法通过vs进行完整的编译luajit,只能通过官方提供的msvcbuild.bat进行编译。

调试luajit的解决办法

通过msvcbuild.bat编译出来debug版本,然后将lua51.dlllua51.liblua51.pdb(这个非常重要,能够调试跳转到源码全部靠他)文件提供给exe使用,最后是勉强跑起来了

命令参数debug无法通过cmake设置,只能自己手动设置了

image.png



现在也能跳转到lua_cpcall了,但是像lj_vm_cpcall这个就无法跳转了,只能从堆栈中查看反汇编看到的结果:


image.png

image.png


不过经过这番折腾,勉强可以跑起来了luajit,并且在对应的源码位置打断点,是可以进行调试的

尝试触发lj_meta_chach

image.png

简单测试了下,目前发现调用该函数是在lua_close的时候,游戏关闭或者被强行退出,也会有可能触发该函数,但是崩溃就有点无法理解了

也有可能是lua gc触发的,也有可能是我的lua脚本太简单,看来还是需要放到项目中进行验证。

至此,我们已经大致了解编译调试luajit的办法了,下一步就是放到cocos2dx中实际跑起来。



目录
相关文章
深入分析luait反编译之luajit-decomp
#背景 Luajit在游戏中应用广泛,在逆向分析游戏过程中免不了与luajit打交道,那网上有非常多关于luajit反编译的资料,汇总起来常用的两种方案:https://github.com/zzwlpx/ljd 和 https://github.com/bobsayshilol/luajit-decomp, 第一种方案相对来说可读性好但兼容性差经常出现反编译异常崩溃。第二种方案反编译
8046 0
|
存储 移动开发 数据安全/隐私保护
高效反编译luac文件
高效反编译luac文件
|
Ubuntu Linux 编译器
openssl 的编译(linux、Ubuntu) 和 交叉编译(arm、Hi3531A)的问题分析、解决
openssl 的编译(linux、Ubuntu) 和 交叉编译(arm、Hi3531A)的问题分析、解决
2727 0
|
4月前
|
机器学习/深度学习 分布式计算 算法
规则引擎开发现在已经演化成算法引擎了
规则引擎是一种基于专家知识的程序,用于解决复杂决策问题。它通过条件与动作的匹配,实现自动化判断,广泛应用于金融、电商等领域。核心功能包括规则管理、推理算法(如Rete算法)及决策模型,如DMN标准,提升了建模能力与执行效率。
|
10月前
|
安全 Unix Linux
VMware Workstation 17.6.3 发布下载,现在完全免费无论个人还是商业用途
VMware Workstation 17.6.3 发布下载,现在完全免费无论个人还是商业用途
84517 65
|
12月前
|
Java Linux iOS开发
如何配置 Java 环境变量:设置 JAVA_HOME 和 PATH
本文详细介绍如何在Windows和Linux/macOS系统上配置Java环境变量。
14181 12
|
12月前
|
SQL Java 数据库连接
如何在 Java 代码中使用 JSqlParser 解析复杂的 SQL 语句?
大家好,我是 V 哥。JSqlParser 是一个用于解析 SQL 语句的 Java 库,可将 SQL 解析为 Java 对象树,支持多种 SQL 类型(如 `SELECT`、`INSERT` 等)。它适用于 SQL 分析、修改、生成和验证等场景。通过 Maven 或 Gradle 安装后,可以方便地在 Java 代码中使用。
3687 11
|
JSON Ubuntu Linux
LuaJit交叉编译移植到ARM Linux
LuaJit交叉编译移植到ARM Linux
503 1
|
数据采集 网络协议 开发者
工业自动化领域常见的通讯协议
工业自动化领域常见的通讯协议
1654 1
|
Linux
CentOS7.8和CentOS7.9的区别
【4月更文挑战第14天】CentOS7.8和CentOS7.9的区别
1694 2