[PATCH] -e write=trace doesn't dump data after error return

Jan Kratochvil jan.kratochvil at redhat.com
Thu Aug 9 21:21:00 UTC 2007

Hi Bruce,

On Sat, 28 Jul 2007 15:11:46 +0200, J. Bruce Fields wrote:
> When you provide the commandline option "-e write=fd", strace still
> doesn't dump the full write data in the case where the write system call
> returns an error.

I think this is the right behavior according to the man page
	-e write=set
		Perform a full hexadecimal and ASCII dump of
		all the data written to file descriptors listed in the
There is not a wording `all the data _attempted_to_be_ written to'.

	There appears another unrelated bug to me.
	This command does not print anything:
		strace -e none -e write=1,42 cmd...
	While this one works:
		strace -e none -e trace=write -e write=1,42 cmd...
	IMO it should dump the data even in the latter case as the man page
	-e write=set
		Note that this is independent from the normal tracing of the
		write(2) system call which is controlled by the option -e

It also IMO performs the expectations - the `-e write' output should show
something like tcpdump(8) trace - the data that were seen "on the wire".
Unwritten data would be excessive there.

You can use the regular `-e trace=write' functionality for the write attempts,
you can see the whole data being written using the `-s SIZE' option.

> So, reorganize the cases in dumpio() so that all the write-like cases
> (where the io is input to the system call) are before all the read-like
> cases, and only exit early in the second case.

The patch would look fine to me when I would follow your functionality
expectations (which I don't so far).

> (You could even wonder whether it makes sense to skip dumping in the
> read case.  I tend to suspect the likelihood of there being interesting
> data in the read buffer is small in that case,

	If a read() is interrupted by a signal before it reads any data, it
	shall return -1 with errno set to [EINTR].
	If a read() is interrupted by a signal after it has successfully read
	some data, it shall return the number of bytes read.

Therefore if no data were read it would report syserror(tcp) and no data make
sense to dump.  If some data were read then syserror(tcp) would not happen (as
the returned syscall value would be larger than zero).

The text there refers only to the case `interrupted by a signal', not in the
case of runtime errors like ECONNRESET or ETIMEDOUT.  Fortunately at least
Linux kernel behaves the same way even for ECONNRESET:
	read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1300) = 1300
	nanosleep({0, 10000000}, NULL)          = 0
	read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1300) = 516
	nanosleep({0, 10000000}, NULL)          = 0
	read(3, 0x82f6a0, 1300)                 = -1 ECONNRESET (Connection reset by peer)

(If it would give ECONNRESET asynchronously of the data stream the last read()
before ECONNRESET should have returned the full buffer 1300 as there were
enough incoming data waiting in the kernel read buffer.)


More information about the Strace-devel mailing list