[RFC v2] Decode UFFDIO_* ioctls

Dmitry V. Levin ldv at altlinux.org
Sun Apr 24 21:53:54 UTC 2016


On Sat, Apr 23, 2016 at 05:39:42AM +0300, Dmitry V. Levin wrote:
> On Fri, Apr 22, 2016 at 07:02:08PM +0100, Dr. David Alan Gilbert (git) wrote:
> >  !!! TODO!
> >    Add some tests (How do I make it immune from kernel changes to flags
> >        returned?)
> 
> 
> Can't you just print whatever is returned?
> 
> 
> >    Tests the zeropage and wake code
> >    don't use my decode_flags64 - I guess I should be using printflags
> >        but printflags uses struct xlat and they're both unsigned int
> >        where I'm dealing in uint64_t's; perhaps if I just rework
> >        printflags/xlat it'll all work ???
> 
> 
> With regards to printing 64-bit flags, see the thread starting at
> https://sourceforge.net/p/strace/mailman/message/34979546/
> 
> 
> > Example output:
> > 14279 ioctl(20, UFFDIO_API{api=0xaa,
> > features.in=0,features.out=0,ioctls=0x8000000000000003(Register|Unregister|API)}) = 0
> 
> 
> This doesn't resemble a plausible C code.
> strace is expected to print something like this:
> 
> 
> 14279 ioctl(20, UFFDIO_API, {api=0xaa, features=0, ioctls=1<<_UFFDIO_REGISTER|1<<_UFFDIO_UNREGISTER|1<<_UFFDIO_API}) = 0
> 
> 
> > +	case UFFDIO_COPY: {
> > +		struct uffdio_copy uc;
> > +		const uint64_t copy_mode_masks[] = {
> > +			UFFDIO_COPY_MODE_DONTWAKE,
> > +			0
> > +			};
> > +		const char *copy_mode_names[] = { "Dontwake" };
> > +		if (entering(tcp)) {
> 
> 
> There needs to be a tprints(", ")
> otherwise the structure (or its address) is printed right after
> UFFDIO_COPY without any delimiter.
> 
> 
> > +			if (umove_or_printaddr(tcp, arg, &uc))
> > +				return RVAL_DECODED | 1;
> 
> 
> > +			tprintf("{dst=%#" PRI__x64 ", src=%#" PRI__x64
> > +				", len=%" PRI__u64,
> > +				uc.dst, uc.src, uc.len);
> > +			decode_flags64(", mode=", uc.mode,
> > +					copy_mode_masks, copy_mode_names);
> > +			return 1;
> > +		} else {
> > +			if (!umove_or_printaddr(tcp, arg, &uc))
> > +				tprintf(", copy=%" PRI__s64, uc.copy);
> > +			tprints("}");
> > +			return 1;
> > +		}
> 
> 
> As umove_or_printaddr conveniently prints the address in case of failure,
> the prefix string has to be printed earlier:
> 
> 
> 	tprints(", copy=");
> 	if (!umove_or_printaddr(tcp, arg, &uc.copy))
> 		tprintf("%" PRI__d64, uc.copy);
> 
> 
> You can easily reproduce this by invoking UFFDIO_COPY with -1 descriptor.
> In that case you might want to omit irrelevant uc.copy field:
> 
> 
> 	if (!syserror(tcp)) {
> 		tprints(", copy=");
> 		if (!umove_or_printaddr(tcp, arg, &uc.copy))
> 			tprintf("%" PRI__d64, uc.copy);
> 	}
> 	tprints("}");

Of course I meant

		long addr = arg + offsetof(struct uffdio_copy, copy);
		if (!umove_or_printaddr(tcp, addr, &uc.copy))
			tprintf("%" PRI__d64, uc.copy);


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20160425/e9bd04fe/attachment.bin>


More information about the Strace-devel mailing list