Tencent / xLua

xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

xlua DoString时候死循环 C#端如何处理

Tunied opened this issue · comments

commented

我使用xlua作为游戏的内嵌脚本语言. 允许玩家自定义脚本.

现在有个玩家在脚本里面写了一个死循环. 当我用DoString去加载这个脚本时候会直接卡死.

于是我在外面加入了一个Task

var isSucceed = false;
var task = Task.Run(() => { 
	isSucceed = sandbox.DoString(xxxx)//这里简化一下.核心就是加载这个脚本执行DoString
});

bool isCompletedSuccessfully = task.Wait(TimeSpan.FromMilliseconds(1500)); //1.5s timeout

if (!isCompletedSuccessfully)
{
    CELog.LogError("加载脚本超时");
    isSucceed = false;

    luaEnv.Dispose(); //Kill掉当前的Evn


    return; //不再加载后续脚本
}

现在是只要调用 luaEnv.Dispose() 编辑器就直接闪退. 无论是这里Timeout了调用.还是等几秒以后.

我感觉是因为 Task的Timeout只是在超时后回调. 但是此时 lua还在死锁中. 所以我无法Dipose

官方的FAQ有提了一句

调用LuaEnv.Dispose崩溃
很可能是这个Dispose操作是由lua那驱动执行,相当于在lua执行的过程中把lua虚拟机给释放了,改为只由C#执行即可。

我感觉和我这个情况是一样的.

所以这种情况我应该怎么处理?

谢谢

虚拟机运行中去Dispose必崩溃。
只有一个办法,先把虚拟机停下来再Dispose

commented

抱歉. 我还想问一下.

https://ld246.com/article/1522147783147

这篇文章里面给了一个思路 就是 设置一个TimeoutHook. 然后如果检测到超时以后 通过luaL_error抛出一个异常来终止当前的执行.

我在 NLua 里面找到了Hook方法

NLua/NLua#56

lua.SetDebugHook(NLua.Event.EventMasks.LUA_MASKLINE, 0);

请问 在xlua里面怎么设置类似的 DebugHook, 然后就是我在Hook里面检测到超时 用哪个方法可以手动抛出异常 终止当前的执行呢.

谢谢

commented

大佬 我刚试了一下

因为我外部是单独起了用一个Task监听的Timeout. 所以我就直接在 Timeout了以后

 public void Kill() { LuaAPI.xlua_csharp_str_error(L, "Kill"); }

直接在 LuaEnv.cs 里面加了一个Kill方法. 然后调用的Kill. 目前问题解决了.

我想问下. 这么做的话会有什么隐患么.

谢谢.

抱歉. 我还想问一下.

https://ld246.com/article/1522147783147

这篇文章里面给了一个思路 就是 设置一个TimeoutHook. 然后如果检测到超时以后 通过luaL_error抛出一个异常来终止当前的执行.

我在 NLua 里面找到了Hook方法

NLua/NLua#56

lua.SetDebugHook(NLua.Event.EventMasks.LUA_MASKLINE, 0);

请问 在xlua里面怎么设置类似的 DebugHook, 然后就是我在Hook里面检测到超时 用哪个方法可以手动抛出异常 终止当前的执行呢.

谢谢

这个思路ok,lua_sethook 自己导出一下就有了。怎么导出查下C# pinvoke的文档

commented

我现在 直接在LuaEnv.cs里面加了一个方法. C#端直接用Task的Timetout监听的. 试了一下.没有闪退

public void Kill() { LuaAPI.xlua_csharp_str_error(L, "Kill"); }

因为我C#调用Lua的情况比较简单. Lua端的逻辑也比较弱. 这个Task监听方式完全满足我的需求了.

我想问下我这么调用LuaAPI.xlua_csharp_str_error有啥隐患么.

底层不太懂 😅

感谢.

我现在 直接在LuaEnv.cs里面加了一个方法. C#端直接用Task的Timetout监听的. 试了一下.没有闪退

public void Kill() { LuaAPI.xlua_csharp_str_error(L, "Kill"); }

因为我C#调用Lua的情况比较简单. Lua端的逻辑也比较弱. 这个Task监听方式完全满足我的需求了.

我想问下我这么调用LuaAPI.xlua_csharp_str_error有啥隐患么.

底层不太懂 😅

感谢.

这种感觉有导致虚拟机错乱的风险。

commented

感谢大佬.

我刚才又测了测 目前我用这个方法没啥问题. 可能我Lua和C#之间调用比较简单吧.

我就先这么用着了:smiley: