Welcome to the Builder Academy

Question simple_list forced to reset itself

More
28 Dec 2017 15:00 - 28 Dec 2017 16:36 #7285 by JTP
Ok after getting 2 of the messages in subject yesterday, i made it dump the core. Marked the line 1231 from fight.c

Hope one of you know whats wrong ?

If i need to post the lines of the other stuff from gdb let me know. Would be good to get fixed, must lie in the Stock code somewhere, since iwe not modificere simple_list.
Code:
(gdb) bt #0 0x00504402 in __kernel_vsyscall () #1 0x002e1b10 in raise () from /lib/libc.so.6 #2 0x002e3421 in abort () from /lib/libc.so.6 #3 0x0816b4d6 in core_dump_real (who=0x81b77f2 "lists.c", line=264) at utils.c:833 #4 0x0810916c in simple_list (pList=0xb446f68) at lists.c:264 #5 0x080e56d7 in perform_violence () at fight.c:1231 #6 0x080b54c5 in heartbeat (heart_pulse=56080) at comm.c:996 #7 0x080b8178 in game_loop (local_mother_desc=3) at comm.c:941 #8 0x080b9d37 in init_game (argc=Cannot access memory at address 0x391b ) at comm.c:536 #9 main (argc=Cannot access memory at address 0x391b ) at comm.c:356 /* control the fights going on. Called every 2 seconds from comm.c. */ void perform_violence(void) { struct char_data *ch, *tch; for (ch = combat_list; ch; ch = next_combat_list) { next_combat_list = ch->next_fighting; if (FIGHTING(ch) == NULL || IN_ROOM(ch) != IN_ROOM(FIGHTING(ch))) { stop_fighting(ch); continue; } if (IS_NPC(ch)) { if (GET_MOB_WAIT(ch) > 0) { GET_MOB_WAIT(ch) -= PULSE_VIOLENCE; continue; } GET_MOB_WAIT(ch) = 0; if (GET_POS(ch) < POS_FIGHTING) { GET_POS(ch) = POS_FIGHTING; act("$n scrambles to $s feet!", TRUE, ch, 0, 0, TO_ROOM); } if ((GET_HIT(FIGHTING(ch)) <= 12) && (MOB_FLAGGED(ch, MOB_MERCY))) { stop_fighting(FIGHTING(ch)); stop_fighting(ch); act("$n says: Blessed are the merciful, for they shall obtain mercy!", FALSE, ch, 0, 0, TO_ROOM); } // re-wield weapon lost to SKILL_DISARM if (LOST_WEAPON(ch)) { if (DISARM_WAIT(ch) > 0) { DISARM_WAIT(ch) -= PULSE_VIOLENCE; } else { do_wield(ch, OBJN(LOST_WEAPON(ch), ch), 0, 0); LOST_WEAPON(ch) = NULL; } } } if (GET_POS(ch) < POS_FIGHTING) { send_to_char(ch, "You can't fight while sitting!!\r\n"); continue; } if (GET_MOVE(ch) <= 0) continue; if (GROUP(ch)) { while ((tch = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL) { <<<---Line 1231 if (tch == ch) continue; if (!IS_NPC(tch) && !PRF_FLAGGED(tch, PRF_AUTOASSIST)) continue; if (IN_ROOM(ch) != IN_ROOM(tch)) continue; if (FIGHTING(tch)) continue; if (GET_POS(tch) != POS_STANDING) continue; if (!CAN_SEE(tch, ch)) continue; do_assist(tch, GET_NAME(ch), 0, 0); } } { hit(ch, FIGHTING(ch), TYPE_UNDEFINED); GET_MOVE(ch) -= 1; }




Update:
Just Saw it in fight...see pic.

Its happening when mobs assist it seems.
Attachments:
Last edit: 28 Dec 2017 16:36 by JTP.

Please Log in or Create an account to join the conversation.

More
29 Dec 2017 13:31 #7286 by thomas
I think this is occurring because simple_list() isn't reentrant.

It looks like you are using mud events for triggering multiple attacks. Those events internally use simple_list() for determining which events to trigger. Unfortunately, calling simple_list() inside a loop governed by a call to simple_list() won't work as you might think it would.
Instead, at least one of the places, one must use the "long work-around":
Code:
- if (GROUP(ch)) { - while ((tch = (struct char_data *) simple_list(GROUP(ch)->members)) != NULL) { + if (GROUP(ch) && GROUP(ch)->members && GROUP(ch)->members->iSize) { + struct iterator_data Iterator; + + tch = (struct char_data *) merge_iterator(&Iterator, GROUP(ch)->members); + for (; tch ; tch = next_in_list(&Iterator)) { if (tch == ch) continue; if (!IS_NPC(tch) && !PRF_FLAGGED(tch, PRF_AUTOASSIST)) continue; if (IN_ROOM(ch) != IN_ROOM(tch)) continue; if (FIGHTING(tch)) continue; if (GET_POS(tch) != POS_STANDING) continue; if (!CAN_SEE(tch, ch)) continue; do_assist(tch, GET_NAME(ch), 0, 0); } + remove_iterator(&Iterator); }

Please Log in or Create an account to join the conversation.

More
03 Jan 2018 19:12 #7290 by JTP
The code you wrote compiles fine, and first attempt to fight 6 mobs at the same time, didnt crash or give any error...will test some more...

Is: != NULL
No longer needed ?

Please Log in or Create an account to join the conversation.

More
03 Jan 2018 22:05 #7291 by thomas
You could add it in the for loop ( ; tch != NULL; ...), but it isn't necessary.

A for loop will evaluate a something pointing to NULL as false; since we have this in utils.h:
Code:
/* OS compatibility */ #ifndef NULL /** Just in case NULL is not defined. */ #define NULL (void *)0 #endif
And 0, as you might know, is evaluated to false.

Of course, if someone was to use an old, strange, architecture it might not work. But then, most of the rest of the code would fail.
The following user(s) said Thank You: WhiskyTest, JTP

Please Log in or Create an account to join the conversation.

More
17 Jan 2018 23:32 #7388 by JTP
Had not seen it for 2 weeks, just just this moment:

[ SYSERR: simple_list() forced to reset itself. ]

:( But didnt crash, just SYSERR in game

Please Log in or Create an account to join the conversation.

More
17 Jan 2018 23:34 #7389 by JTP
Seems a player used whirlwind at the moment, if that makes sense ?

Please Log in or Create an account to join the conversation.

Time to create page: 0.217 seconds