Code Monkey home page Code Monkey logo

Comments (4)

stuartwang avatar stuartwang commented on June 16, 2024

我看了下代码
首先 GetInfo 和 Normalized 都是来源于 debug.getInfo 的返回,所以这个数据是实时取到的。

image

lastRunFunction的赋值是在 function this.real_hook_process(info) 这个函数中,它会记录当前用户函数的 getInfo 信息以及 event(call/line/return) 状态

image

Formated 数据来源于 lastRunFunction["source"],这个数据是最后一次进入 debug.sethook 设置的钩子函数时获取到的.
理论上来讲,这两个数据应该是一致的,预期的结果如下

GetInfo:    @c:/Users/xxx/Desktop/luaTest2/ae.lua
Normalized: c:/users/xxx/desktop/luatest2/ae.lua
Formated:   ae.lua

我另外对比了下 3.2.0和3.3.1的 LuaPanda.lua 代码,处理协程的部分确实有所修改
3.2.0是在调试器启动连接后对协程进行了hook

        --协程调试
        if coroutineCreate == nil and type(coroutine.create) == "function" then
            this.printToConsole("change coroutine.create");
            coroutineCreate = coroutine.create;
            coroutine.create = function(...)
                local co =  coroutineCreate(...)
                table.insert(coroutinePool,  co);
                --运行状态下,创建协程即启动hook
                this.changeCoroutineHookState();
                return co;
            end
        else
            this.printToConsole("restart coroutine");
            this.changeCoroutineHookState();
        end

而3.3.1是在 LuaPanda.lua 被加载时就进行了协程的hook(其实就是重写了协程的创建函数,在创建的协程上加个钩子)
image


这里我的建议是在 this.debug_hook 函数末尾打印下 getinfo 获取到的信息,看是否符合预期。因为Formated数据其实是从这里取的。
我最近也会再测试下协程的hook

from luapanda.

BigMadDonkey avatar BigMadDonkey commented on June 16, 2024

我看了下代码
首先 GetInfo 和 Normalized 都是来源于 debug.getInfo 的返回,所以这个数据是实时取到的。

image

lastRunFunction的赋值是在 function this.real_hook_process(info) 这个函数中,它会记录当前用户函数的 getInfo 信息以及 event(call/line/return) 状态

image

Formated 数据来源于 lastRunFunction["source"],这个数据是最后一次进入 debug.sethook 设置的钩子函数时获取到的.
理论上来讲,这两个数据应该是一致的,预期的结果如下

GetInfo:    @c:/Users/xxx/Desktop/luaTest2/ae.lua
Normalized: c:/users/xxx/desktop/luatest2/ae.lua
Formated:   ae.lua

我另外对比了下 3.2.0和3.3.1的 LuaPanda.lua 代码,处理协程的部分确实有所修改
3.2.0是在调试器启动连接后对协程进行了hook

        --协程调试
        if coroutineCreate == nil and type(coroutine.create) == "function" then
            this.printToConsole("change coroutine.create");
            coroutineCreate = coroutine.create;
            coroutine.create = function(...)
                local co =  coroutineCreate(...)
                table.insert(coroutinePool,  co);
                --运行状态下,创建协程即启动hook
                this.changeCoroutineHookState();
                return co;
            end
        else
            this.printToConsole("restart coroutine");
            this.changeCoroutineHookState();
        end

而3.3.1是在 LuaPanda.lua 被加载时就进行了协程的hook(其实就是重写了协程的创建函数,在创建的协程上加个钩子)
image


这里我的建议是在 this.debug_hook 函数末尾打印下 getinfo 获取到的信息,看是否符合预期。因为Formated数据其实是从这里取的。
我最近也会再测试下协程的hook

感谢回复,下周我会去公司环境下试验一下的 到时候更新一下状态

from luapanda.

BigMadDonkey avatar BigMadDonkey commented on June 16, 2024

