Spooky tmux at a Distance: Difference between revisions
No edit summary Tags: Mobile edit Mobile web edit |
No edit summary |
||
| (9 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
'''[[Dankblog|dankblog!]] 2021-02-20, 2307 EST, at [[Viewpoint|the danktower]]''' | |||
[[GitHub]] user [https://github.com/ton ton] did the noble service of filing [[Notcurses]] bug [https://github.com/dankamongmen/notcurses/issues/1314 #1314] about a month ago (please, please, please file bugs when you encounter problems in my software), and i "fixed" it about a week later. i was uncomfortable with my solution, and i bet you know that shitty feeling. your reasoning about the issue doesn't even convince yourself...doesn't even seem ''plausible'' really. the applied change doesn't clearly rectify a wrong; perhaps you can't explain how, exactly, it has anything to do with the observed problems. perhaps you dress this up with a comment, a prolix row or two full of guarded conjecture, stressing that you've arranged things just this way because "maybe this other way causes this problem...". such a comment can only be necessary because a reasonable, even an informed person could at any point naturally change the code back, since after all, this thing here couldn't affect that thing over there (the irony of software engineering is that such a change might well happen anyway, doubly invalidating your cowardly, mealymouthed comment, which will be left in place to confuse the fuck out of whatever unhappy soul next reads the code, struggling for semantic consonance). | [[GitHub]] user [https://github.com/ton ton] did the noble service of filing [[Notcurses]] bug [https://github.com/dankamongmen/notcurses/issues/1314 #1314] about a month ago (please, please, please file bugs when you encounter problems in my software), and i "fixed" it about a week later. i was uncomfortable with my solution, and i bet you know that shitty feeling. your reasoning about the issue doesn't even convince yourself...doesn't even seem ''plausible'' really. the applied change doesn't clearly rectify a wrong; perhaps you can't explain how, exactly, it has anything to do with the observed problems. perhaps you dress this up with a comment, a prolix row or two full of guarded conjecture, stressing that you've arranged things just this way because "maybe this other way causes this problem...". such a comment can only be necessary because a reasonable, even an informed person could at any point naturally change the code back, since after all, this thing here couldn't affect that thing over there (the irony of software engineering is that such a change might well happen anyway, doubly invalidating your cowardly, mealymouthed comment, which will be left in place to confuse the fuck out of whatever unhappy soul next reads the code, struggling for semantic consonance). | ||
| Line 11: | Line 13: | ||
''unlike'' the poet, though, coding also involves buckets of cash dumped on your head on a daily basis. as [https://genius.com/Lil-jon-act-a-fool-lyrics lil' jon] forthrightly declaimed: | ''unlike'' the poet, though, coding also involves buckets of cash dumped on your head on a daily basis. as [https://genius.com/Lil-jon-act-a-fool-lyrics lil' jon] forthrightly declaimed: | ||
<blockquote>party like a rock star / fuck like a porn star / i don't give a damn / imma buy the whole bar</blockquote> | <blockquote>party like a rock star / fuck like a porn star<br/> | ||
and indeed zero basketball teams are owned by Poets Laureate. so when you half-ass it like this, you're not only being paid phat stacks to spend the day jerking it, an embarrassment to yourself and everyone around you. you're not just being intellectually dishonest in a time when we need our most logical and rational to light the way. no, you're profaning a sacred craft. you were chosen to steward humanity's greatest achievement, the microprocessor, and you took a shit all over it | i don't give a damn / imma buy the whole bar</blockquote> | ||
and indeed zero basketball teams are owned by Poets Laureate. so when you half-ass it like this, you're not only being paid phat stacks to spend the day jerking it, an embarrassment to yourself and everyone around you. you're not just being intellectually dishonest in a time when we need our most logical and rational to light the way. no, you're profaning a sacred craft. you were chosen to steward humanity's greatest achievement, the microprocessor, and you took a shit all over it. | |||
jesus, it's embarrassing to read my comments on that bug. "does <tt>tmux</tt> possibly shim <tt>getc()</tt> or something?" well, you can run programs as root within <tt>tmux</tt>, so probably not, asshole! scandalous levels of stupidity in this analysis. "i have no idea where this behavior is coming from, and intend to get to the bottom of it." famous last words! i did not get to the bottom of it, and indeed blissfully went on, with no idea where the behavior came from, ''because i was wrong''. my changes did absolutely fix the limited case reported, but not the fundamental problem. | jesus, it's embarrassing to read my comments on that bug. "does <tt>tmux</tt> possibly shim <tt>getc()</tt> or something?" well, you can run programs as root within <tt>tmux</tt>, so probably not, asshole! scandalous levels of stupidity in this analysis. "i have no idea where this behavior is coming from, and intend to get to the bottom of it." famous last words! i did not get to the bottom of it, and indeed blissfully went on, with no idea where the behavior came from, ''because i was wrong''. my changes did absolutely fix the limited case reported, but not the fundamental problem. | ||
| Line 28: | Line 31: | ||
same constraints: the Notcurses intro banner had to be disabled, the behavior only happened within <tt>tmux</tt>, but following input, colors were off for the duration of a single render. crazy constraints. intro banners? what the fuck all could those have to do with anything? how is stdin affecting stdout? why don't i understand how computers work? perhaps finally drinking the bathroom cleaner would put this problem to rest once and for all? flinging myself up and over my terrace in a graceless subballistic arc, less gravity's rainbow than gravity's belly flop, seemed not an unreasonable response. alas, taking a lesson from senator warren, i persisted. | same constraints: the Notcurses intro banner had to be disabled, the behavior only happened within <tt>tmux</tt>, but following input, colors were off for the duration of a single render. crazy constraints. intro banners? what the fuck all could those have to do with anything? how is stdin affecting stdout? why don't i understand how computers work? perhaps finally drinking the bathroom cleaner would put this problem to rest once and for all? flinging myself up and over my terrace in a graceless subballistic arc, less gravity's rainbow than gravity's belly flop, seemed not an unreasonable response. alas, taking a lesson from senator warren, i persisted. | ||
you can read the bug for the gory details of epiphany, but the moment of truth came during a perusal of the Glibc Info pages, §12.20.2 "[https://www.gnu.org/software/libc/manual/html_node/Flushing-Buffers.html Flushing Buffers]". now look, my occupation has for over twenty years been that of a [https://www.usenix.org/system/files/1311_05-08_mickens.pdf badass systems programmer], of the take-no-quarters UNIX C variety, ready at any moment to eat death and ask for seconds. part of that is periodically rereading your GNU Info pages, and i'd surely seen this line before, probably multiple times. but it had slipped my mind, or never quite taken hold there: | you can read the bug for the gory details of epiphany, but the moment of truth came during a perusal of the Glibc Info pages, §12.20.2 "[https://www.gnu.org/software/libc/manual/html_node/Flushing-Buffers.html Flushing Buffers]". now look, my occupation has for over twenty years been that of a [https://www.usenix.org/system/files/1311_05-08_mickens.pdf badass systems programmer], of the take-no-quarters UNIX C variety, ready at any moment to [https://getyarn.io/yarn-clip/972a8442-4a49-4181-a057-6ce60236809f eat death and ask for seconds]. part of that is periodically rereading your GNU Info pages, and i'd surely seen this line before, probably multiple times. but it had slipped my mind, or never quite taken hold there: | ||
<blockquote>There are many circumstances when buffered output on a stream is flushed automatically: | <blockquote>There are many circumstances when buffered output on a stream is flushed automatically: | ||
| Line 36: | Line 39: | ||
* When a newline is written, if the stream is line buffered. | * When a newline is written, if the stream is line buffered. | ||
* Whenever an input operation on any stream actually reads data from its file.</blockquote> | * Whenever an input operation on any stream actually reads data from its file.</blockquote> | ||
anaphora aside, that's pretty exhaustive. read that last line again. '''Whenever an input operation on any stream actually reads data from its file.''' in GNU libc (again, this is '''not''' part of ANSI | anaphora aside, that's pretty exhaustive. read that last line again. '''Whenever an input operation on any stream actually reads data from its file.''' in GNU libc (again, this is '''not''' part of ANSI C—though not prohibited, either), any successful read operation (this does '''not''' apply to the <tt>read(2)</tt> system call, despite being wrapped by glibc), ''on any <tt>FILE*</tt>'', flushes all buffered output data. | ||
is this the [https://en.wikipedia.org/wiki/Principle_of_least_astonishment Least Astonishing] thing it could do? no it is not. christ, what a waste of my time. | is this the [https://en.wikipedia.org/wiki/Principle_of_least_astonishment Least Astonishing] thing it could do? no it is not. christ, what a waste of my time. and in what ways does this complicate multithreading? | ||
in <tt>[https://notcurses.com/notcurses_init.3.html notcurses_init()]</tt>, i reset the terminal, pretty reasonable. this reset ought have been flushed, and i'd never considered that it might not be. imagine my surprise when i took a closer look at <tt>reset_term_attributes()</tt>: | in <tt>[https://notcurses.com/notcurses_init.3.html notcurses_init()]</tt>, i reset the terminal, pretty reasonable. this reset ought have been flushed, and i'd never considered that it might not be. imagine my surprise when i took a closer look at <tt>reset_term_attributes()</tt>: | ||
| Line 58: | Line 61: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
the third parameter to <tt>term_emit()</tt> controlled flushery, and our third call flushes, and the world is good, right? well of course | the third parameter to <tt>term_emit()</tt> controlled flushery, and our third call flushes, and the world is good, right? well of course not—that <tt>term_emit()</tt> was conditional on <tt>nc->tcache.oc</tt>. and guess what terminal definition lacks <tt>oc</tt>? here's a hint: it starts with t and rhymes with "fucks". furthermore, <tt>term_emit()</tt> writes to <tt>nc->ttyfp</tt>, a stdio <tt>FILE*</tt>, while <tt>tty_emit()</tt> writes to a file descriptor, and requires actually being attached to a terminal (there's precious little value in, say, clearing the screen when you're writing to a file or pipe). so there are at least 4 bugs in these 14 lines. put another way, the only bug-free operative lines of code are <tt>int ret = 0;</tt>, <tt>ret = -1;</tt>, and <tt>return ret;</tt>. | ||
dijkstra is looking down at me from Dutch heaven, frowning, slowly chewing a De Ruijter Fruit Sprinkle as he ruminates, wincing a time or two, and finally declaring "i do not like it." he's not referring to the | dijkstra is looking down at me from Dutch heaven, frowning, slowly chewing a De Ruijter Fruit Sprinkle as he ruminates, wincing a time or two, and finally declaring "i do not like it." he's not referring to the Sprinkle, of which he is reservedly fond. | ||
so, to wrap everything up in one nice package: | so, to wrap everything up in one nice package: | ||
* <tt>tmux</tt>, alone among tested terminals, did not declare <tt>oc</tt>. everything else flushed the reset early on, as intended, hiding the bug. | * <tt>tmux</tt>, alone among tested terminals, did not declare <tt>oc</tt>. everything else flushed the reset early on, as intended, hiding the bug. | ||
* a bug of mine meant that the reset was written using stdio, though admittedly this is merely a side- | * a bug of mine meant that the reset was written using stdio, though admittedly this is merely a side-effect—the real bug was emitting control sequences to a non-terminal. this bug would otherwise not have been an issue, as <tt>write(2)</tt> is of course unbuffered. | ||
* if the banners were used, they flushed stdout (by virtue of writing a newline), hiding the bug. | * if the banners were used, they flushed stdout (by virtue of writing a newline), hiding the bug. | ||
* stdout was not otherwise explicitly touched during the course of execution, but this unknown, supra-Standard behavior implied a buffer flush in an unrelated <tt>getc(3)</tt>. | * stdout was not otherwise explicitly touched during the course of execution, but this unknown, supra-Standard behavior implied a buffer flush in an unrelated <tt>getc(3)</tt>. | ||
| Line 73: | Line 76: | ||
i had considered naming this entry "a railroad's switch points", in reference to a beloved passage of [https://en.wikipedia.org/wiki/The_Periodic_Table_(short_story_collection) primo levi's]: | i had considered naming this entry "a railroad's switch points", in reference to a beloved passage of [https://en.wikipedia.org/wiki/The_Periodic_Table_(short_story_collection) primo levi's]: | ||
<blockquote>...better not to do than to do, better to meditate than to act, better his astrophysics, the threshold of the Unknowable, than my chemistry, a mess compounded of stenches, explosions and small futile mysteries. I thought of another moral, more down to earth and concrete, and I believe that every militant chemist can confirm it: that one must distrust the almost-the-same (sodium is almost the same as potassium, but with sodium nothing would have happened), the practically identical, the approximate, the or-even, all surrogates, and all patchwork. the difference can be small, but they can lead to radically different consequences, like a railroad's switch points; the chemist's trade consists in good part in being aware of these differences, knowing them close up, and foreseeing their effects. And not only the chemist's trade.</blockquote> | <blockquote>...better not to do than to do, better to meditate than to act, better his astrophysics, the threshold of the Unknowable, than my chemistry, a mess compounded of stenches, explosions and small futile mysteries. I thought of another moral, more down to earth and concrete, and I believe that every militant chemist can confirm it: that one must distrust the almost-the-same (sodium is almost the same as potassium, but with sodium nothing would have happened), the practically identical, the approximate, the or-even, all surrogates, and all patchwork. the difference can be small, but they can lead to radically different consequences, like a railroad's switch points; the chemist's trade consists in good part in being aware of these differences, knowing them close up, and foreseeing their effects. '''And not only the chemist's trade.'''</blockquote> | ||
as an aside, it's interesting to consider that Levi wrote that particular simile after surviving the Holocaust. a railroad's switch points, indeed. | as an aside, it's interesting to consider that Levi wrote that particular simile after surviving the Holocaust. a railroad's switch points, indeed. | ||
| Line 81: | Line 84: | ||
[https://www.youtube.com/watch?v=SZafyT2VYQA i am very tricky, and very nasty, now]. | [https://www.youtube.com/watch?v=SZafyT2VYQA i am very tricky, and very nasty, now]. | ||
'''previously: "[[Threadripper_L3_CPUID_Strangeness|Threadripper L3 CPUID Strangeness]]" | '''previously: "[[Threadripper_L3_CPUID_Strangeness|Threadripper L3 CPUID Strangeness]]" 2021-02-05''' | ||
[[Category:Blog]] | |||