14 Nov, 2008, Sorano wrote in the 1st comment:
Votes: 0
Hello. I am hoping in reaching out to those wiser than I, I can move past my current frustration. I'll break this up to backstory and issue - so that if you want to skip the details on how I got to where I am at (not sure how relevant it may be) you can jump straight to what the issue is.

Backstory:
I have decided to start a new mud as a side project. It has been years since I worked on muds, and my memory is beyond rusty. I decided to revamp an old project from scratch. Premise is a PK mud with 3 tiers on a RoT codebase (yeah - I realize it's been done, but that is the only relevant information to this situation). I had obtained a copy of rot 1.4 with OLC … added all my races and classes - and then added my code for tier 3 classes, and was having difficulty getting the game to compile. So I stripped out the code for tier 3 and left in the classes. Game compiled and I used my IMP character to "advance" a new character to hero. Then I used the reroll function. Everything worked as expected … that is until the rerolled character saved, then *crash* …

I had the shell open and received a large scrolling amount of text that started with *****glibc error**** double free or corruption. (i'll post actual details below). So I was like - "crap I broke it" … so I started from scratch - no changes this time, and tested hoping to see a perfect reroll. Everything was great - until saving the rerolled character … then *crash*. I went out and got a copy of the RoT sourcecode that was cleaned for gcc4 (I had been using gcc2.95.3 in my Makefile and had many warnings on compiling). So with a different and fresh source code I check - advance, reroll, save - crash.

I have tried four different variants of the RoT source code - with and without OLC, cleaned for gcc4 and not … and all result in the same glibc error.


Issue:
After a character has reached 101 (actually not by reaching, to be more specific, by being advanced to 101), I have it reroll. After reroll I get a glibc error. This happens whether the character types "save" or whether the worlds auto saves … it also occurs if the character tries to reroll a second time prior to the game saving. Basically any rerolled character seems to crash the mud whenever the system tries to save over the old player file. Save does not occur at all, as when the mud comes back from crash and player enters they start from the create a tier 2 character script. (I did notice that the script for reroll has the prompt jacked up and it reads "%hhp" instead of the "100hp" it should, but the glibc error occurs whether I correct this or not)

Here is the detail of what I am getting:

[USERNAME@server]$ ***glibc detected *** ./rot: double free or corruption (!prev): 0x08af24f8 ***
======= Backtrace: ========
/lib/i686/nosegneg/libc.so.6 [x281651]
/lib/i686/nosegneg/libc.so.6(cfree+0x90)[0x284cd0]
/lib/i686/nosegneg/libc.so.6(fclose+0x136)[0x26fda6]
./rot [0x80ae2ae]
./rot [0x804b3d4]
./rot [0x8099706]
./rot [0x8072d78]
./rot [0x807b74c]
./rot [0x807bc25]
/lib/i686/nosegneg/libc.so.6(__libc_start_main+0xe0)[0x22d390]
./rot[0x8048d51]
======= Memory map: =======
001f8000-00213000 r-xp 00000000 fd:00 98470 /lib/ld-2.7.so

the memory map stuff goes on for about 20 lines (not sure if it was needed, if so let me know and I can post the rest of it

and it ends with a final line that reads

bfb55000-bfb6b000 rw-p bfb55000 00:00 0 [stack]
Abort (core dumped)


So that is what I get. I really don't want to run without a second tier (as I said I wanted three), but if I can't fix this I am going to have to dump the reroll. However, like I said this is a stock sourcecode doing this - and one that has been around a long time, so I am really hoping that someone else has seen this and it correctable by an entry level mud coder.

Thanks for any help or insight.
Sorano
14 Nov, 2008, David Haley wrote in the 2nd comment:
Votes: 0
I would very strongly suggest that you run this through valgrind – it will identify exactly where your problem occurs. Even just running it through gdb would be very helpful. There are several articles on gdb/valgrind lying around here and on other sites that should give you an idea on how to get started, and we can help you more once we get the output from those tools.
14 Nov, 2008, Sorano wrote in the 3rd comment:
Votes: 0
thanks for the quick response. I will try and spend some time researching those tools and how to get them going - and hopefully have some detail later tonight.
14 Nov, 2008, David Haley wrote in the 4th comment:
Votes: 0
Just to give you some more background on the tools:

gdb is the debugger counterpart to gcc. It lets you do things like step through your code one line at a time, pause execution and look at variable values; it also halts the program on a crash and lets you figure out where you are in the code.

valgrind is a tool that simulates your program's execution, storing all kinds of extra information such as what memory has been allocated, initialized, freed, and so forth. It is extremely good at finding memory problems like double-frees (which looks like what you've got here).
15 Nov, 2008, Tyche wrote in the 5th comment:
Votes: 0
15 Nov, 2008, Sorano wrote in the 6th comment:
Votes: 0
So I am completely green here, but I imagine what you need is the information from glb from the core dump.

(the below was preceded by a bunch of lib reading and such by I imagined that was not important as much as the below)

Core was generated by './rot 1100 4934'.
Program terminated with signal 6, Aborted.
#0 0x00113402 in __kernel_vsyscall ()

I also did the 'bt' command:
#0 0x00112402 in __Kernel_vsyscall ()
#1 0x002408a0 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2 0x00242271 in abort () at abort.c:88
#3 0x002794db in __libc_message (do_abort=2,
fmt=0x344884 "*** glibc detected *** %s: %s: 0x%s ***\n")
at ../sysdeps/unix/sysv/linux/libc_fatal.c:170
#4 0x00281651 in _int_free (av=0x370120, mem=0x9ef74f8) at malloc.c:5891
#5 0x00284cd0 in __libc_free (mem=0x9ef74f8) at malloc.c:3626
#6 0x0026fda6 in _IO_new_fclose (fp=0x9ef74f8) at iofclose.c:88
#8 0x0804b3d4 in do_save (ch=0xb79e513c, argument=0xb79e46d9 "")
at act_comm.c:2650
#9 0x08099706 in interpret (ch=0xb79e513c, argument=0xb79e46d5 "save")
at interp.c:621
#10 0x08072d78 in substitute_alias (d=0xb79e42b8, argument=0xb79e46d5 "save")
at alias.c:72
#11 0x0807b74c in game_loop_unix (control=4, wwwcontrol=5) at comm.c:894
#12 0x0807bc25 in main (argc=Cannot access memory at address 0x1c34) at comm.c:449


I have not tried valgrind yet. I appreciate the support, and let me know if I need to post any additional information.
15 Nov, 2008, Sorano wrote in the 7th comment:
Votes: 0
I didn't realize that running in valgrind would prevent the program from terminating based on the problem. Is that normal? too bad it is such a memory hog, or I would just leave it running through valgrind … anyway, I am going to post two posts back to back. The first is the log when I ran the valgrind and logged into the account answer the tier 2 creation questions, and then tried to do a save. The second (next post) will be one when I did a -v … not sure exactly what was grabbed, but in my research of how to use valgrind it was stated it would be more detailed.


———–Output of Valgrind log based on events that will cause crash running normally —–

==11661== My PID = 11661, parent PID = 10447. Prog and args are:
==11661== ./rot
==11661==
==11661== Invalid read of size 1
==11661== at 0x406A29D: fclose@@GLIBC_2.1 (iofclose.c:52)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A5E is 70 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 1
==11661== at 0x406A2A7: fclose@@GLIBC_2.1 (iofclose.c:57)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A19 is 1 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A2B1: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A2B8: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A60 is 72 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A2C2: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB8 is 160 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A2D9: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB0 is 152 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A2E2: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A60 is 72 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid write of size 4
==11661== at 0x406A2E5: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB8 is 160 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A2E8: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB4 is 156 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A2EC: fclose@@GLIBC_2.1 (iofclose.c:60)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A30E: fclose@@GLIBC_2.1 (libioP.h:969)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A60 is 72 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A311: fclose@@GLIBC_2.1 (libioP.h:969)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB4 is 156 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid write of size 4
==11661== at 0x406A319: fclose@@GLIBC_2.1 (libioP.h:969)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB4 is 156 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid write of size 4
==11661== at 0x406A415: fclose@@GLIBC_2.1 (libioP.h:969)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB8 is 160 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A427: fclose@@GLIBC_2.1 (libioP.h:969)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AB0 is 152 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 1
==11661== at 0x406A322: fclose@@GLIBC_2.1 (iofclose.c:66)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A5E is 70 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A326: fclose@@GLIBC_2.1 (iofclose.c:66)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252AAC is 148 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x407664A: _IO_file_finish@@GLIBC_2.1 (fileops.c:206)
==11661== by 0x406A33A: fclose@@GLIBC_2.1 (iofclose.c:66)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A50 is 56 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x4077CE6: _IO_default_finish (genops.c:690)
==11661== by 0x4076689: _IO_file_finish@@GLIBC_2.1 (fileops.c:212)
==11661== by 0x406A33A: fclose@@GLIBC_2.1 (iofclose.c:66)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A34 is 28 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x4077CF2: _IO_default_finish (genops.c:696)
==11661== by 0x4076689: _IO_file_finish@@GLIBC_2.1 (fileops.c:212)
==11661== by 0x406A33A: fclose@@GLIBC_2.1 (iofclose.c:66)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A48 is 48 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x4077D0D: _IO_default_finish (genops.c:699)
==11661== by 0x4076689: _IO_file_finish@@GLIBC_2.1 (fileops.c:212)
==11661== by 0x406A33A: fclose@@GLIBC_2.1 (iofclose.c:66)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A3C is 36 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 1
==11661== at 0x4076B47: _IO_un_link (genops.c:65)
==11661== by 0x4077D2A: _IO_default_finish (genops.c:705)
==11661== by 0x4076689: _IO_file_finish@@GLIBC_2.1 (fileops.c:212)
==11661== by 0x406A33A: fclose@@GLIBC_2.1 (iofclose.c:66)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A33B: fclose@@GLIBC_2.1 (iofclose.c:67)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A80 is 104 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid read of size 4
==11661== at 0x406A400: fclose@@GLIBC_2.1 (iofclose.c:82)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A3C is 36 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid write of size 4
==11661== at 0x406A3A8: fclose@@GLIBC_2.1 (iofclose.c:87)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
==11661==
==11661== Invalid free() / delete / delete[]
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)
15 Nov, 2008, Sorano wrote in the 8th comment:
Votes: 0
—– version of output when causing the same would be crash with '-v' ———-

