27 Aug, 2009, Banner wrote in the 1st comment:
Votes: 0
The Log on the third line should say Force: Tagart has 0.
[Force]: 26000/26000 [Align]: good
[Health]: 100011/100011 [Move]: 30000/30000 [$$]:[28235]|>
Log: ll spice at 4000 credits per share…….
mpsleep 5
say Ryll-kor at 4500 credits per share…….
mpsleep 12
mpecho The boards close down and the broker looks away.
say That is it for now - any more business will require you to return again.

[INFO] Galactic Insights welcomes Tagart, who has just come to play!
Comm: Tagart has entered the game.


The Log on the first line should say Force: Ephram has 0.
Log: 666.t
[INFO] Galactic Insights welcomes Ephram, who has just come to play!
Comm: Ephram has entered the game.


The 'Imperial Army) [Roleplaying]' should be a + sign.
31500) In the Desert Imperial Army) [Roleplaying] 
[]
31501) In the Desert Imperial Army) [Roleplaying]
[]
31502) Floating in a void (*NO DESC*) []
31503) Floating in a void (*NO DESC*) []


Something is being weird ever since C++ conversion. I was told to snarf my values on the function above and it fixed it, but I was also told sprintf is supposed to do that itself. Is there another function I can pass everything through to fix this problem or something where garbage is being left over in my bufs?
27 Aug, 2009, Kline wrote in the 2nd comment:
Votes: 0
I'm lost. Offending code please? I don't quite understand "snarf my values on the function above" … "sprintf is supposed to do that itself".
27 Aug, 2009, Banner wrote in the 3rd comment:
Votes: 0
Kline said:
I'm lost. Offending code please? I don't quite understand "snarf my values on the function above" … "sprintf is supposed to do that itself".


Snarfing is setting arg1[0] = arg2[0] = arg3[0] = buf[0] = buf2[0] = '\0'; to clear up the variable. Defining all of your variables and making sure they are clean by setting them to blank, I guess. Apparently, from what I was told: Automatics (non pointers, eg. char buf[MSL]) are allocated on the stack as they're called in the scope. When the var runs out of scope, it just drops it (no need to zero the values or anything). It was just left over garbage from a variable previously defined. Setting [0] = '\0' effectively tells it that the end of the string is the first character. Sprintf is supposed to do the snarfing automatically. But it isn't.

EDIT: Some stuff that was left over in a previous use of a variable is showing up elsewhere in my code and isn't being cleared out, which is the problem. There is no 'offending' code as it is unrelated and it may be even appearing somewhere else right now that I can't see, but the underlying problem is that stuff is being shoved into a variable and not being cleaned out beforehand or whatever.
27 Aug, 2009, Kline wrote in the 4th comment:
Votes: 0
I've never liked to chain-define variables like that, but when I do use char arrays I init them individually as "char buf= {'\0'}". I'm still not quite sure what the issue is. Are you using some variables with a global scope? My code, for example, has an extern char *log_buf so there's not a need to create temporary buffers just to write log messages into inside every function you want to log something in. Or are you having shadowed variable problems? I guess I still don't understand how things are broken, but perhaps DH or somebody more C-guru than me will chime in :)
27 Aug, 2009, Banner wrote in the 5th comment:
Votes: 0
Shadowed variable problems sounds like it. And this is C++, not C.
27 Aug, 2009, Kline wrote in the 6th comment:
Votes: 0
Try compiling with -Wshadow; and C++ is just C with fancier syntax ;).
27 Aug, 2009, Banner wrote in the 7th comment:
Votes: 0
Kline said:
Try compiling with -Wshadow; and C++ is just C with fancier syntax ;).

W_FLAGS = -Wall -Werror -Wshadow -Wformat-security -Wpointer-arith -Wcast-align -Wredundant-decls -Wno-write-strings

Already have it.
28 Aug, 2009, Banner wrote in the 8th comment:
Votes: 0
Anyone? Someone? No one? :-/

Kline said:
My code, for example, has an extern char *log_buf so there's not a need to create temporary buffers just to write log messages into inside every function you want to log something in.

So. What if I do a log_buf like that, and perhaps one for buf and one for buf2, or however many, and then instead of declaring a buf in every function I need one, I use the global ones. Would that solve the problem?
28 Aug, 2009, Kline wrote in the 9th comment:
Votes: 0
I can't really say if it would or wouldn't – I'm not that guru :). While it seems slightly "messy" on one hand, throwing about so many globals, in the long run it does save many redundant declarations for simple things. Alternatively you could just write your own ch->print("%s","My string") style function using gcc __attribute__ tags for sprintf checking, and avoid the whole two step process of using a buffer then outputting.
28 Aug, 2009, Tyche wrote in the 10th comment:
Votes: 0
Banner said:
Anyone? Someone? No one? :-/


I would expect the problem might have been solved on the very first post if you'd included the code.
28 Aug, 2009, Banner wrote in the 11th comment:
Votes: 0
Tyche said:
Banner said:
Anyone? Someone? No one? :-/


I would expect the problem might have been solved on the very first post if you'd included the code.

