[RFC v2] Decode UFFDIO_* ioctls

Dmitry V. Levin ldv at altlinux.org
Sat Apr 23 02:39:42 UTC 2016


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("}");


-- 
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/20160423/4235e3db/attachment.bin>


More information about the Strace-devel mailing list