Lua: 错误处理与调试技术详解之从基础到EmmyLua高级调试

【Emmylua】lua的debug无效果connect localhost:9966 ... Connection refused: connect,pycharm使用Emmylua无法连接 Try connect localhost:9966 ... Connection refused: connect unity执行了,就会把端口占用掉,所以pycharm的debug那里就会断开了。然后打开的时候没注意,unity开启了A工程文件,pycharm开启了B工程文件。你可能会注意到每次播放unity的时候,debug工具都会自动断开一次连接。我赶紧改成unity开启了A工程文件, 阅读详情

错误处理机制详解


基础错误处理函数

函数用途示例代码
error(message [, level])抛出错误error(“发生错误”)
assert(value [, message])断言检查assert(type(x) == “number”, “x必须是数字”)
pcall(function, …)保护调用local ok, result = pcall(myFunction)
xpcall(function, errhandler)带错误处理器的保护调用xpcall(myFunc, debug.traceback)

Lua错误处理机制


1 ) 常见错误类型

  • 索引nil值:local t = nil; print(t.key)
  • 对nil运算:local a = nil; print(a + 1)

语法错误:函数/表定义不完整

--- 示例:调用nil函数 
local func = nil 
func()  -- 报错:attempt to call a nil value 

2 ) 错误捕获函数

pcall:保护模式调用,返回状态码和结果
xpcall:可附加错误处理函数(搜索结果显示为最佳实践)

function risky_func()
  error("Intentional error!")
end 
--- pcall示例 
local success, result = pcall(risky_func)
if not success then
  print("PCaught error:", result)
end
--- xpcall示例(含错误处理)
local function error_handler(err)
  print("XPCaught error:", debug.traceback(err))
end
xpcall(riskyfunc, errorhandler)

3 ) 断言与错误日志

assert(type(input) == "number", "Input must be a number")

错误处理最佳实践

--- 1. 使用pcall安全调用可能出错的函数
local function safeDivide(a, b)
    if b == 0 then 
        error("除数不能为零")
    end
    return a / b
end
 
local success, result = pcall(safeDivide, 10, 0)
if not success then
    print("错误:", result)  -- 输出: 错误: 除数不能为零
end

--- 2. 使用xpcall获取完整的错误堆栈 
local function divide(a, b)
    return a / b
end
 
local success, result = xpcall(function()
    return divide(10, 0)
end, debug.traceback)
 
if not success then 
    print("完整错误信息:", result)  -- 包含完整的调用堆栈 
end

调试工具:EmmyLua深度指南


1 ) 环境配置

VSCode安装:扩展市场搜索安装EmmyLua插件

2 ) 调试配置(launch.json)

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "emmylua_new",
      "request": "launch",
      "name": "EmmyLua Debug",
      "host": "localhost",
      "port": 8866,
      "ideConnectDebugger": false,
      "stopOnEntry": false
    }
  ]
}

3 ) 调试流程

主要参考 vscode EmmyLua 插件文档

4 ) 高级调试技巧

条件断点:右键断点设置触发条件
协程调试:EmmyLua支持协程堆栈跟踪
远程调试(OpenWrt示例)

dbg.tcpConnect("192.168.3.3", 9966)  -- 连接远程IDE 

完整调试示例代码

--- debug_example.lua - 完整调试示例
local DebugExample = {}
--- 模拟可能出错的函数 
function DebugExample.processData(data)
    --- 设置断点1: 检查输入数据
    if not data or type(data) ~= "table" then
        error("数据格式错误: 期望table类型")
    end
    
    local result = {}
    for i, v in ipairs(data) do
        --- 设置断点2: 处理每个元素
        if type(v) == "number" then
            table.insert(result, v * 2)
        else
            --- 设置断点3: 处理非数字类型
            print("警告: 非数字类型", v)
        end 
    end
--- 设置断点4: 返回结果
    return result
end
--- 错误处理包装函数
function DebugExample.safeProcess(data)
    local success, result = xpcall(function()
        return DebugExample.processData(data)
    end, function(err)
        print("错误详情:", err)
        print("错误堆栈:", debug.traceback())
        return nil
    end)
    
    if success then
        return result
    else 
        return nil, result
    end
end
--- 测试用例
local testData = {1, 2, 3, "hello", 4, 5}
local result = DebugExample.safeProcess(testData)
 
if result then
    print("处理结果:", table.concat(result, ", "))
else
    print("处理失败")