As I previously stated, it is happening in two places and the code is unrelated and it is only occurring after switching to C++, but if you wish.

rlist:

void do_rlist( CHAR_DATA * ch, char *argument )
{
ROOM_INDEX_DATA *room;
int vnum;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
char arg3[MAX_INPUT_LENGTH];
AREA_DATA *tarea;
int lrange;
int trange;
char buf[MSL];
char buf2[MSL];
arg1[0] = arg2[0] = arg3[0] = buf[0] = buf2[0] = '\0';

if( IS_NPC( ch ) || get_trust( ch ) < LEVEL_AVATAR || !ch->pcdata
|| ( !ch->pcdata->area && get_trust( ch ) < LEVEL_GREATER ) )
{
send_to_char( "You don't have an assigned area.\n\r", ch );
return;
}

tarea = ch->pcdata->area;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
argument = one_argument( argument, arg3 );

if( tarea )
{
if( arg1[0] == '\0' ) /* cleaned a big scary mess */
lrange = tarea->low_r_vnum; /* here. -Thoric */
else
lrange = atoi( arg1 );
if( arg2[0] == '\0' )
trange = tarea->hi_r_vnum;
else
trange = atoi( arg2 );

if( ( lrange < tarea->low_r_vnum || trange > tarea->hi_r_vnum ) && get_trust( ch ) < LEVEL_GREATER )
{
send_to_char( "That is out of your vnum range.\n\r", ch );
return;
}
}
else
{
lrange = ( is_number( arg1 ) ? atoi( arg1 ) : 1 );
trange = ( is_number( arg2 ) ? atoi( arg2 ) : 1 );
}

// Problem area
for( vnum = lrange; vnum <= trange; vnum++ )
{
if( ( room = get_room_index( vnum ) ) == NULL )
continue;
if( room->description && ( strlen( room->description ) <= 1 ) )
sprintf( buf, "&B(&W&R*&WNO DESC&R*&B)" );
else
sprintf( buf, "&B(&G+&B)" );
sprintf( buf2, "%s %s", flag_string(room->room_flags, r_flags ), flag_string(room->room_flags2, r_flags2) );
ch_printf( ch, "&W%5d&B) &W%s %s &B[&W%s&B]\n\r", vnum, room->name, buf, (!str_cmp(arg3, "flags")) ? buf2 : "" );
}
return;
}