–11538– Contents of /proc/version:
–11538– Linux version 2.6.21.7-3.fc8xen (mockbuild@xenbuilder4.fedora.phx.redhat.com) (gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)) #1 SMP Thu Mar 20 14:57:53 EDT 2008
–11538– Arch and hwcaps: X86, x86-sse1-sse2
–11538– Page sizes: currently 4096, max supported 4096
–11538– Valgrind library directory: /usr/lib/valgrind
–11538– Reading syms from /lib/ld-2.7.so (0x1F8000)
–11538– Reading debug info from /usr/lib/debug/lib/ld-2.7.so.debug…
–11538– Reading syms from /home/mud/jayque78/rot/area/rot (0x8048000)
–11538– Reading syms from /usr/lib/valgrind/x86-linux/memcheck (0x38000000)
–11538– object doesn't have a dynamic symbol table
–11538– Reading suppressions file: /usr/lib/valgrind/default.supp
–11538– REDIR: 0x20DBB0 (index) redirected to 0x38027F5F (vgPlain_x86_linux_REDIR_FOR_index)
–11538– Reading syms from /usr/lib/valgrind/x86-linux/vgpreload_core.so (0x4001000)
–11538– Reading syms from /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so (0x4003000)
==11538== WARNING: new redirection conflicts with existing – ignoring it
–11538– new: 0x0020DBB0 (index ) R-> 0x04006230 index
–11538– REDIR: 0x20DD50 (strlen) redirected to 0x40062E0 (strlen)
–11538– Reading syms from /lib/libcrypt-2.7.so (0x402000)
–11538– Reading debug info from /usr/lib/debug/lib/libcrypt-2.7.so.debug…
–11538– Reading syms from /lib/libc-2.7.so (0x4012000)
–11538– Reading debug info from /usr/lib/debug/lib/libc-2.7.so.debug…
–11538– REDIR: 0x40824C0 (rindex) redirected to 0x4006110 (rindex)
–11538– REDIR: 0x4082120 (strlen) redirected to 0x40062C0 (strlen)
–11538– REDIR: 0x407DB00 (malloc) redirected to 0x40054A0 (malloc)
–11538– REDIR: 0x4083890 (memcpy) redirected to 0x4007090 (memcpy)
–11538– REDIR: 0x407F060 (free) redirected to 0x40050BA (free)
–11538– REDIR: 0x4081C30 (strcpy) redirected to 0x40072F0 (strcpy)
–11538– REDIR: 0x4081BC0 (strcmp) redirected to 0x4006390 (strcmp)
–11538– REDIR: 0x4084220 (strchrnul) redirected to 0x40066F0 (strchrnul)
–11538– REDIR: 0x40821D0 (strnlen) redirected to 0x4006290 (strnlen)
–11538– REDIR: 0x4083400 (mempcpy) redirected to 0x4006B70 (mempcpy)
–11538– REDIR: 0x407D810 (calloc) redirected to 0x40047CD (calloc)
–11538– REDIR: 0x40833A0 (memset) redirected to 0x4006640 (memset)
–11538– REDIR: 0x4082410 (strncpy) redirected to 0x4006930 (strncpy)
–11538– REDIR: 0x40818A0 (strcat) redirected to 0x40073E0 (strcat)
15 Nov, 2008, Sorano wrote in the 9th comment:
Votes: 0
OK so I have gone through and pulled out all of the code that was listed. Rather than just pull the line specified, I have pulled the surrounding code so that you may review in context. Please note that the save function DOES work, as stated, just fine as long as it does not inolve a rerolled character. Also while us Valgrind the player file was able to save. These saved "tier 2" players function just fine and do not cause a crash on save. It is only a player that has rerolled and his new race/class/level has not yet been saved to a player file. When that save is attempted that is when the crash occurs. It occurs on save (if typed by the rerolled character) as well as when the world attempts to autosave and a rerolled character who still has a player file that is not saved with post-reroll information is logged in.

