Sometimes I have an idea and then just wish I hadn't [entries|reading|network|archive]
simont

[ userinfo | dreamwidth userinfo ]
[ archive | journal archive ]

Thu 2011-10-06 19:13
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.)

[xpost |http://simont.livejournal.com/234277.html]

LinkReply
[identity profile] hsenag.livejournal.comThu 2011-10-06 21:44
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.
Link Reply to this
[identity profile] antifuchs.livejournal.comThu 2011-10-06 20:50
Brilliant idea.
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.
Link Reply to this
[personal profile] gerald_duckFri 2011-10-07 00:16
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.
Link Reply to this | Thread
[personal profile] simontFri 2011-10-07 06:28
Subterfugue, I said. Here.

It does look pretty bit-rotted, though. "Supports Linux 2.4".
Link Reply to this | Parent
[identity profile] andy bennettFri 2011-10-07 14:11
Code that writes code that writes code
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
Link Reply to this
[identity profile] pasi kallinenMon 2011-10-10 06:35
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 :)
Link Reply to this
navigation
[ go | Previous Entry | Next Entry ]
[ add | to Memories ]