Lua - 调试接口

Lua与VC集成应用实战指南 在现代软件开发领域,特别是在游戏开发和嵌入式系统中,Lua语言因其轻量级和高效的性能被广泛用作脚本语言。而C++作为性能强劲的系统级编程语言,与Lua的集成能够形成互补,提高项目开发的灵活性和效率。本章节旨在为读者提供Lua与C++集成的宏观视角,帮助理解集成的动机、优势和项目集成的基本步骤。Lua 本身只提供了一组基础库来支持核心语言功能。在实际项目中,开发者常常需要创建自定义的库来扩展 Lua 的功能,以适应特定的应用场景。luakz。 阅读详情
  Lua - 调试接口

4 - 调试接口 The Debug Interface

Lua 没有内置的调试设施。它使用一种特殊的接口,这种接口依赖函数和 钩子(hooks)。该接口允许构造不同种类的调试器,分析器以及其他工具用以从解释器得到所需的信息。

4.1 - 堆栈及函数信息 Stack and Function Information

得到解释程序运行时堆栈信息的主要函数是:

       int lua_getstack (lua_State *L, int level, lua_Debug *ar);

这个函数用一个指定等级的函数的 activation record 的标示符填充一个 lua_Debug 结构,等级 0 是当前运行函数,然而等级 n+1 是在等级 n 上调用的函数。当没有错误发生时,lua_getstack 返回 1;当在比栈更深的等级上调用的时候,它返回 0;

lua_Debug 结构被用来携带一个处于活动状态的函数的各种信息:

      typedef struct lua_Debug {
        int event;
        const char *name;      /* (n) */
        const char *namewhat;  /* (n) `global', `local', `field', `method' */
        const char *what;      /* (S) `Lua' function, `C' function, Lua `main' */
        const char *source;    /* (S) */
        int currentline;       /* (l) */
        int nups;              /* (u) number of upvalues */
        int linedefined;       /* (S) */
        char short_src[LUA_IDSIZE]; /* (S) */

        /* private part */
        ...
      } lua_Debug;

lua_getstack 只填充结构的私有部分以备之后使用。要填充 lua_Debug 其他有用信息,调用

       int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);

这个函数发生错误是返回 0 (举个例子,一个无效的 what 选项)。what 字符串中的每个字符选择填充一些 ar 结构的字段,把上面在 lua_Debug 定义中用圆括号括起来的字母作为指示: `S´ 填充在 source, linedefined 和 what 字段中;`l´ 填充在 currentline 字段中,等等...。而且,`f´ 将正在运?性谒燃渡系暮谷攵颜弧?

想要从一个不处于活动状态的函数那得到信息(就是不在栈上的函数),你需要将其压入栈并且用 >´ 作为 what 字符串的开始。举个例子,要知道函数 f 定义在第几行,你需要这样写

       lua_Debug ar;
       lua_pushstring(L, "f");
       lua_gettable(L, LUA_GLOBALSINDEX);  /* get global `f' */
       lua_getinfo(L, ">S", &ar);
       printf("%d/n", ar.linedefined);