I will attempt to format the below text to make it easier to key in on what is being called by valgrind and what is showing in code (specified lines will be in bold red). Perhaps the situation will be obvious to someone, but as I am but ankle deep in knowledge right now my head is completely under the Ocean.



==11661== Invalid free() / delete / delete[]
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)


void save_char_obj( CHAR_DATA *ch )
{
char strsave[MAX_INPUT_LENGTH];
FILE *fp;

if ( IS_NPC(ch) )
return;

if ( ch->desc != NULL && ch->desc->original != NULL )
ch = ch->desc->original;

#if defined(unix)
/* create god log */
if (IS_IMMORTAL(ch) || ch->level >= LEVEL_IMMORTAL)
{
fclose(fpReserve);
sprintf(strsave, "%s%s",GOD_DIR, capitalize(ch->name));
if ((fp = fopen(strsave,"w")) == NULL)
{
bug("Save_char_obj: fopen",0);
perror(strsave);
}

fprintf(fp,"Lev %2d Trust %2d %s%s\n",
ch->level, get_trust(ch), ch->name, ch->pcdata->title);
fclose( fp );
fpReserve = fopen( NULL_FILE, "r" );
}
#endif

fclose( fpReserve );
sprintf( strsave, "%s%s", PLAYER_DIR, capitalize( ch->name ) );
if ( ( fp = fopen( TEMP_FILE, "w" ) ) == NULL )
{
bug( "Save_char_obj: fopen", 0 );
perror( strsave );
}
else
{
fwrite_char( ch, fp );
if ( ch->carrying != NULL )
fwrite_obj( ch, ch->carrying, fp, 0 );
/* save the pets */
if (ch->pet != NULL)
fwrite_pet(ch->pet,fp);
fprintf( fp, "#END\n" );
}
fclose( fp );
rename(TEMP_FILE,strsave);
fpReserve = fopen( NULL_FILE, "r" );
return;
}


