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

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



On 24 September 2016 at 22:31, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> You're probably interested in getbyte() in zle_main.c, but you might
> also attach with a debugger and put a breakpoint in zhandler so you
> can get a stack trace of where the handler is being called [if it is].
> (Starting the debugger first and running zsh inside it won't work as
> well because the debugger itself will trap the signals).

I've set breakpoint to zhandler, it was called on each Ctrl-C. And
.recursiveedit never exited. Following execution paths I've spotted
crucial places and added debug prints. Luckily it's easy to trigger
".recursiveedit not canceled" and ".rec. cancelled" paths when not in
debugger. Attached is 10-context lines diff. Exit from .recursiveedit
is:

-- Doing break / zle_main.c: errflag: 2, retflag: 0, breaks: 0, exit_pending: 0
-- Got EINTR 1
-- Setting error in zlecore.c

I've also observed that following possible, though rare:

-- Got EINTR 1
-- Setting error in zlecore.c

No reaction on Ctrl-C, i.e. no-exit from .recursiveedit, is:

-- Trying again !errtry / zle_main.c
(now another Ctrl-C)
-- Doing break / zle_main.c: errflag: 2, retflag: 0, breaks: 0, exit_pending: 0
-- Got EINTR 2
-- Setting error in zlecore.c

I will go further into this but apparently zhandler should set errflag?

Best regards,
Sebastian Gniazdowski
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 9a83d41..36884c4 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -612,28 +612,40 @@ raw_getbyte(long do_keytmout, char *cptr)
 		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 / zle_main.c: errflag: %d, retflag: %d, breaks: %d, exit_pending: %d\n",
+                            errflag, retflag, breaks, exit_pending );
+                fclose(_F);
 		break;
+            }
+
 	    /*
 	     * 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 !errtry / zle_main.c\n" );
+                fclose(_F);
+
 		errtry = 1;
 		continue;
 	    }
 	    if (selret == 0) {
 		/*
 		 * Nothing ready and no error, so we timed out.
 		 */
 		switch (tmout.tp) {
 		case ZTM_NONE:
 		    /* keeps compiler happy if not debugging */
@@ -888,22 +900,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 +1141,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 */
 


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