{"action":"created","issue":{"url":"https://api.github.com/repos/gnunn1/terminix/issues/589","repository_url":"https://api.github.com/repos/gnunn1/terminix","labels_url":"https://api.github.com/repos/gnunn1/terminix/issues/589/labels{/name}","comments_url":"https://api.github.com/repos/gnunn1/terminix/issues/589/comments","events_url":"https://api.github.com/repos/gnunn1/terminix/issues/589/events","html_url":"https://github.com/gnunn1/terminix/issues/589","id":192142518,"number":589,"title":"Doesn't properly release VTE, causing mem and FD leak","user":{"login":"egmontkob","id":5750745,"avatar_url":"https://avatars.githubusercontent.com/u/5750745?v=3","gravatar_id":"","url":"https://api.github.com/users/egmontkob","html_url":"https://github.com/egmontkob","followers_url":"https://api.github.com/users/egmontkob/followers","following_url":"https://api.github.com/users/egmontkob/following{/other_user}","gists_url":"https://api.github.com/users/egmontkob/gists{/gist_id}","starred_url":"https://api.github.com/users/egmontkob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egmontkob/subscriptions","organizations_url":"https://api.github.com/users/egmontkob/orgs","repos_url":"https://api.github.com/users/egmontkob/repos","events_url":"https://api.github.com/users/egmontkob/events{/privacy}","received_events_url":"https://api.github.com/users/egmontkob/received_events","type":"User","site_admin":false},"labels":[{"id":305148413,"url":"https://api.github.com/repos/gnunn1/terminix/labels/bug","name":"bug","color":"fc2929","default":true}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":14,"created_at":"2016-11-28T23:07:01Z","updated_at":"2017-02-17T20:01:01Z","closed_at":"2016-12-04T00:16:02Z","body":"Terminix and Terminator suffer from this same bug, so it's pretty much a copy-paste of https://bugs.launchpad.net/terminator/+bug/1645500. Other VTE-based terminals I've tried (gnome-terminal, xfce4-terminal, mate-terminal) don't have this issue.\r\n\r\n---\r\n\r\nAs one uses Terminix, it opens up to 3 files (and immediately unlinks them) per VTE. These files contain the scrollback data.\r\n\r\nWhen a terminal is closed, VTE is actually not properly released (apparently someone's still holding a reference [perhaps a callback, signal, whatever...]), and in turn its file descriptors are not closed. That is:\r\n\r\n- All the disk space used by them to store the (potentially unlimited) scrollback remains occupied for the entire lifetime of Terminix, potentially leading to quickly filling up /tmp;\r\n\r\n- There's a limit on the open FDs a process can have, it becomes possible that a user with a long-running Terminix hits this limit.\r\n\r\n---\r\n\r\nHow to reproduce:\r\n\r\n- Start Terminix with a couple of terminals;\r\n\r\n- In each of them produce lot of output including various colors;\r\n\r\n- ls -l /proc/[terminix's pid]/fd;\r\n\r\n- Notice 3 file descriptors for each VTE pointing to \"/tmp/blahblah (deleted)\";\r\n\r\n- Close some of the terminals;\r\n\r\n- Notice that their files are still open.\r\n\r\n- If you really produce a lot (like, really a lot) of data in these terminals with infinite scrollback, you can also see \"df\" reporting a shrinking /tmp.\r\n\r\n- If you add a debug printf to vte's vte_terminal_finalize(), you'll see that it's not called.\r\n\r\nExpected behavior:\r\n\r\n- When a terminal is closed, its 3 file descriptors should disappear from this listing (at any time, the number of such deleted open files should be at most 3 times the number of open terminals). The available disk space (\"df\") under /tmp should grow back.\r\n\r\n- The debug printf should tell you that vte_terminal_finalize() is executed.\r\n\r\n---\r\n\r\nA bit of technical background:\r\n\r\nEach VTE creates 3 streams for the scrollback contents. One is for the plain text. The other is for colors and other attributes, using a runlength encoding (to--from coordinates for each continuous run of identical attributes). The third one contains pointers to the first two for each phyisical line of the buffer.\r\n\r\nEach stream is flushed to disk after every 64kB of data. The file is only created at the first write, that is, when 64kB is already written to that stream.\r\n\r\nThere's compression, encryption, and a weird mapping to get a circular buffer if the scrollback is finite large, I'm not going into these details here.\r\n\r\nIf the teminal's contents consists of plain non-colored single-wide characters only, the file containing the attributes won't grow and hence this stream won't hit the disk. Therefore if you wish to see 3 file descriptors appearing, you need to produce various colors, or double-wide (CJK) characters; a giant plain English text will only get you 2 files.\r\n\r\nWhen the terminal's contents are rewrapped on a resize, 1 of the 3 streams (the one with the row indexes) is regenerated and the old one is thrown away (and so is the underlying file). Therefore when a terminal is resized, you might face the number of opened files decreasing by 1.\r\n\r\nI'm writing these so that you don't get into too many unknowns and wtfs while debugging :)"},"comment":{"url":"https://api.github.com/repos/gnunn1/terminix/issues/comments/280751730","html_url":"https://github.com/gnunn1/terminix/issues/589#issuecomment-280751730","issue_url":"https://api.github.com/repos/gnunn1/terminix/issues/589","id":280751730,"user":{"login":"egmontkob","id":5750745,"avatar_url":"https://avatars.githubusercontent.com/u/5750745?v=3","gravatar_id":"","url":"https://api.github.com/users/egmontkob","html_url":"https://github.com/egmontkob","followers_url":"https://api.github.com/users/egmontkob/followers","following_url":"https://api.github.com/users/egmontkob/following{/other_user}","gists_url":"https://api.github.com/users/egmontkob/gists{/gist_id}","starred_url":"https://api.github.com/users/egmontkob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/egmontkob/subscriptions","organizations_url":"https://api.github.com/users/egmontkob/orgs","repos_url":"https://api.github.com/users/egmontkob/repos","events_url":"https://api.github.com/users/egmontkob/events{/privacy}","received_events_url":"https://api.github.com/users/egmontkob/received_events","type":"User","site_admin":false},"created_at":"2017-02-17T20:01:01Z","updated_at":"2017-02-17T20:01:01Z","body":"Nice job, both of you guys! :) :+1: "}}
{"actor":{"display_login":"egmontkob"}}