[MUD-Dev] How to debug a method taking a variable list of arguments?

Ben Greear greear at cyberhighway.net
Sat Jun 12 23:23:15 CEST 1999


This code is C++, but I figure that the c folks might have hit this
problem too.

I'm trying to pass a list of variable arguments through several methods.
For one reason or another, it's not working right, and I'm having a hard
time getting gdb or any other method to figure out why.

Anyone got any ideas on how to print out the addresses of the variable
args that are being sent in with gdb?  Any other information I
might find useful?


In case someone wants to look at the code I'm working on, here it is.

/** Returns < 0 on error */
int move(critter& pc, int i_th, const char* direction, short do_followers, 
         room& rm, int& is_dead) {
   ...

         mudlog << "DIR_ADDR: " << (void*)(direction) << endl;
         rm.doEmote(pc, Selectors::instance().CC_mob_entry_allow, 
                    Selectors::instance().CC_mob_entry_deny,
                    CS_LEAVES_SPRINTF, direction);

   ...
}//move


//This is the method called above.

int room::doEmote(critter& pc, CSelectorColl& includes,
                  CSelectorColl& denies, CSentryE cs_entry, ...) {
   Cell<critter*> cll(critters);
   critter* ptr;
   String buf(100);
   String buf2(100);

   va_list argp;
   va_start(argp, cs_entry);

   while ((ptr = cll.next())) {
      if (!(denies.matches(ptr, &pc))) {
         if (mudlog.ofLevel(DBG)) {
            mudlog << "room::doEmote, not denied." << endl;
         }
         if (includes.matches(ptr, &pc)) {
            if (mudlog.ofLevel(DBG)) {
               mudlog << "room::doEmote, includes matched." << endl;
            }

//NOTE: the cstr(cs_entry, *ptr) returns a constant string.  In the case I
// am testing, it will be:  "leaves %s."
// I have verified that I am getting the correct string.

            Sprintf(buf, cstr(cs_entry, *ptr), argp);

//ERROR: after this buf is corrupted, starting where the %s string should
// have been appended.

            mudlog << endl << "buf -:" << buf << ":-" << endl << endl;
            Sprintf(buf2, "%S %S", pc.getName(ptr->SEE_BIT), &buf);
            ptr->show(buf2);
         }//if
      }//if
   }//while
   va_end(argp);
   return 0;
}//doEmote


//Here is the Sprintf method:
// I have added some debugging info trying to figure out what is wrong.  What
// is clear is that the pointer is not what I expected.  I have no idea why.

              /* friend functions */

void Sprintf(String& targ, const char* string, ... ) {
   va_list ap;
   int i = 0;
   va_start(ap, string);
   int num = 0;
   String buf(100);
   int s_len;
   char* tmp_chr_str;
   String* tmp_str;

   targ = "\0"; //initialize targ

   for (i = 0; string[i]; ) {
      if (string[i] == '%') {
         i++;
         if (string[i] != '%') {
            switch (string[i]) {
               case 'i':    /* int */  
                  targ.Append(va_arg(ap, int));
                  break;
               case 'I':    /* ignore */
                  va_arg(ap, void*);
                  // Do nothing with it!!
                  break;
               case 'd':     /* long, turn it into an int */
                  targ.Append(va_arg(ap, int));
                  break;
               case 's':      /* char * */
                  if ((tmp_chr_str = va_arg(ap, char *))) {

//ERROR shows up here:
//NOTE:  tmp_chr_str is NOT the same as the:  direction  string passed in earlier.

                     LOGFILE << "Sprintf: got string: " << (void*)(tmp_chr_str) << endl;
                     targ.Append(tmp_chr_str);
                  }//if
                  break;
               case 'p':    /* pointer */
                  targ.appendHex(va_arg(ap, long));
                  break;
               case 'S':      /* String */
                  if ((tmp_str = va_arg(ap, String *))) {
                     targ.Append(*tmp_str);
                  }//if
                  break;
               case 'P':      /* pad w/spaces */
                  i++; //looking at first number now
                  if (isdigit(string[i+1])) { //two digits?
                     if (isdigit(string[i])) { //it should be
                        num = 10 * ((int)(string[i]) - 48);
                        num += (int)(string[i+1]) - 48;
                     }//if
                     else {
                        LOGFILE.log(ERR, 
                                    "ERROR:  Sprintf, case 'P', first not an int\n");
                     }
                  }//if two digits
                  else {
                     LOGFILE.log(ERR,
                                 "ERROR:  Sprintf, case 'P', second not an int\n");
                  }
                  i += 2; //now pointing to next valid letter
                  
                  s_len = targ.Strlen();
                  while (s_len < num) {
                     targ.Append(" ");  //pad another space
                     s_len++;
                  }//while
                  i--;  //slight hack
                  break;
               default:
                  targ.Assert(FALSE, "ERROR: default called in Sprintf.\n");
            }//switch
            i++;
         }//if
         else { //
            i++;
            targ.Append("%");
         }//else
      }//if
      else {
         targ.Append(string[i]);
         i++;
      }//else
   }//for
   va_end(ap);
}//Sprintf



--
Ben Greear (greear at cyberhighway.net)  http://scry.wanfear.com/~greear 
Author of ScryMUD:  scry.wanfear.com 4444        (Released under GPL)
http://scry.wanfear.com


_______________________________________________
MUD-Dev maillist  -  MUD-Dev at kanga.nu
http://www.kanga.nu/lists/listinfo/mud-dev




More information about the mud-dev-archive mailing list