lua_Debug 的字段有如下的含义:

  • source 如果函数在一个字符串中定义,那么 source 就是那个字符串。如果函数定义在一个文件中,source 开始于一个 `@´ 后面跟随文件名。
  • short_src 一个可打印版的 source,用于错误信息。
  • linedefined 函数定义起始的行号。
  • what 如果这是一个Lua函数,显示 "Lua" 字符串, "C" 为C 函数,"main" 如果这是一个语句段的main部分,"tail" 如果这是一个做了尾部调用的函数。在后面的情况里,Lua 没有其他关于这个函部的信息。
  • currentline 代表当前函数执行到的行数。如果没有行信息可用,currentline 被设置为 -1。
  • name 一个所给函数合理的函数名。因为函数在Lua中属于第一类值,它们没有固定的名字:一些函数可能是多个全局变量的值,其他的可能只储存在一个表字段里。lua_getinfo 函数检测函数如何被调用或者是否为一个全局变量的值以寻找一个合适的名字。如果找不到合适的名字,name 被设置为 NULL。
  • namewhat name 字段的解释。根据函数如何被调用,namewhat 的值可以是 "global", "local", "method", "field" 或者 "" (空字符串)。(当没有其他可选项的时候Lua使用空字符串代替)
  • nups 函数上值的数量。

4.2 - 操作局部变量和上值 Manipulating Local Variables and Upvalues

为了更多的操作局部变量和上值,调试接口使用索引:第一个参数或者局部变量索引为 1,以此类推,直到最后一个活动的局部变量。整个函数中的活动的上值没有特定的顺序。

下面的函数允许操作一个所给激活记录的局部变量:

       const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
       const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);

参数 ar 必须是一个被前一个 lua_getstack 调用填充的有效的激活记录或者作为一个钩子函数的参数(见 4.3)。lua_getlocal 获得一个局部变量的索引 n,将变量的值压入栈,并且返回变量名。lua_setlocal 从栈顶分配一个值给变量并且返回变量名。当索引超过活动的局部变量的数量时,两个函数都返回 NULL。

以下的函部可以操作所给函数的上值(不像局部变量,函数的上值即使在函数不处于活动状态的时候都可以被访问):

       const char *lua_getupvalue (lua_State *L, int funcindex, int n);
       const char *lua_setupvalue (lua_State *L, int funcindex, int n);

这些函数可以作为Lua 函数使用也可以作为C 函数使用。(作为Lua 函数,上值是函数外部使用的局部变量,因此它被包含在函数闭包中。)funcindex 指向栈中的一个函数。lua_getupvalue 得到一个上值的索引 n,将上值的值压入栈,并返回其变量名。lua_setupvalue 从栈顶分配一个值给上值并返回变量名。当索引大于上值数量时,两个函数都返回 NULL。对于C 函数来说,这些函数使用空字符串作为所有上值的变量名。

作为一个例子,下面的函数列举了所给等级的栈中的函数的所有局部变量名和上值变量名:

       int listvars (lua_State *L, int level) {
         lua_Debug ar;
         int i;
         const char *name;
         if (lua_getstack(L, level, &ar) == 0)
           return 0;  /* failure: no such level in the stack */
         i = 1;
         while ((name = lua_getlocal(L, &ar, i++)) != NULL) {
           printf("local %d %s/n", i-1, name);
           lua_pop(L, 1);  /* remove variable value */
         }
         lua_getinfo(L, "f", &ar);  /* retrieves function */
         i = 1;
         while ((name = lua_getupvalue(L, -1, i++)) != NULL) {
           printf("upvalue %d %s/n", i-1, name);
           lua_pop(L, 1);  /* remove upvalue value */
         }
         return 1;
       }

4.3 - 钩子 Hooks

Lua offers a mechanism of hooks, which are user-defined C functions that are called during the program execution. A hook may be called in four different events: a call event, when Lua calls a function; a return event, when Lua returns from a function; a line event, when Lua starts executing a new line of code; and a count event, which happens every "count" instructions. Lua identifies these events with the following constants: LUA_HOOKCALL, LUA_HOOKRET (or LUA_HOOKTAILRET, see below), LUA_HOOKLINE, and LUA_HOOKCOUNT.

A hook has type lua_Hook, defined as follows:

       typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);

You can set the hook with the following function:

       int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);

func is the hook. mask specifies on which events the hook will be called: It is formed by a disjunction of the constants LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE, and LUA_MASKCOUNT. The count argument is only meaningful when the mask includes LUA_MASKCOUNT. For each event, the hook is called as explained below:

  • The call hook is called when the interpreter calls a function. The hook is called just after Lua enters the new function.
  • The return hook is called when the interpreter returns from a function. The hook is called just before Lua leaves the function.
  • The line hook is called when the interpreter is about to start the execution of a new line of code, or when it jumps back in the code (even to the same line). (This event only happens while Lua is executing a Lua function.)
  • The count hook is called after the interpreter executes every count instructions. (This event only happens while Lua is executing a Lua function.)

A hook is disabled by setting mask to zero.

You can get the current hook, the current mask, and the current count with the following functions:

       lua_Hook lua_gethook      (lua_State *L);
       int      lua_gethookmask  (lua_State *L);
       int      lua_gethookcount (lua_State *L);

Whenever a hook is called, its ar argument has its field event set to the specific event that triggered the hook. Moreover, for line events, the field currentline is also set. To get the value of any other field in ar, the hook must call lua_getinfo. For return events, event may be LUA_HOOKRET, the normal value, or LUA_HOOKTAILRET. In the latter case, Lua is simulating a return from a function that did a tail call; in this case, it is useless to call lua_getinfo.

While Lua is running a hook, it disables other calls to hooks. Therefore, if a hook calls back Lua to execute a function or a chunk, that execution occurs without any calls to hooks.

使用lighttpd和开发板进行交互 本文介绍了如何在嵌入式开发板上使用Lighttpd Web服务器实现硬件交互功能。主要内容包括:Lighttpd通过CGI程序间接控制硬件的基本原理;lighttpd.conf配置文件的详细解析;开发板文件目录结构设计;用C语言编写控制GPIO的CGI程序示例;网页调用CGI实现按钮触发控制的HTML代码;常见问题调试建议。最后通过效果图展示了网页按钮点击后成功控制LED灯的实际效果,验证了Lighttpd+CGI方案在嵌入式设备Web控制中的可行性。 阅读详情

相关推荐

医学图像中的小目标病灶检测难题:我的硕士研究总结与思考

医学图像中的小目标检测和分割,主要指在CT、MRI、超声等医学影像中识别和分割微小病灶或细小结构。这些小目标通常体积小、边界模糊、特征不明显,却往往是关键病灶,例如肺部小结节、脑微出血、乳腺微钙化等。

weixin_45638136的博客 2368

Lua 5.0 参考手册

 1 - 绪论Lua是一种为支持有数据描述机制的一般过程式编程语言而设计的扩展编程语言。它同样可以对面向对象语言、函数式程序设计(Functional Programming,如Lisp)以及数据驱动编程(data-driven programming)提供很好的支持。它的目标是被用作一种强大的、轻型的配置语言。Lua目前已经被实现为一个扩展库,是用clean C (ANSI C/C++的

JEXO 5170

OpenWrt南京电信PPPoE IPv6配置:从零搭建稳定双栈网络

本文详细指导如何在南京电信PPPoE宽带环境下,为OpenWrt路由器配置稳定的IPv6双栈网络。核心在于正确设置WAN6接口为DHCPv6客户端,并请求/60前缀,同时配置LAN口分发地址并放行防火墙关键流量,确保内网设备获得原生IPv6连接。

water的专栏 1339

LUA源码分析九:Debug."getlocal"

  函数:{"getlocal", db_getlocal} 从db_getlocal开始跟调.该函数是把自身的所有变量打印出来。大体的思路是算到执行码,根据执行码的大小限制,遍历函数保存的变量信息,然后依次打印。       static int db_getlocal (lua_State *L) { int arg; lua_State *L1 = getthread...

lin_style的专栏 1730

Android以太网开关流程分析

Android以太网开关流程分析 一、引言   在Android 以太网服务启动流程中我们启动了EthernetService(ES),NetworkManagementService(NMS)等服务,其中ES作为Binder的服务端,向客户端EthernetManger提供了调用接口的引用。因此,应用可以通过EthernetManger来访问以太网的相关接口。本篇文章将从APP调用以太网的使能和关闭的接口流程作为切入点来分析,以太网框架中,上层app是如何将指令传递到底层。图1-1所示为以太网使能和关闭

franc521的博客 6112

基于sklearn实现LDA主题模型(附实战案例)

目录LDA主题模型1.LDA主题模型原理2.LDA主题模型推演过程3.sklearn实现LDA主题模型(实战)3.1数据集介绍3.2导入数据3.3分词处理 3.4文本向量化3.5构建LDA模型3.6LDA模型可视化 3.7困惑度 其实说到LDA能想到的有两个含义,一种是线性判别分析(Linear Discriminant Analysis),一种说的是概率主题模型:隐含狄利克雷分布(Latent Dirichlet Allocation,简称LDA)。 现在讨论的是主题模型

m0_64336780的博客 2万+

Lua C API中文函数手册

转自http://www.leeon.me/a/lua-c-api-manual lua_Alloc typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize,

zhukangle的博客 3259

Xilinx平台SRIO介绍(五)示例工程Example Design介绍

理解IP的使用,少不了Example Design的学习。

数字IC/FPGA杂货铺,找一找,或许有你想要的~ 1万+

Lua系列文章(1)---Lua5.4参考手册学习总结

lua5.4的参考手册,为后续学习Lua作为铺垫与参考

追赶时代的博客 5205

FPGA实现串口升级及MultiBoot(五)通过约束脚本添加IPROG实例

上一篇文章种总结了MultiBoot 关键技术,分为:一个指令、二种位流、三种方式、四样错误。针对以上四句话我们接下来详细分析。在开始解析之前我们先准备两个文件,一个是控制LED闪烁的文件,通过更换引脚约束可以控制不同LED,这样就可以指示是启动MultiBoot位流还是Golden位流。还有一个文件就是uart发送文件,会指示启动的位流格式和启动地址。文件都比较简单,就不列举了,文件详见文后的链接。对于 IPROG 指令目前有三种实现方式,分别为:1)通过约束脚本添加;2)通过ICAPE2原语

OpenFPGA的博客 2104

Android软键盘系统深度解析:架构、原理与实现

Android软键盘系统深度解析:架构与实现原理 本文系统剖析了Android软键盘的核心工作机制。作为系统级输入服务,软键盘具有双重属性:既是可安装的独立应用,又深度集成于系统框架中。文章详细解读了软键盘的系统架构,包括其与InputMethodManagerService(IMMS)和WindowManagerService(WMS)的交互机制,以及通过InputConnection实现的跨进程通信流程。同时分析了输入法窗口的特殊管理策略、布局调整模式,并深入探讨了输入预测引擎的实现原理,包括词典加载、

保持专注,保持热爱 114

lua_getstack

lua_getstack int lua_getstack (lua_State *L, int level, lua_Debug *ar); 获取解释器的运行时栈的信息。 这个函数用正在运行中的给定级别处的函数的活动记录来填写lua_Debug结构的一部分。 0 级表示当前运行的函数, 而 n+1 级处的函数就是调用第 n 级函数的那一个。 如果没有错误,lua_...

aobu0171的博客 410

主题035:计算流体力学(CFD)

计算流体力学(Computational Fluid Dynamics, CFD)是利用数值方法求解流体流动、传热传质等问题的学科。CFD已成为化学反应工程中反应器设计和优化的重要工具。∂ρ∂t+∇⋅(ρu)=0 \frac{\partial \rho}{\partial t} + \nabla \cdot (\rho \mathbf{u}) = 0 ∂t∂ρ​+∇⋅(ρu)=0对于不可压缩流动:∇⋅u=0 \nabla \cdot \mathbf{u} = 0 ∇⋅u=0动量方程:∂(ρu)∂t+∇⋅(ρ

kkchenjj的博客 266

【翻译】(LRM5.1-8)调试接口(3.8)

【翻译】(LRM5.1-8)调试接口(3.8)   See also: http://www.lua.org/manual/5.1/manual.html   原文见 http://www.lua.org/manual/5.1/manual.html   -----------------------------------------   Lua 5.1 Referen...

weimingtom的待宵草 358

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

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

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

【LUA】调试小技巧

Lua调试记录 项目需要调试lua,有两个小方法记录一下: 通过下载明文的lua脚本,在开发板上直接修改和调试 lua脚本在拷贝到文件系统后,通过luac进行加密,软件运行时,在文件系统中是看不到明文的lua脚本内容。可以通过删除tmp目录下的luci-modulecache/ luci-sessions/目录,重新下载明文的lua脚本代替加密的lua脚本,这时候就可以直接在板子上调试...

vickytong1018的博客 3029

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Lua 常用函数 一

Lua 常用函数 一 分类: 脚本学习2012-02-07 13:56 1165人阅读 评论(0) 收藏 举报 luahooktablenullinteger活动 目录(?)[+]   http://lua-users.org/wiki/LunaFive lua_Alloc lua_getallocf (lua_State *L,

linuxheik的专栏 905

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

cocos2d-x lua misc

1. lua与C++的接口定义在 $cocos2dx-dir/scripting/lua/cocos2dx_support/LuaCocos2d.cpp 2. 将lua脚本的调试信息输出到终端 默认情况下,在lua中使用print函数输出的信息不会显示在调试终端里,解决方法是使用CCLuaLog函数 CCLuaLog("debug message") 或者更简单点 ...

weixin_34216107的博客 81

lua: Lua5.1中的API函数

lua_State* luaL_newstate() Lua脚本的编译执行是相互独立的,在不同的线程上执行。通过luaL_newstate()函数可以申请一个虚拟机,返回指针类型 lua_State。今后其他所有Lua Api函数的调用都需要此指针作为第一参数,用来指定某个虚拟机。 lua_State* L = luaL_newstate(); -----------------------

小天 专栏 627

AI陪伴机器人通信选型:为什么MQTT比HTTP轮询更合适

在物联网设备通信中,HTTP轮询与MQTT是两种常见模型。HTTP轮询基于请求-响应模式,客户端定时向服务端发起请求,实时性受限于轮询间隔,且频繁建连导致功耗较高。MQTT采用发布-订阅模型,通过Broker解耦设备与服务端,支持长连接和消息推送,实现毫秒级实时通信,同时降低功耗。对于AI陪伴机器人这类需要双向实时交互、弱网适应和低功耗续航的场景,MQTT能有效提升响应速度和连接稳定性,是更优的通信协议选择。

weixin_34056162的博客 292

Lua常用函数

lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数。如果 ud 不是 NULL ,Lua 把调用lua_newstate 时传入的那个指针放入*ud 。 lua_getfenv void lua_getfenv (lua_State *L, int index); 把

德玛西亚的专栏 558

<11>Lua 常用函数 一

lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数。如果 ud 不是 NULL ,Lua 把调用lua_newstate 时传入的那个指针放入*ud 。 lua_getfenv void lua_getfenv (lua_State *L, int index); 把索引处值的环境表压入堆...

jadeshu的博客 8440

Lua2.4 参考手册(五)

为什么80%的码农都做不了架构师?>>> ...

weixin_33873846的博客 170

内嵌lua解释器 作为组件命令调试

好处就是调试代码 只在 lua 代码出现,同时为设备初始化 增加了外部脚本配置的功能接口。给不同的组件传递不通的参数。

HongDaYu的搬砖之路 390

LUA常用函数大全

  lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数。如果 ud 不是 NULL ,Lua 把调用lua_newstate 时传入的那个指针放入*ud 。 lua_getfenv void lua_getfenv (lua_State *L, int index); 把索引处...

xudekongjian的博客 5175

lua源代码文件分析

ldebug.c - 调试接口:包含访问调试钩子的函数(lua_sethook/lua_gethook/lua_gethookcount),访问运行时堆栈信息的函数            (lua_getstatck/lua_getlocal/lua_setlocal),检查字节码函数(luaG_checkopenop /luaG_checkcode),           和抛出错误的函数(

NekoCode 的记事本 1078

Lua 常用函数

lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数。如果 ud 不是 NULL ,Lua 把调用lua_newstate 时传入的那个指针放入*ud 。 lua_getfenv void lua_getfenv (lua_State *L, int index); 把索引处值的环境表压入...

auspark的专栏 1081
上一篇: Lua学习笔记二--在Lua中使用自己的C函数收藏
下一篇: lua编译,运行与调试
skyremember
博客等级 码龄20年 204粉丝 484原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值