03 Mar, 2014, Naylor wrote in the 1st comment:
Votes: 0
Not sure if this is where I should post this or not. I know the folks over at DoT weren't able to help.

I am using Dawn of Time codebase, and since moving to an online server (genesismuds) we have been noticing that the game seems to be dumping a TON of junk into object extra desc fields when writing playerfiles…


I am at my limit on patience with this, and since it affects playerfiles AND areafiles it is highly aggitating to my builders as well. Anyone willing to help us fix it??


Some additional info: do not see this problem happening when running on desktop at home. only with instances of it on host server. home comp is windows, host of course is linux
03 Mar, 2014, Patriot wrote in the 2nd comment:
Votes: 0
Sorry i dont think server has anything to do with data getting dumped in wrong fields. That is a code issue.

Check to see if all allocated memory is properly freed.
03 Mar, 2014, Naylor wrote in the 3rd comment:
Votes: 0
I'm pretty sure it's got less to do with machine and OS and is a code issue. I merely mentioned the last bit of info because it was an oddity and one of the other staff thought it might help to make mention of it.

It's not that the data is getting dumped in the wrong field exactly, it's more of a crapload of data that should not have even been written ANYWHERE is getting dumped int the same spot every time, in amounts that are causing files that should be no more than 13 kb to become over 7k to upwards of 50k.

I am rather novice with C++.. I had not even looked at it until I started this project. Might you be willing to give me an idea what I should be looking for to check for if it is being freed properly?
03 Mar, 2014, Tyche wrote in the 4th comment:
Votes: 0
You might try running Viagra on the code. It should fix any ED problems.
03 Mar, 2014, Idealiad wrote in the 5th comment:
Votes: 0
Don't you mean Viagrind?
03 Mar, 2014, Darva wrote in the 6th comment:
Votes: 0
They mean (stripped of the silliness) Valgrind I haven't used c++, I don't know how DoT handles strings, but it sounds like you're writing strings that either aren't initialized, or aren't null terminated, or pointers that point off into hyperspace.

(I think, if you're testing in the IDE, on the desktop, the memory may be initialized to a specific value, but then, when run in the production environment, you no longer have that crutch… If I'm right, and you're running from the IDE, try compiling in release mode, and running that to see if the issue appears on the desktop as well.)
03 Mar, 2014, Tijer wrote in the 7th comment:
Votes: 0
Tyche said:
You might try running Viagra on the code. It should fix any ED problems.


i think that was an attempt of a pun by Tyche which obviously went right over everyones heads… E.D. (think on it :P)
03 Mar, 2014, Naylor wrote in the 8th comment:
Votes: 0
Viagra lol. Good one.

Will try to run this valgrind thing as soon as i can figure out how. As for the other suggestion about the strings being initialized and null termed.. I will try to check for that as well
04 Mar, 2014, Naylor wrote in the 9th comment:
Votes: 0
UPDATE:

Ran Valgrind… Readout confuses the hell out of me but one part I DEFINITELY understand is:

==6302== LEAK SUMMARY:
==6302== definitely lost: 3,815 bytes in 75 blocks
==6302== indirectly lost: 5,680 bytes in 355 blocks
==6302== possibly lost: 844,737 bytes in 129 blocks


Holy. Crap.


A lot of this is stuff I have not even touched.. so i'm kinda.. well lost on how to fix.
04 Mar, 2014, Naylor wrote in the 10th comment:
Votes: 0
Example of what I can't figure out-

how to i make this entry:

delete ((*result)-sizeof(int)*2);

use delete[] instead.. I have tried:

delete [((*result)-sizeof(int)*2)];
and
delete [(*result)-sizeof(int)*2)];

neither of which are allowing compile.

what pointed me to this is this valgrind output:

==6302== Mismatched free() / delete / delete []
==6302== at 0x40054B4: operator delete(void*) (vg_replace_malloc.c:346)
==6302== by 0x80C2574: manage_dynamic_buffer(char**, int) (dawnlib.cpp:111)
==6302== by 0x80B0F82: strip_color(char const*) (color.cpp:1046)
==6302== by 0x80FF3FA: get_char_world(char_data*, char*) (handler.cpp:2882)
==6302== by 0x815435D: cmd_eval(int, char*, int, char_data*, char_data*, void const*, void const*, char_data*) (mud_prog.cpp:791)
==6302== by 0x815614B: program_flow(mudprog_trigger_list*, char_data*, char_data*, void const*, void const*) (mud_prog.cpp:1893)
==6302== by 0x8157CE8: mp_percent_trigger(char_data*, char_data*, void const*, void const*, int) (mud_prog.cpp:2168)
==6302== by 0x81DD3FA: char_update() (update.cpp:1330)
==6302== by 0x81E0DC8: update_handler() (update.cpp:3329)
==6302== by 0x80BA904: game_loop() (comm.cpp:1179)
==6302== by 0x80BB93B: main (comm.cpp:768)
==6302== Address 0x461d340 is 0 bytes inside a block of size 8,217 alloc'd
==6302== at 0x4005FAD: operator new[](unsigned int) (vg_replace_malloc.c:258)
==6302== by 0x80C257F: manage_dynamic_buffer(char**, int) (dawnlib.cpp:115)
==6302== by 0x80B0F82: strip_color(char const*) (color.cpp:1046)
==6302== by 0x80FF3FA: get_char_world(char_data*, char*) (handler.cpp:2882)
==6302== by 0x815435D: cmd_eval(int, char*, int, char_data*, char_data*, void const*, void const*, char_data*) (mud_prog.cpp:791)
==6302== by 0x815614B: program_flow(mudprog_trigger_list*, char_data*, char_data*, void const*, void const*) (mud_prog.cpp:1893)
==6302== by 0x8157CE8: mp_percent_trigger(char_data*, char_data*, void const*, void const*, int) (mud_prog.cpp:2168)
==6302== by 0x81DD3FA: char_update() (update.cpp:1330)
==6302== by 0x81E0DC8: update_handler() (update.cpp:3329)
==6302== by 0x80BA904: game_loop() (comm.cpp:1179)
==6302== by 0x80BB93B: main (comm.cpp:768)
==6302==