==11661== by 0x804B3D3: do_save (act_comm.c:2650)

void do_save( CHAR_DATA *ch, char *argument )
{
if ( IS_NPC(ch) )
return;

save_char_obj( ch );
send_to_char("Saving. Remember that ROT has automatic saving.\n\r", ch);
WAIT_STATE(ch,4 * PULSE_VIOLENCE);
return;
}


*****Please note, while the above command was a forced save to cause the crash to show itself, this crash of a rerolled player's data being saved occurs on auto save, save, and reroll (which would call a save)*****

==11661== by 0x8099705: interpret (interp.c:621)

void interpret( CHAR_DATA *ch, char *argument )
{
char command[MAX_INPUT_LENGTH];
char logline[MAX_INPUT_LENGTH];
int cmd;
int trust;
bool found;

/*
* Placed here, so we don't have to worry about tildes, period.
* RW
*/
smash_tilde( argument );

/*
* Strip leading spaces.
*/
while ( isspace(*argument) )
argument++;
if ( argument[0] == '\0' )
return;

/*
* No hiding.
*/
REMOVE_BIT( ch->affected_by, AFF_HIDE );

/*
* Implement freeze command.
*/
if ( !IS_NPC(ch) && IS_SET(ch->act, PLR_FREEZE) )
{
send_to_char( "You're totally frozen!\n\r", ch );
return;
}

/*
* Grab the command word.
* Special parsing so ' can be a command,
* also no spaces needed after punctuation.
*/
strcpy( logline, argument );
if ( !isalpha(argument[0]) && !isdigit(argument[0]) )
{
command[0] = argument[0];
command[1] = '\0';
argument++;
while ( isspace(*argument) )
argument++;
}
else
{
argument = one_argument( argument, command );
}

/*
* Look for command in command table.
*/
found = FALSE;
trust = get_trust( ch );
for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++ )
{
if ( command[0] == cmd_table[cmd].name[0]
&& !str_prefix( command, cmd_table[cmd].name )
&& cmd_table[cmd].level <= trust )
{
if (cmd_table[cmd].tier == 1)
{
found = TRUE;
break;
} else if (ch->class >= MAX_CLASS/2)
{
found = TRUE;
break;
} else if (ch->level >= LEVEL_HERO)
{
found = TRUE;
break;
}
}
}