end 
--- 调试工具函数
function DebugExample.inspectTable(t, depth)
    depth = depth or 0
    local prefix = string.rep("  ", depth)
    
    if type(t) == "table" then
        print(prefix .. "{")
        for k, v in pairs(t) do
            if type(v) == "table" and depth < 3 then  -- 防止无限递归
                print(prefix .. "  [" .. tostring(k) .. "] = ")
                DebugExample.inspectTable(v, depth + 1)
            else 
                print(prefix .. "  [" .. tostring(k) .. "] = " .. tostring(v))
            end
        end
        print(prefix .. "}")
    else
        print(prefix .. tostring(t))
    end
end
--- 使用调试工具
DebugExample.inspectTable({a = 1, b = {c = 2, d = 3}, e = "test"})
 
return DebugExample

--[[
警告: 非数字类型        hello
处理结果:       2, 4, 6, 8, 10
{
  [b] = 
  {
    [d] = 3
    [c] = 2
  }
  [e] = test
  [a] = 1
}
]]

调试技巧与最佳实践

  • 断点策略: 在关键逻辑分支和循环处设置断点
  • 变量监视: 使用调试器监视变量状态变化
  • 条件断点: 只在满足特定条件时暂停执行
  • 日志输出: 结合print语句输出调试信息

调试原理与技术对比

方法适用场景优势
print日志简单逻辑验证零配置,快速验证
debug.traceback错误上下文分析获取完整调用栈
EmmyLua复杂项目/远程调试可视化断点/变量监控
LuaDebug轻量级嵌入环境低资源占用

实战:性能分析与错误定位


1 ) 函数耗时统计

local function profile(func, ...)
  local start = os.clock()
  func(...)
  return string.format("Time: %.2fms", (os.clock()-start)*1000)
end 

print(profile(heavy_calculation, 1000))

完整示例

-- 定义一个需要性能分析的函数 
local function heavy_calculation(n)
    local sum = 0 
    for i = 1, n do 
        sum = sum + math.sqrt(i)
    end 
    return sum 
end 
 
-- 你的性能分析函数 
local function profile(func, ...)
    local start = os.clock()
    func(...)
    return string.format("Time: %.2fms", (os.clock()-start)*1000)
end 
 
-- 使用示例 
print("开始性能分析...")
print(profile(heavy_calculation, 1000))
print("分析完成")

--[[
开始性能分析...
Time: 0.08ms
分析完成
]]

2 ) 元表安全访问

local safe_mt = {
  __index = function(t, k)
    return "Nil Access Blocked!"
  end 
}
setmetatable(userdata, safemt)

完整示例

local safe_mt = {
  __index = function(t, k)
    return "Nil Access Blocked!"
  end 
}
 
local userdata = {}
setmetatable(userdata, safe_mt)
 
-- 测试访问存在的键 
print(userdata.existing_key)  -- 输出: nil 
 
-- 测试访问不存在的键 
print(userdata.nonexistent_key)  -- 输出: "Nil Access Blocked!"
 
-- 给userdata添加一个键值对 
userdata.name = "test"
print(userdata.name)  -- 输出: "test"
 
-- 再次测试访问不存在的键 
print(userdata.age)  -- 输出: "Nil Access Blocked!"

--[[
Nil Access Blocked!
Nil Access Blocked!
test
Nil Access Blocked!
]]

最佳实践总结

  1. 生产环境用xpcall+日志记录替代pcall
  2. 调试阶段启用EmmyLua的TCP连接
  3. 关键模块添加debug.traceback增强错误信息

完整代码示例及工具下载参考:

EmmyLua官方配置指南
OpenWrt远程调试方案
Lua调试原理剖析

结论与建议

Lua错误处理与调试的核心在于:使用 pcall/xpcall 进行安全调用,配合 EmmyLua 等专业调试工具实现高效开发。建议在开发过程中:

  1. 优先使用xpcall + debug.traceback获取完整错误信息
  2. 在VSCode中配置EmmyLua实现断点调试
  3. 建立规范的错误处理模式,避免程序崩溃
VSCode结合EmmyLua实现Lua代码高效调试指南 本文详细介绍了如何使用VSCode结合EmmyLua插件搭建高效的Lua代码调试环境。通过分步指南,帮助开发者实现断点设置、单步执行和变量查看等现代IDE调试功能,显著提升在游戏开发、OpenResty等场景下的Lua调试效率与体验。 阅读详情

相关推荐

