Top Mud Sites Forum Return to TopMudSites.com
Go Back   Top Mud Sites Forum > Mud Development and Administration > MUD Coding
Click here to Register

Reply
 
Thread Tools
Old 07-21-2004, 02:40 PM   #1
Velveeta
New Member
 
Join Date: Mar 2004
Posts: 4
Velveeta is on a distinguished road
hi everyone, i've got a problem that's kicking my ass on a Rom2.4b6 MUD, and i can't really tell why it's doing what it's doing... it was happening with a different function the other day, and i fixed that by removing the -O (optimize) flag from my Makefile for gcc... i have no idea why that worked, but it did... the function(s) in question are do_pload, which was working fine one day and not the next, but is the one that was fixed by removing compiler optimization, and do_set, which is pretty much a stock function, since any extras i want to add for setting get added into do_mset or do_oset or whatever, and the do_set function gets left alone... anyway, here's the problem... each of the do_fun's in ROM take 2 variables, the character that's calling the function, of type CHAR_DATA *, and a char *argument, which is everything after the command name that they entered on the command line... there's a function (char *one_argument), that is used quite frequently to break off words from the command line and evaluate them... it takes 2 arguments and returns char *... the first argument is the original string, the second is the variable to break off 1 word into... and then it returns everything after the first word... a typical usage would be "argument = one_argument(argument,arg1);" where the entire command line of arguments is sent, the first word is broken off into arg1, and everything after it is returned and reassigned to argument... NOW... here's what's happening, and i can't figure out how or why... when a command function receives the character variable and the argument, the data for each is intact, and gdb will show the argument correctly... when the data is passed to one_argument to be split up, somehow it's getting corrupted in transit from one function to the other... at first i'd suspected the other function was just garbling the data and returning it as screwed up, but when i broke the command function in gdb and stepped into one_argument, here's the output:

Breakpoint 1, do_set (ch=0x4032f388, argument=0xbfff8dd0 "char") at act_wiz.c:4131
4131        argument = one_argument(argument,arg);
(gdb) step
one_argument (argument=0xbfff8dd0 "Đ\215˙żŕ\215˙ż", arg_first=0xbfff8de0 "") at interp.c:943
943         char cEnd;

as you can see, when do_set is called w/ the argument, the code correctly receives "argument" as "char" (in this test i was just typing 'set char' to get a syntax output for the command)... the first line it hits in the function, after variable declarations, is a call to one_argument, and when one_argument receives "argument", it receives it as "Đ\215˙żŕ\215˙ż"... does anyone out there know what's going on with this? please help if you can :) Here's the beginning of the do_set function and the one_argument function, in case you want to see them...

void do_set( CHAR_DATA *ch, char *argument )
{
   char arg[MAX_INPUT_LENGTH];

   argument = one_argument(argument,arg);

   if (arg[0] == '\0')
   {
       xprintf_to_char(ch,"Syntax: set mob     <name> <field> <value>\n\r");
       xprintf_to_char(ch,"        set obj     <name> <field> <value>\n\r");
       xprintf_to_char(ch,"        set room    <room> <field> <value>\n\r");
       xprintf_to_char(ch,"        set skill   <name> <spell or skill> <value>\n\r");
       xprintf_to_char(ch,"        set weather <value>\n\r");
       return;
   }

oh btw, when i said it was "pretty much" stock, the only difference i've made to it was to add the "set weather" to the syntax, and to change the send_to_char's to xprintf_to_char's, which was a snippet i found on mudmagic.com and all it does is help to prevent buffer overflows and log where they're at, and page_to_char them if they don't overflow... and it comes after the call to one_argument, so i'm fairly certain that's not the cause... here's one_argument...

char *one_argument( char *argument, char *arg_first )
{
   char cEnd;

   while ( isspace(*argument) )
       argument++;

   cEnd = ' ';
   if ( *argument == '\'' || *argument == '"' )
       cEnd = *argument++;

   while ( *argument != '\0' )
   {
       if ( *argument == cEnd )
       {
           argument++;
           break;
       }
       *arg_first = LOWER(*argument);
       arg_first++;
       argument++;
   }
   *arg_first = '\0';

   while ( isspace(*argument) )
       argument++;

   return argument;
}

anyway, any help at all would be appreciated, thanks in advance :)

wavewave
Vel.
Velveeta is offline   Reply With Quote
Old 07-22-2004, 12:25 PM   #2
Velveeta
New Member
 
Join Date: Mar 2004
Posts: 4
Velveeta is on a distinguished road
For posterity's sake, i'll post the fix to my own problem here valgrind wasn't too much help since i couldn't figure out how to interpret its output... even tho i knew what it meant, i couldn't see why it was saying what it was saying, such as jumps were based off of uninitialized data, etc... i always initialize my data except in cases where it's drawing a value directly from a function, like i won't initialize a MOB_INDEX_DATA if it's going to be used in a get_mob_index statement or whatnot... anyway, i'd tried to hunt down as many little allocations of extra memory as i could a while back, and one that i saw that i thought was a little unnecessary turned out to be the cause of all my problems don't you just love misguided logic? I have a snippet installed for taking a '$$' entered into an alias and parsing in a target name for it, so that users don't have to change their aliases as often... down near the bottom of the parsing function, it caps off the variable it just filled with the target name, and there's this:

buf[count] = '\0';
return str_dup(buf);

well the function receives the command line as the variable "oldstring" and then runs through it, searching for the $$'s to parse in the target name, and by returning a str_dup, i assumed it was just wasting one extra allocation unit, so i changed it to say this:

buf[count] = '\0';
oldstring = buf;
return oldstring;

so it would just reassign the location oldstring was pointing to, but unfortunately it reassigned it to a local variable that i guess would just get overwritten at a later time and would screw everything... i'm not exactly sure what was happening there, but i switched it back and *poof* my quirky crashes went away

wavewave
Vel.
Velveeta is offline   Reply With Quote
Old 07-22-2004, 03:46 PM   #3
welcor
Member
 
Join Date: Apr 2002
Location: Aarhus, Denmark, Europe
Posts: 59
welcor is on a distinguished road
Send a message via ICQ to welcor
Quote:
Originally Posted by
buf[count] = '\0';
oldstring = buf;
return oldstring;

so it would just reassign the location oldstring was pointing to, but unfortunately it reassigned it to a local variable that i guess would just get overwritten at a later time and would screw everything... i'm not exactly sure what was happening there,
Well, the scope of the variable 'buf' is only the function. After the last } it simply stopped being valid. This doesn't mean it'll crash right away, as you just noted. However, the correct code, using str_dup allocates a new memory section and returns a pointer to it. If you remember to clean it up afterwards (when you're done with it), there should be no problems.

In this case you are probably calling something like
newprompt = substitutedoubledollars(oldprompt);

Just remember to free newprompt before the end of the function and you should be alright.
welcor is offline   Reply With Quote
Reply


Thread Tools


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off

All times are GMT -4. The time now is 06:11 PM.


Powered by vBulletin® Version 3.6.7
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Style based on a design by Essilor
Copyright Top Mud Sites.com 2014