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中实际跑起来。



目录
相关文章
|
C++ Windows
使用 windbg gflags dumpbin 排查应用程序启动错误
使用 windbg gflags dumpbin 排查应用程序启动错误
|
5月前
|
缓存 Java
Electron V8排查问题之避免V8FatalErrorCallback崩溃问题如何解决
Electron V8排查问题之避免V8FatalErrorCallback崩溃问题如何解决
95 0
|
8月前
|
编译器 开发工具 Android开发
|
8月前
|
小程序 开发工具 Android开发
mpaas小程序问题之在x86模拟器下会打不开如何解决
mPaaS小程序是阿里巴巴移动平台服务(mPaaS)推出的一种轻量级应用解决方案,旨在帮助开发者快速构建跨平台的小程序应用;本合集将聚焦mPaaS小程序的开发流程、技术架构和最佳实践,以及如何解决开发中遇到的问题,从而助力开发者高效打造和维护小程序应用。
mpaas小程序问题之在x86模拟器下会打不开如何解决
|
缓存 Android开发 C++
[√]Android平台ParticleSystem内存泄露的排查过程
[√]Android平台ParticleSystem内存泄露的排查过程
93 1
|
NoSQL Linux
Linux下怎样使用core文件查看异常崩溃的程序问题
之前在写程序的时候,遇到了意外崩溃的问题,但是当时并没有生成core文件,想用gdb 对程序进行单步跟踪时,并不能复现。所以想要用core文件看看到底是哪里的问题,这里把问题记录下来当再次遇到时可以解决。
164 0
|
存储 缓存 开发工具
Xcode 清理大法
Xcode 清理大法
1078 0
|
监控 NoSQL Linux
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解(一)
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解
802 0
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解(一)
|
存储 NoSQL IDE
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解(三)
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解
368 0
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解(三)
|
NoSQL Shell C语言
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解(二)
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解
464 0
【五、深入浅出GDB调试器】如何修复程序bug或优化代码:gdb调试器的来龙去脉与debug全方位实战详解(二)

热门文章

最新文章