After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 708496 - Lines disappear after positioning back the cursor
Lines disappear after positioning back the cursor
Status: RESOLVED FIXED
Product: vte
Classification: Core
Component: general
0.34.x
Other Linux
: Normal normal
: ---
Assigned To: VTE Maintainers
VTE Maintainers
[fixed-next][fixed-0-34][fixed-0-36]
Depends on:
Blocks: 708213
 
 
Reported: 2013-09-20 20:34 UTC by Egmont Koblinger
Modified: 2013-10-19 21:08 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
lsoutput.txt to reproduce the bug (2.56 KB, text/plain)
2013-09-20 20:34 UTC, Egmont Koblinger
  Details
I have no idea what I'm doing but it seems to work :) (945 bytes, patch)
2013-09-21 00:15 UTC, Egmont Koblinger
rejected Details | Review
Step 1: Refactoring only, no behavior change (7.71 KB, patch)
2013-09-23 13:53 UTC, Egmont Koblinger
committed Details | Review
Step 2: The actual bugfix (2.21 KB, patch)
2013-09-23 13:54 UTC, Egmont Koblinger
none Details | Review
Step 2: The actual bugfix (2.22 KB, patch)
2013-09-23 14:14 UTC, Egmont Koblinger
committed Details | Review

Description Egmont Koblinger 2013-09-20 20:34:22 UTC
Created attachment 255444 [details]
lsoutput.txt to reproduce the bug

After repositioning the cursor to the top(ish) of the window, then resizing the window to be larger, then again repositioning the cursor, some rows get dropped from the internal data. The cells are not invalidated immediately, the data visually stays on until those lines are repainted.

Steps to reproduce:

Start vte-0.34.8
Execute  cat lsoutput.txt  (the attached file, a colored "ls -l" executed from vte source's root directory)
Execute   echo $'\e[2;0H'  to move the cursor to the 3rd row
Make the window taller, to around 40 lines
Execute the same echo command again
On mouse highlight or focus out, some lines disappear.

Video: https://docs.google.com/file/d/0B9iCZ18clVMiUEo1dFJaSFByc0U/edit?usp=sharing

Notice: I couldn't reproduce with black and white "ls -l --color=never" output.
Comment 1 Egmont Koblinger 2013-09-20 21:02:19 UTC
An even simpler way to reproduce that doesn't require run-time resizing:
 ./src/vte2_90 -g 80x35
 cat lsoutput.txt
 echo $'\e[2;0H'

and the screen is garbled.

Change the default ring->mask from 31 to 63 in the source and the above example doesn't reproduce the bug anymore. Probably it'd need a correspondingly larger screen to reproduce.
Comment 2 Egmont Koblinger 2013-09-20 22:00:10 UTC
Those lines that disappear are actually still present at the very end of the (now truncated) file stream, and they come back to life with proper text but faulty colors (e.g. fully green lines) if you print some more stuff in the terminal and scroll back.

Is attr_stream truncated incorrectly? Or maybe the last entry needs to be updated somehow?
Comment 3 Egmont Koblinger 2013-09-20 22:08:15 UTC
In vte-0.34.8 ring.c _vte_ring_thaw_row() line 218-219:

    if (!_vte_stream_read (ring->attr_stream, record.attr_offset, (char *) &attr_change, sizeof (attr_change)))
        return;

we do hit that return when it behaves buggy. More than suspicious.
Comment 4 Egmont Koblinger 2013-09-20 22:39:07 UTC
Continue the test case of comment 1 by one more line:

 ./src/vte2_90 -g 80x35
 cat lsoutput.txt
 echo $'\e[2;0H'  # some lines disappear here
 seq 1 100

Scroll back, notice that 38 and 39 are missing.
Press Enter, now 39 and 40 are missing, etc.

We're clearly seeing a ring corruption, apparently vte doesn't recover from it until a terminal reset.
Comment 5 Egmont Koblinger 2013-09-21 00:06:49 UTC
When it starts being buggy, in _vte_ring_thaw_row() in the do_truncate branch
the "records[0].text_offset < ring->last_attr.text_offset" condition is true,
but the next one is false. So ring->last_attr.whatever are not updated, and
this seems to be strongly related.

Within the do_truncate branch, swapping the order of this "if" stuff, and
actually truncating the three streams looks good at the very first glimpse.

It's 2am and I can hardly keep my eyes open and I have no idea what I'm doing
:D

Btw the pattern that we store attributes along with the text offset where those attributes _end_ is weird to me. I'm wondering if the code would be much simpler if we stored attributes along with offsets where they _start_. E.g. we probably wouldn't need that extra record called last_attr that we're not writing to the stream yet...
Comment 6 Egmont Koblinger 2013-09-21 00:15:18 UTC
Created attachment 255453 [details] [review]
I have no idea what I'm doing but it seems to work :)
Comment 7 Egmont Koblinger 2013-09-22 00:50:20 UTC
Ugly things happen when truncating somewhere where the attributes change.

In _vte_ring_freeze_row() where writing the attr stream, you first update last_attr.text_offset, then write out last_attr, then update last_attr.attr.

This leads to the bizarre situation that while the in-memory last_attr has a color attribute and its starting offset, the filestream will contain a color attribute along with its end offset (as I've pointed out earlier).

So in _vte_ring_thaw_row()'s do_truncate branch, reading back a record straight to last_attr is definitely wrong.

Or (rather) reading back is right, but writing out (having different semantics for last_attr and attr_stream's records) is wrong.

Apart from this, it seems that after truncating at an attribute change, attr_stream will contain one more record than desired: the one pointing to the new head of text_stream is not stripped off although it should be.
Comment 8 Egmont Koblinger 2013-09-22 00:57:05 UTC
Review of attachment 255453 [details] [review]:

forget it
Comment 9 Egmont Koblinger 2013-09-22 01:00:42 UTC
Review of attachment 255453 [details] [review]:

forget it
Comment 10 Egmont Koblinger 2013-09-22 09:56:50 UTC
Now that I think of it, storing (attr, end_offset) pairs in the text stream does make sense: this way you still know the starting color of a page after dropping the previous page. Storing (attr, start_offset) would require nasty hacks.

So my current plan is to keep this behavior (so luckily I don't need to touch the nontrivial but well-tested freeze/thaw stuff), and only adjust _vte_ring_thaw_row()'s truncate part accordingly.

I'm also planning to make the code more self-documenting: introduce two standalone variables instead of last_attr's two fields to emphasize the semantical difference (e.g. last_attr and last_attr_text_start_offset -- let me see if the latter one is actually required), and rename VteCellAttrChange's text_offset field to text_end_offset.
Comment 11 Egmont Koblinger 2013-09-23 13:53:03 UTC
Created attachment 255563 [details] [review]
Step 1: Refactoring only, no behavior change
Comment 12 Egmont Koblinger 2013-09-23 13:54:47 UTC
Created attachment 255564 [details] [review]
Step 2: The actual bugfix

Please test and review.

Divided into two separate patches, to be applied in top of each other. I hope it's easier to review this way.

The first one only renames variables and similar refactoring, no change in behavior. The second one is the actual bugfix.
Comment 13 Egmont Koblinger 2013-09-23 14:14:28 UTC
Created attachment 255568 [details] [review]
Step 2: The actual bugfix

(just clarified one comment)