从VS Code转Rider:Unity双语言调试环境迁移指南(C#+Lua)

本文详细指导Unity开发者如何从VS Code迁移到Rider,搭建高效的C#和Lua双语言调试环境。涵盖Rider安装、EmmyLua插件配置、调试技巧及工作流优化,帮助开发者提升Unity项目开发效率,特别适合需要同时处理C#和Lua代码的团队。

2w3e4r5t6y的博客 798

Unity-VScode-Emmylua配置报错解决

VScode中用于方便编写Lua代码的一个插件Emmylua再配置环境时,可能会遇到以下的Bug这个时候我们的环境变量配置是有问题的 Win+R打开我们的cmd命令窗口,输入java或者java-version查看 如果输入之后出现了以上这个报错,可能有两种原因:原因1:可能是JDK装的时间比较早,导致环境中的Path中的%JAVA_HOME%\jre\bin排列比较在后。如下图:此时我们需要把这个%JAVA_HOME%\jre\bin上移到最上面即可,下面我们再输入java或者java-version查看

米莱虾 3343

FairyGUI编辑器Lua插件开发实战:从零实现自定义菜单与资源路径复制功能

本文详细介绍了如何为FairyGUI编辑器开发Lua插件,通过两个实战案例——为工具菜单添加“导出UI类名”功能和为资源库右键菜单实现“智能复制组件脚本路径”功能,手把手教你从零开始实现自定义菜单与自动化操作,从而显著提升UI编辑效率。

weixin_28841265的博客 263

【Lua小知识】Vscode中Emmylua插件大量报错的解决方法

问题虽然并不复杂,但总觉得这个这个插件做的并不太好,还有可以改进的空间。如果各位同学有其他什么好用的插件可以推荐交流一下。

Backyard Garden Of Games 6728

Godot引擎集成Lua实现热更新:架构设计与工程实践

热更新是游戏开发中提升迭代效率的关键技术,它允许在不重新编译和发布客户端的情况下,动态更新游戏逻辑与资源。其核心原理是通过将解释型脚本语言作为逻辑载体,在运行时加载和执行。Lua因其轻量、高效和易于嵌入的特性,成为游戏行业实现热更新的首选方案。在Godot引擎中集成Lua,通过GDExtension建立C++胶水层,利用Lua C API实现Godot运行时与Lua虚拟机的双向通信,从而将易变的游戏逻辑(如战斗系统、数值配置)从GDScript中解耦。这种架构显著提升了开发流程的敏捷性和项目后期维护的可持续

diaohuyi6830的博客 356

Unity中C#与Lua通信:依赖注入与UI事件绑定实战解析

在游戏开发与跨语言编程中,依赖注入是一种重要的设计模式,它通过将依赖关系从代码内部转移到外部来提升模块的独立性与可测试性。其核心原理是控制反转,由容器负责创建和管理对象,并在运行时动态注入依赖。这一技术对于构建松耦合、可维护的大型系统具有关键价值,尤其在需要频繁更新和扩展的业务场景中。在Unity引擎的混合编程实践中,C#与Lua的交互是典型应用。C#作为稳定的底层,负责资源管理与核心系统;而Lua凭借其热更新能力,常用于实现灵活的游戏逻辑与UI交互。通过依赖注入,C#可以将管理器等实例安全地提供给Lua使

weixin_33888907的博客 286

EmmyLua的安装与使用

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////// 官方文档 https:/...

蛰伏--当你不够强大时,就不要放弃努力 2万+

XLua实战:C#与Lua互操作核心原理与性能优化指南

在游戏开发和需要热更新的应用场景中,脚本语言与宿主语言的互操作是关键技术。其核心原理是通过虚拟机桥接,实现类型系统映射和函数调用转换,从而允许脚本动态调用宿主语言的功能。这项技术的核心价值在于支持逻辑热更新、提升开发迭代速度,并实现运行时逻辑的动态修改。在Unity引擎中,C#与Lua的互操作是常见实践,广泛应用于游戏业务逻辑、UI系统和配置表解析等场景。腾讯开源的XLua框架通过代码生成和GC优化机制,高效解决了C#与Lua间的类型转换和内存管理问题。本文以XLua为例,深入解析Lua调用C#的完整流程,

weixin_33834137的博客 435

【已解决】黑马点评项目中调用Lua脚本,项目启动失败问题(不要用EmmyLua插件)

是EmmyLua插件的问题,只要启动了它,项目就会崩,EmmyLua2插件也不行,会报错,得用SumnekoLua插件

weixin_57706322的博客 759

深入解析PCIe Retimer:工作原理与典型应用场景

本文深入解析了PCIe Retimer的工作原理与核心价值。作为高速信号的中继再生器,Retimer通过时钟数据恢复和信号再生技术,有效解决长距离或复杂通道中的信号衰减与完整性问题,从而极大地扩展了PCIe链路的有效传输距离。文章详细阐述了其内部架构、自动与手动两种工作模式,并重点介绍了在长距离板间互连、复杂背板设计等典型应用场景中的关键作用。

weixin_29195615的博客 512

Lua学习笔记

环境配置 Unity 2020.3.3f1 + XLua + Rider 创建 Unity 的 单元测试 用 XLua 加载 Lua脚本 在 Rider 中运行 单元测试 注释 -- 单行注释 --[[ 多行注释 多行注释 多行注释 --]] 标识符 字母、下划线、数字(不能以数字开头) 区分大小写 关键字 -- 遍历全局变量 for n in pairs(_G) do print(n) end 一般约定:以下划线开头连接一大串大写字母的名字(如_VERSION),被保留用于Lua内

一十一的博客 1386

Ubuntu运行vmware时报错Vmware Unable to install all modules!Use shipped Linux kernel AIO access library解决。

Ubuntu运行vmware时报错Vmware Unable to install all modules! vmware --version 提示下面内容: [AppLoader] Use shipped Linux kernel AIO access library. An up-to-date "libaio" or "libaio1" package from your system is preferred. VMware Workstation 16.1.2 build-17966106

wto882dim的博客 2850

Unity热更新实战:XLua环境搭建、EmmyLua配置与核心机制解析

热更新是现代游戏开发中实现动态内容迭代的关键技术,它允许开发者在无需重新发布客户端的情况下修复Bug或更新游戏逻辑。其核心原理是通过在运行时加载并执行外部脚本,实现对已编译代码的动态修改或扩展。在Unity生态中,XLua作为主流的Lua热更新解决方案,通过C#与Lua的高效交互,为项目提供了强大的灵活性和可维护性。该技术广泛应用于需要快速响应运营需求、支持多版本兼容或实现代码热修复的移动游戏和大型应用场景。本文基于XLua环境搭建与EmmyLua配置,深入解析了热补丁机制与C#/Lua交互原理,提供了从开

weixin_33095355的博客 265

Groq LPU架构解析:确定性线性处理器如何重塑AI推理

语言模型推理正从‘通用算力堆叠’转向‘确定性硬件定制’。LPU(Language Processing Unit)作为一种面向大模型推理的领域专用处理器,摒弃传统GPU的并行调度、多级缓存与动态执行范式,转而采用空间计算、静态编译与单线程线性流水线设计,实现纳秒级延迟可控性和92%+的HBM带宽利用率。其核心价值在于将模型结构、内存访问、时序路径全部在编译期固化,从而消除运行时抖动——这正是当前MLOps工程师应对A100显存碎片、vLLM调度开销与P99延迟不稳等痛点的关键技术路径。Groq 3 LPU与

weixin_30599521的博客 328

ROS2 Jazzy 学习路线图(2026最新)

摘要: ROS2 Jazzy(LTS版)是2026年长期支持版本,仅适配Ubuntu 24.04。本文提供WSL环境下的学习路线图: 环境搭建(1-2天):配置WSL2+Ubuntu 24.04,安装ROS2 Jazzy及图形工具(VcXsrv、VS Code)。 核心概念(3-5天):掌握节点、话题、服务等通信机制,使用turtlesim和小海龟仿真实践。 开发实战(7-10天):Python/C++节点开发,结合RViz2、Gazebo等工具完成多节点通信和避障项目。 进阶应用(10-15天):导航(N

zheng_ruiguo的专栏 641

VC++集成Lua脚本引擎:从源码编译到高级交互的完整指南

脚本引擎是扩展应用程序动态能力的关键技术,它允许在不重新编译主程序的情况下修改和扩展功能。其核心原理是通过虚拟机解释执行脚本代码,并与宿主语言(如C++)进行高效数据交换。在游戏开发、嵌入式系统和工具链中,脚本引擎能显著提升开发效率和灵活性,实现热更新、配置驱动和逻辑分离。Lua因其轻量、高效和易于嵌入的特性,成为C++项目中最受欢迎的脚本引擎之一。本文将详细介绍如何在Visual C++环境中从源码编译Lua库,解决编译链接中的常见问题,并深入讲解通过Lua栈实现C++与Lua间的数据传递、函数互调等核心

weixin_30832405的博客 349

避坑指南:在Ubuntu 20.04上从零部署IS-Fusion环境(含CUDA 11.1和PyTorch 1.10.1配置)

本文提供了在Ubuntu 20.04系统上从零部署IS-Fusion 3D目标检测环境的详细避坑指南。内容涵盖CUDA 11.1、PyTorch 1.10.1、spconv等核心组件的精确版本安装与兼容性配置,并指导如何准备nuScenes数据集及启动模型训练,旨在帮助研究者和开发者高效搭建稳定的多模态融合算法开发环境。

gitlab7runner的博客 553

FairyGUI插件开发避坑指南:用Lua扩展编辑器功能的5个关键技巧

本文分享了FairyGUI插件开发的5个核心技巧,重点介绍了如何利用Lua脚本高效扩展编辑器功能。内容涵盖插件热更新与生命周期管理、Lua与C# API的桥接、自定义菜单与上下文交互、文件操作与跨平台兼容性,以及调试与错误处理,旨在帮助开发者构建稳定、易维护的生产力工具,提升UI工作流效率。

w3x4y的博客 302

基于STM32设计的校园智慧路灯系统(华为云IOT)(212)

当前设计并研发了基于STM32的智慧路灯系统,本系统的目的是打造一个高效节能、智能化管理的校园照明环境。通过集成STM32F103RCT6高性能微控制器为核心,结合多种传感器模块如BH1750光敏传感器、热释电人体感应模块以及中科微电子GPS模块等,实现了对校园路灯的精准控制与实时监控。

5141

华为od 面试八股文_数据库_01_含答案

华为od 面试八股文_数据库_01_含答案

MISAYAONE的博客 2168

Lua语法速成:从游戏脚本到Nginx开发的核心语法精讲

本文全面讲解Lua语法从基础到进阶的应用,特别聚焦游戏脚本与Nginx开发两大场景。内容涵盖环境搭建、核心语法、性能优化及实战案例,帮助开发者快速掌握Lua在游戏逻辑和Web服务中的高效应用技巧,提升开发效率。

h0i1j2k3l的博客 1360

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

FairyGUI插件开发实战:Lua脚本实现高效UI资源管理

本文详细介绍了如何利用Lua脚本开发FairyGUI插件,以提升UI资源管理效率。通过两个实战案例——批量导出UI界面名称和智能复制组件脚本路径,手把手教你从零创建插件、理解核心API,并实现自定义菜单功能,从而自动化繁琐操作,优化工作流程。

agile9scrum的博客 1040

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Lua在支付系统中的十年实践与技术优势

脚本语言作为系统开发中的重要工具,通过灵活的运行时解释特性解决了业务规则频繁变更的痛点。Lua凭借其轻量级设计(不足1MB运行时)和卓越的C API交互能力,在需要高稳定性与灵活性的支付系统领域展现出独特价值。在支付网关、风控引擎等核心场景中,Lua实现了业务规则热更新秒级生效、内存占用仅为Python方案的1/5等技术突破。特别是在OpenResty生态中,Lua结合Nginx实现了微秒级精度的流量控制,支撑日均百亿级交易。对于支付系统这类对资金安全有极高要求的领域,Lua通过预编译字节码、FFI优化等手

weixin_30457551的博客 430

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

一名合格的Lua高手,该具备什么?

Lua的简洁性既是优点也是挑战。在Lua的世界里,“高手”是一个动态的目标,伴随着新版本(如Lua 5.4的特性)、新工具(如更好的分析器)、新场景(如WebAssembly中的Lua)的出现而不断演进。理解弱引用: 掌握弱表的键(__mode = “k”)、值(__mode = “v”)或键值(__mode = “kv”)为弱引用的含义。熟练设置断点(Breakpoint)、监视点(Watch)、单步执行(Step Over/Into/Out)、查看调用栈(Call Stack)和变量值。

保持专注,保持热爱 1102

Lua脚本语言实战指南:从基础语法到模块化与性能优化

脚本语言作为连接底层系统与上层应用的桥梁,在软件工程中扮演着关键角色。其核心原理在于通过解释执行实现动态逻辑注入,为系统提供灵活扩展能力。这种技术价值在需要热更新、快速原型开发和嵌入式逻辑的场景中尤为突出,例如游戏开发中的插件系统、服务器配置的动态调整等。Lua正是这一领域的杰出代表,凭借其轻量级设计、卓越的嵌入能力和简洁高效的语法,成为众多高性能系统(如Nginx、Redis)的首选扩展语言。本文聚焦Lua的实战应用,深入解析其核心数据结构Table的灵活运用、模块化开发实践以及面向对象编程的实现机制,并

weixin_30386713的博客 303
上一篇: Lua: 文件读写与错误处理详解及实战示例
下一篇: Lua: 基于协程的生产者-消费者模型实现
Wang's Blog
博客等级 码龄12年 7438粉丝 2422原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值