@stuartwang 问题似乎解决了,还真是coroutine hook没挂上的问题,是我们内部框架的改动,导致连接调试器的位置之前有些地方创建了可复用的协程(用完之后会被缓存在pool中),后面再用到协程时用的是这些在没挂上hook时创建的可复用协程,导致hook不上。保证debugger最先require就好了。非常感谢!

不过,我尝试在硬断点的位置查看lastRunFunction["source"]似乎复现不出formatted和getInfo不同的情况了,目前不知道这种情况的具体诱因。

另外我还有个疑问:debugger源码中设置coroutine hook的位置会判断是否有hookLib,为什么hookLib存在时就不用coroutine hook了呢?如果hookLib.lua_set_hookstate就可以对所有的协程都hook,那么这个由于“调试器连接晚于部分可复用协程创建”导致的无法hook的问题,应该只会发生在useCHook:false(不使用CHook)的情况下,不会影响使用CHook时的调试,但是我使用旧的写法在创建可复用协程后再连接调试器,即使设置了useCHook:true还是没有停在断点上。

from luapanda.

stuartwang avatar stuartwang commented on June 16, 2024

不过,我尝试在硬断点的位置查看lastRunFunction["source"]似乎复现不出formatted和getInfo不同的情况了,目前不知道这种情况的具体诱因。

按照最初的设计想法,formatted 就是规范化后的路径,只是 lastRunFunction["source"] 恰好有这个数据,就拿过来用了,理论上二者应该是能匹配上的。我觉得之前出现二者不匹配的问题还是和协程有关,调试器关于协程的处理可能测试还不够充分,导致以某些特定场景下的异常。

另外我还有个疑问:debugger源码中设置coroutine hook的位置会判断是否有hookLib,为什么hookLib存在时就不用coroutine hook了呢?

指的是如下代码中的 if hookLib == nil then 判断对吧。我的理解是,lua 层的 debug.sethook ([thread,] hook, mask [, count]) 接口只针对特定的协程设置钩子函数,每个协程都要单独设置。而luac接口 void lua_sethook (lua_State *L, lua_Hook f, int mask, int count); 是可以进程中包括协程函数一起设置钩子。所以 coroutineCreate 时如果使用的是 hookLib ,就无须对每个协程单独设置了。(这里时间比较久了,我记得是这样的,当然也可以写Demo验证如上规则。如果有错误欢迎指出)

function this.replaceCoroutineFuncs()
    if hookLib == nil then
        if coroutineCreate == nil and type(coroutine.create) == "function" then
            this.printToConsole("change coroutine.create");
            coroutineCreate = coroutine.create;
            coroutine.create = function(...)
                local co =  coroutineCreate(...)
                table.insert(coroutinePool,  co);
                --运行状态下,创建协程即启动hook
                this.changeCoroutineHookState(co, currentHookState);
                return co;
            end
        end
    end
end

如果hookLib.lua_set_hookstate就可以对所有的协程都hook,那么这个由于“调试器连接晚于部分可复用协程创建”导致的无法hook的问题,应该只会发生在useCHook:false(不使用CHook)的情况下,不会影响使用CHook时的调试,但是我使用旧的写法在创建可复用协程后再连接调试器,即使设置了useCHook:true还是没有停在断点上。

这里我们的理解是一致的,hookLib.lua_set_hookstate 是调用了luac接口进行hook的,理论上可以hook包括协程在内的所有函数。如果没有停止,有以下可能性

  1. 因为某些原因chook并没有实际加载上,仍然用的是luahook (BP() 中使用LuaPanda.getInfo()可以看到实际是否加载)
  2. lua 5.4.6 版本中发现使用 lua_getinfo(L, "Slf", ar) 取到的函数起止行号有错。调试器会根据起止行号做性能优化,这个错误导致无法正确识别有断点的函数,导致无法停止。 #167
  3. 其他可能性包括chook下路径处理异常。我觉得这种可能性不大,为了统一路径处理,c也是把路径交给lua层处理的,为例避免频繁调用还做了缓存。

目前想到的就是这些,有问题欢迎交流

from luapanda.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.