问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

使用Visual Studio和LuaDkmDebugger调试Lua脚本

创作时间:
作者:
@小白创作中心

使用Visual Studio和LuaDkmDebugger调试Lua脚本

引用
1
来源
1.
https://www.cswamp.com/post/69

本文介绍了一种在Windows环境下使用Visual Studio和LuaDkmDebugger插件调试Lua脚本的方法。通过这种方法,开发者可以同时查看Lua变量和C变量,极大地提高了调试效率。文章详细介绍了安装步骤、使用方法以及插件存在的缺陷,并提供了相应的解决方案。

一、安装Visual Studio和LuaDkmDebugger

使用这种方法需要在Windows环境下进行,基于Visual Studio平台。在安装Visual Studio时,只需要安装与C/C++相关的基础模块即可。建议使用较新版本的Visual Studio,最低版本要求为2019(Version 16.10.2)。

LuaDkmDebugger是一个开源的Visual Studio插件,它能够帮助开发者调试运行在C++应用程序中的Lua脚本。要安装该插件,可以通过Visual Studio的扩展管理功能进行:

  1. 打开Visual Studio
  2. 进入"Extensions"菜单
  3. 选择"Manage Extensions"
  4. 在扩展管理器中搜索并安装LuaDkmDebugger

安装完成后,你就可以开始使用LuaDkmDebugger进行调试了。下图展示了如何在变量区域查看Lua变量:

在变量区域,还可以查看两个特殊的变量:注册表“[registry]”和环境“_ENV”。

二、LuaDkmDebugger存在的缺陷

2.1 无法在*.lua文件内灵活设置断点

LuaDkmDebugger的官方文档提到,可以通过lua_dkm_debug.json文件在*.lua文件内设置断点。然而,实际使用中发现这种方法并不稳定,偶尔可以成功,但更多时候会失败。

为了解决这个问题,建议采用另一种方法:编写一个可以被*.lua调用的C函数,在该函数内设置断点。当需要查看*.lua中的变量时,调用这个函数即可。例如:

static int intf_breakpoint(lua_State* L)
{
    SDL_Log("for debug. app can insert breakpoint at this line");
    return 0;
}

在调试时,可以在rose.cpp_breakpoint()函数中设置断点,然后通过“Call Stack”切换到查看*.lua文件。

2.2 启用LuaDkmDebugger后,某些Lua库函数无法进入断点

启用LuaDkmDebugger后,可能会遇到一些Lua库函数无法正常进入断点的情况。例如,在lvm.c文件内的luaV_execute函数中设置断点时,程序可能会在*.lua的某个地方停止,而不是在你设置的语句处停止。

这种问题通常发生在靠近执行*.lua代码的C代码处。如果需要深入理解luaV_execute的执行逻辑,建议先禁用LuaDkmDebugger。

LuaDkmDebugger虽然解决了实时查看Lua脚本变量的需求,但对于Lua的语法错误问题,它就无能为力了。

三、定位*.lua脚本语法错误

编写Lua脚本时难免会遇到语法错误,因此需要一种快速定位错误位置并了解错误原因的方法。Lua内部有一套错误上报机制,但需要调用Lua框架的配合。

3.1 lua_kernel_base::protected_call

Rose实现了一套基于Lua的错误处理机制,目前还在不断完善中。为了快速定位语法错误,建议在lua_kernel_base::protected_call函数内设置断点。此时,msg变量会指示错误发生的位置和具体错误信息。

3.2 luaB_assert:查看assert诊断时的变量值

在Lua代码中,经常会使用assert语句进行条件检查:

-- assert(诊断)
assert(minor == this.WHEELTEC_MINOR_BOX);

当assert语句返回false时,会在"3.1 lua_kernel_base::protected_call"处触发断点,此时msg变量会显示类似下面的错误信息:

lua/home.lua:208: assertion failed!
stack traceback:
 [C]: in function '.assert'
 lua/home.lua:208: in field 'pre_base_wheeltec'
 lua/home.lua:171: in field 'pre_driver'
 lua/home.lua:71: in function <lua/home.lua:55>

通过msg变量,可以定位出哪条assert语句出错,但无法第一时间知道assert语句中变量的具体值。例如,上面的"minor"变量。有些assert错误可能较难复现,因此第一时间知道变量值就变得非常重要。

这时,可以在luaB_assert函数处设置断点。这个断点会先于"3.1 lua_kernel_base::protected_call"触发。通过"Call Stack"切换到"lua_vm!@lua/home.lua ..."处,就可以查看变量"minor"的具体值。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号