Force thing in nanny:
void nanny( DESCRIPTOR_DATA * d, char *argument )
{
/* extern int lang_array[];
extern char *lang_names[];*/
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
char col;
char arg[MAX_STRING_LENGTH];
char tmp[MAX_STRING_LENGTH];
CHAR_DATA *ch;
int iRace, iClass;
int iHair, iEye, iBuild, iDroid, iHeight;
BAN_DATA *pban;
/* int iLang;*/
bool fOld, chk;
int sn, cnt = 0, fpnt = 0;
buf[0] = buf2[0] = arg[0] = tmp[0] = '\0';

// few lines down


sprintf( buf2, "Force: %s has %d.", ch->name, ch->perm_frc );
log_string_plus( buf2, LOG_NORMAL, sysdata.admin_level );


Adding the snarfing stuff fixed the problem, but I'd like a more permanent solution as this is not supposed to be happening.
28 Aug, 2009, Guest wrote in the 12th comment:
Votes: 0
sprintf( buf2, "%s %s", flag_string(room->room_flags, r_flags ), flag_string(room->room_flags2, r_flags2) );


You can't do this. flag_string() returns a static char[] and you can't call more than one of these on one line. Usually you end up with only the contents of the second call. Sometimes you get junk in the buffer.
28 Aug, 2009, Tyche wrote in the 13th comment:
Votes: 0
From reading the code this "snarfing" ain't doing crap, because…
The three calls to one_argument() initialize arg1, arg2, and arg3 well before they are used.
The calls to sprintf write over buf and buf2 before they are referenced as well.

And Samson is correct, flag_string is not re-entrant. You would need to make separate calls and concat the results.
Also order of calls to function arguments is undefined.

Not enough info for your second problem (nanny)
28 Aug, 2009, Banner wrote in the 14th comment:
Votes: 0
Samson said:
sprintf( buf2, "%s %s", flag_string(room->room_flags, r_flags ), flag_string(room->room_flags2, r_flags2) );


You can't do this. flag_string() returns a static char[] and you can't call more than one of these on one line. Usually you end up with only the contents of the second call. Sometimes you get junk in the buffer.
They may very well be, but its not the problem I'm having. It's with the no desc part as I said previously, quoted, and then explained twice.
29 Aug, 2009, elanthis wrote in the 15th comment:
Votes: 0
Banner said:
Snarfing is setting arg1[0] = arg2[0] = arg3[0] = buf[0] = buf2[0] = '\0'; to clear up the variable.


No, it isn't. Please do not make up new definitions for computer jargon and expect us to understand what the hell you're talking about.

Quote
They may very well be, but its not the problem I'm having. It's with the no desc part as I said previously, quoted, and then explained twice.


Fix the error Tyche told you about. There is a chance that – depending on what exactly flag_string() is doing – it my be causing your error. The function returns two pointers that may point to different parts of the static buffer, resulting in the first pointer potentially pointing to mangled data (say, without a NUL terminator), and hence causing all kinds of screwed up memory issues. NEVER waste time debugging an error when you have another error staring you in the face. You can very easily end up thinking the known error is irrelevant, but it is the core cause of the problem, and then you end up pissing away time trying to find an error you already found.
Fix the error Samson told you about. There is a chance that – depending on what exactly flag_string() is doing – it my be causing your error. The function returns two pointers that may point to different parts of the static buffer, resulting in the first pointer potentially pointing to mangled data (say, no NUL terminator), and hence causing all kinds of screwed up memory issues when sprintf() appends them to the buffer and then tries to append more stuff to the buffer.

NEVER waste time debugging an error when you have another error staring you in the face. You can very easily end up thinking the known error is irrelevant, but it is the core cause of the problem, and then you end up pissing away time trying to find an error you already found.

Banner said:
Some stuff that was left over in a previous use of a variable is showing up elsewhere in my code and isn't being cleared out, which is the problem. There is no 'offending' code as it is unrelated and it may be even appearing somewhere else right now that I can't see, but the underlying problem is that stuff is being shoved into a variable and not being cleaned out beforehand or whatever.


That is a key symptom of one of several potential memory errors, usually a buffer overrun or writing into memory references by an improperly initialized pointer. Your code has probably always had these errors (it's MUD code, so it was written by idiots who barely understood C, which this whole thread kind of drives home). The conversion to C++ has changed the layout of the stack and parts of the heap, so where you were previously smashing unimportant memory, you're now smashing the stack. Adding the NUL initialization to the buffers once again changed the layout of the stack.

Initializing the buffer before using sprintf on it should have no effect in terms of how sprintf is actually behavior. Sprintf writes over the buffer's first character independent of what you set it to, which is why the code didn't bother to initialize those buffers in the first place. Whatever is wrong, the actual fix has nothing to do with sprintf or initializing those buffers, unless you've managed to find an honest-to-goodness bug in gcc or libc, or you tried to compile and install them yourself and screwed it up.

Valgrind will probably find the issue for you. If not, learn to use GDB. Set a break point after the buffer is set, and then inspect the variables to see where they're getting corrupted. If nothing else, add a good ol' fashioned puts() on the buffers right after you sprintf() to them, and verify if your sprintf() really is magically broken, or if the stack is getting smashed in the following function calls.

My initial hunch is that ch_printf and/or log_string_plus are the culprits. It's entirely possible for some totally unrelated bit of code to be the problem, though. That's the fun part of using an unmanaged, memory-unsafe programming language. A bug in one bit of code can cause entirely crazy and very difficult to track errors that don't present themselves until way later in an unrelated bit of code, and the appearance of those errors can be completely random with every run or with any change to the source code. People who don't understand how C and the hardware works end up writing crap like:

char buf[4];
int unused; /* don't remove this or the program crashes lolz!121!`` */

strcpy(buf, "Hiya");


Which is pretty much what many MUD codebase programmers end up doing, albeit without realizing it.
03 Sep, 2009, Davion wrote in the 16th comment:
Votes: 0
Elanthis said:
No, it isn't. Please do not make up new definitions for computer jargon and expect us to understand what the hell you're talking about.


Actually, in the Diku realm, snarfing is a perfectly legitimate term! Banner's definitely not making it up.

mb@mb:~/Rom24/src$ grep narf *
act_wiz.c: * Snarf the value.
act_wiz.c: * Snarf the value (which need not be numeric).
act_wiz.c: * Snarf the value (which need not be numeric).
act_wiz.c: * Snarf the value.
comm.c: /* Snarf input. */
db2.c:/* snarf a socials file */
db2.c: * Snarf a mob section. new style
db2.c: * Snarf an obj section. new style
db.c: * Snarf an 'area' header line.
db.c: * Snarf a help section.
db.c: * Snarf a mob section. old style
db.c: * Snarf an obj section. old style
db.c: * Snarf a reset section.
db.c: * Snarf a room section.
db.c: * Snarf a shop section.
db.c: * Snarf spec proc declarations.
03 Sep, 2009, Tyche wrote in the 17th comment:
Votes: 0
Davion said:
Elanthis said:
No, it isn't. Please do not make up new definitions for computer jargon and expect us to understand what the hell you're talking about.


Actually, in the Diku realm, snarfing is a perfectly legitimate term! Banner's definitely not making it up.


You won't find it in either Diku or Circle. It seems to have been inserted by someone on the Merc team.
It was slang for eat or slurp. So you could snarf or slurp an input line or a file into memory.
However, even as stupid hacker slang it's being used incorrectly in this thread.

I've also seen it used as a substitute for profanity as in "This code is all snarfed up!", which seems more applicable here. ;-)
03 Sep, 2009, Cratylus wrote in the 18th comment:
Votes: 0
03 Sep, 2009, tphegley wrote in the 19th comment:
Votes: 0
Loved thunder catsback in the day.
0.0/19