Pointing to line 111 in dawnlib.cpp:
delete ((*result)-sizeof(int)*2);

Allocation line if I am reading correctly is line 115 of dawnlib.cpp which reads
char *new_allocation =new char[allocated_length];

function is (with comments already in code kept):
void manage_dynamic_buffer(char **result, int max_length)
{
int allocated_length=max_length + sizeof(int)*2 + sizeof(int)+1;
// "sizeof(int)+1" is safety padding for '\0' and if there is misuse
const int magic_num=0x1234ABCD; // used to detect memory corruption

// store the max length and a 'magic' number
// MAGIC_NUMBER (sizeof(int)), EXISTING MAX LENGTH (sizeof(int))
// then the memory for what we are dealing with
assertp(result); // we should never be given a null result char ** pointer

if(*result!=NULL){ // we can only check previous allocations if there have been some

int previous_magic_num=*((int*)(*result-(sizeof(int)*2)));
int previous_max_length=*((int*)(*result-sizeof(int)));

if(previous_magic_num!=magic_num){
bugf("MDB(): previous_magic_num=%d, magic_num=%d… "
"they should the same… this indicates memory corruption! - aborting!",
previous_magic_num, magic_num);
do_abort();
}

if(previous_max_length>max_length){

return; // we don't have to do anything, since we have already enough memory allocated
}

// we need to reallocate things
// first deallocate the previous memory
delete ((*result)-sizeof(int)*2);
}

// allocate the memory
char *new_allocation =new char[allocated_length];
assertp(new_allocation);

// set the magic number
*((int*)new_allocation)=magic_num;

// set the max_length
*((int*)(new_allocation +sizeof(int)))=max_length;

// set the new result value, jumping over our two hidden integers
*result=new_allocation +sizeof(int)*2;
}
04 Mar, 2014, Kaz wrote in the 11th comment:
Votes: 0
Naylor said:
Example of what I can't figure out-

how to i make this entry:

delete ((*result)-sizeof(int)*2);

use delete[] instead.. I have tried:

delete [((*result)-sizeof(int)*2)];
and
delete [(*result)-sizeof(int)*2)];


That's not how delete works.

int main()
{
int *ptr = new int(3); // pointer to single int with value 3.
int *arr = new int[3]; // pointer to array of 3 ints with undetermined values.

delete ptr; // That which is allocated with new must be deallocated with delete.
delete [] arr; // That which is allocated with new [] must be deallocated with delete []. Note: empty [] brackets.
}
04 Mar, 2014, Naylor wrote in the 12th comment:
Votes: 0
so umm..

delete [] ((*result)-sizeof(int)*2);

might work perhaps?? or does it need to target something else entirely?
05 Mar, 2014, Kaz wrote in the 13th comment:
Votes: 0
Naylor said:
so umm..

delete [] ((*result)-sizeof(int)*2);

might work perhaps?? or does it need to target something else entirely?


Looking at the code, what happens is this:

Result
|
V
+—–+—–+—–+—–+
|Magic| Len | Data… |
+—–+—–+—–+—–+
^
|
Actual Returned Data Block


Essentially, a magic int to identify the memory block (can be useful in some scenarios) is allocated at the beginning. Next is the length of the data section. It then returns a pointer to the data chunk. An extra byte is added at the end to hide programming errors (boooooooo).

int *allocate(int len) {
int *block = new int[len + 3];
block[0] = magic_number;
block[1] = len;

int *data = block+2;
return data;
}


So to deallocate this, you take the pointer to the data block and perform the reverse:

void allocate(int *data) {
int *block = data-2;
delete [] block;
}


The code above then gets more complicated because it's actually an array of char, not int, so the offsets are multiplied by the size of an int and there's a bunch of casting to be able to dump the int values into the array. It's also complicated because the result is being returned via a pointer to a pointer. But it's all essentially the same.

Short answer: yes, it looks like that would work.
05 Mar, 2014, quixadhal wrote in the 14th comment:
Votes: 0
Or you could just use gcmalloc, and stop worrying about fiddly memory bits, like most applications programmers do these days (or use a language that already does garbage collection).
06 Mar, 2014, Naylor wrote in the 15th comment:
Votes: 0
ok so putting delete [] worked to get rid of some error messages, fixing the rest is looking much trickier though.
19 Jun, 2014, Naylor wrote in the 16th comment:
Votes: 0
okay.. so.. update on this issue

still getting trash dumped into files BUT not as bad as before, yay.

can not for the life of me figure out the rest of the valgrind errors.

HAVE tracked down the point in which the Ed's appear to be getting funkdefied, i think.

if anyone is willing to help me fix this (not fix it FOR me because then I wouldn't learn a darn thing) please let me know what info you require to be of assistance and I will quite happily do my utmost to get you it.
0.0/16