Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow highlight to be interrupted by C-c #57

Open
temporaryrespite opened this issue Apr 24, 2020 · 2 comments
Open

Allow highlight to be interrupted by C-c #57

temporaryrespite opened this issue Apr 24, 2020 · 2 comments
Labels

Comments

@temporaryrespite
Copy link

temporaryrespite commented Apr 24, 2020

In the following run, try searching for : ie. type /:(and press Enter), (I also pressed q during the search, to show how many seconds it takes of 100% CPU aka 1 core, on my system)

$ time seq 1 32109|tr '\n' ':'| less

real	0m24.743s
user	0m24.011s
sys	0m0.026s

During the search for : in the above, pressing C-c (aka Ctrl+C) doesn't stop the highlight operation.

I naively tried to patch in this functionality but while it seems to work and breaks the operation, something keeps restarting it indefinitely and I'm thus forced to allow the high cpu usage to finish to regain any input control(unless ofc I kill the less process):

Index: less-551/search.c
===================================================================
--- less-551.orig/search.c
+++ less-551/search.c
@@ -1021,6 +1025,8 @@ hilite_line(linepos, line, line_len, chp
 			searchp++;
 		else /* end of line */
 			break;
+		if (ABORT_SIGS())
+			break;
 	} while (match_pattern(info_compiled(&search_info), search_info.text,
 			searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
 }

Thanks.

EDIT: To give an idea (of maybe)what's restarting it:

(gdb) bt2
executing: 'frame apply all -q frame'
#0  0x00007f0d5a032143 in ?? () from /usr/lib/libpcre.so.1
#1  0x00007f0d5a006f14 in pcre_exec () from /usr/lib/libpcre.so.1
#2  0x0000557129cd2927 in match_pattern (pattern=<optimized out>, tpattern=<optimized out>, line=line@entry=0x55712ab0e836 "7526:7527:7528:7529:7530:7531:7532:7533:7534:7535:7536:7537:7538:7539:7540:7541:7542:7543:7544:7545:7546:7547:7548:7549:7550:7551:7552:7553:7554:7555:7556:7557:7558:7559:7560:7561:7562:7563:7564:7565:"..., line_len=line_len@entry=145030, sp=sp@entry=0x7ffdd7f6eb58, ep=ep@entry=0x7ffdd7f6eb50, notbol=1, search_type=1) at pattern.c:373
373			matched = pcre_exec(pattern, NULL, line, line_len,
#3  0x0000557129cd40e9 in hilite_line (linepos=linepos@entry=0, line=line@entry=0x55712ab05990 "1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17:18:19:20:21:22:23:24:25:26:27:28:29:30:31:32:33:34:35:36:37:38:39:40:41:42:43:44:45:46:47:48:49:50:51:52:53:54:55:56:57:58:59:60:61:62:63:64:65:66:67:68:69:70"..., line_len=<optimized out>, chpos=chpos@entry=0x55712abb6e50, sp=<optimized out>, ep=<optimized out>, cvt_ops=<optimized out>) at search.c:1026
1026		} while (match_pattern(info_compiled(&search_info), search_info.text,
#4  0x0000557129cd4a7e in search_range (pos=181548, pos@entry=0, endpos=endpos@entry=1835008, search_type=search_type@entry=17, matches=matches@entry=0, maxlines=maxlines@entry=-1, plinepos=plinepos@entry=0x0, pendpos=0x7ffdd7f6eca0) at search.c:1316
1316						hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
#5  0x0000557129cd4f67 in prep_hilite (spos=spos@entry=0, epos=1835008, maxlines=-1) at search.c:1670
1670				result = search_range(spos, epos, search_type, 0, maxlines, (POSITION*)NULL, &new_epos);
#6  0x0000557129ccae28 in forw (n=35, pos=0, force=1, only_last=0, nblank=0) at forwback.c:153
153			prep_hilite(pos, pos + 4*size_linebuf, ignore_eoi ? 1 : -1);
#7  0x0000557129cc5feb in prompt () at command.c:740
740		make_display();
#8  commands () at command.c:1158
1158			prompt();
#9  0x0000557129cbf7be in main (argc=<optimized out>, argv=0x7ffdd7f6eef0) at main.c:285
285		commands();
(gdb) 
@temporaryrespite
Copy link
Author

temporaryrespite commented Apr 29, 2020

For some reason, the first time less is started and a search is performed for say :(ie. /:) then the hilite_line function is called twice. But for any subsequent searches, even for other patterns, hilite_line is called only once as it should.

If an interruption of the only-once called hilite_line happens however, such as by C-c with the above(or below) patch, then hilite_line is restarted each time C-c happens.

To showcase the above, the below patch can be used to better see when stuff happens:
just run tail -F /tmp/blah.log in one terminal and seq 1 32109|tr '\n' ':' >/tmp/a ; less /tmp/a in another then start a search by /: and watch it say

called hilite_line (1 times thus far)
called hilite_line (2 times thus far)

and then the control is returned to user, then try searching (/: or another pattern: /4) again and see only:

called hilite_line (3 times thus far)

, also try interrupting a search via C-c, just as mentioned above and notice the output, then keep pressing C-c, even the in-less output changes.
The first ever C-c yields: Line numbers turned off (press RETURN) (here, it's the only chance you have to press q to quit), then if you press RETURN(aka Enter key), then hilite_line gets called and if you C-c before it finishes, you can repeat C-c-ing it and you keep getting:

/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)...skipping...
/tmp/a byte 181548/181548 (END)

and you thus cannot quit less until you let it finish, after which you have control(so can press q)

diff --git a/search.c b/search.c
index 1761a6a..de4c137 100644
--- a/search.c
+++ b/search.c
@@ -999,9 +999,16 @@ hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
 	 *    (currently POSIX, PCRE and V8-with-regexec2). }}
 	 */
 	searchp = line;
+	static int called=0;
+	called++;
+	FILE *f=fopen("/tmp/blah.log","a");
+	if (NULL == f) {
+		f=stderr;
+	}
+	fprintf(f, "called hilite_line (%d times thus far)\n",called); fflush(f);
 	do {
 		if (sp == NULL || ep == NULL)
-			return;
+			goto ret;
 		create_hilites(linepos, sp-line, ep-line, chpos);
 		/*
 		 * If we matched more than zero characters,
@@ -1014,8 +1021,19 @@ hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
 			searchp++;
 		else /* end of line */
 			break;
+		if (ABORT_SIGS()) {
+			static int times=0;
+			times++;
+			fprintf(f,"interrupted (so far %d times)\n", times); fflush(f);
+			break;
+		}
 	} while (match_pattern(info_compiled(&search_info), search_info.text,
-			searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
+				searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
+ret:
+	if (stderr != f) {
+		fclose(f);
+		sync();
+	}
 }
 #endif

@gwsw
Copy link
Owner

gwsw commented May 16, 2020

I have some ideas but I'd like to be able to reproduce this and haven't had much luck. I don't understand why you see so much CPU usage to highlight this file. On my aged MacBook, your time command shows much lower user space CPU usage:

time seq 1 32109|tr '\n' ':' |less
real	0m2.473s
user	0m0.094s
sys	0m0.012s

What type of machine are you using?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants