Welcome to the Builder Academy

Question Crashing On Shutdown

More
20 Mar 2018 06:16 #7734 by Papaya Pete
This is a problem I've had for a while, but haven't really dealt with it seeing as it didn't really affect very much (except for the crafting snippet). I'm hoping that by taking a fresh look at it, perhaps the problem can be found.

So, I found that it is not the crafting snippet that is the problem; I removed it completely (I think?) and it still suffers the same crash. I looked over the gdb tutorial a little bit, and here are the results of doing a quick test.
Code:
Mar 19 23:01:50 :: Normal termination of game. Mar 19 23:01:50 :: Clearing game world. Mar 19 23:01:50 :: Clearing other memory. Mar 19 23:01:50 :: WARNING: Attempting to merge iterator to empty list. Mar 19 23:01:50 :: WARNING: Attempting to remove iterator from NULL list. Mar 19 23:01:50 :: WARNING: Attempting to remove contents that don't exist in list. Mar 19 23:01:50 :: WARNING: Attempting to merge iterator to empty list. Mar 19 23:01:50 :: WARNING: Attempting to remove iterator from NULL list. Mar 19 23:01:50 :: WARNING: Attempting to remove contents that don't exist in list. Program received signal SIGSEGV, Segmentation fault. 0x004e6d7a in next_in_list (pIterator=0x632cb0 <Iterator>) at lists.c:196 warning: Source file is more recent than executable. 196 pContent = pIterator->pItem ? pIterator->pItem->pContent : NULL; (gdb) bt #0 0x004e6d7a in next_in_list (pIterator=0x632cb0 <Iterator>) at lists.c:196 #1 0x004e6f5d in simple_list (pList=pList@entry=0x8003a2d0) at lists.c:274 #2 0x004e6ff6 in free_list (pList=0x8003a2d0) at lists.c:64 #3 0x0050456d in main (argc=2, argv=0x28ac2c) at comm.c:380 (gdb) info local pTempItem = 0x61 (gdb) list 191 /* Cycle down the list */ 192 pTempItem = pIterator->pItem->pNextItem; 193 pIterator->pItem = pTempItem; 194 195 /* Grab the content */ 196 pContent = pIterator->pItem ? pIterator->pItem->pContent : NULL; 197 198 return (pContent); 199 } 200 (gdb) up #1 0x004e6f5d in simple_list (pList=pList@entry=0x8003a2d0) at lists.c:274 274 if ((pContent = next_in_list(&Iterator)) != NULL) (gdb) list 269 return (pContent); 270 } else 271 return NULL; 272 } 273 274 if ((pContent = next_in_list(&Iterator)) != NULL) 275 return (pContent); 276 277 remove_iterator(&Iterator); 278 loop = FALSE; (gdb) info local pContent = <optimized out> (gdb) up #2 0x004e6ff6 in free_list (pList=0x8003a2d0) at lists.c:64 64 while ((pContent = simple_list(pList))) (gdb) list 59 void * pContent; 60 61 clear_simple_list(); 62 63 if (pList->iSize) 64 while ((pContent = simple_list(pList))) 65 remove_from_list(pContent, pList); 66 67 if (pList->iSize > 0) 68 mudlog(CMP, LVL_GOD, TRUE, "List being freed while not empty."); (gdb) info local pContent = <optimized out> (gdb) up #3 0x0050456d in main (argc=2, argv=0x28ac2c) at comm.c:380 380 free_list(global_lists); (gdb) list 375 free_save_list(); /* genolc.c */ 376 free_strings(&config_info, OASIS_CFG); /* oasis_delete.c */ 377 free_ibt_lists(); /* ibt.c */ 378 free_recent_players(); /* act.informative.c */ 379 free_list(world_events); /* free up our global lists */ 380 free_list(global_lists); 381 } 382 383 if (last_act_message) 384 free(last_act_message); (gdb) info local pos = <optimized out> dir = <optimized out> (gdb) up Initial frame selected; you cannot go up. (gdb)

While pTempItem has a value plugged into it, I noticed that every variable that comes before it has been optimized out. Is this the source of the problem? This is going into another area I'm not too familiar with and don't quite understand. I know that you want to free up memory at times (including shutting down), and that if you start messing with a pointer that is pointing to nothing you're going to start having problems.

Also, I'm pretty sure this is just a different way to do an if statement, but it drives me crazy because I don't easily understand the syntax.
Code:
pContent = pIterator->pItem ? pIterator->pItem->pContent : NULL;

Any insight into this would be greatly appreciated. I'm not sure how I exactly screwed up, or where; the pItem makes me think that perhaps it has to do with some changes I've made to items (durability). Hard to say.

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

More
20 Mar 2018 21:37 #7741 by thomas
Replied by thomas on topic Crashing On Shutdown
Well, the ? : construct is called the ternary operator. There's a whole wikipedia page about it : en.wikipedia.org/wiki/%3F :

It is indeed shorthand for an if statement.
Code:
int foo; if (condition) foo = x; else foo = y; vs. int foo = condition ? x : y;
In some cases it makes the code easier to read, and in others, not so much. Avoid nesting them :S

value <optimized out> simply means that the compiler has determined that the actual value of whatever variable is not referenced in the given context, so it hasn't bothered to actually make it available. Sometimes you want - for debugging purposes, for instance - to have the values all present.
To make this work, you'll need to alter your Makefile so it doesn't trigger so much optimization. Simply remove the -O2 from your flags line.

In this case, you are likely crashing because something isn't set up correctly earlier on:
Code:
Mar 19 23:01:50 :: WARNING: Attempting to merge iterator to empty list. Mar 19 23:01:50 :: WARNING: Attempting to remove iterator from NULL list. Mar 19 23:01:50 :: WARNING: Attempting to remove contents that don't exist in list. Mar 19 23:01:50 :: WARNING: Attempting to merge iterator to empty list. Mar 19 23:01:50 :: WARNING: Attempting to remove iterator from NULL list. Mar 19 23:01:50 :: WARNING: Attempting to remove contents that don't exist in list.
This looks quite strange to me; at this point, the lists should pretty well be pointing to something.

If this is a reproducible crash, I'd start by recompiling, starting, and connecting gdb to the process ("gdb bin/circle", then "attach <pid>" from within gdb. Add a breakpoint at where you are seeing the problem, "break comm.c:378", and trigger the problem.

This will allow you to debug the running code.
Interesting commands are "step" (steps into), "next" (steps over), "until" (steps over loops) and "finish" (steps out of). See ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_37.html#SEC38 . Also "print" which will print the value of anything following, for instance "print pContent" and "print *pContent".
My first plan would be to "next" until I see where those log statements come from...
The following user(s) said Thank You: Papaya Pete

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

