Welcome to the Builder Academy

Question tba having "Heart Attacks" - signal 10, Bus error

More
01 Jul 2015 17:01 - 02 Jul 2015 01:21 #5361 by krell
Prior to my logon issue I was having some trouble where I would logon successfully to the MUD (local version) and, after a whilee the MUD would crash. Now that my logon issue appears to be resolved the random crashing issue persists. I've pasted some details from the gdb output below. I'll include the backtrace later. Anyhow, it appears to have something to do with the DG Script.

Sorry I'm doing this between my phone and my server. I don't have constant access to the internet ATM.
Code:
GNU gdb 6.3 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "amd64-unknown-openbsd5.8"... Core was generated by `circle'. Program terminated with signal 10, Bus error. Loaded symbols for <snipped>/bin/circle Reading symbols from /usr/lib/libc.so.79.0...done. Loaded symbols for /usr/lib/libc.so.79.0 Reading symbols from /usr/libexec/ld.so...done. Loaded symbols for /usr/libexec/ld.so #0 0x00001f27e9c51220 in timer_otrigger (obj=0x0) at dg_triggers.c:659 659 if (TRIGGER_CHECK(t, OTRIG_TIMER)) { (gdb)

When I list the code around the deepest level of the crash:
Code:
#0 0x00001f27e9c51220 in timer_otrigger (obj=0x0) at dg_triggers.c:659 659 if (TRIGGER_CHECK(t, OTRIG_TIMER)) { (gdb) list 654 655 if (!SCRIPT_CHECK(obj, OTRIG_TIMER)) 656 return; 657 658 for (t = TRIGGERS(SCRIPT(obj)); t; t = t->next) { 659 if (TRIGGER_CHECK(t, OTRIG_TIMER)) { 660 script_driver(&obj, t, OBJ_TRIGGER, TRIG_NEW); 661 } 662 } 663

The aforepromised backtrace.
Code:
(gdb) bt #0 0x00001f27e9c51220 in timer_otrigger (obj=0x0) at dg_triggers.c:659 #1 0x00001f27e9d29707 in point_update () at limits.c:456 #2 0x00001f27e9d9030c in heartbeat (heart_pulse=750) at comm.c:1006 #3 0x00001f27e9d900a2 in game_loop (local_mother_desc=3) at comm.c:946 #4 0x00001f27e9d8f0b2 in init_game (local_port=4000) at comm.c:534 #5 0x00001f27e9d8e83f in main (argc=3, argv=0x7f7ffffe50f8) at comm.c:354 (gdb)
Last edit: 02 Jul 2015 01:21 by krell.

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

More
01 Jul 2015 21:02 #5362 by thomas
#0 0x00001f27e9c51220 in timer_otrigger (obj=0x0) at dg_triggers.c:659

So, timer_otrigger is called with a NULL arg, from point_update, no less. How does point_update() (in limits.c) look for you? (just the code pertaining to objects).

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

More
01 Jul 2015 22:12 - 02 Jul 2015 03:38 #5364 by krell
Yeah, I noticed the NULL but I didn't know if it was legal or not for a pointer of the obj_data structure. Anyhow, here's the code segment in limits.c for objects.
Code:
/* objects */ for (j = object_list; j; j = next_thing) { next_thing = j->next; /* Next in object list */ /* If this is a corpse */ if (IS_CORPSE(j)) { /* timer count down */ if (GET_OBJ_TIMER(j) > 0) GET_OBJ_TIMER(j)--; if (!GET_OBJ_TIMER(j)) { if (j->carried_by) act("$p decays in your hands.", FALSE, j->carried_by, j, 0, TO_CHAR); else if ((IN_ROOM(j) != NOWHERE) && (world[IN_ROOM(j)].people)) { act("A quivering horde of maggots consumes $p.", TRUE, world[IN_ROOM(j)].people, j, 0, TO_ROOM); act("A quivering horde of maggots consumes $p.", TRUE, world[IN_ROOM(j)].people, j, 0, TO_CHAR); } for (jj = j->contains; jj; jj = next_thing2) { next_thing2 = jj->next_content; /* Next in inventory */ obj_from_obj(jj); if (j->in_obj) obj_to_obj(jj, j->in_obj); else if (j->carried_by) obj_to_room(jj, IN_ROOM(j->carried_by)); else if (IN_ROOM(j) != NOWHERE) obj_to_room(jj, IN_ROOM(j)); else core_dump(); } extract_obj(j); } } /* If the timer is set, count it down and at 0, try the trigger * note to .rej hand-patchers: make this last in your point-update() */ else if (GET_OBJ_TIMER(j)>0) { GET_OBJ_TIMER(j)--; if (!GET_OBJ_TIMER(j)) timer_otrigger(j); } }
Last edit: 02 Jul 2015 03:38 by krell. Reason: corrected obj_type to obj_data

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

More
02 Jul 2015 17:55 #5368 by krell
Code:
* objects */ for (j = object_list; j; j = next_thing) { next_thing = j->next; /* Next in object list */

If j is a pointer iterate j to point to the value of NEXT_thing and repeat the loop.

So if NEXT_thing is NULL then j will be NULL throughout that iteration of the loop.

is some sort of sanity check required to prevent passing a NULL to TIMER_otrigger() or should j being a NULL not matter?

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

More
02 Jul 2015 21:04 #5369 by thomas
There are two problems here.

The symptom, which is giving you grief, of having a null pointer sent to a function that dereferences it. This is easily remedied by adding a null check, as you're mentioning.

The cause, which doesn't reside in this loop.
The reason for the "next_thing = j->next;" is that the object could be extracted (and is extracted for sure if it's a corpse where the timer runs out) in the loop. If the loop was "...;j = j->next) {" this would bite us.
The next problem is that it shouldn't be possible for j to be NULL. The loop variable is checked for null-ness in the for loop (that's the "; j;" part). This in turn makes me think that the problem isn't this null pointer - it could be a fluke in the debugger, stack corruption or similar.

One thing you can do to log a little more info on which objects you're triggering.
Switch out

if (!GET_OBJ_TIMER(j))
timer_otrigger(j);

with

if (!GET_OBJ_TIMER(j)) {
log("triggering timer for object %d", GET_OBJ_VNUM(j));
timer_otrigger(j);
}

Now you should get output for every timer you're triggering. The last one is the one with the problem.

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

More
02 Jul 2015 23:11 #5372 by krell
So...I guess that makes me the proverbial man with the proverbial hammer looking for the proverbial nail.

Okay, I'll make that modification and report my results.

***Today's word is "Proverbial" brought to you by the letter "P".***

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

Time to create page: 0.385 seconds