Blank Screen
< Newer Topic
:: Older Topic >
#1 Feb 28, 2010 6:45 pm
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
Recently, I noticed that sometimes when I or other players would log into the MUD, the greeting and all subsequent data would fail to be sent, yet the connection was established. Sometimes using a separate client helps, and sometimes the issue resolves itself after several minutes and/or restarting the client/opening a new window. In the screenshot below, I connected and logged into the MUD and this is all I can see, and the player is connected to the MUD, just not receiving and output. My only guess is that perhaps something on the descriptor got eaten so it can't send more data or something, but alas, I wouldn't know where to begin, so help is requested and appreciated. If it helps, the text that DID get sent is in the mudtitle.ans file.
#2 Feb 28, 2010 11:05 pm
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
I've found that send_to_desc exting because d->descriptor is null. Which doesn't make sense because it sets sometimes but not others?
#3 Mar 1, 2010 8:50 am
Last edited Mar 1, 2010 8:58 am by Banner
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
/* Writes to a descriptor, usually best used when there's no character to send to ( like logins ) */ void send_to_desc_color( const char *txt, DESCRIPTOR_DATA * d ) { if( !d ) { bug( "%s: NULL *d", __FUNCTION__ ); return; } if( !txt ) { bug( "%s: NULL txt", __FUNCTION__ ); return; } /* if( !d->descriptor ) { bug( "%s: NULL d->descriptor", __FUNCTION__ ); return; } */ write_to_buffer( d, colorize( txt, d ), 0 ); }
When someone connects and are assigned a descriptor of 0, this function won't send them anything because of the ifcheck !d->descriptor. I commented it out and connected, was assigned a descriptor of 0 and logged into the MUD without crashing anything, then connected in another window and was assigned a descriptor of 6, and myself and another player already had descriptors of 4 and 5. Is being assigned a descriptor of 0 not okay and is this check inside send_to_desc_color unncessary if a descriptor of 0 is okay? Check is inside stock FUSS bases.
#4 Mar 1, 2010 10:13 am
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
And on an unrelated note, after having installed mccp:
zlib.h is included in the mccp.h file which is included in comm.cppo and mccpcpp. Smaug 1.9F compiles correctly with MCCP installed so I assume I missed a declaration of some sort somewhere. Any ideas?
make -s swgi -j5 o/comm.o: In function `write_to_descriptor(descriptor_data*, char const*, int)': /home2/dev/swgi/src/comm.cpp:1413: undefined reference to `deflate' o/mccp.o: In function `compressStart(descriptor_data*)': /home2/dev/swgi/src/mccp.cpp:124: undefined reference to `deflateInit_' o/mccp.o: In function `compressEnd(descriptor_data*)': /home2/dev/swgi/src/mccp.cpp:149: undefined reference to `deflate' /home2/dev/swgi/src/mccp.cpp:155: undefined reference to `deflateEnd' collect2: ld returned 1 exit status make[1]: *** [swgi] Error 1 make: *** [all] Error 2 dev@swgi:~/swgi/src$
zlib.h is included in the mccp.h file which is included in comm.cppo and mccpcpp. Smaug 1.9F compiles correctly with MCCP installed so I assume I missed a declaration of some sort somewhere. Any ideas?
#5 Mar 1, 2010 11:55 am
Magician
GroupMembers
Posts132
JoinedJan 29, 2006
Make sure that zlib is linked into the executable by supplying -lz to the linker in the Makefile. It should be in the L_FLAGS variable. I believe it's already there in stock SWRFUSS, but check it anyway.
It's also possible that the zlib header doesn't contain a wrapper for C++ linking. Try changing this:
To this:
It's also possible that the zlib header doesn't contain a wrapper for C++ linking. Try changing this:
#include
To this:
#ifdef __cplusplus extern "C" { #endif #include#ifdef __cplusplus } #endif
#6 Mar 1, 2010 11:58 am
Magician
GroupMembers
Posts132
JoinedJan 29, 2006
As for descriptor zero, I believe that belongs to standard input, and descriptor one belongs to standard output, so a socket should not have descriptor zero.
#7 Mar 1, 2010 12:21 pm
Last edited Mar 1, 2010 12:23 pm by Banner
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
Caius said:And if a descriptor of 0 is being assigned by the accept ifcheck, what would be the cause and fix? I have a descriptor of 0 at the moment and I haven't noticed anything out of the ordinary (aside from a random disconnect when another player logged off), but I also noticed that no other descriptors are assigned below 4.
As for descriptor zero, I believe that belongs to standard input, and descriptor one belongs to standard output, so a socket should not have descriptor zero.
Caius said:
Make sure that zlib is linked into the executable by supplying -lz to the linker in the Makefile. It should be in the L_FLAGS variable. I believe it's already there in stock SWRFUSS, but check it anyway.
It's also possible that the zlib header doesn't contain a wrapper for C++ linking. Try changing this:
#include
To this:
#ifdef __cplusplus extern "C" { #endif #include#ifdef __cplusplus } #endif
Fixed that issue. Thanks once again.
#8 Mar 1, 2010 12:31 pm
Magician
GroupMembers
Posts132
JoinedJan 29, 2006
Banner said:
And if a descriptor of 0 is being assigned by the accept ifcheck, what would be the cause and fix?
I've never encountered this. However I found a thread where someone had the same behaviour. The fix is in the last post of page 1. Whether this is the same issue as yours, I can't say.
#9 Mar 1, 2010 12:45 pm
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
Caius said:Banner said:
And if a descriptor of 0 is being assigned by the accept ifcheck, what would be the cause and fix?
I've never encountered this. However I found a thread where someone had the same behaviour. The fix is in the last post of page 1. Whether this is the same issue as yours, I can't say.
Not my issue.
if( ( desc = accept( new_desc, ( struct sockaddr * )&sock, &size ) ) < 0 ) { perror( "New_descriptor: accept" ); bug( "new_descriptor: accept" ); set_alarm( 0 ); return; }
#10 Mar 1, 2010 12:50 pm
Magician
GroupMembers
Posts148
JoinedJan 24, 2008
I've seen this problem - but only sporadically. How often is this happening to you Banner?
#11 Mar 1, 2010 12:53 pm
Last edited Mar 1, 2010 12:56 pm by Banner
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
Keirath said:I can't say with any certainty because I only recently noticed it. After logging when send_to_desc_color() was finding a descriptor of 0, it seems to be happening nearly with every connection by 10-15 different connections, but I can only occasionally get the error myself.
I've seen this problem - but only sporadically. How often is this happening to you Banner?
EDIT: It also seems to only want to assign a 0 to the first person that connects. Anyone connecting after that receivers a normal descriptor that is 1 greater than the previos as long as that person with the 0 descriptor stays (this was after removing the check in send_to_desc_color() so a descriptor of 0 didn't stop the function from executing, thus allowing a 0 descriptor to login).
#12 Mar 1, 2010 12:57 pm
Magician
GroupMembers
Posts132
JoinedJan 29, 2006
Well, after a bit of googling it seems that accept returns zero if stdin is closed. Grep for stdin. Also grep for things like "close( 0 )", and similar.
#13 Mar 1, 2010 1:00 pm
Magician
GroupMembers
Posts132
JoinedJan 29, 2006
And keep in mind that you could be closing it implicitly as well:
And if these two lines happens in different functions it's harder to spot.
descriptor = 0; close( descriptor ); /* Oops */
And if these two lines happens in different functions it's harder to spot.
#14 Mar 1, 2010 1:01 pm
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
Caius said:
Well, after a bit of googling it seems that accept returns zero if stdin is closed. Grep for stdin. Also grep for things like "close( 0 )", and similar.
'stdin' is here:
db.cpp, bug() if( fpArea == stdin ) { iLine = 0; } else {
As flor 'close( 0 )', I've got several calls to close a variable, i.e. close(control) or close(fd), but not specific close(0).
#15 Mar 1, 2010 3:04 pm
Off the Edge of the Map
GroupAdministrators
Posts1,200
JoinedMar 21, 2006
Banner said:
if( ( desc = accept( new_desc, ( struct sockaddr * )&sock, &size ) ) < 0 ) { perror( "New_descriptor: accept" ); bug( "new_descriptor: accept" ); set_alarm( 0 ); return; }
If you want to stop assigning 0, change it to:
if( ( desc = accept( new_desc, ( struct sockaddr * )&sock, &size ) ) <= 0 ) { perror( "New_descriptor: accept" ); bug( "new_descriptor: accept" ); set_alarm( 0 ); return; }
#16 Mar 1, 2010 3:14 pm
Magician
GroupMembers
Posts132
JoinedJan 29, 2006
If you do that then whoever was trying to connect would be disconnected, right?
Don't brush it under the rug. Somewhere, somehow, your stdin is closed. Get to the root of the problem and fix it permanently.
Don't brush it under the rug. Somewhere, somehow, your stdin is closed. Get to the root of the problem and fix it permanently.
#17 Mar 1, 2010 3:28 pm
Last edited Mar 1, 2010 3:29 pm by Samson
Black Hand
GroupAdministrators
Posts3,697
JoinedJan 1, 2002
It might be helpful to have free_desc() alert you when descriptor 0 is being closed:
It may not be perfect, but you can always set a breakpoint in GDB and wait for this to happen and do a backtrace when it does.
void free_desc( DESCRIPTOR_DATA * d ) { compressEnd( d ); if( d->descriptor > 0 ) close( d->descriptor ); else if( d->descriptor == 0 ) bug( "%s: }RALERT! Closing socket 0! BAD BAD BAD!", __FUNCTION__ ); STRFREE( d->host ); DISPOSE( d->outbuf ); if( d->pagebuf ) DISPOSE( d->pagebuf ); DISPOSE( d->mccp ); DISPOSE( d ); --num_descriptors; return; }
It may not be perfect, but you can always set a breakpoint in GDB and wait for this to happen and do a backtrace when it does.
#18 Mar 1, 2010 3:47 pm
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
Kayle said:
If you want to stop assigning 0, change it to:
code
I thought of that, but the problem is that whoever is connecting is always going to get that 0 descriptor when it's not taken ingame, so nobody will be able to connect once the error occurs.
Samson said:
It might be helpful to have free_desc() alert you when descriptor 0 is being closed:
void free_desc( DESCRIPTOR_DATA * d ) { compressEnd( d ); if( d->descriptor > 0 ) close( d->descriptor ); else if( d->descriptor == 0 ) bug( "%s: }RALERT! Closing socket 0! BAD BAD BAD!", __FUNCTION__ ); STRFREE( d->host ); DISPOSE( d->outbuf ); if( d->pagebuf ) DISPOSE( d->pagebuf ); DISPOSE( d->mccp ); DISPOSE( d ); --num_descriptors; return; }
It may not be perfect, but you can always set a breakpoint in GDB and wait for this to happen and do a backtrace when it does.
Man, I was hoping to avoid this at all costs.
#19 Mar 1, 2010 4:02 pm
Black Hand
GroupAdministrators
Posts3,697
JoinedJan 1, 2002
Unfortunately it looks like you don't have much choice. It sounds to me like you have a spot somewhere that did something like desc = x instead of desc == x because what you describe shouldn't be happening.
#20 Mar 1, 2010 4:12 pm
Magician
GroupMembers
Posts169
JoinedNov 29, 2005
Samson said:What steps do you suggest I take? How do you connect to a running process with gdb, where should I place breakpoints, and what should I be looking for?
Unfortunately it looks like you don't have much choice. It sounds to me like you have a spot somewhere that did something like desc = x instead of desc == x because what you describe shouldn't be happening.