More
23 Mar 2018 07:41 - 23 Mar 2018 07:57 #7764 by Papaya Pete
Replied by Papaya Pete on topic Crashing On Shutdown
Wow that makes ternary operators easier to understand! A newbie question however: I started doing the above steps (finally; I've been writing dialog and fixing little issues here and there before attempting to tackle this) and then realized I don't know what process ID I am supposed to become attached to. How would I find that out?

On a side note, I discovered a small bug that was giving a lot of errors and squashed it. Huzzah!

Edit:

I decided to repeat the previous action from before: up, list, info local. Here are the results of that:
Code:
Mar 23 00:53:48 :: WARNING: Attempting to merge iterator to empty list. Mar 23 00:53:48 :: WARNING: Attempting to remove iterator from NULL list. Mar 23 00:53:48 :: WARNING: Attempting to remove contents that don't exist in list. Mar 23 00:53:48 :: WARNING: Attempting to merge iterator to empty list. Mar 23 00:53:48 :: WARNING: Attempting to remove iterator from NULL list. Mar 23 00:53:48 :: WARNING: Attempting to remove contents that don't exist in list. Program received signal SIGSEGV, Segmentation fault. 0x0052c317 in next_in_list (pIterator=0x677c08 <Iterator>) at lists.c:196 196 pContent = pIterator->pItem ? pIterator->pItem->pContent : NULL; (gdb) bt #0 0x0052c317 in next_in_list (pIterator=0x677c08 <Iterator>) at lists.c:196 #1 0x0052c45e in simple_list (pList=0x8003a2d8) at lists.c:274 #2 0x0052bfce in free_list (pList=0x8003a2d8) at lists.c:64 #3 0x005244d1 in main (argc=2, argv=0x28ac2c) at comm.c:380 (gdb) info local pContent = 0x49d8c7 <mudlog+16> pTempItem = 0x61 (gdb) list 191 /* Cycle down the list */ 192 pTempItem = pIterator->pItem->pNextItem; 193 pIterator->pItem = pTempItem; 194 195 /* Grab the content */ 196 pContent = pIterator->pItem ? pIterator->pItem->pContent : NULL; 197 198 return (pContent); 199 } 200 (gdb) up #1 0x0052c45e in simple_list (pList=0x8003a2d8) at lists.c:274 274 if ((pContent = next_in_list(&Iterator)) != NULL) (gdb) list 269 return (pContent); 270 } else 271 return NULL; 272 } 273 274 if ((pContent = next_in_list(&Iterator)) != NULL) 275 return (pContent); 276 277 remove_iterator(&Iterator); 278 loop = FALSE; (gdb) info local pContent = 0x0 (gdb) up #2 0x0052bfce in free_list (pList=0x8003a2d8) at lists.c:64 64 while ((pContent = simple_list(pList))) (gdb) list 59 void * pContent; 60 61 clear_simple_list(); 62 63 if (pList->iSize) 64 while ((pContent = simple_list(pList))) 65 remove_from_list(pContent, pList); 66 67 if (pList->iSize > 0) 68 mudlog(CMP, LVL_GOD, TRUE, "List being freed while not empty."); (gdb) info local pContent = 0x61282b68 <_gm_+136> (gdb) up #3 0x005244d1 in main (argc=2, argv=0x28ac2c) at comm.c:380 380 free_list(global_lists); (gdb) list 375 free_save_list(); /* genolc.c */ 376 free_strings(&config_info, OASIS_CFG); /* oasis_delete.c */ 377 free_ibt_lists(); /* ibt.c */ 378 free_recent_players(); /* act.informative.c */ 379 free_list(world_events); /* free up our global lists */ 380 free_list(global_lists); 381 } 382 383 if (last_act_message) 384 free(last_act_message); (gdb) info local pos = 1 dir = 0x8003a1d8 "lib" (gdb) up Initial frame selected; you cannot go up. (gdb)

So this probably is just me, but this part right here doesn't look right.
Code:
277 remove_iterator(&Iterator); 278 loop = FALSE; (gdb) info local pContent = 0x0 <<<<<<--------------------------------- (gdb) up #2 0x0052bfce in free_list (pList=0x8003a2d8) at lists.c:64 64 while ((pContent = simple_list(pList)))

Wouldn't 0x0 mean no value? Or is this just read/interpreted differently because it's dealing with memory? If this is supposed to mean NULL, that could be a problem. Will take another look when I'm not tired.
Last edit: 23 Mar 2018 07:57 by Papaya Pete.

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

More
24 Mar 2018 01:30 #7777 by thomas
Replied by thomas on topic Crashing On Shutdown
You are right, 0x0 is a null pointer. But it's NULL because the assignment on that line hasn't happened yet.

What seems to be occurring is that the global_lists variable seem to be messed up.
I think this is more serious:
Code:
pTempItem = 0x61
This is supposed to be a pointer to the stored item. It obviously isn't. So, somewhere, there's an iff by one (or more) error. Finding that one is somewhat harder.

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

More
24 Mar 2018 01:36 #7778 by Papaya Pete
Replied by Papaya Pete on topic Crashing On Shutdown
I have a possible theory as to how it started. I'm going to plug the item durability snippet into a fresh batch of stock code and see if the problem comes up. If it does, I have an idea where to start. If not, more digging!

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

More
24 Mar 2018 07:54 #7784 by Papaya Pete
Replied by Papaya Pete on topic Crashing On Shutdown
So my bit of digging shows that the item durability snippet doesn't seem to be the problem; I plugged it into the stock tbamud code and no issues. I've been trying to go through the above process mentioned (break comm.c:379, step, info local, print) to try and figure out what's going on. It's not really making a whole lot of sense. I wish I could tell what exactly is in these different variables; does it have to do with the player files? Objects? Mobs?

Honestly, I'm not really sure what free_list(global_lists) even does. Hah, it would help if I understood what exactly the error was in the first place in order to fix it! What global variables does it deal with? Would taking out stock areas possibly cause an error like this? There's still a lot to tbamud (and coding in general) I don't understand. I'll be doing some reading here and there to see if I can get some answers, but any input would be appreciated; thank you for patiently answering my questions!

As much work as it would be, I'm sort of tempted to try plugging in all of my snippets into a fresh batch of code, one by one, and see if one of them is the problem. The talk and ask chain will be very difficult, because (thanks to me walking away from coding for a few months) I can't remember exactly all the work that went into it.

Side note: rebooting the mud does NOT trigger the crash. "Shutdown" and "shutdown die" do trigger it. I suppose that narrows it down slightly!

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

Time to create page: 0.427 seconds