icer 发表于 2009-1-22 01:23:47

Illegal to move or destruct an object....错误分析

debug.log里目前常见的错误为:执行时段错误:*Illegal to move or destruct an object defining actions from a verb function which returns zero.
user (clone/user/user#1971)
程式:0 第 0 行
物件: No object.

追踪后发现这是由于房间在重载valid_leave函数之后,在满足某些条件下直接move obj到另外一个房间,然后又返回0所致。因为从逻辑上来说,
如果一个函数返回0,意味着这个函数的执行条件不满足,那么它里面所作的操作都应该被回滚,所以在此函数中move或者destruct obj都被mudos
认为是非法的,可能导致此类错误的房间代码如迷魂阵的valid_leave中的一段:

if (me->query_temp("mark/steps") == -10)
{
         me->move("/d/wuliang/dlroad3");
         me->delete_temp("mark/steps");
         return notify_fail("你累的精疲力尽, 终于回到了迷魂阵入口处");
}

在move了me之后又返回notify_fail,等同于返回0,mudos就认为出问题了,记录错误日志。

我在此处的修改是把valid_leave时的判断移到了init处,如果满足条件则set exits到出口,然后几十秒出口自动关闭。
另外一个可能的修改方法是不在valid_leave里直接move,而是call_out一个函数,在那里move,这样可能简单一些。

这个错误貌似不是每次都出,至少我测试迷魂阵的时候没有出,但在日志里确实记录了在迷魂阵出现了这类错误。
另外不记得在windows下是否见过此类错误,可能那时候日志里琐碎的错误太多,此类错误不太显眼,现在debug.log
里改得比较干净,就显出来了。

某些地方,比如沙漠,设置的是obj->unconcious(),然后move到另外一个房间,然后return 0,而大部分任务npc
在unconcious()时会自动死亡消失,此时log中就无法记录出现错误的npc和地点,也不好追查产生错误的房间代码。
这需要jason修改mudos代码以便更深追查。

需要注意以后在valid_leave或者其他return 0的函数流程中避免直接move或者destruct object,尽量采用call_out方式。

icer 发表于 2009-1-22 18:05:41

昨天晚上为了追查出现类似问题的房间,把任务npc晕倒就死改为晕倒后call_out die,以避免log里的no object。
结果发现改过之后log里再也没出过类似错误,结合原来基本上出错的都是晕了就死的任务npc,莫非
这个错误只有在move之后destruct掉并返回0的object身上才会出现?

reallove 发表于 2010-12-19 20:00:14

这个问题是这样的
当player所在的环境中存在某些object包含action,并且player在返回0的调用中move出去了
就会出现这个问题,大多数mudlib里都存在这个bug,目前的改变出口的valid_leave基本都是这样写的,严重时会造成player所有指令失效。

zgbl 发表于 2010-12-19 20:15:45

reallove真能挖坟
不过这种坟贴含金量真不低,正好充实我的笔记

fanzeyi 发表于 2010-12-21 19:19:09

= =||||

还是不习惯LPC return 0表示错误运行。。。

jason 发表于 2010-12-22 09:14:45

0在c的世界里代表false。不一定是错误。

add_action这个机制虽然有些问题,但是相当精巧。

fanzeyi 发表于 2010-12-22 23:11:00

原帖由 jason 于 2010-12-22 09:14 AM 发表 http://pkuxkx.com/forum/images/common/back.gif
0在c的世界里代表false。不一定是错误。

add_action这个机制虽然有些问题,但是相当精巧。

嗯... 不是说 main函数最后要return 0 表示运行成功..来着..

maliyu 发表于 2016-11-11 12:58:15

最近改bug,icer已经给出解决方案,想知道原因,google了一下,以下的说法更具体,在北侠留个记录。
#####
这种错误通常的原因是:设置了一个让obj昏迷或者涉及到action verbs的过程
比如一个npc在某种情况下自动触发晕倒等,所以尽量绕开这么做

具体说起来有点复杂,要涉及到mudos得很多东西,我只说个大概:

在destruct、move_object、enable_commands的时候都要调用remove_sent这个函数
用来remove物件的所有commands,同时设置illegal_sentence_action=2
然后在调用user_parser的时候,illegal_sentence_action被储存并清0
随后取出command进行一个大循环,接着生成一个结构指针svalue_t *ret
用来判断是否是正确的动作,若不是则根据illegal_sentence_action的值抛出error
//......
case 2:
      error("Illegal to move or destruct an object defining actions from a verb function which returns zero.\\n");
//......
具体的代码请看MudOS中的simulate.c和add_action.c
#####
页: [1]
查看完整版本: Illegal to move or destruct an object....错误分析