From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#13864: 24.3.50; emacsclient -t loops when connected to emacs server running in X11 Date: Sun, 24 Mar 2013 21:54:04 +0200 Message-ID: <83k3ow376r.fsf@gnu.org> References: <86y5e4xpd8.fsf@chateau.d.if> <83ehfvt5pp.fsf@gnu.org> <86mwujou60.fsf@chateau.d.if> <83y5e2synt.fsf@gnu.org> <86ip56adz3.fsf@chateau.d.if> <83txoo1mp3.fsf@gnu.org> <868v60743o.fsf@chateau.d.if> <83ppzc1bx9.fsf@gnu.org> <866214m1bh.fsf@chateau.d.if> <838v5z1yx4.fsf@gnu.org> <86mwuf8xrq.fsf@chateau.d.if> <8362131sf1.fsf@gnu.org> <86ip538qb8.fsf@chateau.d.if> <83y5dzz88b.fsf@gnu.org> <868v5y9pb5.fsf@chateau.d.if> <837glhzxvs.fsf@gnu.org> <86sj3zy8ru.fsf@chateau.d.if> <83620t57e1.fsf@gnu.org> <864ng3hae1.fsf@chateau.d.if> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1364154898 3010 80.91.229.3 (24 Mar 2013 19:54:58 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 24 Mar 2013 19:54:58 +0000 (UTC) Cc: 13864@debbugs.gnu.org To: ashish.is@lostca.se (Ashish SHUKLA) Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Mar 24 20:55:24 2013 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UJr0m-0005zV-0n for geb-bug-gnu-emacs@m.gmane.org; Sun, 24 Mar 2013 20:55:24 +0100 Original-Received: from localhost ([::1]:50628 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UJr0N-00034Z-EO for geb-bug-gnu-emacs@m.gmane.org; Sun, 24 Mar 2013 15:54:59 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:47952) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UJr0J-00034D-BH for bug-gnu-emacs@gnu.org; Sun, 24 Mar 2013 15:54:56 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UJr0H-0001WV-GA for bug-gnu-emacs@gnu.org; Sun, 24 Mar 2013 15:54:55 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:39567) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UJr0H-0001WJ-CQ for bug-gnu-emacs@gnu.org; Sun, 24 Mar 2013 15:54:53 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1UJr2M-0006Jp-8p for bug-gnu-emacs@gnu.org; Sun, 24 Mar 2013 15:57:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 24 Mar 2013 19:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 13864 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 13864-submit@debbugs.gnu.org id=B13864.136415498024240 (code B ref 13864); Sun, 24 Mar 2013 19:57:02 +0000 Original-Received: (at 13864) by debbugs.gnu.org; 24 Mar 2013 19:56:20 +0000 Original-Received: from localhost ([127.0.0.1]:43676 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UJr1f-0006Iu-VA for submit@debbugs.gnu.org; Sun, 24 Mar 2013 15:56:20 -0400 Original-Received: from mtaout23.012.net.il ([80.179.55.175]:59857) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UJr1T-0006Ic-6b for 13864@debbugs.gnu.org; Sun, 24 Mar 2013 15:56:18 -0400 Original-Received: from conversion-daemon.a-mtaout23.012.net.il by a-mtaout23.012.net.il (HyperSendmail v2007.08) id <0MK600300KLMK500@a-mtaout23.012.net.il> for 13864@debbugs.gnu.org; Sun, 24 Mar 2013 21:53:56 +0200 (IST) Original-Received: from HOME-C4E4A596F7 ([87.69.4.28]) by a-mtaout23.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0MK6003Z8KLVF460@a-mtaout23.012.net.il>; Sun, 24 Mar 2013 21:53:56 +0200 (IST) In-reply-to: <864ng3hae1.fsf@chateau.d.if> X-012-Sender: halo1@inter.net.il X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:72860 Archived-At: > From: ashish.is@lostca.se (Ashish SHUKLA) > Cc: 13864@debbugs.gnu.org > Date: Fri, 22 Mar 2013 18:14:22 +0530 > > > That's strange, I'm probably missing something. Not terribly > > important (it's tangential to the issue I'm hunting with your GDB > > collected data), but could you give me a recipe to cause such a > > tooltip in the xterm frame by some key-press? > > Sure, you set a breakpoint to some function which gets invoked as 'emacsclient > -t' starts, like update_frame_line, but forgot to add 'cont' to the list of > commands. And then you forgot that you didn't add 'cont' and starts > 'emacsclient -t' and start typing (like some arrow key) without noticing that > 'emacsclient' frame has yet to appear on the screen. Now look at gdb window, > breakpoint must have it, do 'cont' there so that emacsclient starts, and now > you'll see some characters in buffer, with "End of buffer" message in > minibuffer (tooltip). But the text I saw was different: it was the text of a tooltip for mouse-sensitive portions of the mode line: Major mode, mouse-1: Display major mode menu, mouse-2: Show help for major mode Strange. Anyway, you can forget this for now; if this is important, we'll get back to it later. > FTR, I'm still running r111924 for this debugging to avoid adding more > variables. OK, that's good. > > Once you are set up in GDB, make Emacs flicker, and collect the data > > printed by GDB. The goal of these breakpoints is to see which code is > > involved in the flickering situation, and which parts of it are > > actually writing to the screen. > > The output is attached Thanks. Here's what flickering looks like: Breakpoint 4, update_frame_line (f=0x12efd88, vpos=0) at dispnew.c:4845 4845 write_glyphs (f, nbody, nlen); $36808 = 0 $36809 = 239 $36810 = 239 Breakpoint 6, update_frame_line (f=0x12efd88, vpos=0) at dispnew.c:4859 4859 cursor_to (f, vpos, 0); $36811 = 0 Breakpoint 4, update_frame_line (f=0x12efd88, vpos=1) at dispnew.c:4845 4845 write_glyphs (f, nbody, nlen); $36812 = 1 $36813 = 239 $36814 = 239 Breakpoint 6, update_frame_line (f=0x12efd88, vpos=1) at dispnew.c:4859 4859 cursor_to (f, vpos, 0); $36815 = 1 Breakpoint 4, update_frame_line (f=0x12efd88, vpos=2) at dispnew.c:4845 4845 write_glyphs (f, nbody, nlen); $36816 = 2 $36817 = 239 $36818 = 239 Breakpoint 6, update_frame_line (f=0x12efd88, vpos=2) at dispnew.c:4859 4859 cursor_to (f, vpos, 0); $36819 = 2 Breakpoint 4, update_frame_line (f=0x12efd88, vpos=3) at dispnew.c:4845 4845 write_glyphs (f, nbody, nlen); $36820 = 3 $36821 = 239 $36822 = 239 Breakpoint 6, update_frame_line (f=0x12efd88, vpos=3) at dispnew.c:4859 4859 cursor_to (f, vpos, 0); $36823 = 3 Breakpoint 5, update_frame_line (f=0x12efd88, vpos=4) at dispnew.c:4854 4854 clear_end_of_line (f, FRAME_TOTAL_COLS (f)); $36824 = 4 $36825 = 239 $36826 = 0 Breakpoint 4, update_frame_line (f=0x12efd88, vpos=5) at dispnew.c:4845 4845 write_glyphs (f, nbody, nlen); $36827 = 5 $36828 = 239 $36829 = 27 Breakpoint 5, update_frame_line (f=0x12efd88, vpos=5) at dispnew.c:4854 4854 clear_end_of_line (f, FRAME_TOTAL_COLS (f)); $36830 = 5 $36831 = 239 $36832 = 27 Breakpoint 5, update_frame_line (f=0x12efd88, vpos=6) at dispnew.c:4854 4854 clear_end_of_line (f, FRAME_TOTAL_COLS (f)); $36833 = 6 $36834 = 239 $36835 = 0 Breakpoint 5, update_frame_line (f=0x12efd88, vpos=7) at dispnew.c:4854 4854 clear_end_of_line (f, FRAME_TOTAL_COLS (f)); $36836 = 7 $36837 = 239 $36838 = 0 Breakpoint 5, update_frame_line (f=0x12efd88, vpos=8) at dispnew.c:4854 4854 clear_end_of_line (f, FRAME_TOTAL_COLS (f)); $36839 = 8 $36840 = 239 $36841 = 0 etc., for all the lines of the TTY frame (note the vpos values going from 0 to 43, for 43-line frame). For each line on that frame, Emacs first writes the characters, if any, of the text on that line, and then clears to the end of the line. This code is here: /* If display line has unknown contents, write the whole line. */ if (must_write_whole_line_p) { [...] /* Write the contents of the desired line. */ if (nlen) { cursor_to (f, vpos, 0); write_glyphs (f, nbody, nlen); } /* Don't call clear_end_of_line if we already wrote the whole line. The cursor will not be at the right margin in that case but in the line below. */ if (nlen < FRAME_TOTAL_COLS (f)) { cursor_to (f, vpos, nlen); clear_end_of_line (f, FRAME_TOTAL_COLS (f)); } else and must_write_whole_line_p is computed like this: /* Current row not enabled means it has unknown contents. We must write the whole desired line in that case. */ must_write_whole_line_p = !current_row->enabled_p; IOW, the problem that causes continuous redrawing of the entire frame is that every single line ("glyph row") of that frame is marked as "not enabled" (i.e., invalid) in the current glyph matrix, which is a structure that describes what is currently on the glass. The current matrix has every one of its lines marked as valid at the end of each redisplay cycle. So the question now is: which code resets those enabled_p flags of every glyph row in the current matrix, and thus defeats the code that avoids redrawing the same contents? To answer that, let's put a watchpoint at the enabled_p flag of one of the glyph rows. Like this: (gdb) break dispnew.c:2623 if vpos == 5 This breakpoint is inside the make_current function: static void make_current (struct glyph_matrix *desired_matrix, struct glyph_matrix *current_matrix, int row) { struct glyph_row *current_row = MATRIX_ROW (current_matrix, row); struct glyph_row *desired_row = MATRIX_ROW (desired_matrix, row); bool mouse_face_p = current_row->mouse_face_p; /* Do current_row = desired_row. This exchanges glyph pointers between both rows, and does a structure assignment otherwise. */ assign_row (current_row, desired_row); /* Enable current_row to mark it as valid. */ current_row->enabled_p = 1; current_row->mouse_face_p = mouse_face_p; <<<<<<<<<<<<<<<<<<<<<< The choice of the line (5) is arbitrary. Then wait until the breakpoint breaks, and do this: (gdb) p current_row $1 = (struct glyph_row *) 0x37e1158 (The address will be different in your case.) Now use that address to put a hardware watchpoint on the enabled_p flag of that glyph row, and continue the program: (gdb) watch ((struct glyph_row *) 0x37e1158)->enabled_p (gdb) c Now do whatever it takes to cause the flicker, and wait for the watchpoint to trigger, it should say something like Hardware watchpoint 5: ((struct glyph_row *) 0x37e1158)->enabled_p Old value = 1 New value = 0 and will next show the source line which modified the value. Then type (gdb) bt and let it continue (gdb) c Do this several times, each time waiting until the watchpoint triggers, and displaying the backtrace. That should point towards the code which resets these flags and causes excessive re-drawing. Thanks.