/*
* Log and snoop.
*/
if ( cmd_table[cmd].log == LOG_NEVER )
strcpy( logline, "" );

if ( ( !IS_NPC(ch) && IS_SET(ch->act, PLR_LOG) )
|| fLogAll
|| (cmd_table[cmd].log == LOG_ALWAYS
&& ch->level != MAX_LEVEL ) )
{
sprintf( log_buf, "Log %s: %s", ch->name, logline );
wiznet(log_buf,ch,NULL,WIZ_SECURE,0,get_trust(ch));
log_string( log_buf );
}

if ( ch->desc != NULL && ch->desc->snoop_by != NULL )
{
write_to_buffer( ch->desc->snoop_by, "% ", 2 );
write_to_buffer( ch->desc->snoop_by, logline, 0 );
write_to_buffer( ch->desc->snoop_by, "\n\r", 2 );
}

if ( !found )
{
/*
* Look for command in socials table.
*/
if ( !check_social( ch, command, argument ) )
send_to_char( "Huh?\n\r", ch );
return;
}

/*
* Character not in position for command?
*/
if ( ch->position < cmd_table[cmd].position )
{
switch( ch->position )
{
case POS_DEAD:
send_to_char( "Lie still; you are DEAD.\n\r", ch );
break;

case POS_MORTAL:
case POS_INCAP:
send_to_char( "You are hurt far too bad for that.\n\r", ch );
break;

case POS_STUNNED:
send_to_char( "You are too stunned to do that.\n\r", ch );
break;

case POS_SLEEPING:
send_to_char( "In your dreams, or what?\n\r", ch );
break;

case POS_RESTING:
send_to_char( "Nah… You feel too relaxed…\n\r", ch);
break;

case POS_SITTING:
send_to_char( "Better stand up first.\n\r",ch);
break;

case POS_FIGHTING:
send_to_char( "No way! You are still fighting!\n\r", ch);
break;

}
return;
}

/*
* Dispatch the command.
*/
(*cmd_table[cmd].do_fun) ( ch, argument );
tail_chain( );
return;
}




==11661== by 0x8072D77: substitute_alias (alias.c:72)

void substitute_alias(DESCRIPTOR_DATA *d, char *argument)
{
CHAR_DATA *ch;
char buf[MAX_STRING_LENGTH],prefix[MAX_INPUT_LENGTH],name[MAX_INPUT_LENGTH];
char *point;
int alias;

ch = d->original ? d->original : d->character;

smash_tilde( argument );

/* check for prefix */
if (ch->prefix[0] != '\0' && str_prefix("prefix",argument))
{
if (strlen(ch->prefix) + strlen(argument) > MAX_INPUT_LENGTH)
send_to_char("Line to long, prefix not processed.\r\n",ch);
else
{
sprintf(prefix,"%s %s",ch->prefix,argument);
argument = prefix;
}
}

if (IS_NPC(ch) || ch->pcdata->alias[0] == NULL
|| !str_prefix("alias",argument) || !str_prefix("una",argument)
|| !str_prefix("prefix",argument))
{
interpret(d->character,argument);
return;
}



==11661== by 0x807B74B: game_loop_unix (comm.c:894)

#if defined(unix)
void game_loop_unix( int control, int wwwcontrol )
{
static struct timeval null_time;
struct timeval last_time;

signal( SIGPIPE, SIG_IGN );
gettimeofday( &last_time, NULL );
current_time = (time_t) last_time.tv_sec;

/* Main loop */
while ( !merc_down )
{
fd_set in_set;
fd_set out_set;
fd_set exc_set;
DESCRIPTOR_DATA *d;
int maxdesc;

#if defined(MALLOC_DEBUG)
if ( malloc_verify( ) != 1 )
abort( );
#endif

/*
* Poll all active descriptors.
*/
FD_ZERO( &in_set );
FD_ZERO( &out_set );
FD_ZERO( &exc_set );
FD_SET( control, &in_set );
maxdesc = control;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX( maxdesc, d->descriptor );
FD_SET( d->descriptor, &in_set );
FD_SET( d->descriptor, &out_set );
FD_SET( d->descriptor, &exc_set );
}

if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 )
{
perror( "Game_loop: select: poll" );
exit( 1 );
}

/*
* New connection?
*/
if ( FD_ISSET( control, &in_set ) )
init_descriptor( control );

FD_ZERO( &in_set );
FD_ZERO( &out_set );
FD_ZERO( &exc_set );
FD_SET( wwwcontrol, &in_set );
maxdesc = wwwcontrol;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX( maxdesc, d->descriptor );
FD_SET( d->descriptor, &in_set );
FD_SET( d->descriptor, &out_set );
FD_SET( d->descriptor, &exc_set );
}

