From: Maciej Z. <ma...@ce...> - 2003-11-11 21:39:59
|
On Sun, 9 Nov 2003, Roland McGrath wrote: > This is not something that is really apropos to strace, or at least not in > the current circumstances. strace uses the operating system's facilities > for catching a process doing a system call. You would need an equivalent > facility in the operating system, i.e. the Linux kernel. As far as I know, > there is no aspect of the ptrace facility that lets you trap io instructions. > >From my understanding of the x86 hardware facilities, it would have to work > by disallowing the permissions that ioperm/iopl enable, catching the fault, > and then handling it specially. Not real hard to do, but it has to be done > before strace can consider supporting it. I've spent a good while thinking about what you've written - even so far as almost starting coding it within kernel space and I've come to the conclusion that this belongs in user space. All the functionality necessary to implement this is present in the kernel. I'm including a 'proof-of-concept' or whatever program. 8160 bytes and it pretty much does what I was looking for. It's not 100% perfect. a) pushf/popf/iret/cli/sti can't be emulated period - processor limitation - they'll be silently ignored (cli/sti) and the interrupt flag will be silently unchanged (popf/iret) and the interrupt flag and iopl levels will contain unemulated values (pushf) - if something is critical enough to require this we can't really trace it like this anyway since our timing is way off... each io instruction causes at least two task switches... b) I'm not fully familiar with the ptrace/signal interaction and I'm sure I'm missing something (iotrace mc with subshell hangs in rt_sigsuspend for no apparent reason - I don't need such functionality so I'm not fixing it [don't really know how] - strace handles mc nicely, so it can be done, besides if this gets converted into a patch for strace then it'll fix itself... :) ) [actually it's already fixed] c) I haven't implemented string/stream i/o (ie. insb/insw/insl/ outsb/outsw/outsl and the same preceded by rep) because: 1) I haven't seen it used that much 2) we're not catching mmaped IO anyway 3) it's not trivial to implement if DS/ES registers are set to non-default values - on the other hand if this was to go into strace as a patch the DS/ES == default value should probably be implemented for pseudo-completeness. If someone tells me how to access our traced processes user memory at address seg:ofs (note that seg is not necessarily the normal user DS!) and figure out whether segment seg is 32bit operand/address sized default or not - then I'll do it. - currently string I/O instructions should cause a SIGSEGV (untested) - undefined instructions should also cause a SIGSEGV (untested) This is probably much easier to get right by patching strace then by writing it from scratch :) especially due to the lack of good ptrace documentation... d) at the moment we're assuming the code segment is fully 32 bit (default 32bit operand and address sizes) - as above this requires determining whether a segment is 32bit operand and/or 32bit address not. Most nice one-threaded programs which don't screw around with signals should work with this version, most others will probably work as well :), although we don't follow any forks. For example "iotrace SVGATextMode 80x25 2>log" works fine for me. And "iotrace zgv 2>/dev/null" also works (didn't examine the actual log of this svgalib console graphics viewer - it's possible it forks...). What do you people think? Should this be patched into strace? If so anybody willing to tell me where to cut&paste this into the strace source? Anybody know how to get segment code16/32 data16/32 boolean values and segment base/limit for any given segment? I expect GDB does this somehow... Cheers, MaZe. |