Stock code : syserr multiple login crash

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
1 year 1 month ago #6776 by JTP
Seems there is something messing in the Stock code to prevent a crash. It has happened 3 times in a year now.

One of the attached pictures is the backtrace
Attachments:

Please Log in or Create an account to join the conversation.

More
1 year 1 month ago #6778 by thomas
Replied by thomas on topic Stock code : syserr multiple login crash

JTP wrote: Seems there is something messing in the Stock code to prevent a crash. It has happened 3 times in a year now.

One of the attached pictures is the backtrace


This is BAD. The code around the crashing line looks like this:
 case CON_NAME_CNFRM:		/* wait for conf. of new name    */
    if (UPPER(*arg) == 'Y') {
      if (isbanned(d->host) >= BAN_NEW) {
	mudlog(NRM, LVL_GOD, TRUE, "Request for new char %s denied from [%s] (siteban)", GET_PC_NAME(d->character), d->host);
	write_to_output(d, "Sorry, new characters are not allowed from your site!\r\n");
	STATE(d) = CON_CLOSE;
	return;
      }
      if (circle_restrict) {
	write_to_output(d, "Sorry, new players can't be created at the moment.\r\n");
	mudlog(NRM, LVL_GOD, TRUE, "Request for new char %s denied from [%s] (wizlock)", GET_PC_NAME(d->character), d->host);
	STATE(d) = CON_CLOSE;
	return;
      }
      perform_new_char_dupe_check(d);
      write_to_output(d, "New character.\r\nGive me a password for %s: ", GET_PC_NAME(d->character));
      echo_off(d);
      STATE(d) = CON_NEWPASSWD;

But the innocent call to perform_new_char_dupe_check(d) can alter the connectedness (and in particular, can close close the connection as well as nulling out d->character, which causes the crash).
The log statement you are showing tells us as much.

So, what is really happening here? Well, nanny() is buggy - I think it really could use a cleanup. It seems we are getting a situation where we have no player file for a player that is logged in. Then, a second attempt with the same name will trigger the dupe_check. There may be more ways to reach this situation, but that one will surely cause it.

One, simple, band-aid could be to do this:
      if (!perform_new_char_dupe_check(d)) {
        write_to_output(d, "New character.\r\nGive me a password for %s: ", GET_PC_NAME(d->character));
        echo_off(d);
        STATE(d) = CON_NEWPASSWD;
      }
But it doesn't fix the underlying issue.

Please Log in or Create an account to join the conversation.

More
1 year 1 month ago #6779 by thomas
Replied by thomas on topic Stock code : syserr multiple login crash
By the way - how does your connected-states in structs.h look ?
github.com/tbamud/tbamud/blob/master/src/structs.h#L306

Please Log in or Create an account to join the conversation.

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
1 year 1 month ago #6780 by JTP
I have this:

/* Modes of connectedness: used by descriptor_data.state 		*/
#define CON_PLAYING       0 /**< Playing - Nominal state 		*/
#define CON_CLOSE         1 /**< User disconnect, remove character.	*/
#define CON_GET_NAME      2 /**< Login with name */
#define CON_NAME_CNFRM    3 /**< New character, confirm name */
#define CON_PASSWORD      4 /**< Login with password */
#define CON_NEWPASSWD     5 /**< New character, create password */
#define CON_CNFPASSWD     6 /**< New character, confirm password */
#define CON_QSEX          7 /**< Choose character sex */
#define CON_QCLASS        8 /**< Choose character class */
#define CON_RMOTD         9 /**< Reading the message of the day */
#define CON_MENU         10 /**< At the main menu */
#define CON_PLR_DESC     11 /**< Enter a new character description prompt */
#define CON_CHPWD_GETOLD 12 /**< Changing passwd: Get old		*/
#define CON_CHPWD_GETNEW 13 /**< Changing passwd: Get new */
#define CON_CHPWD_VRFY   14 /**< Changing passwd: Verify new password */
#define CON_DELCNF1      15 /**< Character Delete: Confirmation 1		*/
#define CON_DELCNF2      16 /**< Character Delete: Confirmation 2		*/
#define CON_DISCONNECT   17 /**< In-game link loss (leave character)	*/
#define CON_OEDIT        18 /**< OLC mode - object editor		*/
#define CON_REDIT        19 /**< OLC mode - room editor		*/
#define CON_ZEDIT        20 /**< OLC mode - zone info editor		*/
#define CON_MEDIT        21 /**< OLC mode - mobile editor		*/
#define CON_SEDIT        22 /**< OLC mode - shop editor		*/
#define CON_TEDIT        23 /**< OLC mode - text editor		*/
#define CON_CEDIT        24 /**< OLC mode - conf editor		*/
#define CON_AEDIT        25 /**< OLC mode - social (action) edit      */
#define CON_TRIGEDIT     26 /**< OLC mode - trigger edit              */
#define CON_HEDIT        27 /**< OLC mode - help edit */
#define CON_QEDIT        28 /**< OLC mode - quest edit */
#define CON_PREFEDIT     29 /**< OLC mode - preference edit */
#define CON_IBTEDIT      30 /**< OLC mode - idea/bug/typo edit */
#define CON_MSGEDIT      31 /**< OLC mode - message editor */
#define CON_GET_PROTOCOL 32 /**< Used at log-in while attempting to get protocols > */
#define CON_QRACE	 33 /**< Choose character race */
#define CON_QROLLSTATS   34

Please Log in or Create an account to join the conversation.

More
1 year 1 month ago #6781 by thomas
Replied by thomas on topic Stock code : syserr multiple login crash
Ok, there's your problem, I think.

Move CON_QRACE and CON_QROLLSTATS up in that list, to above CON_QCLASS, and renumber the list:
#define CON_QSEX          7 /**< Choose character sex */
#define CON_QRACE	  8 /**< Choose character race */
#define CON_QROLLSTATS    9
#define CON_QCLASS       10 /**< Choose character class */
#define CON_RMOTD        11 /**< Reading the message of the day */
#define CON_MENU         12 /**< At the main menu */
...
Then alter the check in perform_new_char_dupe_check to this:
  /* Do the player names match? */
    if (!strcmp(GET_NAME(k->character), GET_NAME(d->character))) {
      /* Check the other character is still in creation? */
-      if ((STATE(k) > CON_PLAYING) && (STATE(k) < CON_QCLASS)) {
+      if ((STATE(k) > CON_PLAYING) && (STATE(k) < CON_RMOTD)) {
        /* Boot the older one */
You crash happens because having a char in rollstats or race selection and reconnecting causes both chars to be purged.

Please Log in or Create an account to join the conversation.

  • JTP
  • Topic Author
  • Offline
  • Platinum Boarder
  • Platinum Boarder
More
1 year 1 month ago #6782 by JTP
Thanks Thomas. Now implemented, time will show if its better now. But makes sense, so hope so.

Please Log in or Create an account to join the conversation.

Time to create page: 1.322 seconds