if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 )
{
perror( "Game_loop: select: poll" );
exit( 1 );
}

if ( FD_ISSET( wwwcontrol, &in_set ) )
init_descriptor_www( wwwcontrol );

/*
* Kick out the freaky folks.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
if ( FD_ISSET( d->descriptor, &exc_set ) )
{
FD_CLR( d->descriptor, &in_set );
FD_CLR( d->descriptor, &out_set );
if ( d->character && d->character->level > 1)
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
}
}

/*
* Process input.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
d->fcommand = FALSE;

if ( FD_ISSET( d->descriptor, &in_set ) )
{
if ( d->character != NULL )
d->character->timer = 0;
if ( !read_from_descriptor( d ) )
{
FD_CLR( d->descriptor, &out_set );
if ( d->character != NULL && d->character->level > 1)
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
continue;
}
}

if (d->character != NULL && d->character->daze > 0)
–d->character->daze;

if ( d->character != NULL && d->character->wait > 0 )
{
–d->character->wait;
continue;
}

read_from_buffer( d );
if ( d->incomm[0] != '\0' )
{
d->fcommand = TRUE;
stop_idling( d->character );

/* OLC */
if ( d->showstr_point )
show_string( d, d->incomm );
else
if ( d->pString )
string_add( d->character, d->incomm );
else
switch ( d->connected )
{
case CON_PLAYING:
if ( !run_olc_editor( d ) )
substitute_alias( d, d->incomm );
break;
default:

nanny( d, d->incomm );
break;
}

d->incomm[0] = '\0';
}
}



==11661== by 0x807BC24: main (comm.c:449)

#if defined(unix)
control = init_socket( port );
wwwcontrol = init_socket( wwwport );
boot_db( );
sprintf( log_buf, "RoD is ready to rock on ports %d and %d.", port, wwwport );
log_string( log_buf );
game_loop_unix( control, wwwcontrol );
close (wwwcontrol);
close (control);
#endif


==11661== Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)


==11661== by 0x80AC400: load_char_reroll (save.c:829)


bool load_char_reroll( DESCRIPTOR_DATA *d, char *name )
{
CHAR_DATA *ch;
bool found;
int stat;

ch = new_char();
ch->pcdata = new_pcdata();

d->character = ch;
ch->desc = d;
ch->name = str_dup( name );
ch->id = get_pc_id();
ch->race = race_lookup("human");
ch->act = PLR_NOSUMMON;
ch->comm = COMM_COMBINE
| COMM_PROMPT
| COMM_STORE;
ch->prompt = str_dup("<%{Rhhp {M%mm {G%vmv{x>");
ch->pcdata->confirm_delete = FALSE;
ch->pcdata->pwd = str_dup( "" );
ch->pcdata->bamfin = str_dup( "" );
ch->pcdata->bamfout = str_dup( "" );
ch->pcdata->who_descr = str_dup( "" );
ch->pcdata->title = str_dup( "" );
ch->pcdata->tier = 1;
for (stat =0; stat < MAX_STATS; stat++)
ch->perm_stat[stat] = 13;
ch->pcdata->condition[COND_THIRST] = 48;
ch->pcdata->condition[COND_FULL] = 48;
ch->pcdata->condition[COND_HUNGER] = 48;

found = FALSE;
fclose( fpReserve );
return found;
}




==11661== by 0x8078303: nanny (comm.c:2125)


