Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Where to start debugging zle recursive-edit? / Ctrl-C



Investigated this further. The handler isn't exactly late. It is
called before errflag checks, but exits here without setting errflag:

    /* Are we queueing signals now?      */
    if (queueing_enabled) {

The log looks now like this:

-- tmoutp != ZTM_NONE / raw_getbyte() zle_main.c
## zhandler(2) signals.c (debug message in first line of zhandler)
## zhandler(2) EXIT 1 signals.c (debug message in if(queueing_enabled))
-- NOT doing break selret[-1/4/4] / zle_main.c: errflag: 0, retflag:
0, breaks: 0, exit_pending: 0
-- Trying again selret[-1], !errtry[0] / zle_main.c

-- tmoutp != ZTM_NONE / raw_getbyte() zle_main.c
-- (**) NOT doing break selret[0/4/4] / zle_main.c: errflag: 0,
retflag: 0, breaks: 0, exit_pending: 0
--  Passed !errtry(errtry:1) selret[0] / zle_main.c
## zhandler(2) signals.c
## set errflag to 2 (ERRFLAG_INT:2) / signals.c
-- tmoutp->tp <- ZTM_NONE / calc_timeout( do_keytmout: 0 ),
keytimeout: 40 / zle_main.c
== CALC_TIMEOUT() one more chance (timedfns exp100ths: 100)
-- CALC_TIMEOUT() tfnode TRUE no break NOT calling >> DIFF=1 <<
-- CALC_TIMEOUT() 0 != 1 || 100 <= 100 ZTM_FUNC(2)
^^^ LOOP-CALLED calc_timeout: tmout.tp == 2 / zle_main.c

Interesting is (**) line, it still has errno == 4 (last number in
[%d/%d/%d]), apparently errno=0 is needed before select, doing so
clears the value. What's with the queueing and early exit from
zhandler()? It brings disorder to .recursiveedit.

Best regards,
Sebastian Gniazdowski
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 9a83d41..79d6e20 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -450,47 +450,87 @@ static void
 calc_timeout(struct ztmout *tmoutp, long do_keytmout)
 {
     if (do_keytmout && (keytimeout > 0 || do_keytmout < 0)) {
 	if (do_keytmout < 0)
 	    tmoutp->exp100ths = (time_t)-do_keytmout;
 	else if (keytimeout > ZMAXTIMEOUT * 100 /* 24 days for a keypress???? */)
 	    tmoutp->exp100ths = ZMAXTIMEOUT * 100;
 	else
 	    tmoutp->exp100ths = keytimeout;
 	tmoutp->tp = ZTM_KEY;
-    } else
+        // MY DEBUG
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "-- tmoutp->tp <- ZTM_KEY (%d) / calc_timeout() zle_main.c\n", tmoutp->exp100ths );
+        fclose(_F);
+    } else {
+        // MY DEBUG
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "-- tmoutp->tp <- ZTM_NONE / calc_timeout( do_keytmout: %d ), keytimeout: %d / zle_main.c\n", do_keytmout, keytimeout );
+        fclose(_F);
+
 	tmoutp->tp = ZTM_NONE;
+    }
 
     if (timedfns) {
+        // MY DEBUG
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "== CALC_TIMEOUT() one more chance (timedfns exp100ths: %d)\n", tmoutp->exp100ths );
+        fclose(_F);
 	for (;;) {
 	    LinkNode tfnode = firstnode(timedfns);
 	    Timedfn tfdat;
 	    time_t diff, exp100ths;
 
-	    if (!tfnode)
+	    if (!tfnode) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() !tfnode break\n" );
+                fclose(_F);
 		break;
+            }
 
 	    tfdat = (Timedfn)getdata(tfnode);
 	    diff = tfdat->when - time(NULL);
+
 	    if (diff < 0) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() tfnode TRUE no break CALLING >> DIFF=%d <<\n", diff );
+                fclose(_F);
+
 		/* Already due; call it and rescan. */
 		tfdat->func();
 		continue;
-	    }
+	    } else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() tfnode TRUE no break NOT calling >> DIFF=%d <<\n", diff );
+                fclose(_F);
+            }
 
 	    if (diff > ZMAXTIMEOUT) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- CALC_TIMEOUT() %d > %d ZTM_MAX(%d)\n", diff, ZMAXTIMEOUT, ZTM_MAX );
+                fclose(_F);
+
 		tmoutp->exp100ths = ZMAXTIMEOUT * 100;
 		tmoutp->tp = ZTM_MAX;
-	    } else if (diff > 0) {
+	    } else if (diff >= 0) {
 		exp100ths = diff * 100;
 		if (tmoutp->tp != ZTM_KEY ||
-		    exp100ths < tmoutp->exp100ths) {
+		    exp100ths <= tmoutp->exp100ths) {
+                    // MY DEBUG
+                    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "-- CALC_TIMEOUT() %d != %d || %d <= %d ZTM_FUNC(%d)\n", tmoutp->tp, ZTM_KEY, exp100ths, tmoutp->exp100ths, ZTM_FUNC );
+                    fclose(_F);
+
 		    tmoutp->exp100ths = exp100ths;
 		    tmoutp->tp = ZTM_FUNC;
 		}
 	    }
 	    break;
 	}
 	/* In case we called a function which messed up the display... */
 	if (resetneeded)
 	    zrefresh();
     }
