![]() |
![]() |
#1 |
高级会员
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 注册: 08年04月11日
来自: 盘丝洞
帖子: 311
声望力: 20
声望:
50
![]() 现金:29两梁山币
资产:1245两梁山币
致谢数: 0
获感谢文章数:0
获会员感谢数:0 |
一个引起当机的bug
一个引起当机的BUG的讨论。 作者:jackyboy 发表时间:2001年7月31日 12:45 -------------------------------------------------------------------------------- 在我自己的环境上,我编写下面的命令代码,运行后自己即刻断线,然后在第一个call_out 未调用前自己再次上线,再次执行改命令,在第一个call_out到达时间开始执行时,将会因 为me的值由object变为0导致MUDOS的段失败崩溃。如果运行两次命令不会当,可以多运行几 次看看。在我自己的OS + LIB里这个问题似乎是屡试屡“爽”,但是我不能100%肯定,所以 贴出来请大家也试试看。我用的是v22.2b11版本。 int main(object me,string arg) { string out=""; if(!arg) arg="1234567890"; for(int i=0;i<3;i++) out+=arg; //remove_call_out("do_out"); call_out("do_out",10,me,out); destruct(me); return 1; } void do_out(object me,string out) { tell_object(me,out); } 以下是关于解决途径的讨论,可以参考下goodtaste关于MudOS中call_out的讲解 作者:Super 发表时间:2001年7月31日 13:15 -------------------------------------------------------------------------------- 确实有这个BUG。 我看了一下mudos,发现里面的在destruct_objetct()时,并没有消除call_out。 不过只要把simulate.c里面的destruct_object()里面最后加一句 remove_all_callout(ob); 应该就能解决问题了,呵呵。 作者:goodtaste 发表时间:2001年8月1日 19:10 -------------------------------------------------------------------------------- 你说的那个方法有效么?我看了看v22pre11的代码, 感觉不对阿。 这里被destruct 的是call_out调用的函数里使用到 的对象,而不是发起call_out时候的current_object。 在efuns_main.c的f_call_out这个efun里,传递给 new_call_out的第一个参数是current_object,也就是 调用call_out这个efun的物件,这里就是这个命令。 new_call_out将这个对象存入一个pending_call_t 的结构中,然后将这个结构放进一个数组里。 而remove_all_call_out()的唯一参数就是一个object_t 他的做法是把整个结构数组遍历一遍,如果发现某个 元素(是一个pending_call_t结构)中的ob是remove_all_call_out 的参数,那么就把这个call_out去掉。所以在destruct调 user_ob之前调用remove....所传递过去的参数user_ob是没有用的, 他查找不到你所希望去掉的那个call_out。 作者:Super 发表时间:2001年8月1日 19:46 -------------------------------------------------------------------------------- 确实。。 我那样做是徒劳无功的,都怪当时没有看仔细:P 现在重新看了一遍,发现在new_call_out()里面 有一句cop->ob = ob这里的OB是call_out的发起者。 恩,这么说来,那个问题就完完全全是代码的问题了。呵呵。。 以下是由这个问题引发的代码效率的讨论 作者:darks 发表时间:2001年7月31日 15:49 -------------------------------------------------------------------------------- 所以es为 char 增加一个start_call_out 来处理这个问题 作为一个call_out本身 他不应该在me这个对象不存在的时候 取消call_out 这不符合这个函数的原则 这个函数的原意就是延时呼叫 参数传递以后 应该做新的判断 就好像 x/0 这不能作为bug来处理 我是这么认为的 我更喜欢说 嗨 jackyboy 你写了这个代码会出错的 :) 作者:doing 发表时间:2001年7月31日 19:36 -------------------------------------------------------------------------------- 所以es为 char 增加一个start_call_out 来处理这个问题 作为一个call_out本身 他不应该在me这个对象不存在的时候 取消call_out 其实 start_call_out 并不在于这个目的。事实上即使是 ob 自身呼叫的顶时器,在 析构的时候也不会自动清除 call_out 的。 而且 es 里面的 start_call_out 几乎可以说就是一个 bug,没有任何用处。因为如果 定时器发起者调用 ob 的 start_call_out,但是如果在定时器呼叫前发起者就被析构了 的话,结果该定时器也无法执行 -- 因为定时器中的函数 owner 被析构了。如果需要使 用这个功能,必须用 bind。 这不符合这个函数的原则 这个函数的原意就是延时呼叫 参数传递以后 应该做新的判断 就好像 x/0 这不能作为bug来处理 我是这么认为的 我更喜欢说 嗨 jackyboy 你写了这个代码会出错的 :) 代码当然是错的,但是不能搞得系统当机呢,否则说明系统有问题啊。 作者:find 发表时间:2001年7月31日 21:10 -------------------------------------------------------------------------------- 在 es2 系统里 tell_object 好像是一个 simul efun, 再此函数里做个检查就是了,但 tell_object 函数使用频率过高, 这会降低执行效率。 这其实就象是 C 和 BASIC,C 把责任交给程序员,C 不做严格的 检查,你的代码有问题他也一样执行,出问题就挂,这有机高的效 率。BASIC 有严格的检查机制,分担了程序员的责任,但是效率 极其低下。 要成为一个高效的系统,就要尽量减少 MudOS 和 LIB 底层的检查 机制,同时严格把关,提高代码质量。要不就加大检查力度,但效 率的代价是必须要负的 以上转引自www.niub.net之mud制作讨论组 |
![]() |
![]() |