if (IS_SET(ch->act, PLR_REROLL ) )
{
sprintf( strsave, "%s%s", PLAYER_DIR, capitalize( ch->name ) );
sprintf(newbuf, "%s", str_dup( ch->pcdata->pwd ));
sprintf( argument, "%s", capitalize( ch->name ) );
free_char( d->character );
d->character = NULL;
fOld = load_char_reroll( d, argument );
ch = d->character;
free_string( ch->pcdata->pwd );
ch->pcdata->pwd = str_dup( newbuf );
newbuf[0] = '\0';
ch->pcdata->tier = 1;
ch->pcdata->socket = str_dup( d->host );
write_to_buffer( d, echo_on_str, 0 );
write_to_buffer(d,"The following races are available:\n\r\n\r",0);
pos = 0;
for ( race = 1; race_table[race].name != NULL; race++ )
{
if (!race_table[race].pc_race)
break;
sprintf(newbuf, "%6s%-24s", " ", race_table[race].name);
write_to_buffer(d,newbuf,0);
pos++;
if (pos >= 2) {
write_to_buffer(d,"\n\r",1);
pos = 0;
}
}
newbuf[0] = '\0';
write_to_buffer(d,"\n\r\n\r",0);
write_to_buffer(d,"What is your race (help for more information)? ",0);
d->connected = CON_GET_NEW_RACE;
break;
}



==11661== by 0x807B75F: game_loop_unix (comm.c:898)

#if defined(unix)
void game_loop_unix( int control, int wwwcontrol )
{
static struct timeval null_time;
struct timeval last_time;

signal( SIGPIPE, SIG_IGN );
gettimeofday( &last_time, NULL );
current_time = (time_t) last_time.tv_sec;

/* Main loop */
while ( !merc_down )
{
fd_set in_set;
fd_set out_set;
fd_set exc_set;
DESCRIPTOR_DATA *d;
int maxdesc;

#if defined(MALLOC_DEBUG)
if ( malloc_verify( ) != 1 )
abort( );
#endif

/*
* Poll all active descriptors.
*/
FD_ZERO( &in_set );
FD_ZERO( &out_set );
FD_ZERO( &exc_set );
FD_SET( control, &in_set );
maxdesc = control;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX( maxdesc, d->descriptor );
FD_SET( d->descriptor, &in_set );
FD_SET( d->descriptor, &out_set );
FD_SET( d->descriptor, &exc_set );
}

if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 )
{
perror( "Game_loop: select: poll" );
exit( 1 );
}

/*
* New connection?
*/
if ( FD_ISSET( control, &in_set ) )
init_descriptor( control );

FD_ZERO( &in_set );
FD_ZERO( &out_set );
FD_ZERO( &exc_set );
FD_SET( wwwcontrol, &in_set );
maxdesc = wwwcontrol;
for ( d = descriptor_list; d; d = d->next )
{
maxdesc = UMAX( maxdesc, d->descriptor );
FD_SET( d->descriptor, &in_set );
FD_SET( d->descriptor, &out_set );
FD_SET( d->descriptor, &exc_set );
}

if ( select( maxdesc+1, &in_set, &out_set, &exc_set, &null_time ) < 0 )
{
perror( "Game_loop: select: poll" );
exit( 1 );
}

if ( FD_ISSET( wwwcontrol, &in_set ) )
init_descriptor_www( wwwcontrol );

/*
* Kick out the freaky folks.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
if ( FD_ISSET( d->descriptor, &exc_set ) )
{
FD_CLR( d->descriptor, &in_set );
FD_CLR( d->descriptor, &out_set );
if ( d->character && d->character->level > 1)
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
}
}

/*
* Process input.
*/
for ( d = descriptor_list; d != NULL; d = d_next )
{
d_next = d->next;
d->fcommand = FALSE;

if ( FD_ISSET( d->descriptor, &in_set ) )
{
if ( d->character != NULL )
d->character->timer = 0;
if ( !read_from_descriptor( d ) )
{
FD_CLR( d->descriptor, &out_set );
if ( d->character != NULL && d->character->level > 1)
save_char_obj( d->character );
d->outtop = 0;
close_socket( d );
continue;
}
}

if (d->character != NULL && d->character->daze > 0)
–d->character->daze;

if ( d->character != NULL && d->character->wait > 0 )
{
–d->character->wait;
continue;
}

read_from_buffer( d );
if ( d->incomm[0] != '\0' )
{
d->fcommand = TRUE;
stop_idling( d->character );

/* OLC */
if ( d->showstr_point )
show_string( d, d->incomm );
else
if ( d->pString )
string_add( d->character, d->incomm );
else
switch ( d->connected )
{
case CON_PLAYING:
if ( !run_olc_editor( d ) )
substitute_alias( d, d->incomm );
break;
default:

nanny( d, d->incomm );
break;
}

d->incomm[0] = '\0';
}
}



==11661== by 0x807BC24: main (comm.c:449)


