simont: A picture of me in 2016 (Default)
simont ([personal profile] simont) wrote2011-10-06 07:13 pm

Sometimes I have an idea and then just wish I hadn't

Many Unix programmers will be familiar with the utility variously called strace, truss, ktrace, dtrace and probably other names too, which logs all communication between a process and the kernel across the system call interface.

A couple of years ago I wrote an analogous program called xtruss, which produces similar logging but operates at the interface between an X11 client program and the X server. (Of course, that wasn't a new idea; I just liked my version's design better than prior ones, mostly because it behaves more like strace.)

A related piece of software to strace is Subterfugue, which intercepts system calls using the same underlying technology that strace does, but instead of passively monitoring them, is able to modify the results as it sees fit. The result is a user-scriptable system that allows you to subject a process to all sorts of subtle and not-so-subtle illusions or behaviour modifications; it can be quite tricky to do anything that's both useful and robust with it, but it's potentially pretty powerful. (It's also not been maintained for ages, but that's not relevant to my current train of thought.)

Today I had the idea: why not fill in the blank in that table, and write the thing that is to xtruss what Subterfugue is to strace? Reuse xtruss's framework for conveniently setting up one-off X11 proxies between a specific application and the X server, and then implement a marshalling and demarshalling layer which translates between wire-encoded X11 messages and an unpacked format that can be accessed by a popular scripting language. Then you could arrange both large and small special effects on X programs, and in particular you could cause them to happen on a per-client basis rather than uniformly across the whole server.

But that wasn't the idea I started off with. I was actually wondering about a much more specific problem: remapping – and occasional complete destruction – of X keystroke events on a per-application basis, for applications with inadequate built-in keymap configurability. (For instance, I keep accidentally hitting a key combination in my work email client which causes half-composed messages to be sent without confirmation, but I'm unwilling to just define that key combination to be a window-manager hot key for ‘do nothing’ in case I turn out to need it in some totally different application.)

And since I already have the X proxy framework from xtruss, the thought occurred that I could enhance it just a little to let it rewrite or squash X events, and then I'd have a proxy that would do the thing I wanted; and although this would certainly be a disproportionate effort for the result if I were writing that X proxy from scratch, doing it by slightly modifying code I've already got seemed almost practical by comparison.

But of course once I'd thought of doing this job by proxying an X connection and rewriting pieces of it, I realised that that certainly wouldn't be the only use for such technology, which led immediately to the idea of a Subterfugue-like general framework.

And on the one hand that does sound like quite a fun piece of software … and yet, we're now back to it being a huge amount of work to go to for the sake of the one specific application I actually wanted it for, and I'm pretty sure I can't be bothered. But on the other hand, now I've imagined the generic version, I also wouldn't feel right about writing just the one-off utility that only does key mapping (or, worse still, only the specific key mapping I wanted). Bah.

(There seems a good chance that at least one reader will point out some totally different way in which I could impose keystroke-mangling of my choice on an uncooperative X client. I will be grateful for that, but it won't affect the main point, which is that sometimes having an apparently cool and generalising and elegant idea makes me less happy, and furthermore, bah.)

[identity profile] hsenag.livejournal.com 2011-10-06 09:44 pm (UTC)(link)
These days, when I start generalising ideas into frameworks in my head, I control the impulse by actually writing the one-off thing first, and then only then start abstracting out the code in the general direction of a framework until I lose interest. It sort of works.

Brilliant idea.

[identity profile] antifuchs.livejournal.com 2011-10-06 08:50 pm (UTC)(link)
I think I could use something like this for when I have to debug interaction between various versions of Motif and the X server (and of course, our library on top of Motif). Also, thanks for pointing out xtruss, which I will install ASAP and use to try and figure out a couple of nasty bugs myself.
gerald_duck: (frontal)

[personal profile] gerald_duck 2011-10-07 12:16 am (UTC)(link)
Google can't trivially find a program called "subterfuge"; do you happen to have a link for it?

Just last week I wanted something that could compel a specific program to use a TCP port other than the one it had hardwired, though I'd been intending to do that at the LD_PRELOAD level.

Code that writes code that writes code

[identity profile] andy bennett (from livejournal.com) 2011-10-07 02:11 pm (UTC)(link)
It's an interesting idea to write something that works at the IPC level like that.
I once wrote something that you pass something like a Linux .so shared object and it'll write you a shim for it with the same signatures. This shim just calls the original symbols and passes through the arguments. It can then be LD_PRELOADed in front of the actual library.
Once I got that far it was easy to make the shim do arbitrary things with the calls such as API logging. What's even more interesting is that once you have that API log you can compile *that* and use it to replay the calls. This is really useful when trying to debug behaviour on, say, a production system without debugging symbols: you can capture your log and take it off for compilation on your testing systems.


Regards,
@ndy

[identity profile] pasi kallinen (from livejournal.com) 2011-10-10 06:35 am (UTC)(link)
As if you don't know this already:

Write the one-off utility, because there's guaranteed to be other people who want to do the same as you. And they might even send patches :)