Skip to content

Instantly share code, notes, and snippets.

@zipizap
Last active December 31, 2015 06:29
Show Gist options
  • Save zipizap/7947933 to your computer and use it in GitHub Desktop.
Save zipizap/7947933 to your computer and use it in GitHub Desktop.
Understanding better strace, in order to write up a good reply to C Evans comment :)
#
# This gist is related to C Evan's comment on
# http://zipizap.wordpress.com/2012/10/15/xkl-ubuntu-install-resizing-ntfs-partition-takes-too-long-check-ntfsresize-from-console-with-strace/
#
# Hi Evans :)
#
# I see what you mean: only strace the writes to stdout, and not all writes that
# also contain moved data of the resize... And it got me interested in better understanding
# the strace options, so I did a little "man strace" study and then a little program in C
# that would write to filedescriptors, and some tests with it in bash to see the strace info.
# Will try to expose it as good as I can:
red@ownc:~$ cat /tmp/a.c
#include <stdio.h>
void write2fp(FILE *fp, char* fp_name) {
fprintf(fp, "Writting to %s \n", fp_name);
}
void main() {
FILE *fp;
// sleep 2secs
sleep(2);
// write to FILE
fp=fopen("/tmp/tmp.txt", "w");
write2fp(fp, "FILE");
fclose(fp);
// write to STDOUT
write2fp(stdout, "STDOUT");
// write to STDERR
write2fp(stderr, "STDERR");
}
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$ /tmp/a &>/dev/null & sudo strace -p $(pidof "/tmp/a") -e trace=write
[1] 29112
Process 29112 attached - interrupt to quit
write(3, "Writting to FILE \n", 18) = 18
write(2, "Writting to STDERR \n", 20) = 20
write(1, "Writting to STDOUT \n", 20) = 20
Process 29112 detached
[1]+ Exit 20 /tmp/a &>/dev/null
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$ /tmp/a &>/dev/null & sudo strace -p $(pidof "/tmp/a") -e write=1,2
[1] 29122
Process 29122 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...>) = 0
brk(0) = 0x81fc000
brk(0x821d000) = 0x821d000
open("/tmp/tmp.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fstat64(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77cf000
write(3, "Writting to FILE \n", 18) = 18
close(3) = 0
munmap(0xb77cf000, 4096) = 0
fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfa299e8) = -1 ENOTTY (Inappropriate ioctl for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77cf000
write(2, "Writting to STDERR \n", 20) = 20
| 00000 57 72 69 74 74 69 6e 67 20 74 6f 20 53 54 44 45 Writting to STDE |
| 00010 52 52 20 0a RR . |
write(1, "Writting to STDOUT \n", 20) = 20
| 00000 57 72 69 74 74 69 6e 67 20 74 6f 20 53 54 44 4f Writting to STDO |
| 00010 55 54 20 0a UT . |
exit_group(20) = ?
Process 29122 detached
[1]+ Exit 20 /tmp/a &>/dev/null
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$ /tmp/a &>/dev/null & sudo strace -p $(pidof "/tmp/a") -e trace=write -e write=1,2
[1] 29141
Process 29141 attached - interrupt to quit
write(3, "Writting to FILE \n", 18) = 18
write(2, "Writting to STDERR \n", 20) = 20
| 00000 57 72 69 74 74 69 6e 67 20 74 6f 20 53 54 44 45 Writting to STDE |
| 00010 52 52 20 0a RR . |
write(1, "Writting to STDOUT \n", 20) = 20
| 00000 57 72 69 74 74 69 6e 67 20 74 6f 20 53 54 44 4f Writting to STDO |
| 00010 55 54 20 0a UT . |
Process 29141 detached
[1]+ Exit 20 /tmp/a &>/dev/null
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$
red@ownc:~$
#
#
#
# I've tried this with strace of Ubuntu Linux 12.04.3
#
# What I got from these tests and manpage-reading is that:
#
# a) option "-e trace=write" can be written as "-e write", they are one same option which can
# be called in there 2 different ways
# This option will output *all* write calls, to *all* filedescriptors (including files/sockets/...
# opened by program!). It does not seem possible to tell strace to only show the "write-calls-to-stdoud"
# I did not found the way to "mute" this option - if its omitted it will trace all system calls
# (open,write,read,...) which gives a lot of noise...so it seemed that the best would be to limit
# the output of this option to only show the write calls, with "-e trace=write"
# On the other hand, this would show the write calls pretty clearly, although its for *all*
# file-descriptors... So this option applies to all filedescriptors (bad) but is easily grepable (good)
#
# b) option "-e write=1,2" has a similar name to "-e write" but they are 2 different options that
# work independently (just share the similar unfortunate name...)
# I initially thought that this option would be a filter to the a) option but your comment led me
# to look into it better. I now see that it is not a filter: option a) will show all writes from all
# filedescriptors regardlessly, and option b) will show its own info - both of them are really independent
# options, not a filter.
# This option will show the WRITEs of *only* some specified file-descriptors, but on the other side
# the written data is shown in a wrapped ASCII/HEX format that is not very helpfull for cleartext data,
# and so difficult to grep. Maybe there exists another "strace" option to control how this info is shown,
# but I did not had the opportunity to read the entire manpage to search for it
# So, this option applies only to some filedescriptors (good), but is grep-unfriendly (bad)
#
#
# With all this in mind, and focusing now on your comment, the "sudo strace -p $(pidof “ntfstrace”) -e write"
# would provide a more clean output but would show WRITE calls of *all* file-descriptors (not just stdout,
# and still including the HDD resize data...), so we would still need to grep/awk it afterwards. Also I did
# not found a way (?is it possible?) to limit the "-e trace=write" to only stdout... nonetheless I understood
# your point and removed the "-e write=1,2" option which was only cluttering the info shown :) Thanks :)
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment