- Posts: 937
- Thank you received: 17
Wierd crash - Need help to locate the problem from this GDB info
- JTP
- Topic Author
- Offline
- Platinum Member
-
(gdb) up
#1 0x002e1b10 in raise () from /lib/libc.so.6
(gdb) up
#2 0x002e3421 in abort () from /lib/libc.so.6
(gdb) up
#3 0x080f30dd in char_from_room (ch=0xa82bc30) at handler.c:395
395 abort();
(gdb) up
#4 0x080ca48d in do_mteleport (ch=0xa6c66d8, argument=0xbf89b7ad " }722 2311", cmd=0, subcmd=0) at dg_mobcmd.c:615
615 char_from_room(vict);
(gdb) up
#5 0x08105246 in script_command_interpreter (ch=0xa6c66d8, arg=0xbf89b7a4 "mteleport }722 2311") at interpreter.c:510
510 ((*mob_script_commands[i].command_pointer) (ch, line, 0,
(gdb) up
#6 0x080d604c in script_driver (go_adress=0xbf89ba68, trig=0xa6c68b0, type=0, mode=1) at dg_scripts.c:2670
2670 if (!script_command_interpreter((char_data *) go, cmd))
(gdb) up
#7 0x080d6152 in trig_wait_event (event_obj=0xad84b70) at dg_scripts.c:757
757 script_driver(&go, trig, type, TRIG_RESTART);
(gdb) up
#8 0x080c827a in event_process () at dg_event.c:126
126 if ((new_time = (the_event->func)(the_event->event_obj)) > 0)
(gdb) up
#9 0x080b6531 in heartbeat (heart_pulse=393536) at comm.c:974
974 event_process();
(gdb) up
#10 0x080b98c8 in game_loop (local_mother_desc=3) at comm.c:941
941 heartbeat(++pulse);
(gdb) up
#11 0x080bb487 in init_game (argc=Cannot access memory at address 0x46a
) at comm.c:536
536 game_loop(mother_desc);
(gdb) up
#12 main (argc=Cannot access memory at address 0x46a
) at comm.c:356
356 init_game(port);
What is happening ?
After reboot this was in file error from the time of the crash:
Apr 6 12:55:06 :: SYSERR: NULL character or NOWHERE in handler.c, char_from_room
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 818
- Thank you received: 159
And indeed - there is a check to make sure the game is in a consistent state when calling char_from_room():
/* move a player out of a room */
void char_from_room(struct char_data *ch)
{
struct char_data *temp;
if (ch == NULL || IN_ROOM(ch) == NOWHERE) {
log("SYSERR: NULL character or NOWHERE in %s, char_from_room", __FILE__);
exit(1);
}
...
So, whoever is being teleported was in NOWHERE when they were moved from the room.
This might happen if they just died, I think.
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 818
- Thank you received: 159
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
Trigger Intended Assignment: Mobiles
Trigger Type: Greet-All , Numeric Arg: 100, Arg list: None
Commands:
if %actor.class% != Thief
wait 1 sec
%send% %actor% %self.name% ...
%echoaround% %actor% %self.name% ... %actor.name% ...
wait 1 sec
%asound% %actor.name% ...
%teleport% %actor% 2311
%force% %actor% look
else
wait 1 sec
emote ...
say bla bla
end
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 818
- Thank you received: 159
At least I can extrapolate on how it fails.
Assume char X enters the room
X is not a thief, so he triggers the first if
The trigger waits a sec
... sends something to X
... and X's room
X quits (or rents out, or dies). X is now not in a room. But X is still online, so the trigger isn't stopped.
The trigger sends something to the room
... and attempts to move X
This fails, because X no longer is in the game (but at the menu, doing whatever).
So, how to fix this?
Either,
1) in the action functions (%force%, %teleport%, etc), checking if the player is in game before performing an action on them, or
2) when waking after waitstates, check that the player is actually a valid target
It turns out we have 1) in place in most such functions, but miss it in do_mteleport github.com/tbamud/tbamud/blob/master/src/dg_mobcmd.c#L624 :
} else {
if (*arg1 == UID_CHAR) {
if (!(vict = get_char(arg1))) {
mob_log(ch, "mteleport: victim (%s) does not exist",arg1);
return;
}
} else if (!(vict = get_char_vis(ch, arg1, NULL, FIND_CHAR_WORLD))) {
mob_log(ch, "mteleport: victim (%s) does not exist",arg1);
return;
}
- if (valid_dg_target(ch, DG_ALLOW_GODS)) {
+ if (valid_dg_target(vict, DG_ALLOW_GODS)) {
char_from_room(vict);
char_to_room(vict, target);
enter_wtrigger(&world[IN_ROOM(ch)], ch, -1);
}
}
}
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
- if (valid_dg_target(ch, DG_ALLOW_GODS)) {
+ if (valid_dg_target(vict, DG_ALLOW_GODS)) {
Below isnt needed after all ?
+ if (IN_ROOM(vict) == NOWHERE)
+ return;
+
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 818
- Thank you received: 159
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
That is still ch and ch or should also be vict ?
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 818
- Thank you received: 159
We're triggering an enter trigger in the new room we just sent vict to.
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
if (valid_dg_target(vict, DG_ALLOW_GODS)) {
char_from_room(vict);
char_to_room(vict, target);
enter_wtrigger(&world[IN_ROOM(ch)], ch, -1); <<<---but still ch and ch here.
And the else if:
if (valid_dg_target(ch, DG_ALLOW_GODS)) {
char_from_room(vict);
char_to_room(vict, target);
enter_wtrigger(&world[IN_ROOM(ch)], ch, -1);
Alittle confusing...is the all part corrent then ?
if (!str_cmp(arg1, "all")) {
if (target == IN_ROOM(ch)) {
mob_log(ch, "mteleport all target is itself");
return;
}
for (vict = world[IN_ROOM(ch)].people; vict; vict = next_ch) {
next_ch = vict->next_in_room;
if (valid_dg_target(vict, DG_ALLOW_GODS)) {
char_from_room(vict);
char_to_room(vict, target);
enter_wtrigger(&world[IN_ROOM(ch)], ch, -1);
}
}
} else {
if (*arg1 == UID_CHAR) {
if (!(vict = get_char(arg1))) {
mob_log(ch, "mteleport: victim (%s) does not exist",arg1);
return;
}
} else if (!(vict = get_char_vis(ch, arg1, NULL, FIND_CHAR_WORLD))) {
mob_log(ch, "mteleport: victim (%s) does not exist",arg1);
return;
}
if (valid_dg_target(ch, DG_ALLOW_GODS)) {
char_from_room(vict);
char_to_room(vict, target);
enter_wtrigger(&world[IN_ROOM(ch)], ch, -1);
}
}
}
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 818
- Thank you received: 159
github.com/tbamud/tbamud/pull/48/commits...5a8d86178dd23287c789
I also double-checked that oteleport and wteleport are correct. This is a long-standing bug. Nice that you could help make it go away :)
Please Log in or Create an account to join the conversation.
- JTP
- Topic Author
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
Im best at finding bugs, not so good at fixing them :
So was oteleport and wteleport ok ?
Please Log in or Create an account to join the conversation.
- Parnassus
- Offline
- Administrator
-
- Posts: 370
- Thank you received: 54
Trigger Intended Assignment: Mobiles
Trigger Type: Greet-All , Numeric Arg: 100, Arg list: None
Commands:
+ wait 1 sec
if %actor.class% != Thief
- wait 1 sec
%send% %actor% %self.name% ...
%echoaround% %actor% %self.name% ... %actor.name% ...
- wait 1 sec
%asound% %actor.name% ...
%teleport% %actor% 2311
+ wait 1 sec
%force% %actor% look
else
- wait 1 sec
emote ...
say bla bla
end
This gives much less time for movement although it's still possible. If this works, it might explain why the teleport crashes seem so random. My way would crash infrequently, the original way would crash sometimes, and it would never always crash.
Of course, finding the reason and fixing it beats lucky or unlucky triggers any time :)
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 818
- Thank you received: 159
The fix will make sure it works both ways, though :)
Please Log in or Create an account to join the conversation.