import{_ as e,c as a,o as t,a4 as u}from"./chunks/framework.Cy9JvDAg.js";const c=JSON.parse('{"title":"6.10 - 调试库","description":"","frontmatter":{"title":"6.10 - 调试库","footer":true,"lastUpdated":true,"outline":"deep"},"headers":[],"relativePath":"6.10.md","filePath":"6.10.md"}'),l={name:"6.10.md"},o=u('<h2 id="_6-10-调试库" tabindex="-1">6.10 - 调试库 <a class="header-anchor" href="#_6-10-调试库" aria-label="Permalink to &quot;6.10 - 调试库&quot;">​</a></h2><p>该库提供了关于Lua程序的调试接口函数。你应当在使用该库时额外小心。这些函数破坏了Lua代码的基本假设（例如，某个函数内的局部变量不可以在外部访问；userdata 的元表不可以在Lua代码中改变；Lua程序不会crash等）并且它们会破坏其他的安全代码。此外，该库中的一些函数可能很慢。</p><p>该库中的所有函数都提供在 debug 表中。所有对Lua线程做操作的函数中的第一个参数都是需要操作的Lua线程。其默认为当前线程。</p><h3 id="debug.debug" tabindex="-1">debug.debug () <a class="header-anchor" href="#debug.debug" aria-label="Permalink to &quot;debug.debug () {#debug.debug}&quot;">​</a></h3><p>进入可交互模式，运行用户输入的每一个字符串。使用简单的命令和其他调试工具，用户可以查看全局或本地变量、改变它们的值、计算表达式等等。一行只包含单词 cont 的输入会结束这个函数，所以调用者代码会在此处之后继续执行。</p><p>注意 debug.debug 的命令在词法上没有嵌入到任何函数中，所以你无法通过本地变量直接访问。</p><h3 id="debug.gethook" tabindex="-1">debug.gethook ([thread]) <a class="header-anchor" href="#debug.gethook" aria-label="Permalink to &quot;debug.gethook (\\[thread\\]) {#debug.gethook}&quot;">​</a></h3><p>返回当前设置在给出Lua线程中的 hook ，有三个值：当前 hook 的函数、当前 hook 的掩码、当前 hook 的数量，同<a href="#debug.sethook">debug.sethook</a>函数。</p><p>如果没有活跃的 hook 则返回<strong>fail</strong>。</p><h3 id="debug.getinfo" tabindex="-1">debug.getinfo ([thread,] f [, what]) <a class="header-anchor" href="#debug.getinfo" aria-label="Permalink to &quot;debug.getinfo (\\[thread,\\] f [, what]) {#debug.getinfo}&quot;">​</a></h3><p>返回带有某个函数的相关信息的表。你可以直接给定一个函数，或者你可以给定一个数字作为参数 f ，意思是运行在给定Lua线程的调用栈的第 f 层的函数：0层为当前函数（getinfo 函数自身）；1层为调用 getinfo 的函数（尾调用除外，其不在调用栈计数中）；以此类推。如果 f 是一个大于活跃数量的数字，则 geinfo 返回<strong>fail</strong>。</p><p>这里返回的表中所能包含的字段同<a href="/lua5.4-manual-zh/4.6.html#lua_getinfo">lua_getinfo</a>，字符串参数 what 描述了那些要填充的字段。参数 what 默认获取所有可用的信息，除了有效行的表。如果有选项 &#39;f&#39; 则会将该函数自身添加到一个名为 func 的字段上。如果有选项 &#39;L&#39; 则会将有效行的表添加到名为 activelines 的字段上。</p><p>例如，表达式 debug.getinfo(1,&quot;n&quot;).name 会返回当前函数的名称，如果可以找到合理的名称的话。表达式 debug.getinfo(print) 则会返回带有<a href="/lua5.4-manual-zh/6.1.html#print">print</a>函数所有相关信息的表。</p><h3 id="debug.getlocal" tabindex="-1">debug.getlocal ([thread,] f, local) <a class="header-anchor" href="#debug.getlocal" aria-label="Permalink to &quot;debug.getlocal (\\[thread,\\] f, local) {#debug.getlocal}&quot;">​</a></h3><p>返回在某个函数中 local 索引处的局部变量的名称和值，该函数位于调用栈上的第 f 层。该函数不但可以访问本地变量，也可以访问闯入的参数和临时变量。</p><p>第一个参数或本地变量的索引是1，以此类推，往后的顺序都依据代码中的声明先后而来，此处只计数函数的当前作用域中的活跃变量。编译时的常量可能并没有加在声明列表中，其会被编译器优化掉。负数索引引用了可变参数：-1表示第一个可变参数。当给出索引处没有变量时该函数会返回<strong>fail</strong>，并在超出调用层数时抛出一个错误。（你可以调用<a href="#debug.getinfo">debug.getinfo</a>来检查给定的层数是否有效。）</p><p>由 &#39;(&#39; （开圆括号）打头的变量名表示变量的名称未知（例如像循环控制变量之类的内部变量，以及代码块中没有调试信息的变量）。</p><p>参数 f 也可以是个函数。在这种情况下，getlocal 只返回该函数中各个参数的名称。</p><h3 id="debug.getmetatable" tabindex="-1">debug.getmetatable (value) <a class="header-anchor" href="#debug.getmetatable" aria-label="Permalink to &quot;debug.getmetatable (value) {#debug.getmetatable}&quot;">​</a></h3><p>返回给定 value 的元表，没有元表则返回<strong>nil</strong>。</p><h3 id="debug.getregistry" tabindex="-1">debug.getregistry () <a class="header-anchor" href="#debug.getregistry" aria-label="Permalink to &quot;debug.getregistry () {#debug.getregistry}&quot;">​</a></h3><p>返回注册表（参见<a href="/lua5.4-manual-zh/4.3.html">4.3</a>）。</p><h3 id="debug.getupvalue" tabindex="-1">debug.getupvalue (f, up) <a class="header-anchor" href="#debug.getupvalue" aria-label="Permalink to &quot;debug.getupvalue (f, up) {#debug.getupvalue}&quot;">​</a></h3><p>返回在函数 f 中索引为 up 的 upvalue 的名称和值。不存在相应 upvalue 则返回<strong>fail</strong>。</p><p>（对于Lua函数，upvalue 是在该函数中使用的外部局部变量，随之包含在该闭包中。）</p><p>对于C函数，该函数使用空字符串 &quot;&quot; 作为所有 upvalue 的名称。</p><p>变量名 &#39;?&#39;（问号）表示该变量的名称未知（代码块中不带调试信息的变量）。</p><h3 id="debug.getuservalue" tabindex="-1">debug.getuservalue (u, n) <a class="header-anchor" href="#debug.getuservalue" aria-label="Permalink to &quot;debug.getuservalue (u, n) {#debug.getuservalue}&quot;">​</a></h3><p>返回给出的 userdata 参数 u 对应的第 n 个 user value ，以及一个布尔值，如果没有相应的 user value 时，这个布尔值为<strong>false</strong>。</p><h3 id="debug.sethook" tabindex="-1">debug.sethook ([thread,] hook, mask [, count]) <a class="header-anchor" href="#debug.sethook" aria-label="Permalink to &quot;debug.sethook (\\[thread,\\] hook, mask [, count]) {#debug.sethook}&quot;">​</a></h3><p>设置调试 hook 。字符串参数 mask 和数字参数 count 表明了触发 hook 的时机。mask 可以由以下字符组合而成，其各含义为：</p><ul><li><strong>&#39;c&#39;：</strong> 每次发生函数调用时触发 hook 。</li><li><strong>&#39;r&#39;：</strong> 每次发生函数返回时触发 hook 。</li><li><strong>&#39;c&#39;：</strong> 每次执行到下一行代码时触发 hook 。</li></ul><p>此外，当 count 不为零时，该 hook 会在每执行 count 条指令后触发。</p><p>不带参数调用该函数时，会关闭 hook 。</p><p>每当 hook 被触发，其第一个传入的参数为描述了触发事件的字符串：&quot;call&quot;、&quot;tail call&quot;、&quot;return&quot;、&quot;line&quot;、和 &quot;count&quot;。对于行事件，还会将新行的行数作为 hook 的第二个参数传入。在 hook 内部，你可以对第 2 层调用 getinfo 来获取关于当前函数更多的信息。（第0层是 getinfo 函数本身，第一层是这个 hook 函数。）</p><h3 id="debug.setlocal" tabindex="-1">debug.setlocal ([thread,] level, local, value) <a class="header-anchor" href="#debug.setlocal" aria-label="Permalink to &quot;debug.setlocal (\\[thread,\\] level, local, value) {#debug.setlocal}&quot;">​</a></h3><p>将处于调用栈的第 level 层的函数中索引为 local 的局部变量赋值为 value 。如果没有相应的局部变量，该函数会返回<strong>fail</strong>，并且如果当 level 超出了调用层数，则会另外抛出一个错误。（你可以调用 getinfo 以确认层数是否有效。）否则，其会返回局部变量的名称。</p><p>更多关于变量索引和名称的信息请参考<a href="#debug.getlocal">debug.getlocal</a>。</p><h3 id="debug.setmetatable" tabindex="-1">debug.setmetatable (value, table) <a class="header-anchor" href="#debug.setmetatable" aria-label="Permalink to &quot;debug.setmetatable (value, table) {#debug.setmetatable}&quot;">​</a></h3><p>将给定的 value 的元表设置为给定的 table（可以是个<strong>nil</strong>）。并返回 value 本身。</p><h3 id="debug.setupvalue" tabindex="-1">debug.setupvalue (f, up, value) <a class="header-anchor" href="#debug.setupvalue" aria-label="Permalink to &quot;debug.setupvalue (f, up, value) {#debug.setupvalue}&quot;">​</a></h3><p>该函数会将函数 f 中索引为 up 的 upvalue 设置为给定值 value 。当不存在相应的 upvalue 时会返回<strong>fail</strong>。否则会返回上值的名称。</p><p>更多关于上值的信息请参考<a href="#debug.getupvalue">debug.getupvalue</a>。</p><h3 id="debug.setuservalue" tabindex="-1">debug.setuservalue (udata, value, n) <a class="header-anchor" href="#debug.setuservalue" aria-label="Permalink to &quot;debug.setuservalue (udata, value, n) {#debug.setuservalue}&quot;">​</a></h3><p>将给定的 udata 中的第 n 个 user value 设为 value 值。参数 udata 必须是一个 full userdata 。</p><p>返回 usdata，或者当不存在相应的 userdata 和 user value 时返回<strong>fail</strong>。</p><h3 id="debug.traceback" tabindex="-1">debug.traceback ([thread,] [message [, level]]) <a class="header-anchor" href="#debug.traceback" aria-label="Permalink to &quot;debug.traceback (\\[thread,\\] [message [, level]]) {#debug.traceback}&quot;">​</a></h3><p>如果 message 未缺省并且既不是个字符串或<strong>nil</strong>，该函数不会做进一步处理并直接返回 message 。否则会返回一个带上了这个 message 的调用栈回溯信息。可选字符串参数 message 回被加到回溯信息的开头。可选数字参数 level 制定了从调用栈的哪一层开始回溯（默认为1，是调用 traceback 的函数）。</p><h3 id="debug.upvalueid" tabindex="-1">debug.upvalueid (f, n) <a class="header-anchor" href="#debug.upvalueid" aria-label="Permalink to &quot;debug.upvalueid (f, n) {#debug.upvalueid}&quot;">​</a></h3><p>返回给定函数中的第 n 个上值的唯一索引（是个 light userdata）。</p><p>这个唯一索引使得程序可以分辨不同的闭包是否共享了某个上值。对于Lua闭包所共享的某个上值（即访问同名的外部局部变量）将返回相同的索引。</p><h3 id="debug.upvaluejoin" tabindex="-1">debug.upvaluejoin (f1, n1, f2, n2) <a class="header-anchor" href="#debug.upvaluejoin" aria-label="Permalink to &quot;debug.upvaluejoin (f1, n1, f2, n2) {#debug.upvaluejoin}&quot;">​</a></h3><p>使得Lua闭包 f1 中的第 n1 个上值引用Lua闭包 f2 中的第 n2 个上值。</p>',53),r=[o];function d(g,n,s,h,b,i){return t(),a("div",null,r)}const f=e(l,[["render",d]]);export{c as __pageData,f as default};
