Julia Evans

A useful new strace feature

I just upgraded my computer to Ubuntu 16.04, from 12.04. So, expect occasional updates on what has happened in the last 4 years since I am a computer dinosaur.

Now, as you all know, strace is my favorite program. So updates to my favorite program are EXTREMELY EXCITING.

When you run strace, you’ll see a lot of lines like this:

write(1, "aio.h\t       btrfs\t   elf.h...") = 172

The number “1” is a file descriptor. Another thing that it is is NOT VERY INFORMATIVE. It’s important to know about file descriptors, but when I tell people about strace, I always feel like it’s kind of annoying! Why can’t strace just tell me which file it wrote to, instead of hiding it behind some number?

WELL NOW IT CAN. There is a new flag: -y! Let’s imagine we don’t fully understand the difference between cp and mv, and we want to find out. For this task, I decided to copy a 1GB Ubuntu 16.04 ISO image from my desktop to /tmp/blah.

strace -o out -y cp ubuntu-16.04-desktop-amd64.iso /tmp/blah 

Now let’s see what it did! We still get to keep the file descriptors, but it appends the filename of the file it was reading from! Awesome! We can see that it’s reading 128KB (128 * 1024 = 131072 bytes) at a time from the source file (/home/bork/Desktop/ubuntu-16.04-desktop-amd64.iso), and writing them into the destination file (/tmp/blah). Seems reasonable!

read(3</home/bork/Desktop/ubuntu-16.04-desktop-amd64.iso>, "\315\350\5p\244\334\266\213 \2553~\37\7\330w\3125\316\360u\204P\236\255\n\244\344\264\327\213\241"..., 131072) = 131072
write(4</tmp/blah>, "\315\350\5p\244\334\266\213 \2553~\37\7\330w\3125\316\360u\204P\236\255\n\244\344\264\327\213\241"..., 131072) = 131072
read(3</home/bork/Desktop/ubuntu-16.04-desktop-amd64.iso>, "\37\367\336\377\247!\357\377\200\337wV\335\366|\232\337?\373iz\37r\376/z5\275\377\360\247\335"..., 131072) = 131072
write(4</tmp/blah>, "\37\367\336\377\247!\357\377\200\337wV\335\366|\232\337?\373iz\37r\376/z5\275\377\360\247\335"..., 131072) = 131072
read(3</home/bork/Desktop/ubuntu-16.04-desktop-amd64.iso>, "x\321/|'m\25\313o \261t^b\306\17r4~\3138j\6\4\244\3308\300E\366\364\22"..., 131072) = 131072
write(4</tmp/blah>, "x\321/|'m\25\313o \261t^b\306\17r4~\3138j\6\4\244\3308\300E\366\364\22"..., 131072) = 131072
read(3</home/bork/Desktop/ubuntu-16.04-desktop-amd64.iso>, "j\273\324\332\216\361\207\204\336\243\326\267\227\35\322\370\205\245N6+\211h\246\215\32k\336\0\r\320."..., 131072) = 131072
write(4</tmp/blah>, "j\273\324\332\216\361\207\204\336\243\326\267\227\35\322\370\

What about mv ubuntu-16.04-desktop-amd64.iso ..? What does that do?

rename("ubuntu-16.04-desktop-amd64.iso", "../ubuntu-16.04-desktop-amd64.iso") = 0

That’s just one system call! No wonder moving is so fast and copying is so slow :)

usability is cool (and, -yy!)

I love seeing programs like strace get usability improvements! This is awesome. If you run strace with -yy, and you’re doing networking, it’ll resolve file descriptors into a source & destination IP address and port, like this!

This is querying my DNS server on localhost for blah.com and getting no answer.

$ strace -yy wget blah.com
recvfrom(3<UDP:[127.0.0.1:46218->127.0.1.1:53]>, "\270\222\201\205\0\1\0\0\0\0\0\0\4blah\3com\0\0\1\0\1", 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.1.1")}, [16]) = 26