@@ -508,20 +548,24 @@ raw_getbyte(long do_keytmout, char *cptr)
     struct ttyinfo ti;
 #endif
 #ifndef HAVE_POLL
 # ifdef HAVE_SELECT
     fd_set foofd, errfd;
     FD_ZERO(&errfd);
 # endif
 #endif
 
     calc_timeout(&tmout, do_keytmout);
+    // MY DEBUG
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "-- INIT tmout.tp(%d) ZTM_NONE(%d) ZTM_KEY(%d) / BEGIN RAW_GETBYTE() zle_main.c\n", tmout.tp, ZTM_NONE, ZTM_KEY );
+    fclose(_F);
 
     /*
      * Handle timeouts and watched fd's.  If a watched fd or a function
      * timeout triggers we restart any key timeout.  This is likely to
      * be harmless: the combination is extremely rare and a function
      * is likely to occupy the user for a little while anyway.  We used
      * to make timeouts take precedence, but we can't now that the
      * timeouts may be external, so we may have both a permanent watched
      * fd and a long-term timeout.
      */
@@ -600,43 +644,78 @@ raw_getbyte(long do_keytmout, char *cptr)
 		    if (fd > fdmax)
 			fdmax = fd;
 		}
 	    }
 	    FD_ZERO(&errfd);
 
 	    if (tmout.tp != ZTM_NONE) {
 		expire_tv.tv_sec = tmout.exp100ths / 100;
 		expire_tv.tv_usec = (tmout.exp100ths % 100) * 10000L;
 		tvptr = &expire_tv;
+
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "\n-- tmoutp != ZTM_NONE / raw_getbyte() zle_main.c\n" );
+                fclose(_F);
 	    }
-	    else
+	    else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "\n-- FINAL (STOP) tmoutp == ZTM_NONE / raw_getbyte() zle_main.c\n" );
+                fclose(_F);
+
 		tvptr = NULL;
+            }
 
 	    winch_unblock();
 	    selret = select(fdmax+1, (SELECT_ARG_2_T) & foofd,
 			    NULL, NULL, tvptr);
 	    winch_block();
 # endif
 	    /*
 	     * Make sure a user interrupt gets passed on straight away.
 	     */
-	    if (selret < 0 && (errflag || retflag || breaks || exit_pending))
+	    if (selret < 0 && (errflag || retflag || breaks || exit_pending)) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- Doing break [selret:%d/%d/%d] / zle_main.c: errflag: %d, retflag: %d, breaks: %d, exit_pending: %d\n",
+                            selret, EINTR, errno, errflag, retflag, breaks, exit_pending );
+                fclose(_F);
 		break;
+            } else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- NOT doing break selret[%d/%d/%d] / zle_main.c: errflag: %d, retflag: %d, breaks: %d, exit_pending: %d\n",
+                            selret, EINTR, errno, errflag, retflag, breaks, exit_pending );
+                fclose(_F);
+            }
+
 	    /*
 	     * Try to avoid errors on our special fd's from
 	     * messing up reads from the terminal.  Try first
 	     * with all fds, then try unsetting the special ones.
 	     */
 	    if (selret < 0 && !errtry) {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- Trying again selret[%d], !errtry[%d] / zle_main.c\n", selret, errtry );
+                fclose(_F);
+
 		errtry = 1;
 		continue;
-	    }
+	    } else {
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "--  Passed !errtry(errtry:%d) selret[%d] / zle_main.c\n", errtry, selret );
+                fclose(_F);
+            }
+
 	    if (selret == 0) {
 		/*
 		 * Nothing ready and no error, so we timed out.
 		 */
 		switch (tmout.tp) {
 		case ZTM_NONE:
 		    /* keeps compiler happy if not debugging */
 #ifdef DEBUG
 		    dputs("BUG: timeout fired with no timeout set.");
 #endif
@@ -669,20 +748,24 @@ raw_getbyte(long do_keytmout, char *cptr)
 		case ZTM_MAX:
 		    /*
 		     * Reached the limit of our range, but not the
 		     * actual timeout; recalculate the timeout.
 		     * We're cheating with the key timeout here:
 		     * if one clashed with a function timeout we
 		     * reconsider the key timeout from scratch.
 		     * The effect of this is microscopic.
 		     */
 		    calc_timeout(&tmout, do_keytmout);
+                    // MY DEBUG
+                    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "^^^ LOOP-CALLED calc_timeout: tmout.tp == %d / zle_main.c\n", tmout.tp );
+                    fclose(_F);
 		    break;
 		}
 		/*
 		 * If we handled the timeout successfully,
 		 * carry on.
 		 */
 		if (selret == 0)
 		    continue;
 	    }
 	    /* If error or unhandled timeout, give up. */
