Check out my first novel, midnight's simulacra!

Spooky tmux at a Distance

From dankwiki
Revision as of 03:03, 20 February 2021 by Dank (talk | contribs)

GitHub user ton did the noble service of filing Notcurses bug #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).

one feels bad at times like this because one is bad, and one ought feel bad. computer science and programming, at their best, are about the most wonderful jobs one can have. as fred brooks wrote:

The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by the exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. Yet the program construct, unlike the poet's words, is real in the sense that it moves and works, producing visible outputs separate from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.

brooks was extending a simile made famous decades before by g.h. hardy:

The mathematician’s patterns, like the painter’s or the poet’s must be beautiful; the ideas like the colours or the words, must fit together in a harmonious way. Beauty is the first test: there is no permanent place in the world for ugly mathematics. A mathematician, on the other hand, has no material to work with but ideas, and so his patterns are likely to last longer.

rather unlike the poet, however, coding also involves buckets of cash dumped on your head on a daily basis. as lil' jon said:

party like a rock star / fuck like a porn star / i don't give a damn / imma buy the whole bar

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 humankind's greatest achievement, the microprocessor, and you took a shit all over it and played with the shit and went up to other people with shit smeared on your grinning simpleton face and shit dribbling from your hand and said, "isn't this a runny, nasty shit i took? i applied all my ingenuity and craft, for which i was paid $3,000 per diem, which i used to bronze my anal leakage". then you wonder how AOC keeps getting elected.

jesus, it's embarrassing to read my comments on that bug. "does tmux possibly shim getc() or something?" well, you can run programs as root within tmux, 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.

essentially, within tmux, the code did some drawing, then prompted for input. upon prompting for input, the active colors were reset. Notcurses heavily optimizes its rasterization, never emitting a styling escape unless it's needed (just a foreground and background RGB escape represent 2800%(!!) overhead relative to a single-byte glyph, so these optimizations are essential), so this reset caused subsequent draws to be incorrectly styled (in this case, the background color was incorrect). analysis with strace(1) revealed the resets in my write(2) calls, but i had no write call anywhere nearby. indeed, the output was being provably generated within my getc(3) call! as a sane fucking human being, i excluded the possibility that ANSI C getc(3) spontaneously emits console control codes. as that old fraud sherlock holmes is so fond of patronizing poor watson:

How often have I said to you that when you have eliminated the impossible, whatever remains, however improbable, must be the truth?

i thus attributed the behavior to some "spooooooooky tmux action at a distance", however improbable, and called it a day.

the difficulty gone unspoken in doyle's bromidic platitude, of course, is knowing what's truly impossible. i had assumed that getc(3) does not emit precipitous, mysterious writes like ink from a squid enraged by a plate of calamari. after all, from the DESCRIPTION section of the 2020-12-21 getc.3 man page:

fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error. getc() is equivalent to fgetc() except that it may be implemented as a macro which evaluates stream more than once.

and the ANSI/ISO C18 standard makes 18 non-index uses of "flush", exactly zero of them suggesting that getc(3) might spontaneously vomit control sequences into what was a perfectly serviceable output FILE*. c might be harsh and unforgiving, but tourette's isn't its style.