actboy168 / YDWE

A Tool to Help the Creation of Warcraft III Map
GNU General Public License v3.0
473 stars 141 forks source link

发现一个lua引擎比较隐晦的bug #175

Open w4454962 opened 5 years ago

w4454962 commented 5 years ago

疑似注册war3触发器的lua回调函数有bug, 复现代码如下 6开魔兽 然后局域网联机的时候 输入任意字符 执行100次注册触发器。有概率出现不同步

local jass = require 'jass.common'
local console = require 'jass.console'
local debug = require 'jass.debug'

war3 = {}

function war3.CreateTrigger(call_back)
    local trg = jass.CreateTrigger()
    debug.handle_ref(trg)
    jass.TriggerAddAction(trg, call_back)
    return trg
end

function war3.DestroyTrigger(trg)
    jass.DestroyTrigger(trg)
    debug.handle_unref(trg)
end

console.enable = true 
print = console.write

--聊天触发 输入任意字符事件
local trg = war3.CreateTrigger(function ()
    for i = 1,100 do 
        test_func(i)
    end 
end)
jass.TriggerRegisterPlayerChatEvent(trg, jass.Player(0), "", false)

local count = 0

function test_func(i)
    count = count + 1
    print('test <<<',i,count)
    local j_trg = war3.CreateTrigger(function()
        print('test')
    end)
    for i = 1, 13 do
        jass.TriggerRegisterPlayerUnitEvent(j_trg, jass.Player(0), jass.EVENT_PLAYER_UNIT_SELL_ITEM, nil)
    end
    print(i,'test >>>')

end

test2

如图所示 输入3次字符串 其中多个客户端执行了 300次test_func函数,而只有一个客户端 只执行了100次而掉线了

测试ydwe版本 1.32.13 具体原因未知 也许跟这里的闭包函数有关。

w4454962 commented 5 years ago

复现的概率比较低,大概 1次开6个魔兽进一局游戏, 我大概测试6 7次出现一次,频率高的时候连续2把都出现。 可能跟函数的调用堆栈的深度有关,我朋友的地图里 调用深度比较复杂,每次多开都是必现的,在他的地图里,测试时是循环就掉线。

luciouskami commented 5 years ago

同测,使用再一个正式版本的lua引擎不会出现这个问题,具体原因还需要检查

w4454962 commented 5 years ago

这个问题是存在的,贴吧也有人发帖说 循环 选取单位组 +闭包的方式出现掉线。

w4454962 commented 3 years ago

注册闭包掉线我修好了, 测试过了不再掉线了。

你自己合一下吧 我的分支是几年前的 fix_closure.txt

修改了一下Condition 跟Filter的处理 很奇怪的机制 就是 如果没有对对象调用一次 DestroyCondition 方法的话 之后创建相同code的 都会返回同一个 handle。 而真正销毁 filter对象的却是 DestroyBoolExpr 奇怪的机制