#if defined(unix)
control = init_socket( port );
wwwcontrol = init_socket( wwwport );
boot_db( );
sprintf( log_buf, "RoD is ready to rock on ports %d and %d.", port, wwwport );
log_string( log_buf );
game_loop_unix( control, wwwcontrol );
close (wwwcontrol);
close (control);
#endif
16 Nov, 2008, David Haley wrote in the 10th comment:
Votes: 0
Valgrind gave you some very interesting information here (even though it is admittedly very cryptic until you know what's going on)…

==11661== Invalid free() / delete / delete[]
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AE2AD: save_char_obj (save.c:142)
==11661== by 0x804B3D3: do_save (act_comm.c:2650)
==11661== by 0x8099705: interpret (interp.c:621)
==11661== by 0x8072D77: substitute_alias (alias.c:72)
==11661== by 0x807B74B: game_loop_unix (comm.c:894)
==11661== by 0x807BC24: main (comm.c:449)
==11661== Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
==11661== at 0x400513F: free (vg_replace_malloc.c:233)
==11661== by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
==11661== by 0x80AC400: load_char_reroll (save.c:829)
==11661== by 0x8078303: nanny (comm.c:2125)
==11661== by 0x807B75F: game_loop_unix (comm.c:898)
==11661== by 0x807BC24: main (comm.c:449)


Note in particular:

Invalid free() / delete / delete[]
by 0x80AE2AD: save_char_obj (save.c:142)

followed shortly by:

Address 0x4252A18 is 0 bytes inside a block of size 352 free'd
at 0x400513F: free (vg_replace_malloc.c:233)
by 0x406A3B5: fclose@@GLIBC_2.1 (iofclose.c:88)
by 0x80AC400: load_char_reroll (save.c:829)

This is telling you where your problem is. You are trying to free memory (via fclose) that you already freed (also via fclose) in load_char_reroll. In other words, you're closing a file twice. (One of the reasons why valgrind is such a memory/CPU hog is that it tracks every memory allocation made, which is how it can tell you here the exact line of code where the memory was previously freed.)

So now you need to investigate why the file is being closed in load_char_reroll, and whether you really need to be closing the file there.

In case you don't already feel comfortable with memory management, you should also try to read up a bit on what it means to free things twice and just general memory allocation, freeing, corruption and so forth.
16 Nov, 2008, Sorano wrote in the 11th comment:
Votes: 0
I commented out the fclose in load_char_reroll and the mud no longer crashes upon rerolled character save. I appreciate the help.

I will continue to play with it to see if I can figure the logic in having it there, and make sure it is not needed by any other sub-routine. I am curious as to why it was in the code - not the logic, but the fact that it was apparently not causing a problem for others running the same "out of the box" setup.

Pardon my noob ignorance on the code side, but does every system handle the code differently … ie if I were on a different server the double free might not have crashed the mud?
16 Nov, 2008, David Haley wrote in the 12th comment:
Votes: 0
Nope, a double-free is going to cause trouble no matter where it is. Are you sure that you didn't add this in during one of your projects? One thing you could do is compare your code to the "out of the box" setup by using tools like 'diff' that show you differences. (Actually, there are better tools for looking at differences; under Windows I suggest WinMerge or WinDiff (can't remember the name); for Linux, I'd recommend something like 'meld'.)
16 Nov, 2008, Sorano wrote in the 13th comment:
Votes: 0
Nope this was "my project free". I pulled 4 different versions of rot from various sources (mudbytes is the source of the active one I am using … the and always got the same thing. As I stated in the OP, I found this problem after a change I made - so I went back to scratch and found it in all of them.

Rot1.4OLCGCC4.tar.gz which was listed as Rot cleaned for gcc 4 was the latest one I downloaded from MudBytes. All I did was:
1) download to server
2) unzip contents
3) change startup port
4) run make clean
5) run make
6) start it up
7) create a character
8) log out and change player file to reflect IMP level (110)
9) log in
10) log in a new character
11) use "advance" to change character to 101
12) typed "reroll" two times (which saves the player file adding a reroll flag checked at login, and then boots the character)
13) login in
14) create tier 2 character (race/class/alignment/sex/skills/spells)
15) Game would continue to function until there was a save. If the player type "saved" it would crash. If the world auto-saved it would crash. if the character typed "reroll" twice to reroll again, it would crash.

I tried several different things, including not using advance but just setting the player file to level 101. Always the same result.

Knowing that this should have happened to anyone just seems odd. One that I couldn't find mention of it anywhere. Two that it would be the same setup from all rot source code download I took (with and without OLC, prepared and not prepared for gcc 4; all pooped out on saving a rerolled character).
16 Nov, 2008, Tyche wrote in the 14th comment:
Votes: 0
ROT is notoriously bug ridden.
0.0/14