@@ -888,22 +971,36 @@ getbyte(long do_keytmout, int *timeout)
 		   the counter (icnt) so that this happens 20 times and than
 		   the shell gives up (yes, this is a bit dirty...). */
 		if ((zlereadflags & ZLRF_IGNOREEOF) && icnt++ < 20)
 		    continue;
 		stopmsg = 1;
 		zexit(1, 0);
 	    }
 	    icnt = 0;
 	    if (errno == EINTR) {
 		die = 0;
+                static int counter = 0;
+
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "-- Got EINTR %d\n", ++counter );
+                fclose(_F);
+
 		if (!errflag && !retflag && !breaks && !exit_pending)
+                {
+                    // MY DEBUG
+                    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                    fprintf( _F, "-- Continuing despite EINTR / zle_main.c: errflag: %d, retflag: %d, breaks: %d, exit_pending: %d\n",
+                                errflag, retflag, breaks, exit_pending );
+                    fclose(_F);
 		    continue;
+                }
 		errflag &= ~ERRFLAG_ERROR;
 		breaks = obreaks;
 		errno = old_errno;
 		return lastchar = EOF;
 	    } else if (errno == EWOULDBLOCK) {
 		fcntl(0, F_SETFL, 0);
 	    } else if (errno == EIO && !die) {
 		ret = opts[MONITOR];
 		opts[MONITOR] = 1;
 		attachtty(mypgrp);
@@ -1115,20 +1212,24 @@ zlecore(void)
 		if (eofsent)
 		    break;
 	    }
 	    handleprefixes();
 	    /* for vi mode, make sure the cursor isn't somewhere illegal */
 	    if (invicmdmode() && zlecs > findbol() &&
 		(zlecs == zlell || zleline[zlecs] == ZWC('\n')))
 		DECCS();
 	    handleundo();
 	} else {
+            // MY DEBUG
+            FILE *_F = fopen("/tmp/recursive.txt", "a+");
+            fprintf( _F, "-- Setting error in zlecore.c\n" );
+            fclose(_F);
 	    errflag |= ERRFLAG_ERROR;
 	    break;
 	}
 
 	redrawhook();
 #ifdef HAVE_POLL
 	if (baud && !(lastcmd & ZLE_MENUCMP)) {
 	    struct pollfd pfd;
 	    int to = cost * costmult / 1000; /* milliseconds */
 
diff --git a/Src/signals.c b/Src/signals.c
index e2587dc..ea2f472 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -555,20 +555,23 @@ wait_for_processes(void)
 	unqueue_signals();
     }
 }
 
 /* the signal handler */
  
 /**/
 mod_export RETSIGTYPE
 zhandler(int sig)
 {
+    FILE *_F = fopen("/tmp/recursive.txt", "a+");
+    fprintf( _F, "## zhandler(%d) signals.c\n", sig );
+    fclose( _F );
     sigset_t newmask, oldmask;
 
 #if defined(NO_SIGNAL_BLOCKING)
     int do_jump;
     signal_jmp_buf jump_to;
 #endif
  
     last_signal = sig;
     signal_process(sig);
  
@@ -599,20 +602,24 @@ zhandler(int sig)
 	/* Make sure it's not full (extremely unlikely) */
         if (temp_rear != queue_front) {
 	    /* ok, not full, so add to queue   */
             queue_rear = temp_rear;
 	    /* save signal caught              */
             signal_queue[queue_rear] = sig;
 	    /* save current signal mask        */
             signal_mask_queue[queue_rear] = oldmask;
         }
         signal_reset(sig);
+
+        FILE *_F = fopen("/tmp/recursive.txt", "a+");
+        fprintf( _F, "## zhandler(%d) EXIT 1 signals.c\n", sig );
+        fclose( _F );
         return;
     }
  
     /* Reset signal mask, signal traps ok now */
     signal_setmask(oldmask);
  
     switch (sig) {
     case SIGCHLD:
 	wait_for_processes();
         break;
@@ -638,20 +645,25 @@ zhandler(int sig)
     case SIGINT:
         if (!handletrap(SIGINT)) {
 	    if ((isset(PRIVILEGED) || isset(RESTRICTED)) &&
 		isset(INTERACTIVE) && noerrexit < 0)
 		zexit(SIGINT, 1);
             if (list_pipe || chline || simple_pline) {
                 breaks = loops;
                 errflag |= ERRFLAG_INT;
 		inerrflush();
 		check_cursh_sig(SIGINT);
+
+                // MY DEBUG
+                FILE *_F = fopen("/tmp/recursive.txt", "a+");
+                fprintf( _F, "## set errflag to %d (ERRFLAG_INT:%d) / signals.c\n", errflag, ERRFLAG_INT );
+                fclose(_F);
             }
 	    lastval = 128 + SIGINT;
         }
         break;
 
 #ifdef SIGWINCH
     case SIGWINCH:
         adjustwinsize(1);  /* check window size and adjust */
 	(void) handletrap(SIGWINCH);
         break;


Messages sorted by: Reverse Date, Date, Thread, Author