A Very Short vi Session with strace

August 09, 2017

Having seen Dan Luu’s tweet of the table “Time to load 3 GB file, insert character at start and exit” here, I want to see how vi does file I/O and also very briefly demonstrate strace.

First we need a large (ASCII) file. It does not need to be ASCII but it looks better like that in vi. So to generate a large ASCII file (thanks to this stackoverflow post):

$ base64 /dev/urandom | head -c 1000000000 > a

a is a 1GB file. ls output is:

-rw-rw-r-- 1 mete mete 1000000000 Aug  9 12:42 a

Now it is time to strace.

strace -etrace=open,close,write,read -o log vi a

This traces open, close, write and read system calls during the vi session, outputting the log to file named log.

In the vi session, I deleted the first character in the file.

The generated log file is very big, even if it contains only 4 system calls. ls output is:

-rw-rw-r-- 1 mete mete 8557348 Aug  9 12:48 log

Now, I open the log file and search for the name of the file “a” since it is going to be argument to open system calls. There are only 3 open calls like this:

open("a", O_RDONLY)                     = 3

The first is followed immediately by a close:

close(3)                                = 0

Then it is opened again and file is read:

read(3, "XqP2mbHhDltEMmkbl5wyJ/DumdU4l222"..., 8192) = 8192
read(3, "T/lS0yRhinZhJmpVsnBUn+xKQmCETVVv"..., 65536) = 65536

This repeats 15259 times and ends with:

read(3, "4N16OycPhT8yavc\nVYnACYDA9ez2IVpW"..., 65536) = 43520
read(3, "", 65536)                      = 0

Then it is closed.

The last open is followed by write calls:

write(3, "qP2mbHhDltEMmkbl5wyJ/DumdU4l222A"..., 8192) = 8192

repeating 122070 times and finishes with:

write(3, "6w/uUEf9a6N//vIHV3\n79x458WIdmCKN"..., 2560) = 2560

So basically, vi reads the file in 64K blocks, and then writes it out in 8K blocks.

strace is a great utility to examine system calls.