<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:webfeeds="http://webfeeds.org/rss/1.0">
  <channel>
    <title>Jussi Judin&#39;s weblog</title>
    <description>Programming related topics. Maybe even some original content!
</description>
    <link>https://barro.github.io/</link>
    <atom:link href="https://barro.github.io/feed.xml" rel="self" type="application/rss+xml"/>
    <atom:icon>https://barro.github.io/icons/favicon-96x96.png</atom:icon>
    <icon>https://barro.github.io/icons/favicon-96x96.png</icon>
    <webfeeds:icon>https://barro.github.io/icons/favicon-96x96.png</webfeeds:icon>
    <pubDate>Sun, 01 Jul 2018 00:28:07 +0300</pubDate>
    <lastBuildDate>Sun, 01 Jul 2018 00:28:07 +0300</lastBuildDate>
    <generator>Jekyll v3.1.6</generator>
    <webfeeds:analytics id="UA-71880517-1" engine="GoogleAnalytics"/>
    
      <item>
        <title>afl-fuzz on different file systems</title>
        <description>&lt;p&gt;One day I was fuzzing around with
&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/&quot;&gt;american fuzzy lop&lt;/a&gt; and accidentally
pointed the output directory for fuzzer findings to point onto a file
system on a physical disk instead of the usual shared memory file
system. I noticed my mistake and changed the output directory to
the usual place. Consequently there was a clear difference on how many
fuzzing iterations/second &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; program could do. This then lead
into this comparison of different file systems and fuzzing modes on
them with the workload that &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; has.&lt;/p&gt;

&lt;h2 id=&quot;hardware-and-software-background&quot;&gt;Hardware and software background&lt;/h2&gt;

&lt;p&gt;Fuzzing is a computationally intensive way to find bugs in programs,
usually fully exercising the machine CPU. This and writing data to the
disk can have adverse effects on the hardware even if we are working
with software. Some risks are listed in the common-sense risks section
at
&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/README.txt&quot;&gt;american fuzzy lop’s README.txt&lt;/a&gt;
file that is a good read about the subject. In this article I’m mainly
interested in what happens when you happen to point the output of
&lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; to a device with a specific file system.&lt;/p&gt;

&lt;h3 id=&quot;afl-fuzz-as-part-of-american-fuzzy-lop&quot;&gt;afl-fuzz as part of american fuzzy lop&lt;/h3&gt;

&lt;p&gt;American fuzzy lop is a successful generic purpose
&lt;a href=&quot;https://en.wikipedia.org/wiki/Fuzzing&quot;&gt;fuzzer&lt;/a&gt; that finds bugs for
you while you sleep. &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; is the executable program that does
the hard work of generating new data, repeatedly running the target
program (fuzz target), and analyzing the results that come up in these
fuzz target executions. It has handcrafted heuristics and fuzzing
strategies that in practice provide quite successful results without
the need for tuning.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;afl-fuzz-forkserver&quot;&gt;

&lt;a href=&quot;https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-2900.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-736.webp 736w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-920.webp 920w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-1104.webp 1104w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-1472.webp 1472w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-2208.webp 2208w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-2900.webp 2900w&quot; sizes=&quot;736px, 920px, 1104px, 1472px, 2208px, 2900px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-736.png 736w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-920.png 920w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-1104.png 1104w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-1472.png 1472w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-2208.png 2208w,     https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/afl-forkserver-visualization-2900.png 2900w&quot; sizes=&quot;736px, 920px, 1104px, 1472px, 2208px, 2900px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/.png Interworkings of afl-fuzz, the fork server, and the fuzz target.&amp;quot;&quot; alt=&quot;Interworkings of afl-fuzz, the fork server, and the fuzz target.&quot; width=&quot;736&quot; height=&quot;355&quot; class=&quot;figure-image&quot; title=&quot;Interworkings of afl-fuzz, the fork server, and the fuzz target.&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption class=&quot;text-center&quot;&gt;
Figure 1: Interworkings of afl-fuzz, the fork server, and the fuzz target.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#afl-fuzz-forkserver&quot;&gt;Figure 1&lt;/a&gt; roughly visualizes the different
parts that are part of a fuzzing session when using &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt;. It
spawns the program that we try to fuzz. This program then
creates a
&lt;a href=&quot;https://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html&quot;&gt;fork server&lt;/a&gt;
that is responsible for communicating with the main &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt;
executable over
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/pipe.2.html&quot;&gt;pipes&lt;/a&gt; and spawning
new fuzz target instances with
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/fork.2.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fork()&lt;/code&gt;&lt;/a&gt; call. The
fork server actually a small shim that is part of the fuzz
target. Also the new program instance that &lt;code class=&quot;highlighter-rouge&quot;&gt;fork()&lt;/code&gt; call spawns still
technically holds a reference to the fork server, but those parts are
just active at different times, visualized as gray in the figure. If
the fuzz target is in
&lt;a href=&quot;https://lcamtuf.blogspot.com/2015/06/new-in-afl-persistent-mode.html&quot;&gt;persistent mode&lt;/a&gt;,
it doesn’t get restarted for every new input.&lt;/p&gt;

&lt;p&gt;Data is passed to the fuzz target either over standard input or over a
newly created file that the fuzz target reads. Then the fuzz target
executes itself by writing an execution trace to a
&lt;a href=&quot;http://man7.org/linux/man-pages/man7/shm_overview.7.html&quot;&gt;shared memory&lt;/a&gt;
and finishes running. &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; then reads the trace left by the fuzz
target from the shared memory and creates a new input by mutating old
ones. What to mutate is controlled by the new and historical
information that the instrumentation data from the fuzz target
provides.&lt;/p&gt;

&lt;h3 id=&quot;solid-state-drives&quot;&gt;Solid state drives&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Solid-state_drive&quot;&gt;Solid state drives&lt;/a&gt;
are nowadays the most common physical storage medium in generic and
special purpose computers. They are fast and relatively decently
priced for the storage needs of a regular software developer. The
decently priced solid state drives come with a price of somewhat
limited write endurance due to the properties of the physical world
and manufacturing compromises.&lt;/p&gt;

&lt;p&gt;Currently (early 2018) the write endurance of a solid state drive
promises to be around half in terabytes than what the drive capacity
is in gigabytes on consumer level drives using
(&lt;a href=&quot;https://en.wikipedia.org/wiki/Multi-level_cell&quot;&gt;TLC NAND&lt;/a&gt;). This
means that 200-250 gigabyte SSD has a write endurance around 100
terabytes. In practice, the write endurance will likely be more at
least on
&lt;a href=&quot;https://techreport.com/review/27909/the-ssd-endurance-experiment-theyre-all-dead&quot;&gt;a test from 2013-2015&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Such write endurance does not really pose any limitations in the usual
consumer level and professional workloads. But when it comes to
fuzzing, it’s not the most usual workload. The whole idea of a fuzzer
is to generate new data all the time, make the program execute it, and
then either discard or save it depending of the program behavior is
interesting or not. So we can expect that a fuzzer will generate quite
a lot of data while it’s running.&lt;/p&gt;

&lt;p&gt;Quick back-of-the-envelope calculation when assuming 10 parallel
fuzzers running 1000 executions/second with 1000 byte input/execution
on average would result in over 20 terabytes of data
generated every month. If all this is directly written to a drive,
then we can expect to have around 5 months until we reach the promised
write endurance limits of a typical solid state drive at the time of
this writing. There is caching that works to prolong this, but then
there are all the invisible file system data structures, minimum file
system block sizes, and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Write_amplification&quot;&gt;write amplification&lt;/a&gt;
then fight against these savings.&lt;/p&gt;

&lt;h3 id=&quot;two-data-passing-modes-of-afl-fuzz&quot;&gt;Two data passing modes of afl-fuzz&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; program has two ways to pass the new input to the fuzz
target: passing the data over the standard input and creating a new
file with the new data and having the fuzz target to read the data
from the just created file file.&lt;/p&gt;

&lt;p&gt;The most compact &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; command only includes the information for
initial inputs, output directory and the command to execute the fuzz
target without any special arguments:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; out/ &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; fuzz-target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The fuzz target gets the input data from its standard input file
descriptor so it does not need to explicitly open any
files. Technically the standard input of the child process is backed
by a file that is always modified by the &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; process when new
input it generated. This file is also &lt;code class=&quot;highlighter-rouge&quot;&gt;.cur_input&lt;/code&gt; file at the fuzzer
instance directory. The exact details of how this works are explained
later.&lt;/p&gt;

&lt;p&gt;The more explicit input file path information including commands look
like this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# &quot;@@&quot; indicates the name of the file that the program gets with new&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# fuzz data. &quot;-f&quot; can be used to hard code the input file location&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# that then can be passed to the fuzz target or not.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; out/ &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; fuzz-target @@
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; out/ &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; target.file &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; fuzz-target @@
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;afl-fuzz &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt;/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; out/ &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; target.file &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; fuzz-target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the first command there is no explicit path to the input file
specified, so the target program will get the path as the first
argument, indicated by &lt;code class=&quot;highlighter-rouge&quot;&gt;@@&lt;/code&gt;. The actual file is located at the fuzzer
instance output directory (here it’s &lt;code class=&quot;highlighter-rouge&quot;&gt;out/&lt;/code&gt;) as &lt;code class=&quot;highlighter-rouge&quot;&gt;.cur_input&lt;/code&gt;
file. Second two forms with &lt;code class=&quot;highlighter-rouge&quot;&gt;-f target.file&lt;/code&gt; switch make it possible
to define the location of the input file so that it can reside outside
the output directory.&lt;/p&gt;

&lt;h4 id=&quot;details-of-input-data-writing&quot;&gt;Details of input data writing&lt;/h4&gt;

&lt;p&gt;Now that we know that &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; provides two different ways for the
data to end in the program, then let’s look at the extracted details
of
&lt;a href=&quot;https://github.com/mirrorer/afl/blob/2fb5a3482ec27b593c57258baae7089ebdc89043/afl-fuzz.c#L2468&quot; title=&quot;afl 2.52b&quot;&gt;write_to_testcase() function&lt;/a&gt;
to see how this data is passed to the child process.&lt;/p&gt;

&lt;p id=&quot;data-passing-stdin&quot;&gt;When &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; writes data into the standard input stream of the fuzz
target, the main parts of the code look like this in both &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; and
fuzz target side:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// afl-fuzz part:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Make sure that reads done by fuzz target do not affect
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// new testcase writes:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;lseek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testcase_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEEK_SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Write new testcase data to the file:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testcase_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;testcase_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Make sure that old data in testcase file does not leak
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// into the new fuzzing iteration:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;ftruncate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testcase_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Make read() act as it would read a fresh standard input
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// instance:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;lseek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testcase_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEEK_SET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Fuzz target part:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// stdin file descriptor inside fuzz target is actually
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// identical to testcase_fd thanks to dup2(). So we just
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// read whatever happens to be there:
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testcase_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Do some actual fuzzing:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What happens in here that first the position in the file is changed to
the beginning. A new data is written over the old one. The file length
is changed to correspond to the new data length. The position is set
to the beginning of the file again. Then the fuzz target reads from
this file descriptor and runs the just written data through the actual
program logic.&lt;/p&gt;

&lt;p id=&quot;data-passing-file&quot;&gt;When passing data to the program through a named file following types
of operations happen:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// afl-fuzz part:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Remove the old output file.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;unlink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Create a new file with the same name.
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;O_WRONLY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;O_CREAT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;O_EXCL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mo&quot;&gt;0600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Write the test data into the created file.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Close the created file so that the data is available to other
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// processes.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Fuzz target part:
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Open the file created by afl-fuzz.
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;O_RDONLY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Read enough data from the opened file descriptor for fuzzing.
&lt;/span&gt;    &lt;span class=&quot;kt&quot;&gt;ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Close the opened file descriptor so that we don&#39;t leak
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// resources.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Do some actual fuzzing:
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Basically old input file is removed and a new file is created, data is
written to it and it’s closed. Then the fuzz target opens the just
created file, reads the data out of it and closes the opened file
descriptor closes it, and runs the data through the actual program
logic.&lt;/p&gt;

&lt;p&gt;You can already see that there are more file system related functions
used when the fuzz data file is recreated. Then these functions
are also more heavy than the ones used in the standard input
version. When you call
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/unlink.2.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;unlink()&lt;/code&gt;&lt;/a&gt; and
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/open.2.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;open()&lt;/code&gt;&lt;/a&gt;, Linux
kernel needs to do
&lt;a href=&quot;https://github.com/torvalds/linux/blob/03f51d4efa2287cc628bb20b0c032036d2a9e66a/Documentation/filesystems/path-lookup.md&quot;&gt;pathname lookup&lt;/a&gt;
to figure out what exact file objects are accessed. When you
only have the file descriptor to manipulate in the standard input
case, you avoid these pathname lookups and hopefully manipulate
purely numeric data. Also when you open a new file, it has to actually
create the corresponding &lt;a href=&quot;https://en.wikipedia.org/wiki/Inode&quot;&gt;inodes&lt;/a&gt;
and their data structures to the file system. This has a certain
amount of overhead.&lt;/p&gt;

&lt;p&gt;So looking at the called functions, it would feel like there is going
to be a fuzzing overhead difference between these two input data
creation approaches.&lt;/p&gt;

&lt;h2 id=&quot;benchmarking&quot;&gt;Benchmarking&lt;/h2&gt;

&lt;p&gt;Theoretical speculation is always nice, but the real hard data comes
from the benchmarking. This section looks at the fuzzing overhead from
both &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; perspective with low and high level filesystem access
functions and from raw file system access perspective. Also the
&lt;a href=&quot;#data-writes&quot;&gt;section about data writes&lt;/a&gt; tries to find an answer to
the question that how damaging fuzzing can actually be to a solid
state drive with a relatively limited write endurance.&lt;/p&gt;

&lt;p&gt;I did these benchmarks with several major general purpose file systems
found from &lt;a href=&quot;https://www.debian.org/&quot;&gt;Debian&lt;/a&gt; provided Linux kernels
4.14.13-1 and 4.15.11-1. These can show up as differences in numbers
between tables, but numbers inside the same table are done with the
same system. Also there is small variance between fuzzing sessions
that I have tried to eliminate running the fuzzers for long enough
that system maintenance and other short running tasks don’t have too
big of an impact. But the relative mileage may vary between kernel
versions, operating system libraries, and between the actual physical
machines.&lt;/p&gt;

&lt;h3 id=&quot;executionssecond&quot;&gt;Executions/second&lt;/h3&gt;

&lt;p&gt;General purpose instrumentation guided fuzzers like american fuzzy lop
and &lt;a href=&quot;https://llvm.org/docs/LibFuzzer.html&quot;&gt;libFuzzer&lt;/a&gt; get their power
from the fact that they can repeatedly execute the fuzz target in
quick succession. Speed is one factor, but also the program stability
from one execution to another is a second one. Having stable program
ensures that the issues that fuzzing finds can be easily
replicated. This basically leads into a compromise of selecting the
appropriate fuzzer and fuzz target execution strategy.&lt;/p&gt;

&lt;p&gt;It can be that the program has a global state that needs program
restart or other tricks between runs. For these types of situations
the default forkserver mode in &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; is appropriate. On the other
hand if everything can be functionally wrapped inside a function that
does not leak its state outside, we can use the much faster persistent
mode in &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt;. From this it should be actually quite easy to port
the fuzz target to libFuzzer.&lt;/p&gt;

&lt;p&gt;In this case libFuzzer shows 735 k executions/second with the
&lt;a href=&quot;#the-example-fuzz-target&quot;&gt;sample target&lt;/a&gt; when the data is not passed
between process boundaries. It is also possible to simulate in-memory
file streams with
&lt;a href=&quot;http://man7.org/linux/man-pages/man3/fmemopen.3.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fmemopen()&lt;/code&gt;&lt;/a&gt;
function where libFuzzer achieved with this example program 550 k
executions/second. This is 15-20 times lower fuzzing overhead than
with &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt;. But in this article we focus on american fuzzy lop’s
persistent mode and leave the fuzzing engine selection for some
other time.&lt;/p&gt;

&lt;p&gt;A typical american fuzzy lop’s persistent mode fuzz target would
generally have some generic configuration in the beginning and then
the actual data dependent program execution would reside inside a
&lt;code class=&quot;highlighter-rouge&quot;&gt;while (__AFL_LOOP(40000)) { ... }&lt;/code&gt; loop. The number 40000 is just the
number of iterations that the program does before it restarts again
and can be lower or higher depending on how confident you are that the
program does not badly misbehave.&lt;/p&gt;

&lt;p&gt;Using the standard input with the persistent mode makes the data
reading code look like following:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;generic_configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__AFL_LOOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Do the actual fuzzing.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using named files with the persistent mode on the other hand requires
opening a new file every iteration:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;generic_configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__AFL_LOOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;O_RDONLY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;ssize_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Do the actual fuzzing.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;the-example-fuzz-target&quot;&gt;The example fuzz target&lt;/h4&gt;

&lt;p&gt;I directly used the code from my
&lt;a href=&quot;/2018/01/taking-a-look-at-python-afl/&quot;&gt;Taking a look at python-afl&lt;/a&gt;
article and modified it to support the file and stdin reader
variants. This code is available from
&lt;a href=&quot;target-simple.cpp&quot;&gt;target-simple.cpp&lt;/a&gt; for the prying eyes. Also the
later on introduced C and C++ standard library variants are available
as &lt;a href=&quot;target-fread.cpp&quot;&gt;target-fread.cpp&lt;/a&gt; and
&lt;a href=&quot;target-ifstream.cpp&quot;&gt;target-ifstream.cpp&lt;/a&gt;.&lt;/p&gt;

&lt;h4 id=&quot;file-system-dependent-results&quot;&gt;File system dependent results&lt;/h4&gt;

&lt;p&gt;The benchmarking was done with a
&lt;a href=&quot;https://linux.die.net/man/8/losetup&quot;&gt;loopback device&lt;/a&gt; that fully
resides in memory. Each of these file systems was created and mounted
with their default options and the performance test was run for 2
minutes. Only a single instance of &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; was running. You can see
from the &lt;a href=&quot;#execs-per-second&quot;&gt;table 1&lt;/a&gt; the difference between the same
workload on different file systems. The
&lt;a href=&quot;https://www.kernel.org/doc/gorman/html/understand/understand015.html&quot;&gt;shared memory virtual file system&lt;/a&gt;
(tmpfs) was the most efficient in both of these cases.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;execs-per-second&quot;&gt;

    &lt;table style=&quot;margin: 0 auto;&quot;&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th style=&quot;text-align: left&quot;&gt;execs/second&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-stdin&quot;&gt;stdin&lt;/a&gt;&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-file&quot;&gt;file&lt;/a&gt;&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;btrfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;20.5 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;14.6 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext2&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;31.6 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;19.2 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext3&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;30.0 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;18.4 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext4&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;28.0 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;18.2 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;JFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;31.7 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;17.1 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ReiserFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;28.0 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;14.5 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;tmpfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;34.6 k&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;25.5 k&lt;/strong&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;XFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;21.1 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;16.8 k&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;figcaption class=&quot;text-center&quot;&gt;Table 1: Average number of fuzz
target executions/second over 2 minute measuring period with different
file systems.&lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;This result also shows an interesting history between ext2, ext3, and
ext4 file systems. Their performance seems to decrease the newer the
file system is, likely due to larger amount of data safety operations
that the newer file systems do. There could be difference when
parallel access to a file system is concerned.&lt;/p&gt;

&lt;h3 id=&quot;execution-speed-with-different-standard-libraries&quot;&gt;Execution speed with different standard libraries&lt;/h3&gt;

&lt;p&gt;I also wanted to see how the use of more portable file system calls in
both C and C++ standard libraries affects the fuzzing speed. Standard
libraries like &lt;a href=&quot;https://www.gnu.org/software/libc/&quot;&gt;glibc&lt;/a&gt;,
&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/&quot;&gt;libstdc++&lt;/a&gt;, and
&lt;a href=&quot;https://libcxx.llvm.org/&quot;&gt;libc++&lt;/a&gt; provide a portable file system
interface across operating systems. They also provide a certain amount
of buffering so that every small read does not result in a system call
and suffer from context switch overhead. These higher level library
functions also aim to be thread safe so that concurrent manipulation
of the same file descriptor would be a little bit less surprising.&lt;/p&gt;

&lt;p&gt;When doing fuzzing, we are usually just reading small amount of data
once and then either close the input file or expect the &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt;
to &lt;a href=&quot;#data-passing-stdin&quot;&gt;reset the input stream for us&lt;/a&gt;. Any buffering
information must also be discarded and the stream position must be
reset so that the input data for the fuzz target is the same what
&lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; expects it to be. If it’s not, it will show as a lower than
100 % stability value on &lt;a href=&quot;http://lcamtuf.coredump.cx/afl/status_screen.txt&quot;&gt;AFL status screen&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Following is the C code used to benchmark how much overhead the
standard C library functions bring into this. Standard input is put
into unbuffered mode with &lt;a href=&quot;http://man7.org/linux/man-pages/man3/setvbuf.3p.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;setvbuf()&lt;/code&gt;&lt;/a&gt; function call, so buffer
manipulation should not have a meaningful amount of overhead.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// C version for glibc benchmarking with standard file manipulation functions.
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setvbuf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_IONBF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__AFL_LOOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// We get the fuzz data filename from argv[1].
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__AFL_LOOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;rb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fread&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fclose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;C++ streams don’t have a working unbuffered reads that would behave
reliably. The closest equivalent to this is to call
&lt;a href=&quot;http://en.cppreference.com/w/cpp/io/basic_istream/seekg&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;istream::seekg()&lt;/code&gt;&lt;/a&gt;
and after that
&lt;a href=&quot;http://en.cppreference.com/w/cpp/io/basic_ios/clear&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;istream::clear()&lt;/code&gt;&lt;/a&gt;
function. This basically is theoretically equivalent to what
&lt;a href=&quot;http://man7.org/linux/man-pages/man3/rewind.3p.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;rewind()&lt;/code&gt;&lt;/a&gt;
function does. Other solution of trying to set
&lt;a href=&quot;http://en.cppreference.com/w/cpp/io/basic_ios/rdbuf&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;istream::rdbuf()&lt;/code&gt;&lt;/a&gt;
to a zero sized one had no real effect on increasing stability.&lt;/p&gt;

&lt;p&gt;C++ code for these fuzzing benchmarks looks like following:&lt;/p&gt;

&lt;div class=&quot;language-c++ highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// C++ version for libstdc++ and libc++ benchmarking with the standard
// C++11 file manipulation functions.
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__AFL_LOOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Resetting stream state is 2 function calls.
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seekg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;beg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// We get the fuzz data filename from argv[1].
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__AFL_LOOP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ifstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ifstream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ifstream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gcount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;input_fd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;buffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;C++ code is a little bit more verbose than C code, as there are extra
layers of abstraction that need to be removed so that &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; style
data processing is possible. &lt;a href=&quot;#libs-execs-per-second&quot;&gt;Table 2&lt;/a&gt;
then shows what is the speed difference of these different
implementations and standard libraries.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;libs-execs-per-second&quot;&gt;

    &lt;table style=&quot;margin: 0 auto;&quot;&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th style=&quot;text-align: left&quot;&gt;execs/second&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;syscalls&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;glibc&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;libstdc++&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;libc++&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#data-passing-stdin&quot;&gt;stdin&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;33.5 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;32.4 k (98 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;31.2 k (93 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;30.7 k (92 %)*&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#data-passing-file&quot;&gt;file&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;24.2 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;22.8 k (94 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;22.0 k (91 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;20.7 k (86 %)&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;figcaption class=&quot;text-center&quot;&gt;Table 2: Fuzz target
executions/second over 2 minute period with different standard
libraries on tmpfs.
&lt;div&gt;* The stability of libc++ stdin session was not 100 %.&lt;/div&gt;&lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;We can see that the pure combination of &lt;code class=&quot;highlighter-rouge&quot;&gt;open()&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;read()&lt;/code&gt;
functions is the fastest one. Portable C standard library
implementation comes quite close with the unbuffered standard input
implementation, but everywhere else there is a clear performance
loss.&lt;/p&gt;

&lt;p&gt;Stability is an important measurement of how reliably fuzzing can
continue. Unfortunately in this tests everything was not 100 %
stable. The standard input reading and resetting for libc++ does not
fully work as expected and leads into reading old data.&lt;/p&gt;

&lt;p&gt;The conclusion here is that try to stay with the low level unbuffered
file manipulation functions or as close to their equivalents. More
portable higher level functions for file access may provide speed
benefits through buffering for regular file access patterns, but in
this case they just add extra layers that slow down the data passing
from &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; to the fuzz target. Unless the fuzz target itself
relies on using those higher level functions.&lt;/p&gt;

&lt;h3 id=&quot;data-writes&quot;&gt;Data writes&lt;/h3&gt;

&lt;p&gt;In the &lt;a href=&quot;#hardware-and-software-background&quot;&gt;background section&lt;/a&gt; I
described how it generally is a bad idea to write data to a physical
disk, as modern solid state drives have a limited write
durability. But one could think that the write caching done by Linux
would prevent a situation from happening where data is constantly
written to the disk if the lifetime of a file contents is really
short.&lt;/p&gt;

&lt;p&gt;The write caching towards block devices is handled by the
&lt;a href=&quot;https://en.wikipedia.org/wiki/Page_cache&quot;&gt;page cache&lt;/a&gt; in the
kernel. But as different file systems may write every new file or file
part into a new location, this cache is not necessarily as effective
as it could be. Even if the writes happen to the same file with very
little data.&lt;/p&gt;

&lt;p&gt;In this section I let &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; to run for 30 minutes and looked at the
kilobytes written by
&lt;a href=&quot;http://man7.org/linux/man-pages/man1/iostat.1.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;iostat&lt;/code&gt;&lt;/a&gt; to a
block device that was a file in memory that was mounted on a
&lt;a href=&quot;https://linux.die.net/man/8/losetup&quot;&gt;loopback device&lt;/a&gt;. This way the
device should have looked like a real block device without the risk of
shortening the lifespan of any real hardware. Estimated monthly values
for disk writes for various file systems can be seen from
&lt;a href=&quot;#data-writes-month-single&quot;&gt;table 3&lt;/a&gt; for a single &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; instance.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;data-writes-month-single&quot;&gt;

    &lt;table style=&quot;margin: 0 auto;&quot;&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th style=&quot;text-align: left&quot;&gt;writes/month&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-stdin&quot;&gt;stdin&lt;/a&gt;&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-file&quot;&gt;file&lt;/a&gt;&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;btrfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;3.052 TiB&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.020 TiB&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext2&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.004 TiB&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.005 TiB&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext3&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.020 TiB&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.028 TiB&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext4&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.035 TiB&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.021 TiB&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;JFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;9.74 TiB&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;69.8 TiB&lt;/strong&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ReiserFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.021 TiB&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.024 TiB&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;tmpfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;XFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;201 TiB&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.004 TiB&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;figcaption class=&quot;text-center&quot;&gt;Table 3: Estimated monthly data
writes for a single fuzzer on different file systems.&lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;The numbers for the amount of data that would be written to the device
is an extrapolation of the 30 minute run and show values are in
terabytes (2&lt;sup&gt;40&lt;/sup&gt; bytes). These numbers are for the persistent
mode and for an extremely light algorithm. They still give some
estimate on the amount of data writes to the disk even for algorithms
that are 10-100 times slower. Nowadays a typical desktop computer can
easily have 8-16 threads and the order of typically processed data per
fuzzer iteration is closer to 1 kilobyte than to 128 bytes as in this
case.&lt;/p&gt;

&lt;p&gt;When looking at these numbers, btrfs, JFS, and XFS file systems are
pretty dangerous ones to accidentally use, as the faster stdin mode
where data is fed to always open file handle actually causes a
meaningful amount of data to be written to a disk per
month. Especially with XFS it’s 4 kilobytes of data written/fuzzing
iteration. Taking into account that many solid state disk drives have
write endurance only in hundreds of terabytes, accidentally running
even one fuzzer for one month or more makes a significant dent in its
lifetime for these file systems.&lt;/p&gt;

&lt;p&gt;I also wanted to see what happens when you run multiple fuzzers in
parallel on the same machine. The most trivial assumption for multiple
fuzzers would be that the file system writes would increase about
linearly with the number of fuzzers. The results on
&lt;a href=&quot;#data-writes-month-x4&quot;&gt;table 4&lt;/a&gt; show that this is indeed the case
for most of the file systems, except for ext2. Fortunately ext2 is not
the worst data writer of the measured file systems and you really need
to go extra mile to use it nowadays, as newer ext3 and ext4 file
systems have replaced it by default.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;data-writes-month-x4&quot;&gt;

    &lt;table style=&quot;margin: 0 auto;&quot;&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th style=&quot;text-align: left&quot;&gt;writes/month&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-stdin&quot;&gt;stdin&lt;/a&gt; x4&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-file&quot;&gt;file&lt;/a&gt; x4&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;btrfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;9.53 TiB&lt;/strong&gt; (78 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.052 TiB  (65 %)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext2&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.072 TiB (&lt;strong&gt;450 %&lt;/strong&gt;)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.120 TiB (&lt;strong&gt;600 %&lt;/strong&gt;)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext3&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.075 TiB  (94 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.147 TiB (130 %)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext4&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.090 TiB  (64 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.088 TiB (100 %)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;JFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;44.4 TiB&lt;/strong&gt; (110 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;339 TiB&lt;/strong&gt; (120 %)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ReiserFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.069 TiB  (82 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.072 TiB  (75 %)&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;tmpfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;XFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;786 TiB&lt;/strong&gt; (98 %)&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;0.035 TiB (220 %)&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;figcaption class=&quot;text-center&quot;&gt;Table 4: Monthly data writes for a
4 parallel fuzzers on different file systems and the percentage to an
extrapolated number based on one afl-fuzz instance.&lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;The worrying part here is that two quite actively and widely used file
systems, btrfs and XFS, suffer greatly from the writes with the
standard input data generation pattern. As this is the faster mode of
fuzzing from executions/second perspective, it’s quite nasty if you
put the output directory for fuzzer findings on such file system.&lt;/p&gt;

&lt;h3 id=&quot;theoretical-limits&quot;&gt;Theoretical limits&lt;/h3&gt;

&lt;p&gt;I also wanted to see what would be the theoretical limits for the type
of file system access pattern that &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; does. This is quite a
synthetic benchmark, as it does not involve any context switches
between processes,
&lt;a href=&quot;http://man7.org/linux/man-pages/man7/signal.7.html&quot;&gt;signal&lt;/a&gt; delivery,
&lt;a href=&quot;http://man7.org/linux/man-pages/man7/shm_overview.7.html&quot;&gt;shared memory&lt;/a&gt;
manipulation,
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/dup.2.html&quot;&gt;file descriptor duplication&lt;/a&gt;,
and other types of data processing that &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; does.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;theoretical-fs-benchmark&quot;&gt;

    &lt;table style=&quot;margin: 0 auto;&quot;&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th style=&quot;text-align: left&quot;&gt;sequences/second&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-stdin&quot;&gt;stdin&lt;/a&gt;&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;&lt;a href=&quot;#data-passing-file&quot;&gt;file&lt;/a&gt;&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;btrfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;87.5 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;40.7 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext2&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;446.1 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;66.5 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext3&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;305.4 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;60.3 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ext4&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;211.5 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;56.4 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;JFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;737.7 k&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;59.5 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;ReiserFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;594.1 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;40.4 k&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;tmpfs&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;682.5 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;138.0 k&lt;/strong&gt;&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;XFS&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;101.9 k&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;48.5 k&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;figcaption class=&quot;text-center&quot;&gt;Table 5: Theoretical file system
performance numbers with `afl-fuzz` like access pattern.&lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;The difference between file systems in
&lt;a href=&quot;#theoretical-fs-benchmark&quot;&gt;table 5&lt;/a&gt; is many times larger for
standard input based data generation than for &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt;
(&lt;a href=&quot;#execs-per-second&quot;&gt;table 1&lt;/a&gt;). When opening and closing files, the
overhead is bigger and the difference between different file systems
is also smaller.&lt;/p&gt;

&lt;p&gt;If you also compare the overhead of pure file system accesses, it is
higher than the overhead of
&lt;a href=&quot;#executionssecond&quot;&gt;libFuzzer’s 735 k executions/second&lt;/a&gt; basically
for all cases. On top of this there is the overhead of everything else
that happens inside &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt; program.&lt;/p&gt;

&lt;h2 id=&quot;end-notes&quot;&gt;End notes&lt;/h2&gt;

&lt;p&gt;You should use tmpfs that fully resides in memory for your fuzzing
data generation with &lt;code class=&quot;highlighter-rouge&quot;&gt;afl-fuzz&lt;/code&gt;. Usually this is available on
&lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/shm/&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;/run/shm/&lt;/code&gt; globally and on systemd based systems also
available under &lt;code class=&quot;highlighter-rouge&quot;&gt;/run/user/$UID/&lt;/code&gt;. It’s faster and less straining to
the hardware than trusting that the Linux block layer does not too
often write to the physical device. Especially if you happen to use
btrfs or XFS file systems.&lt;/p&gt;

&lt;p&gt;In the end, this is mostly Linux specific information and for example
OS X based systems need
&lt;a href=&quot;https://gist.github.com/koshigoe/822455&quot;&gt;specific tricks&lt;/a&gt; to use
memory based file systems. Same with FreeBSD where tmpfs based file
system is not mounted by default.&lt;/p&gt;
</description>
        <pubDate>Sun, 10 Jun 2018 18:00:10 +0300</pubDate>
        <link>https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/</link>
        <guid isPermaLink="true">https://barro.github.io/2018/06/afl-fuzz-on-different-file-systems/</guid>
        
        <category>fuzzing,</category>
        
        <category>afl,</category>
        
        <category>american</category>
        
        <category>fuzzy</category>
        
        <category>lop,</category>
        
        <category>afl-fuzz,</category>
        
        <category>libfuzzer</category>
        
        
      </item>
    
      <item>
        <title>Avatars, identicons, and hash visualization</title>
        <description>&lt;p&gt;Oftentimes we have a situation where we have a situation where we want
an easy way to distinguish people of which we only know the name or a
nickname. Probably the most common examples of these are
distinguishing different people from each other on various discussion
platforms, like chat rooms, forums, wikis, or issue tracking
systems. These very often provide the possibility to use handles,
often real names or nicknames, and profile images as an
alternative. But as very often people don’t provide any profile image,
many services use a programmatically generated images to give some
uniqueness to default profile images.&lt;/p&gt;

&lt;p&gt;In this article I’ll take a look at a few approaches to
generate default profile images and other object identifiers. I also
take a look at the process of creating some specific hash
visualization algorithms that you may have encountered on the web. The
general name for such programmatically generated images is hash
visualization.&lt;/p&gt;

&lt;h2 id=&quot;use-cases-and-background&quot;&gt;Use cases and background&lt;/h2&gt;

&lt;p&gt;A starting point to visualize arbitrary data is often
&lt;a href=&quot;https://en.wikipedia.org/wiki/Hash_function&quot;&gt;hashing&lt;/a&gt;. Hashing in
this context is to make a fixed length representation of an arbitrary
value. This fixed length representation is just a big number that can
be then used as a starting point for distinguishing different things
from each other.&lt;/p&gt;

&lt;p&gt;Hash visualization aims to generate a visual identifier for easy
differentiation of different objects that takes an advantage of
&lt;a href=&quot;https://en.wikipedia.org/wiki/Pre-attentive_processing&quot;&gt;preattentive processing&lt;/a&gt;
of human visual system. There are various categories that human visual
system uses to do preattentive processing, like &lt;span style=&quot;border-bottom: 1px dashed;&quot; title=&quot;Ware, Colin. Information visualization: perception for design. Elsevier, 2012.&quot;&gt;form, color, motion, and spatial position&lt;/span&gt;. Different
hash visualization schemes knowingly or unknowingly take advantage of
these.&lt;/p&gt;

&lt;p&gt;Simple methods use specific colors as a visualization method, but at
the same time limit the values that can be preattentively
distinguished to maybe around 10-20 (around 4 bits of
information) per colored area. Using additional graphical elements
provides a possibility to create more distinct unique elements that
are easy to separate from each other. &lt;span title=&quot;Kilian, Timo. Visualization of Hash-functions. June 2012.&quot;&gt;&lt;a href=&quot;https://www.secuso.informatik.tu-darmstadt.de/fileadmin/user_upload/Group_SECUSO/Theses/BA/Visualization_of_Hash-functions.pdf&quot;&gt;One thesis&lt;/a&gt;&lt;/span&gt;
tries hash visualization with 60 bits of data with varying success. So
the amount of visualized data that can be easily distinguished from
each other by graphical means is somewhere between 4 and 60 bits.&lt;/p&gt;

&lt;h2 id=&quot;avatars&quot;&gt;Avatars&lt;/h2&gt;

&lt;p&gt;Perhaps the most common way to distinguish different users of an
Internet based service is to use an user name and an avatar
image. Avatars often go with custom avatar images that users
themselves upload to the service. In case the service itself does not
want to host avatars, it can link to services like &lt;a href=&quot;https://gravatar.com&quot;&gt;Gravatar&lt;/a&gt; that provides avatar hosting
as a service. This way user can use the same avatar in multiple
services just by providing their email address.&lt;/p&gt;

&lt;p&gt;But what about a situation where the user has not uploaded or does not
want to upload an avatar image to the service? There usually is a
placeholder image that indicates that the user has not set their
custom avatar.&lt;/p&gt;

&lt;p&gt;There seem to be three major approaches to generate this placeholder
image:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A generic dummy placeholder image. These often come in a shape of a
generic human profile.&lt;/li&gt;
  &lt;li&gt;An image from predefined collection of images. These are usually
related to a theme that the site wants to present.&lt;/li&gt;
  &lt;li&gt;A partially or fully algorithmically generated image. These usually
make it possible to get the most variety for placeholders with the
least amount of work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Algorithmically generated images vary greatly and usually come in
three varieties:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Simple images that mainly use a color and a letter to distinguish
users.&lt;/li&gt;
  &lt;li&gt;Images that consist of a set of a predefined parts and color
variations.&lt;/li&gt;
  &lt;li&gt;More complex shapes usually created fully algorithmically.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I have taken a closer look at different algorithmic avatar creation
methods in form of &lt;a href=&quot;#wordpress-identicon&quot;&gt;WordPress
identicon&lt;/a&gt;, &lt;a href=&quot;#github-identicon&quot;&gt;GitHub identicon&lt;/a&gt;, and
&lt;a href=&quot;#monsterid&quot;&gt;MonsterID&lt;/a&gt;. These provide an overview on how
algorithmic avatar generation can work. There is also a chapter of
using &lt;a href=&quot;#character-on-a-colored-background&quot;&gt;a character on a
colored background&lt;/a&gt; to give an example of a simple algorithmic
method for default avatar generation.&lt;/p&gt;

&lt;p&gt;I want to focus here on visualizing the few methods that I have
encountered rather than having a all-encompassing overview of avatar
generation. For that, there is
&lt;a href=&quot;https://en.wikipedia.org/wiki/Avatar_(computing)&quot;&gt;Avatar article on Wikipedia&lt;/a&gt;
that gives a better textual overview of these and many more methods
than I could give.&lt;/p&gt;

&lt;h3 id=&quot;character-on-a-colored-background&quot;&gt;Character on a colored background&lt;/h3&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;colored-background-examples&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-2880.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-720.webp 720w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-960.webp 960w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-1152.webp 1152w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-1440.webp 1440w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-1920.webp 1920w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-2880.webp 2880w&quot; sizes=&quot;720px, 960px, 1152px, 1440px, 1920px, 2880px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-720.png 720w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-960.png 960w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-1152.png 1152w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-1440.png 1440w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-1920.png 1920w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-2880.png 2880w&quot; sizes=&quot;720px, 960px, 1152px, 1440px, 1920px, 2880px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/colored-background-examples-720.png Avatar examples having a colored background with the first letter of an user name.&amp;quot;&quot; alt=&quot;Avatar examples having a colored background with the first letter of an user name.&quot; width=&quot;720&quot; height=&quot;120&quot; class=&quot;figure-image&quot; title=&quot;Avatar examples having a colored background with the first letter of an user name.&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 1: Avatar examples having a colored background with the first letter of an user name.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Services like &lt;a href=&quot;https://hangouts.google.com/&quot;&gt;Google Hangouts&lt;/a&gt;,
&lt;a href=&quot;https://telegram.org/&quot;&gt;Telegram&lt;/a&gt; and &lt;a href=&quot;https://signal.org/&quot;&gt;Signal&lt;/a&gt;, and software with people
collaboration functionality like
&lt;a href=&quot;https://www.atlassian.com/software/jira&quot;&gt;Jira&lt;/a&gt; generate a default
avatar for an user by using the first letter of user’s name with a
colored background. This is simple method where you need to select a
font, a shape that you want to use to surround the letter, and size of
the avatar. Some example avatars generated by this method are visible
from &lt;a href=&quot;#colored-background-examples&quot;&gt;figure 1&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;wordpress-identicon&quot;&gt;WordPress identicon&lt;/h3&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;identicon-examples&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-2880.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-720.webp 720w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-960.webp 960w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-1152.webp 1152w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-1440.webp 1440w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-1920.webp 1920w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-2880.webp 2880w&quot; sizes=&quot;720px, 960px, 1152px, 1440px, 1920px, 2880px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-720.png 720w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-960.png 960w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-1152.png 1152w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-1440.png 1440w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-1920.png 1920w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-2880.png 2880w&quot; sizes=&quot;720px, 960px, 1152px, 1440px, 1920px, 2880px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-examples-720.png Example WordPress identicons.&amp;quot;&quot; alt=&quot;Example WordPress identicons.&quot; width=&quot;720&quot; height=&quot;120&quot; class=&quot;figure-image&quot; title=&quot;Example WordPress identicons.&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 2: Example WordPress identicons.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://wordpress.org/plugins/wp-identicon/&quot;&gt;WordPress identicon&lt;/a&gt; has
been a well known algorithmically generated avatar for quite long time
on web forums. It has been used to distinguish between users based on
their &lt;a href=&quot;https://en.wikipedia.org/wiki/IP_address&quot;&gt;IP addresses&lt;/a&gt; and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Email_address&quot;&gt;email addresses&lt;/a&gt;. Example
WordPress identicons can be seen from &lt;a href=&quot;#identicon-examples&quot;&gt;figure 2&lt;/a&gt;
where you should be able to notice that there is some symmetry in
these images.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;identicon-parts&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-2900.png&quot;&gt;
&lt;picture&gt;

&lt;!--
Quantized webp is bigger than quantized PNG.
&lt;source type=&quot;image/webp&quot;
    srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-736.webp 736w,
    https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-920.webp 920w,
    https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-1104.webp 1104w,
    https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-1472.webp 1472w,
    https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-2208.webp 2208w,
    https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-2900.webp 2900w&quot;
    sizes=&quot;736px, 920px, 1104px, 1472px, 2208px, 2900px&quot; /&gt;
--&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-736.png 736w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-920.png 920w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-1104.png 1104w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-1472.png 1472w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-2208.png 2208w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-2900.png 2900w&quot; sizes=&quot;736px, 920px, 1104px, 1472px, 2208px, 2900px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-parts-736.png&quot; alt=&quot;44 parts from which a WordPress identicon is generated.&quot; title=&quot;44 parts from which a WordPress identicon is generated.&quot; width=&quot;736&quot; height=&quot;267&quot; class=&quot;figure-image webfeedsFeaturedVisual&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 3: 44 parts from which a WordPress identicon is generated.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Looking at the code how these avatars are generated reveals 44
patterns, shown in &lt;a href=&quot;#identicon-parts&quot;&gt;figure 3&lt;/a&gt; that the generators
uses to generate these images. They are symmetrically placed around
the center and rotated 90 degrees when they reach the next
quadrant. This process is illustrated in
&lt;a href=&quot;#identicon-animated&quot;&gt;figure 4&lt;/a&gt; that shows how these parts are
placed and rotated around the center. In case the requested identicon
has an even number of parts, these parts will get duplicated. So 4x4
WordPress identicon will only have 3 distinct parts in it. This is the
same number as for 3x3 WordPress identicon.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;identicon-animated&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-480.gif&quot;&gt;
&lt;picture&gt;

&lt;!--[if IE 9]&gt;&lt;video style=&quot;display: none;&quot;&gt;&lt;![endif]--&gt;
&lt;source type=&quot;image/apng&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-120.apng 120w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-150.apng 150w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-180.apng 180w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-240.apng 240w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-360.apng 360w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-480.apng 480w&quot; sizes=&quot;120px, 150px, 180px, 240px, 360px, 480px&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-120.webp 120w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-150.webp 150w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-180.webp 180w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-240.webp 240w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-360.webp 360w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-480.webp 480w&quot; sizes=&quot;120px, 150px, 180px, 240px, 360px, 480px&quot; /&gt;
&lt;source type=&quot;image/gif&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-120.gif 120w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-150.gif 150w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-180.gif 180w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-240.gif 240w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-360.gif 360w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-480.gif 480w&quot; sizes=&quot;120px, 150px, 180px, 240px, 360px, 480px&quot; /&gt;
&lt;!--[if IE 9]&gt;&lt;/video&gt;&lt;![endif]--&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/identicon-animated-120.gif 5x5 WordPress identicon generation animated.&quot; alt=&quot;5x5 WordPress identicon generation animated.&quot; width=&quot;120&quot; height=&quot;120&quot; title=&quot;5x5 WordPress identicon generation animated.&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 4: 5x5 WordPress identicon generation animated.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;h3 id=&quot;github-identicon&quot;&gt;GitHub identicon&lt;/h3&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;github-identicon-examples&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-2880.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-720.webp 720w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-1440.webp 1440w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-2160.webp 2160w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-2880.webp 2880w&quot; sizes=&quot;720px, 1440px, 2160px, 2880px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-720.png 720w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-1440.png 1440w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-2160.png 2160w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-2880.png 2880w&quot; sizes=&quot;720px, 1440px, 2160px, 2880px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-examples-720.png Example GitHub style identicons.&amp;quot;&quot; alt=&quot;Example GitHub style identicons.&quot; width=&quot;720&quot; height=&quot;120&quot; class=&quot;figure-image&quot; title=&quot;Example GitHub style identicons.&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 5: Example GitHub style identicons.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/&quot;&gt;GitHub&lt;/a&gt; is a great collaborative code repository
sharing service where users can have identifying images. If user,
however, does not have any profile image,
&lt;a href=&quot;https://github.com/blog/1586-identicons&quot;&gt;GitHub will generate&lt;/a&gt; an
identicon that forms a 5x5 pixel
sprite. &lt;a href=&quot;#github-identicon-examples&quot;&gt;Figure 5&lt;/a&gt; examples how such
identicons can look like. The exact algorithm that GitHub uses to
generate these identicons is not public, so these example images just
imitating the style of GitHub identicons.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;github-identicon-animated&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-480.gif&quot;&gt;
&lt;picture&gt;

&lt;!--[if IE 9]&gt;&lt;video style=&quot;display: none;&quot;&gt;&lt;![endif]--&gt;
&lt;source type=&quot;image/apng&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-120.apng 120w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-240.apng 240w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-360.apng 360w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-480.apng 480w&quot; sizes=&quot;120px, 240px, 360px, 480px&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-120.webp 120w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-240.webp 240w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-360.webp 360w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-480.webp 480w&quot; sizes=&quot;120px, 240px, 360px, 480px&quot; /&gt;
&lt;source type=&quot;image/gif&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-120.gif 120w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-240.gif 240w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-360.gif 360w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-480.gif 480w&quot; sizes=&quot;120px, 240px, 360px, 480px&quot; /&gt;
&lt;!--[if IE 9]&gt;&lt;/video&gt;&lt;![endif]--&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/github-identicon-animated-120.gif GitHub style identicon creation process animated. Visible pixels are horizontally mirrored.&quot; alt=&quot;GitHub style identicon creation process animated. Visible pixels are horizontally mirrored.&quot; width=&quot;120&quot; height=&quot;120&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 6: GitHub style identicon creation process animated. Visible
pixels are horizontally mirrored.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#github-identicon-animated&quot;&gt;Figure 6&lt;/a&gt; shows the process of creating
such identicon. Basically the given data is hashed and from that hash
a specific color is selected as the value for a visible pixel. Then
other part of the hash (15 bits) is used to form an image that is
horizontally mirrored. I have used a modified
&lt;a href=&quot;https://github.com/chrisbranson/ruby_identicon&quot;&gt;ruby_identicon&lt;/a&gt; to
generate these images and animations. This library also enables the
generation of other sizes than 5x5 sprites.&lt;/p&gt;

&lt;h3 id=&quot;monsterid&quot;&gt;MonsterID&lt;/h3&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;monsterid-examples&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-examples-720.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-examples-720.webp 720w&quot; sizes=&quot;720px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-examples-720.png 720w&quot; sizes=&quot;720px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-examples-720.png Example artistic MonsterIDs.&quot; alt=&quot;Example artistic MosterIDs.&quot; width=&quot;720&quot; height=&quot;120&quot; class=&quot;figure-image&quot; title=&quot;Example artistic MosterIDs.&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 7: Example artistic MonsterIDs.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://wordpress.org/plugins/wp-monsterid/&quot;&gt;WordPress MonsterID&lt;/a&gt; is
a hash visualization method where hashes are converted to various
types of monsters. It’s a one type of hash visualization method where
lifelike creature is created from predefined body parts. WordPress
MonsterID actually offers two types of monsters, the default ones and
artistic ones. Here I’m showing some example artistic monsters in
&lt;a href=&quot;#monsterid-examples&quot;&gt;figure 7&lt;/a&gt; just because they look better than
the default ones.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;monsterid-forming&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-forming-720.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-forming-720.webp 720w&quot; sizes=&quot;720px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-forming-720.png 720w&quot; sizes=&quot;720px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-736.png Creating an artistic MonsterID image by selecting and colorizing an appropriate part from each category.&quot; alt=&quot;Creating an artistic MonsterID image by selecting and colorizing an appropriate part from each category.&quot; width=&quot;720&quot; height=&quot;360&quot; class=&quot;figure-image&quot; title=&quot;Creating an artistic MonsterID image by selecting and colorizing an appropriate part from each category.&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 8: Creating an artistic MonsterID image by selecting and
colorizing an appropriate part from each category.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;#monsterid-forming&quot;&gt;Figure 8&lt;/a&gt; shows the MonsterID creation
process. First there is a lightly colored background on top of which
we start forming the monster. We select a body part in order of legs,
hair, arms, body, eyes, and mouth. These parts are show in
&lt;a href=&quot;#monsterid-parts&quot;&gt;figure 9&lt;/a&gt;. Then assign a color to the selected
part, unless it’s one of the special cases. Then just overlay it on
top of the image formed from previous parts. There are special cases
that what parts should have a predefined color or be left uncolored,
but that does not change the general monster creation process.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;monsterid-parts&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-2400.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-736.webp 736w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-920.webp 920w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-1104.webp 1104w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-1472.webp 1472w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-2208.webp 2400w&quot; sizes=&quot;736px, 920px, 1104px, 1472px, 2400px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-736.png 736w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-920.png 920w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-1104.png 1104w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-1472.png 1472w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-2900.png 2400w&quot; sizes=&quot;736px, 920px, 1104px, 1472px, 2400px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/monsterid-parts-736.png Parts from which a MonsterID is created divided into categories (hair, eyes, mouth, arms, body, and legs).&quot; alt=&quot;Parts from which a MonsterID is created divided into categories (hair, eyes, mouth, arms, body, and legs).&quot; width=&quot;736&quot; height=&quot;221&quot; class=&quot;figure-image&quot; title=&quot;Parts from which a MonsterID is created divided into categories (hair, eyes, mouth, arms, body, and legs).&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 9: Parts from which a MonsterID is created divided into
categories (hair, eyes, mouth, arms, body, and legs).
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;In addition to WordPress MonsterID plugin,
&lt;a href=&quot;https://en.gravatar.com/site/implement/images/&quot;&gt;Gravatar&lt;/a&gt; also
supports old style MonsterIDs. These unfortunately do not as good as
the artistic monsters in the WordPress MonsterID plugin and there is
no option to select an alternative form for these avatars.&lt;/p&gt;

&lt;h2 id=&quot;openssh-visual-host-key&quot;&gt;OpenSSH visual host key&lt;/h2&gt;

&lt;p&gt;Hash visualization has also its place in
cryptography. &lt;a href=&quot;http://www.openssh.com/&quot;&gt;OpenSSH&lt;/a&gt; client has an option
to display so called visual host keys.&lt;/p&gt;

&lt;p&gt;When a SSH client connects to a remote server that it has not ever
seen before, it needs to accept the public key of this server so that
it can communicate with it securely. To prevent
&lt;a href=&quot;https://en.wikipedia.org/wiki/Man-in-the-middle_attack&quot;&gt;man-in-the-middle attacks&lt;/a&gt;,
user initiating the connection is supposed to verify that the host key
indeed matches. An example message about host key verification request
is shown in &lt;a href=&quot;#ssh-hostkey-verification&quot;&gt;figure 10&lt;/a&gt;. The idea is, that
either you have seen the this key beforehand or you have some other
means to get this key fingerprint and verify that it indeed belongs to
the server you are trying to connect to. How this works in practice or
not, is a completely different discussion.&lt;/p&gt;

&lt;div&gt;
&lt;figure style=&quot;max-width: 100%; overflow: auto;&quot; class=&quot;inline-figure&quot; id=&quot;ssh-hostkey-verification&quot;&gt;

&lt;pre style=&quot;max-width: 100%; overflow: auto;&quot;&gt;$ ssh example.com
The authenticity of host &#39;example.com (127.1.2.3)&#39; can&#39;t be established.
RSA key fingerprint is SHA256:Cy86563vH6bGaY/jcsIsikpYOHvxZe/MVLJTcEQA3IU.
Are you sure you want to continue connecting (yes/no)?&lt;/pre&gt;

&lt;figcaption class=&quot;text-center&quot;&gt;
Figure 10: The default SSH server key verification request on the first connection.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;As you can see, the key fingerprint is not easy to remember and also
the comparison of two fingerprints can be quite hairy. When you enable
visual host key support, as show in
&lt;a href=&quot;#ssh-first-connection-visualhostkey&quot;&gt;figure 11&lt;/a&gt;, the idea is that
you can quickly glance to figure out if the key of a server is
different than expected. This should not be treated as a method to see
if two keys are equal, as different keys can produce the same image.&lt;/p&gt;

&lt;div&gt;
&lt;figure style=&quot;max-width: 100%; overflow: auto;&quot; class=&quot;inline-figure&quot; id=&quot;ssh-first-connection-visualhostkey&quot;&gt;

&lt;pre style=&quot;max-width: 100%; overflow: auto;&quot;&gt;$ ssh -o VisualHostKey=true example.com
The authenticity of host &#39;example.com (127.1.2.3)&#39; can&#39;t be established.
RSA key fingerprint is SHA256:Cy86563vH6bGaY/jcsIsikpYOHvxZe/MVLJTcEQA3IU.
+---[RSA 8192]----+
|     ..o.=+      |
|      . E.       |
|        . .      |
| .       o       |
|o o   + S o      |
|.+ o o + *       |
|o.. .o..B.o      |
|.o  o.*BB= .     |
|+ ...=o@@+o      |
+----[SHA-256]----+
Are you sure you want to continue connecting (yes/no)?&lt;/pre&gt;

&lt;figcaption class=&quot;text-center&quot;&gt;
Figure 11: Visual host key enabled SSH server key verification request
on the first connection.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;The algorithm to generate these visual host keys is visualized at
&lt;a href=&quot;#openssh-visualhostkey&quot;&gt;figure 12&lt;/a&gt;. It’s also described in detail in
an article that analyzes the algorithmic security of this visual host
key generation:
&lt;a href=&quot;http://www.dirk-loss.de/sshvis/drunken_bishop.pdf&quot;&gt;The drunken bishop: An analysis of the OpenSSH fingerprint visualization algorithm&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;OpenSSH’s visual host key is formed in such way that the formation
starts from the center of the image. Then 2 bits of the host key
fingerprint are selected and the location is moved in a diagonal
direction. The visual element on the plane where this movement happens
is changed based on how many times a certain location is visited. This
can be better seen from the animation where each visual host key
generation step is visualized as its own frame and where the bits
related to the movement are highlighted.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;openssh-visualhostkey&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-2048.gif&quot;&gt;
&lt;picture&gt;

&lt;!--[if IE 9]&gt;&lt;video style=&quot;display: none;&quot;&gt;&lt;![endif]--&gt;
&lt;source type=&quot;image/apng&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-578.apng 578w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-964.apng 964w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-1412.apng 1412w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-2048.apng 2048w&quot; sizes=&quot;578px, 964px, 1412px, 2048px&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-578.webp 578w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-964.webp 964w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-1412.webp 1412w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-2048.webp 2048w&quot; sizes=&quot;578px, 964px, 1412px, 2048px&quot; /&gt;
&lt;source type=&quot;image/gif&quot; srcset=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-578.gif 578w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-964.gif 964w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-1412.gif 1412w,     https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-2048.gif 2048w&quot; sizes=&quot;578px, 964px, 1412px, 2048px&quot; /&gt;
&lt;!--[if IE 9]&gt;&lt;/video&gt;&lt;![endif]--&gt;

&lt;img src=&quot;https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/openssh-visualkey-578.gif OpenSSH visual host key generation animated.&amp;quot;&quot; alt=&quot;OpenSSH visual host key generation animated.&quot; width=&quot;578&quot; height=&quot;287&quot; class=&quot;figure-image&quot; title=&quot;OpenSSH visual host key generation animated&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
Figure 12: OpenSSH visual host key generation animated.
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;The exact details how the key is generated can be seen from
&lt;a href=&quot;https://github.com/openssh/openssh-portable/blob/77199d6ec8986d470487e66f8ea8f4cf43d2e20c/sshkey.c#L1044&quot;&gt;OpenSSH’s source code&lt;/a&gt;.
This source code also refers to a paper called &lt;span title=&quot;Perring, Adrian. Song, Dawn. Hash Visualization: a New Technique to improve Real-World Security.&quot;&gt;
&lt;a href=&quot;http://www.netsec.ethz.ch/publications/papers/validation.pdf&quot;&gt;Hash Visualization: a New Technique to improve Real-World Security&lt;/a&gt;&lt;/span&gt;.
But the fact that OpenSSH is usually limited to terminals with text
interface makes it quite hard to use the more advanced &lt;em&gt;Random Art&lt;/em&gt;
methods described in the paper. But the idea for host key verification
by using images has at least taken one form in the OpenSSH world.&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;I presented here some methods that I have encountered over the years
on various sites and programs. I can not possibly cover all of them,
as there likely are as many algorithms to create avatars as there
are people inventing them. The biggest question with any of these
algorithms is that how many bits they should try to visualize and what
types of graphical elements they can use in the visualization without
just creating indistinguishable clutter.&lt;/p&gt;
</description>
        <pubDate>Sun, 04 Feb 2018 18:00:09 +0200</pubDate>
        <link>https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/</link>
        <guid isPermaLink="true">https://barro.github.io/2018/02/avatars-identicons-and-hash-visualization/</guid>
        
        <category>identicon,</category>
        
        <category>avatar,</category>
        
        <category>visualization</category>
        
        
      </item>
    
      <item>
        <title>Taking a look at python-afl</title>
        <description>&lt;p&gt;I have been using
&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/&quot;&gt;american fuzzy lop&lt;/a&gt; to
&lt;a href=&quot;https://en.wikipedia.org/wiki/Fuzzing&quot;&gt;fuzz&lt;/a&gt; various C and C++
programs and libraries. It is a wonderfully fast fuzzer that is
generally easy to get started with and it usually finds new bugs in
programs that have not been fuzzed previously. Support for american
fuzzy lop instrumentation has also been added for other languages and
I decided to try out how it works with
&lt;a href=&quot;https://www.python.org/&quot;&gt;Python&lt;/a&gt;. More specifically with the
reference CPython implementation of it.&lt;/p&gt;

&lt;h2 id=&quot;fuzzing-python-programs-with-american-fuzzy-lop&quot;&gt;Fuzzing Python programs with american fuzzy lop&lt;/h2&gt;

&lt;p&gt;American fuzzy lop generally works by running a program that is
compiled with american fuzzy lop instrumentation built in. It executes
the program with &lt;em&gt;afl-fuzz&lt;/em&gt; command that modifies the input data that is
fed to the program, monitors how the program behaves, and registers
everything that causes abnormal program behavior. This works well for
natively compiled programs, but causes various issues with interpreted
programs.&lt;/p&gt;

&lt;p&gt;Python is by default an interpreted language, so to execute Python
programs, you need to start a Python interpreter before executing your
code. This means that if you would instrument the Python interpreter
with american fuzzy lop instrumentation and run the
interpreter with &lt;em&gt;afl-fuzz&lt;/em&gt;, it would mostly fuzz the inner workings of
the interpreter, not the actual Python program.&lt;/p&gt;

&lt;p&gt;Fortunately there is &lt;a href=&quot;https://github.com/jwilk/python-afl&quot;&gt;python-afl&lt;/a&gt;
module that enables american fuzzy lop instrumentation for just the
Python code instead of instrumenting the Python interpreter. In native
programs american fuzzy lop compiler wrapper (&lt;em&gt;afl-gcc&lt;/em&gt;, &lt;em&gt;afl-clang&lt;/em&gt;,
&lt;em&gt;afl-clang-fast&lt;/em&gt;) adds the necessary instrumentation and the
connection to &lt;em&gt;afl-fuzz&lt;/em&gt;. Python-afl is, however, designed in such way
that it doesn’t try to wrap the whole program, but requires you to
create a wrapper module that initializes fuzzing.&lt;/p&gt;

&lt;p&gt;The most simple way to wrap a Python program with python-afl is to
initialize python-afl and then run the program (assuming that &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt;
function exists):&lt;/p&gt;

&lt;div id=&quot;instrumentation-pre-init&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;fuzzable_module&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This script, saved to &lt;code class=&quot;highlighter-rouge&quot;&gt;fuzz-wrapper.py&lt;/code&gt;, can be then run with
&lt;em&gt;py-afl-fuzz&lt;/em&gt; command that wraps &lt;em&gt;afl-fuzz&lt;/em&gt; for Python programs:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;py-afl-fuzz &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; 400 &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; initial-inputs/ &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; fuzzing-results/ &lt;span class=&quot;nt&quot;&gt;--&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    python fuzz-wrapper.py @@
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;More details about these command line switches can be found from
&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/README.txt&quot;&gt;AFL readme file&lt;/a&gt;. This
then brings out the famous
&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/status_screen.txt&quot;&gt;american fuzzy lop status screen&lt;/a&gt;,
but now for Python programs:&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;figure-afl-status&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen.html&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-736.webp 736w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-920.webp 920w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-1104.webp 1104w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-1472.webp 1472w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-2208.webp 2208w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-2900.webp 2900w&quot; sizes=&quot;736px, 920px, 1104px, 1472px, 2208px, 2900px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-736.png 736w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-920.png 920w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-1104.png 1104w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-1472.png 1472w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-2208.png 2208w,     https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-2900.png 2900w&quot; sizes=&quot;736px, 920px, 1104px, 1472px, 2208px, 2900px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2018/01/taking-a-look-at-python-afl/afl-status-screen-736.png&quot; alt=&quot;afl-fuzz status screen with python-afl. Yes, I use white background.&quot; title=&quot;afl-fuzz status screen with python-afl. Yes, I use white background.&quot; width=&quot;736&quot; height=&quot;441&quot; class=&quot;figure-image&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;

&lt;figcaption&gt;
      &lt;p&gt;Figure 1: &lt;em&gt;afl-fuzz&lt;/em&gt; status screen with python-afl. Yes, I use white background.&lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Next sections will explain in more details how to make fuzzing these
programs more efficient and what pitfalls there could be in Python
programs from fuzzing efficiency point of view.&lt;/p&gt;

&lt;h3 id=&quot;afl-fuzz-modes-and-their-python-afl-equivalents&quot;&gt;Afl-fuzz modes and their python-afl equivalents&lt;/h3&gt;

&lt;p&gt;Generally &lt;em&gt;afl-fuzz&lt;/em&gt; provides 4 fuzzing modes that differ in how the
program execution between different fuzzing inputs behaves:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;span id=&quot;afl-dumb-mode&quot;&gt;Dumb mode that just executes
the program by doing
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/fork.2.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;fork()&lt;/code&gt;&lt;/a&gt; and
&lt;a href=&quot;http://man7.org/linux/man-pages/man3/exec.3.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;execv()&lt;/code&gt;&lt;/a&gt;. This is
the slowest mode that does not rely on any fancy tricks to speed up
program execution and also does not provide any insights how the
program behaves with different inputs.
&lt;/span&gt;&lt;/li&gt;
  &lt;li&gt;Basic
&lt;a href=&quot;http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html&quot;&gt;fork server mode&lt;/a&gt;
where the fuzzed binary does all the initialization steps that
happen before calling the
&lt;a href=&quot;http://en.cppreference.com/w/cpp/language/main_function&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; function&lt;/a&gt;
and then program is repeatedly forked from that point on. This also
includes instrumentation that is compiled in to the program so there
already is some insight on what is happening inside the program when
a specific input is processed. There exists QEMU mode for &lt;em&gt;afl-fuzz&lt;/em&gt;
that technically enables fork server mode for uninstrumented
binaries, but with some performance penalty.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mirrorer/afl/tree/master/llvm_mode&quot;&gt;Deferred instrumentation&lt;/a&gt;
that works in similar fashion as the basic fork server mode. Instead
forking just before calling &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; function, this enables to move
the fork point further down the line and enables heavy program
initialization steps to be avoided if they can be executed
independently of the input.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://lcamtuf.blogspot.fi/2015/06/new-in-afl-persistent-mode.html&quot;&gt;Persistent mode&lt;/a&gt;
where the fuzzable part of the program is repeatedly executed
without resetting the program memory every time the program is
called. This only works in practice if the program does not have a
modifiable global state that can not be reset to the previous state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Afl-fuzz&lt;/em&gt; generates new inputs and analyzes the program execution
results roughly at the same speed regardless of the mode. So these
modes are in the order of efficiency in a sense that how much overhead
there is for fuzzing one input. They are also in the order of
complexity on how easy they are to integrate into an existing program
that has not been made to be fuzzed. Especially as the fastest modes
require &lt;a href=&quot;http://clang.llvm.org/&quot;&gt;clang&lt;/a&gt; to be available as a compiler
and the fuzzable program needs to be able to be compiled and linked
with it.&lt;/p&gt;

&lt;p&gt;Python-afl, fortunately, provides equivalent modes without having to
use special tools. These are also very fast to try out, as you don’t
need to compile Python programs from scratch.&lt;/p&gt;

&lt;p&gt;The dumb mode would be just equivalent of running Python interpreter
directly with &lt;em&gt;afl-fuzz&lt;/em&gt; without any instrumentation, so we will skip
over it. The more interesting part is to use the deferred
instrumentation. The code in the introductory section called
&lt;code class=&quot;highlighter-rouge&quot;&gt;afl.init()&lt;/code&gt; before the fuzzable module was imported. This is the
most safe approach, as the fuzz target might do something with the
input at import time. But more realistically,
Python programs generally only call &lt;code class=&quot;highlighter-rouge&quot;&gt;import&lt;/code&gt; statements, possibly
conditionally, during the start-up and don’t handle any user provided
data yet. So in this case, we can do imports first and move the
&lt;code class=&quot;highlighter-rouge&quot;&gt;afl.init()&lt;/code&gt; function just before where the actual work happens:&lt;/p&gt;

&lt;div id=&quot;instrumentation-deferred&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can gain some speed-ups with this by calling &lt;code class=&quot;highlighter-rouge&quot;&gt;os._exit()&lt;/code&gt; function
instead of letting Python to exit in the usual fashion where all the
destructors and other functions that are called at exit:&lt;/p&gt;

&lt;div id=&quot;instrumentation-os-exit&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Previous examples assume that the input file generated by the fuzzer
comes as the first parameter on the command line. This is quite a good
assumption, as many data processing modules for Python include a
command line interface where they read and process files given on the
command line. But if we can directly call the data processing
function, we can instead use the standard input to feed the data:&lt;/p&gt;

&lt;div id=&quot;instrumentation-os-exit-stdin&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With Python 3 comes additional complexity. Python 3 processes the
standard input using the encoding specified in the environment. Often
in Unix environments it is UTF-8. As &lt;em&gt;afl-fuzz&lt;/em&gt; mostly does bit
manipulation, input is going to end up with broken UTF-8 data and
results in exception when reading from the standard input file
object. To work around this, you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;sys.stdin.buffer&lt;/code&gt; instead of
&lt;code class=&quot;highlighter-rouge&quot;&gt;sys.stdin&lt;/code&gt; in Python 3 based programs. Or create a shim that always
results in raw bytes:&lt;/p&gt;

&lt;div id=&quot;instrumentation-stdin-python23&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Python 3:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;buffer&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# There is no buffer attribute in Python 2:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The fastest persistent mode requires that the program should not have
a global state where the previous program execution affects the next
one. There unfortunately is a surprising amount of global state in
Python programs. It is not that uncommon to initialize some specific
variables only during the program execution and then re-use the
results later. This usually is harmless, but negatively affects the
program stability that &lt;em&gt;afl-fuzz&lt;/em&gt; is going to show in its status
screen.&lt;/p&gt;

&lt;p&gt;Persistent mode code for a fuzzable program could look like following
including the learnings from the deferred instrumentation and its
speedups:&lt;/p&gt;

&lt;div id=&quot;instrumentation-persistent&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Python 3:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;buffer&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# There is no buffer attribute in Python 2:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;persistent-mode-stability&quot;&gt;Persistent mode stability&lt;/h4&gt;

&lt;blockquote&gt;
  &lt;p&gt;This section has been added 6 months after writing the original
article when Jakub Wilk pointed out potential stability issues with
the original persistent mode code example on OS X and FreeBSD.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some systems where Python runs implement file manipulation by using
buffered functions. The most prominent operating system where
&lt;em&gt;afl-fuzz&lt;/em&gt; runs that uses buffered I/O in Python is OS X/macOS and
using the
&lt;a href=&quot;#instrumentation-persistent&quot;&gt;persistent mode example in the previous section&lt;/a&gt;
does not work in Python 2 on these systems. It shows up as a low
stability percentage in &lt;em&gt;afl-fuzz&lt;/em&gt; user interface that means that the
same input from &lt;em&gt;afl-fuzz&lt;/em&gt; perspective leads program taking different
paths between subsequent executions, as the input read by the program
is not the same as what &lt;em&gt;afl-fuzz&lt;/em&gt; has provided.&lt;/p&gt;

&lt;p&gt;Buffered reads from a file work by calling low level file reading
system calls with a moderately sized input buffer. This input buffer
then makes sure that if we do a lot of small file system reads, like
reading frame based data formats frame by frame, they will not result
in as many system calls as they would result without buffering. This
generally increases program performance, as programmers can rely on
file system functions to work relatively fast even with non-optimal
access patterns.&lt;/p&gt;

&lt;p&gt;You need to set the stream position to the beginning when using
persistent mode with &lt;em&gt;afl-fuzz&lt;/em&gt; on systems that use buffered I/O and
you are reading from the standard input. All these examples read data
from the standard input, as it is generally more efficient than
opening a new file for each fuzzing iteration. Rewinding the stream
position to the beginning by using
&lt;a href=&quot;https://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects&quot;&gt;file.seek(0) method&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately not all streams support seeking and with &lt;em&gt;afl-fuzz&lt;/em&gt; the
situation is more tricky. If you execute the program normally and read
from &lt;code class=&quot;highlighter-rouge&quot;&gt;sys.stdin&lt;/code&gt;, by default the standard input does not support
seeking. But when you run it through &lt;em&gt;afl-fuzz&lt;/em&gt;, the standard input is
in reality a file descriptor that is backed up by a file on a file
system. And this file supports seeking. So you need some extra code to
detect if the standard input supports seeking or not:&lt;/p&gt;

&lt;div id=&quot;instrumentation-persistent-rewind&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Python 3:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;buffer&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# There is no buffer attribute in Python 2:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Figure out if the standard input supports seeking or not:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rewind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# In Python 2 and 3 seek failure exception differs:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;IOError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;OSError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# Do nothing if we can not seek the stream:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rewind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fuzzable_module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rewind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin_compat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The effect of adding standard input rewinding more than doubles the
fuzzing overhead for the persistent mode on the Debian GNU/Linux
system that I have used to do these benchmarks. On OS X the effect is
less than 10 % overhead increase for Python 3 and is required for
Python 2 to even work with &lt;em&gt;afl-fuzz&lt;/em&gt; on OS X.&lt;/p&gt;

&lt;h3 id=&quot;benchmarking-different-afl-fuzz-modes&quot;&gt;Benchmarking different afl-fuzz modes&lt;/h3&gt;

&lt;p&gt;I wanted to measure how these different &lt;em&gt;afl-fuzz&lt;/em&gt; modes behave with
Python. So I created a small fuzz target whose main algorithm does
some conditional computation based on the input data and prints out
the result:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fuzz_one&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c&quot;&gt;# This only includes lowercase ASCII letters:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is just to exercise the fuzzer a little bit more than a trivial
function that does nothing would do. I also created an equivalent
fuzz target in C++ to give numbers to compare what kind of an overhead
different fuzzing modes incur for both Python and native
applications. The approximate results are summarized in table
&lt;a href=&quot;#table-benchmarks&quot;&gt;1&lt;/a&gt;. The actual scripts used to generate this data
are available from following links:
&lt;a href=&quot;measure-times.sh&quot;&gt;measure-times.sh&lt;/a&gt;,
&lt;a href=&quot;target-simple.template.py&quot;&gt;target-simple.template.py&lt;/a&gt;, and
&lt;a href=&quot;target-simple.cpp&quot;&gt;target-simple.cpp&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;table-benchmarks&quot;&gt;

    &lt;table style=&quot;margin: 0 auto;&quot;&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th style=&quot;text-align: left&quot;&gt; &lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;Python 2&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;Python 3&lt;/th&gt;
          &lt;th style=&quot;text-align: right&quot;&gt;Native&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#afl-dumb-mode&quot;&gt;dumb mode&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;110/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;47/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;1200/s&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#instrumentation-pre-init&quot;&gt;pre-init&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;130/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;46/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;5800/s&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#instrumentation-deferred&quot;&gt;deferred&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;560/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;260/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;6800/s&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#instrumentation-os-exit-stdin&quot;&gt;quick exit&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;2700/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;2100/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;8700/s&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#instrumentation-persistent-rewind&quot;&gt;rewinding persistent mode&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;5800/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;5900/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;text-align: left&quot;&gt;&lt;a href=&quot;#instrumentation-persistent&quot;&gt;persistent mode&lt;/a&gt;&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;17000/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;15000/s&lt;/td&gt;
          &lt;td style=&quot;text-align: right&quot;&gt;44000/s&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;figcaption class=&quot;text-center&quot;&gt;Table 1: afl-fuzz benchmarks for various fuzzing modes for Python 2, Python 3, and for C++ versions of the example fuzz target.&lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;What these results show, it is possible to make fuzzable program in
Python in such way that the fuzzing start-up overhead is only three to
four times larger than for a native one with &lt;em&gt;afl-fuzz&lt;/em&gt;. This is
an excellent result considering that generally algorithms implemented
in Python can be considered 10-100 times slower than ones implemented
in C family languages. But if you want to use Python for performance
critical tasks, you are anyways using &lt;a href=&quot;http://cython.org/&quot;&gt;Cython&lt;/a&gt; or
&lt;a href=&quot;https://docs.python.org/2/extending/extending.html&quot;&gt;write performance critical parts in C&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is a clear performance difference between Python 2.7.14 and
Python 3.6.4 especially when all start-up and exit optimization tricks
are not in use. This difference is also visible in Python start-up
benchmarks at &lt;a href=&quot;https://speed.python.org/&quot;&gt;speed.python.org&lt;/a&gt;. This
difference gets smaller when the persistent mode is used as Python
executable is not shut down immediately after processing one
input. What can also help Python 3 in the persistent fuzzing mode is
the fact that the tracing function that python-afl sets with
&lt;a href=&quot;https://docs.python.org/2/library/sys.html#sys.settrace&quot;&gt;sys.settrace()&lt;/a&gt;
is called only half as often with Python 3 is it is called with Python
2 for this fuzz target.&lt;/p&gt;

&lt;h2 id=&quot;more-speed-for-repeated-python-executions&quot;&gt;More speed for repeated Python executions&lt;/h2&gt;

&lt;p&gt;Python enables imports and other type of code loading at any phase of
the program execution. This makes it quite possible that program has
not fully loaded before it is executed for the first time. This is
usually used as a configuration mechanism to configure the program
based on the runtime environment and other type of
configuration. It also provides the possibility to write plugins,
similarly to what
&lt;a href=&quot;https://en.wikipedia.org/wiki/Dynamic_loading&quot;&gt;dynamically loaded libraries&lt;/a&gt;
provide.&lt;/p&gt;

&lt;p&gt;You can see from table &lt;a href=&quot;#table-benchmarks&quot;&gt;1&lt;/a&gt; how the fuzzing overhead
decreases a lot when the fuzzing start point moved after &lt;code class=&quot;highlighter-rouge&quot;&gt;import&lt;/code&gt;
statements for this simple example program. So when I was fuzzing an
old version of &lt;a href=&quot;https://pypi.python.org/pypi/flake8&quot;&gt;flake8&lt;/a&gt;, I tried
to see if it had any hidden configuration statements that would
execute and cache their results for repeated calls. And it did!&lt;/p&gt;

&lt;p&gt;Initially I used following type of fuzzing wrapper for flake8:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-python2&quot;&gt;import afl, sys, flake8.run
afl.init()
flake8.run.check_code(sys.stdin.read())
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is basically a simple wrapper that imports all what it needs and
then fuzzes what is fed from the standard input to the program. But
the performance of this was horrible, around 15 executions/second. So
I tried to see what happens when I change the code a little bit by
calling the &lt;code class=&quot;highlighter-rouge&quot;&gt;flake8.run.check_code()&lt;/code&gt; function with an empty string
before setting the fuzzing starting point:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flake8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Make sure that the hidden runtime configuration is executed:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;flake8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;afl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;flake8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;check_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This doubled the execution speed to around 30 executions/second. It is
still quite slow for the small inputs that &lt;em&gt;afl-fuzz&lt;/em&gt; initially
creates, but an improvement nonetheless. I looked at what flake8 does
when it is executed and a following line popped up:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pkg_resources&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iter_entry_points&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There basically is a hidden &lt;code class=&quot;highlighter-rouge&quot;&gt;import&lt;/code&gt; statement in the execution path
whose result is cached after the first time it is encountered. Also
this &lt;code class=&quot;highlighter-rouge&quot;&gt;pkg_resources.iter_entry_points()&lt;/code&gt; function is used to
&lt;a href=&quot;http://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points&quot;&gt;configure the program at runtime&lt;/a&gt;
and that also adds some extra overhead to the process.&lt;/p&gt;

&lt;p&gt;Flake8 also by default tries to execute checks in parallel with
&lt;a href=&quot;https://docs.python.org/2/library/multiprocessing.html&quot;&gt;multiprocessing module&lt;/a&gt;. This
might be a good idea when you have multiple files to verify at once,
but during fuzzing it just adds unneeded overhead. Also the fact that
it starts a new process makes the fuzzer lose all information about
what is happening in the subprocess. Fortunately in flake8 it was
possible to override the detected multiprocessing support by just
setting one variable into &lt;code class=&quot;language-python highlighter-rouge&quot;&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;/code&gt; and then flake8
will act as there is no multiprocessing support. This increased the
average fuzzing speed of flake8 by threefold.&lt;/p&gt;

&lt;p&gt;The final speedup with flake8 came when looking at how flake8 is
constructed. It is basically a wrapper around
&lt;a href=&quot;https://pypi.python.org/pypi/mccabe/&quot;&gt;mccabe&lt;/a&gt;,
&lt;a href=&quot;https://pypi.python.org/pypi/pycodestyle/&quot;&gt;pycodestyle&lt;/a&gt;, and
&lt;a href=&quot;https://pypi.python.org/pypi/pyflakes/&quot;&gt;pyflakes&lt;/a&gt; packages. So rather
than fuzz flake8, it is much more productive to create a fuzz target
for each one of those packages individually. I did this for
pycodestyle and ended up finally executing it with around 420
executions/second for trivial data and around 200 executions/second
for more realistic. So basic recommendations on how to fuzz native
programs also apply for Python.&lt;/p&gt;

&lt;h2 id=&quot;monkey-patching-around-fuzzing-barriers&quot;&gt;Monkey patching around fuzzing barriers&lt;/h2&gt;

&lt;p&gt;As american fuzzy lop does not know almost anything about the input,
it can encounter various impediments (see section 13 from
&lt;a href=&quot;http://lcamtuf.coredump.cx/afl/README.txt&quot;&gt;afl’s README.txt&lt;/a&gt;) when
the file format includes any values that depend on the previously
encountered data. This is especially problematic with checksums and is
also an issue with other mutation based fuzzers. To work around
this the C world, you can generally use
&lt;a href=&quot;https://llvm.org/docs/LibFuzzer.html#fuzzer-friendly-build-mode&quot;&gt;C preprocessor to turn off checksum verification&lt;/a&gt;
when such thing is encountered. This also applies for all other types
of barriers that might skew fuzzing results, like random number usage.&lt;/p&gt;

&lt;p&gt;Unfortunately Python does not have preprocessor support by default, so
this type of conditional compiling is out of the question. Fortunately
Python provides the possibility to do
&lt;a href=&quot;https://en.wikipedia.org/wiki/Monkey_patch&quot;&gt;monkey patching&lt;/a&gt; where
you can replace functions or methods at runtime. So to make a library
more fuzzer friendly, you can monkey patch all functions related to
data verification to always return &lt;code class=&quot;highlighter-rouge&quot;&gt;True&lt;/code&gt;, or return some constant
value when checksums are considered.&lt;/p&gt;

&lt;p&gt;I used this approach to fuzz
&lt;a href=&quot;https://pypi.python.org/pypi/python-evtx/0.6.1&quot;&gt;python-evxt 0.6.1&lt;/a&gt;
library. Python-evxt is a library to parse Windows event log files and
is one of the first hits when you search
&lt;a href=&quot;https://pypi.python.org/&quot;&gt;Python Package Index&lt;/a&gt; with “pure python
parser” keyword. The file format includes
&lt;a href=&quot;https://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRC-32_algorithm&quot;&gt;CRC32&lt;/a&gt;
checksum that will prevent the fuzzer from being able to meaningfully
modify the input file, as almost all modifications will create an
incorrect checksum in the file.&lt;/p&gt;

&lt;p&gt;To monkey patch around this issue, I searched the source code for all
functions that potentially have anything to do with checksum
generation and made them always to return a constant value:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Evtx.Evtx&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;checksum_patches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChunkHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;calculate_header_checksum&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChunkHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;header_checksum&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChunkHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;calculate_data_checksum&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ChunkHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;data_checksum&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;checksum&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Evtx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FileHeader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;calculate_checksum&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;class_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method_name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checksum_patches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;setattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;class_obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-python highlighter-rouge&quot;&gt;&lt;span class=&quot;n&quot;&gt;checksum_patches&lt;/span&gt;&lt;/code&gt; variable holds all the
functions that you need to overwrite to ignore checksums. You can use
&lt;code class=&quot;highlighter-rouge&quot;&gt;setattr()&lt;/code&gt; to overwrite these methods on class level with an
anonymous function &lt;code class=&quot;language-python highlighter-rouge&quot;&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;/code&gt; that
always returns &lt;code class=&quot;highlighter-rouge&quot;&gt;0&lt;/code&gt; and takes any arguments. Taking any number of
arguments in any fashion is enabled with &lt;code class=&quot;highlighter-rouge&quot;&gt;*args&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;**kw&lt;/code&gt; and this
syntax is explained in
&lt;a href=&quot;https://docs.python.org/2/tutorial/controlflow.html#keyword-arguments&quot;&gt;keyword arguments&lt;/a&gt;
section on Python’s control flow tools manual.&lt;/p&gt;

&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;/h2&gt;

&lt;p&gt;I was impressed on how low fuzzing overhead Python programs can have
when compared to C family languages. When looking at how python-afl is
implemented, it becomes quite clear that the deferred mode of &lt;em&gt;afl-fuzz&lt;/em&gt;
has a great part in this where the whole Python environment and
program initialization is skipped between different fuzzing
runs.&lt;/p&gt;

&lt;p&gt;Making a Python module fuzzable was also more easy than in C family
languages. Although american fuzzy lop is already the easiest fuzzing
engine to get started with, the fact that it uses clang to do the more
advanced tricks often gives headaches when trying to get software to
compile. The fact that I did not have to use any modified Python
interpreter to get started but only had to &lt;code class=&quot;highlighter-rouge&quot;&gt;import afl&lt;/code&gt; module made me
to realize how many steps I skipped that I normally have to do when
using american fuzzy lop on new systems.&lt;/p&gt;

&lt;p&gt;Thanks to Python’s dynamic execution and monkey patching capabilities
I could also try out fuzz target creation with external libraries
without having to actually modify the original code. Especially
selecting some specific functions to fuzz and overriding checksum
generation would generally require nasty software patches with C
family languages. Especially if there is &lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; function to
override.&lt;/p&gt;

&lt;p&gt;It was also nice to realize that the &lt;code class=&quot;language-python highlighter-rouge&quot;&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;
equivalent in standard C library function call &lt;code class=&quot;language-c highlighter-rouge&quot;&gt;&lt;span class=&quot;n&quot;&gt;_Exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt; could help make light native fuzz targets even
faster. The process cleanup in this relatively trivial C++ program
adds almost 30% overhead for repeated program execution. Although it
will likely break any
&lt;a href=&quot;https://github.com/google/sanitizers&quot;&gt;sanitizer&lt;/a&gt; that does any
verification work during the exit, like searching for dynamically
allocated memory that was not freed.&lt;/p&gt;
</description>
        <pubDate>Sun, 07 Jan 2018 18:00:08 +0200</pubDate>
        <link>https://barro.github.io/2018/01/taking-a-look-at-python-afl/</link>
        <guid isPermaLink="true">https://barro.github.io/2018/01/taking-a-look-at-python-afl/</guid>
        
        <category>python-afl</category>
        
        <category>afl</category>
        
        <category>afl-fuzz</category>
        
        <category>fuzzing</category>
        
        <category>python</category>
        
        <category>benchmark</category>
        
        
      </item>
    
      <item>
        <title>Nanorepositories</title>
        <description>&lt;p&gt;I recently encountered a microservice antipattern called
&lt;a href=&quot;http://arnon.me/wp-content/uploads/2010/10/Nanoservices.pdf&quot;&gt;nanoservice&lt;/a&gt;
that is described in following manner:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Nanoservice is an Anti-pattern where a service is too fine
grained. Nanoservice is a service whose overhead (communications,
maintenance etc.) out-weights its utility.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have encountered a lot of similar situations with source code
repositories where different parts of a program or a system that was
shipped as a single entity were divided into smaller
repositories. The code in these repositories was not used by anything
else than the product (the unit of release) that the code was part
of.&lt;/p&gt;

&lt;p&gt;In the most extreme case there were thousands of smaller
repositories. Many of those repositories were just holding less than
10 files in a deep directory hierarchy implementing some tiny
functionality of the whole. Plus some boilerplate functionality for
building and repository management that could just have been a couple
of extra lines in a build system for a larger entity.&lt;/p&gt;

&lt;p&gt;In more common cases, one product consists of dozens of smaller
repositories where one or two repositories get over 90% of the whole
weekly commit traffic and other repositories just get one commit here
and there. Or that there are multiple interlinked repositories (see an
example in
&lt;a href=&quot;http://baatz.io/posts/how-many-git-repos/&quot;&gt;How many Git repos&lt;/a&gt;
article) that depend on each other and very often all of them need to
go through the same interface changes.&lt;/p&gt;

&lt;p&gt;Sometimes there also is a situation that all the work is done in
smaller repositories and then there is one
superproject[&lt;a href=&quot;https://en.wikibooks.org/wiki/Git/Submodules_and_Superprojects&quot;&gt;1&lt;/a&gt;,
&lt;a href=&quot;http://svnbook.red-bean.com/en/1.7/svn.advanced.externals.html&quot;&gt;2&lt;/a&gt;,
&lt;a href=&quot;https://www.mercurial-scm.org/wiki/Subrepository&quot;&gt;3&lt;/a&gt;]
that is automatically updated when a commit happens in any of its
child projects. So basically you have one big repository that just
consists of pointers to smaller repositories and has one unneeded
layer of indirection. Also instead of making one commit that would
reveal integration problems immediately, you now need to have multiple
commits to reveal these issues. With some extra unneeded delay.&lt;/p&gt;

&lt;p&gt;I would suggest calling these types of repositories
nanorepositories. A nanorepository is a repository that holds a
subsystem that is too limited to stand on its own and needs a bigger
system to be part of. This bigger system usually is also the only
system that is using this nanorepository. The nanorepository is also
owned by the same organization as the larger entity it’s part
of. Therefore it doesn’t give any advantages, for example, in access
control. Nanorepositories can hold just couple of files, but they can
also be relatively large applications that are, however, tightly
coupled with the system they are part of.&lt;/p&gt;

&lt;h2 id=&quot;downsides-of-premature-repository-division&quot;&gt;Downsides of premature repository division&lt;/h2&gt;

&lt;p&gt;Nanorepositories are a case of premature optimization for code sharing
where there is no real need for it. There are articles
(&lt;a href=&quot;http://danluu.com/monorepo/&quot;&gt;Advantages of monolithic version control&lt;/a&gt;,
&lt;a href=&quot;http://gregoryszorc.com/blog/2014/09/09/on-monolithic-repositories/&quot;&gt;On Monolithic Repositories&lt;/a&gt;) and
presentations
(&lt;a href=&quot;https://www.youtube.com/watch?v=W71BTkUbdqE&quot;&gt;Why Google Stores Billions of Lines of Code in a Single Repository&lt;/a&gt;,
&lt;a href=&quot;https://www.youtube.com/watch?v=X0VH78ye4yY&quot;&gt;F8 2015 - Big Code: Developer Infrastructure at Facebook’s Scale&lt;/a&gt;)
talking about the advantages of monolithic repositories, but those
advantages can be hard to grasp without knowing the disadvantages of
the other end.&lt;/p&gt;

&lt;p&gt;I’ll list some issues that I have encountered when working with
independent repositories. These all lead to a situation where
developers need to spend extra time in repository management that
could be avoided by grouping all software components that form the
final product into one repository.&lt;/p&gt;

&lt;h3 id=&quot;expensive-interface-changes&quot;&gt;Expensive interface changes&lt;/h3&gt;

&lt;p&gt;Interface changes between components become expensive. You also need
cumbersome interface deprecation policies and a way to support the old
and new interface versions between repositories until the change has
propagated everywhere. It can take months or years to ensure that all
interface users have done the intended interface change. And if you
don’t have a good search at your disposal, you still can’t be sure
about it before you really remove the old interface.&lt;/p&gt;

&lt;p&gt;With separate repositories it’s often the case that you can’t easily
search where the interface you are deprecating is used at. This means
that you don’t beforehand know what is actually depending on the
interface. There naturally are search engines that span over multiple
repositories, but they very rarely beat a simple &lt;code class=&quot;highlighter-rouge&quot;&gt;grep -r&lt;/code&gt; (or &lt;code class=&quot;highlighter-rouge&quot;&gt;git
grep&lt;/code&gt;) command whose output you can further filter with simple command
line tools. Especially if there are hundreds of small repositories
that you need to include in your search.&lt;/p&gt;

&lt;h3 id=&quot;ignore-file-duplication&quot;&gt;Ignore file duplication&lt;/h3&gt;

&lt;p&gt;Often you need to add ignore files
(&lt;a href=&quot;https://git-scm.com/docs/gitignore&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt;&lt;/a&gt;,
&lt;a href=&quot;https://www.mercurial-scm.org/wiki/.hgignore&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;.hgignore&lt;/code&gt;&lt;/a&gt;, etc…)
to prevent junk going in to the repository by accident. Situations
that can generate junk next to your code can be for example:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;In-source build
(versus &lt;a href=&quot;http://voices.canonical.com/jussi.pakkanen/2013/04/16/why-you-should-consider-using-separate-build-directories/&quot;&gt;separate build directories&lt;/a&gt;)
generated files (&lt;code class=&quot;highlighter-rouge&quot;&gt;*.a&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;*.o&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;*.exe&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;*.class&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;*.jar&lt;/code&gt;…).&lt;/li&gt;
  &lt;li&gt;Using any editor that creates backup and other files next to the
file you are editing (&lt;code class=&quot;highlighter-rouge&quot;&gt;*~&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;*.swp&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;*.bak&lt;/code&gt;…).&lt;/li&gt;
  &lt;li&gt;Using interpreted languages, like Python, whose default
implementation byte compile the scripts for faster start-up
(&lt;code class=&quot;highlighter-rouge&quot;&gt;*.pyc&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;*.pyo&lt;/code&gt;…).&lt;/li&gt;
  &lt;li&gt;Using integrated development environments that require their own
project directories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these generic ignore rules need to be included in every project in
addition to project specific ignores. Other possibility is forcing
these ignore rules on developers themselves instead of taking care of
them centrally. In case of nanorepositories there likely is just one
or two languages used per repository, so the amount of ignore rules
likely depends on the development environment that the developers work
with. But it’s still needless duplication when you could get by
without.&lt;/p&gt;

&lt;h3 id=&quot;re-inventing-inefficient-build-system-rules&quot;&gt;Re-inventing inefficient build system rules&lt;/h3&gt;

&lt;p&gt;Small repositories lead into having to reinvent build system rules for
every repository from scratch if you want to test and build your
component in isolation. Or doing a lot of code duplication or
including references to a repository including common build
rules. This also applies for test runners, as different levels of
testing for different languages usually have their own test
runners. Sometimes multiple test runners per language, that all have
some non-default options that provide various advantages in test
result reporting.&lt;/p&gt;

&lt;p&gt;Modern build systems like, &lt;a href=&quot;https://ninja-build.org/&quot;&gt;ninja&lt;/a&gt; and
&lt;a href=&quot;http://bazel.io/&quot;&gt;Bazel&lt;/a&gt;, usually work on knowing the whole build
graph of the system that they are trying to build. This makes it more
easy to discover dependencies that only rebuild parts that are
necessary to rebuild. Building every repository independently from
each other leads into recursive build systems that treat their inputs
as black boxes
(&lt;a href=&quot;https://www.yoctoproject.org/tools-resources/projects/bitbake&quot;&gt;Bitbake&lt;/a&gt;,
&lt;a href=&quot;https://www.npmjs.com/&quot;&gt;npm&lt;/a&gt;, &lt;a href=&quot;https://maven.apache.org/&quot;&gt;Maven&lt;/a&gt;,
&lt;a href=&quot;https://www.gnu.org/software/make/&quot;&gt;Make&lt;/a&gt;…). Changes in these black
boxes are either communicated with version number changes or always
rebuilding the component in question. This leads into a wasteful
process and resource usage when compared to
&lt;a href=&quot;https://trunkbaseddevelopment.com/&quot;&gt;trunk based development&lt;/a&gt; of
monolithic repositories.&lt;/p&gt;

&lt;h3 id=&quot;overly-complicated-continuous-integration-machinery&quot;&gt;Overly complicated continuous integration machinery&lt;/h3&gt;

&lt;p&gt;One of the defining principles of modern software development is
having a working continuous integration system in place. This ensures
that independent changes also work when they leave developer’s machine
and also work when they are integrated with the rest of the product
that the change is part of. And this is done multiple times every
day. This, combined with trunk based development, keeps integration
issues short (minutes to days) and avoids
&lt;a href=&quot;https://wiki.debian.org/DebianReleases#Release_statistics&quot;&gt;many-month release freezes&lt;/a&gt;
compared to branched or forked development methods.&lt;/p&gt;

&lt;p&gt;Nanorepositories likely end up in a repository specific checks in the
continuous integration machinery that only verify that the component
in the repository itself works well. And if this continuous
integration machinery has an automatic per repository check job
generation, it likely needs to have an entry point (like &lt;code class=&quot;highlighter-rouge&quot;&gt;make test&lt;/code&gt;
or &lt;code class=&quot;highlighter-rouge&quot;&gt;test.sh&lt;/code&gt; script) to execute those tests. And the same applies for
compilation. Not to mention the extra work when trying to compile
and test against different systems and runtime instrumentation (like
&lt;a href=&quot;https://github.com/google/sanitizers/wiki/AddressSanitizer&quot;&gt;AddressSanitizer&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;When the component finally gets integrated with everything else and
the system breaks, figuring out the exact commit where the breakage
happens (besides the integrating one) can be really painful. This is
because it is easily possible to have dozens to thousands of commits
between component releases. See a
&lt;a href=&quot;https://9gag.com/gag/a9rPY46&quot;&gt;physical world example&lt;/a&gt; where
components work perfectly together, but fail when integrated. And its
&lt;a href=&quot;https://9gag.com/gag/appBmD8&quot;&gt;hotfix&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;a-case-for-small-repositories&quot;&gt;A case for small repositories&lt;/h2&gt;

&lt;p&gt;Nanorepositories should not be confused with small independent
repositories, as not everything needs to aim to be a part of a bigger
product. A very common reason for small repositories is the
combination of ownership management with shareable components. Most
open source projects are such that they are owned by a certain people,
or an organization, and it’s just not a good case for them to be part
of anything bigger. Especially if they provide independent components
that really are used by multiple external entities. Same downsides,
however, generally apply to a collection of open source projects as to
products consisting of multiple repositories.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://barro.github.io/2017/02/nanorepositories/id-square-400x400.png&quot; alt=&quot;Article identicon for Feedly&quot; style=&quot;display: none;&quot; width=&quot;400&quot; height=&quot;400&quot; class=&quot;webfeedsFeaturedVisual&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 19 Feb 2017 18:00:07 +0200</pubDate>
        <link>https://barro.github.io/2017/02/nanorepositories/</link>
        <guid isPermaLink="true">https://barro.github.io/2017/02/nanorepositories/</guid>
        
        <category>source-control</category>
        
        <category>git</category>
        
        
      </item>
    
      <item>
        <title>Static code analysis and compiler warnings</title>
        <description>&lt;p&gt;Compiler generated warnings are one form of
&lt;a href=&quot;https://en.wikipedia.org/wiki/Static_program_analysis&quot;&gt;static code analysis&lt;/a&gt;
that provides a codified form of certain types of beneficial
programming practices. Nowadays modern compilers used to compile C
family languages
(&lt;a href=&quot;https://en.wikipedia.org/wiki/C_(programming_language)&quot;&gt;C&lt;/a&gt;,
&lt;a href=&quot;https://en.wikipedia.org/wiki/C%2B%2B&quot;&gt;C++&lt;/a&gt;, and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Objective-C&quot;&gt;Objective-C&lt;/a&gt;) provide
hundreds of different warnings whose usefulness varies depending on
project and its aims.&lt;/p&gt;

&lt;p&gt;In this article I will examine what level of issues compiler warnings
can find, what is the cost of enabling warnings and analyze compiler
warning flag lists for both &lt;a href=&quot;http://clang.llvm.org/&quot;&gt;clang&lt;/a&gt; and
&lt;a href=&quot;https://gcc.gnu.org/&quot;&gt;GCC&lt;/a&gt; compilers.&lt;/p&gt;

&lt;h1 id=&quot;levels-of-static-code-analysis&quot;&gt;Levels of static code analysis&lt;/h1&gt;

&lt;p&gt;Compiling C family languages usually involves preprocessor, compiler,
assembler, and a linker. This also leads to situation that static code
analysis can be done in various phases of program construction. These
generally are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Analysis on plain source files.&lt;/li&gt;
  &lt;li&gt;Analysis on preprocesses source files.&lt;/li&gt;
  &lt;li&gt;Analysis on compilation unit level.&lt;/li&gt;
  &lt;li&gt;Link-time analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This multi-stage program construction results in difficulties for
tools that are not called with the exact same arguments providing
information about preprocessor definitions, and  include and library
directories. For example tools like &lt;a href=&quot;http://www.splint.org/&quot;&gt;splint&lt;/a&gt;,
&lt;a href=&quot;http://cppcheck.sourceforge.net/&quot;&gt;Cppcheck&lt;/a&gt;, and many editor
front-ends work outside the build system and can result in false
warnings because they can not see inside some macro definitions that
were not included in the simple static analysis setup. This becomes an
issue with larger projects that do not necessarily have the most
straightforward build setups and the most trivial header file
inclusion policies. This does not mean that such tools are useless,
but they will result in false positive warnings that can be really
annoying unless they are silenced or ignored in some way.&lt;/p&gt;

&lt;p&gt;Analysis on preprocessed source files already provides pretty accurate
picture of what kind of issues there can be in the program, but it
necessarily is not enough. In the compilation phase compilers
constantly transform the program into new, functionally equivalent,
forms during optimization phases that can even result in
&lt;a href=&quot;http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html&quot;&gt;unexpected code removal&lt;/a&gt;
that is not necessarily trivial to notice. Compilation phase also
gives more opportunities for target platform specific static code
analysis. For example pipeline stalls or value overflows due to
incorrect assumptions on data type sizes can usually be noticed only
after the target platform is known.&lt;/p&gt;

&lt;p&gt;Final phase in program construction, that provides options for static
analysis, is the linking phase. In the linking phase linker takes care
that all the functions and global variables that the program calls
come from somewhere and that there are no conflicting duplicate names
defined. This should also enable some automatic detection capabilities
for memory leaks and such that come from calling functions defined in
different compilation units. I’m not sure if any freely available
static analyzer does this.&lt;/p&gt;

&lt;h1 id=&quot;compiler-warning-flags&quot;&gt;Compiler warning flags&lt;/h1&gt;

&lt;p&gt;Compiler warning flags are one way to do static code analysis that
cover all possible phases of program construction. This assumes that
the compiler is involved in all phases of program construction. And
they usually are, as in all phases from preprocessing to linking
compiler front-end is used as a wrapper to all the tools that do the
actual hard work.&lt;/p&gt;

&lt;h2 id=&quot;warning-flags-and-compilation-time&quot;&gt;Warning flags and compilation time&lt;/h2&gt;

&lt;p&gt;Using static code analysis in form of compiler warnings incurs some
penalty, as they need to execute some extra code in addition to normal
code related to compilation. To measure the penalty and to contrast it
with some more advanced static analysis tools,&lt;/p&gt;

&lt;p&gt;I did some benchmarks by compiling
&lt;a href=&quot;http://cppcheck.sourceforge.net/&quot;&gt;Cppcheck&lt;/a&gt; 1.73 and
&lt;a href=&quot;http://www.fftw.org/&quot;&gt;FFTW&lt;/a&gt; 3.3.4 with clang 3.8, GCC 6.1, and Infer
0.8.1 by using &lt;code class=&quot;highlighter-rouge&quot;&gt;-O3&lt;/code&gt; optimization level. Cppcheck is a program mainly
written in C++ and FFTW is mainly written in C. Infer has some
experimental checks for C++ enabled with &lt;code class=&quot;highlighter-rouge&quot;&gt;--cxx&lt;/code&gt; command line option,
so I ran Infer twice for Cppcheck, with and without C++ checks. Clang
had all warnings enabled &lt;code class=&quot;highlighter-rouge&quot;&gt;-Weverything&lt;/code&gt; and GCC had all warning
options that did not require any special values. This resulted in
following minimum execution times of 3 runs:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Compiler&lt;/th&gt;
      &lt;th&gt;Program&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;No warnings&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;All warnings&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;clang&lt;/td&gt;
      &lt;td&gt;Cppcheck&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;59.3 s&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1 min 1.1 s (+ 3.0 %)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;GCC&lt;/td&gt;
      &lt;td&gt;Cppcheck&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1 min 32.7 s&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1 min 38.8 s (+ 6.6 %)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Infer&lt;/td&gt;
      &lt;td&gt;Cppcheck&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;17 min 50 s (18x slower)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Infer &lt;code class=&quot;highlighter-rouge&quot;&gt;--cxx&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Cppcheck&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1 h 36 min (&lt;strong&gt;97x slower&lt;/strong&gt;)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;clang&lt;/td&gt;
      &lt;td&gt;FFTW&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;40.5 s&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;40.9 s (+ 1 %)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;GCC&lt;/td&gt;
      &lt;td&gt;FFTW&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;42.7 s&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;58.1 s (&lt;strong&gt;+ 36 %&lt;/strong&gt;)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Infer&lt;/td&gt;
      &lt;td&gt;FFTW&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;-&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;4 min 43 s (10x slower)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;We can see that for clang and GCC the extra processing time added even
by all warnings flags is pretty small compared to all the other
compilation and optimization steps for a C++ application
(Cppcheck). But for mostly C based application (FFTW) GCC gets
surprisingly heavy, although build times still remain within the same
order of magnitude.&lt;/p&gt;

&lt;p&gt;If we then compare the time that a more heavy static code analyzer
takes, these compiler warnings are extremely cheap way to add static
code analysis. They may not catch all the same bugs as these more
advanced methods do, but they do offer a cheap way to avoid the basic
mistakes.&lt;/p&gt;

&lt;h1 id=&quot;warning-flag-lists&quot;&gt;Warning flag lists&lt;/h1&gt;

&lt;p&gt;I have created a project that can automatically parse
&lt;a href=&quot;https://github.com/Barro/compiler-warnings&quot;&gt;compiler warning flags from command line option definition files in clang and GCC&lt;/a&gt;. This
came partially from a necessity and partially from curiosity to
examine what kind of options clang and GCC provide in easy to digest
format. Although both compiler provide some kind of lists of warning
flags as part of their documentation, they are pretty cumbersome to go
through when the main interest is first figure what there is available
and then just look at the details.&lt;/p&gt;

&lt;h2 id=&quot;warning-options-and-deprecation&quot;&gt;Warning options and deprecation&lt;/h2&gt;

&lt;p&gt;Different compilers have different policies about backwards
compatibility and deprecation. When looking at how warning options
have evolved, GCC has not removed between versions 3.4 and 6.1 a
single switch, it has just switched them to do nothing (&lt;code class=&quot;highlighter-rouge&quot;&gt;-Wimport&lt;/code&gt;,
&lt;code class=&quot;highlighter-rouge&quot;&gt;-Wunreachable-code&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wmudflap&lt;/code&gt; switches). Clang on the other hand
has removed multiple switches between versions and for example there
is no references to &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wcxx98-cxx11-compat&lt;/code&gt; in the current codebase
even if clang 3.3 had such switch.&lt;/p&gt;

&lt;h2 id=&quot;examining-differences-visually&quot;&gt;Examining differences visually&lt;/h2&gt;

&lt;p&gt;Generating large purely textual differences between different files
becomes quite cumbersome quite soon if you want to do anything more
complicated than a simple difference of unique command line options
between two subsequent versions. For example if we look at
&lt;a href=&quot;#figure-gcc-5-6-wall&quot;&gt;figure 1&lt;/a&gt; that shows what other warnings
&lt;code class=&quot;highlighter-rouge&quot;&gt;-Wall&lt;/code&gt; flag enables in GCC 6 when compared to GCC 5. We can see that
there are quite many extra warnings added to &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wall&lt;/code&gt; switch so newer
compiler versions provide extra analysis capabilities even without
adding all the new options individually.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;figure-gcc-5-6-wall&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-wall.png&quot;&gt;
&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-wall.webp 887w&quot; sizes=&quot;887px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-wall.png 887w&quot; sizes=&quot;887px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-wall.png&quot; alt=&quot;Meld showing differences what flags
-Wall enables between GCC 5 and 6.&quot; title=&quot;Meld showing differences what flags -Wall enables between GCC 5 and 6.&quot; width=&quot;700&quot; height=&quot;469&quot; class=&quot;figure-image&quot; /&gt;
&lt;/picture&gt;
&lt;/a&gt;
&lt;figcaption&gt;
      &lt;p&gt;Figure 1: &lt;a href=&quot;http://meldmerge.org/&quot;&gt;Meld&lt;/a&gt; showing differences what flags &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wall&lt;/code&gt; enables between GCC 5 and 6.&lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;From &lt;a href=&quot;#figure-gcc-5-6-cxx-compat&quot;&gt;figure 2&lt;/a&gt; we can also see that GCC 6
uses &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wc++11-compat&lt;/code&gt; as the default warning flag indicating
differences between ISO C++ 1998 and ISO C++ 2011 for constructs that
have the same name instead of &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wc++0x-compat&lt;/code&gt;, that refers to a draft
standard. So GCC has basically deprecated &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wc++0x-compat&lt;/code&gt; switch in
favor of a switch that refers to the actual standard.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;figure-gcc-5-6-cxx-compat&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-cxx-compat.png&quot;&gt;

&lt;picture&gt;

&lt;source type=&quot;image/webp&quot; srcset=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-cxx-compat.webp 887w&quot; sizes=&quot;887px&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-cxx-compat.png 887w&quot; sizes=&quot;887px&quot; /&gt;

&lt;img src=&quot;https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/meld-gcc-5-6-cxx-compat.png&quot; alt=&quot;-Wc++0x-compat is an alias of -Wc++11-compat in GCC 6 instead the other way around.&quot; title=&quot;-Wc++0x-compat is an alias of -Wc++11-compat in GCC 6 instead the other way around.&quot; width=&quot;700&quot; height=&quot;99&quot; class=&quot;figure-image&quot; /&gt;

&lt;/picture&gt;
&lt;/a&gt;
&lt;figcaption&gt;
      &lt;p&gt;Figure 2: &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wc++0x-compat&lt;/code&gt; is an alias of &lt;code class=&quot;highlighter-rouge&quot;&gt;-Wc++11-compat&lt;/code&gt; in GCC 6 instead the other way around.&lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;h1 id=&quot;suggestions-for-usable-warning-options&quot;&gt;Suggestions for usable warning options&lt;/h1&gt;

&lt;p&gt;I won’t be giving any specific suggestions here for warning
flags, as there seem to be new options for each subsequent compiler
release. A good place to start is &lt;a href=&quot;https://www.nasa.gov/&quot;&gt;NASA&lt;/a&gt;’s
&lt;a href=&quot;http://lars-lab.jpl.nasa.gov/JPL_Coding_Standard_C.pdf&quot;&gt;JPL Institutional Coding Standard for the C Programming Language&lt;/a&gt;
that includes a very short list of rudimentary warning flags for
GCC. It also includes a short list of coding standards of which
&lt;a href=&quot;https://vimeo.com/84991949&quot;&gt;each one would have prevented a mission failure&lt;/a&gt;
for
NASA. &lt;a href=&quot;https://www.securecoding.cert.org/&quot;&gt;SEI CERT coding standards&lt;/a&gt;
for secure coding  also provide various automatically generated lists
for
&lt;a href=&quot;https://www.securecoding.cert.org/confluence/display/cplusplus/Clang&quot;&gt;clang warning flags&lt;/a&gt;
and
&lt;a href=&quot;https://www.securecoding.cert.org/confluence/display/cplusplus/GCC&quot;&gt;GCC warning flags&lt;/a&gt;
based on the issues that these standards take into account.&lt;/p&gt;

&lt;p&gt;And finally, check out the
&lt;a href=&quot;https://github.com/Barro/compiler-warnings&quot;&gt;warning flag lists for clang and GCC&lt;/a&gt;
and make your own combinations that bring the most benefit for
whatever you are working with. Not all of them are appropriate for
your project and some of them may be even working against the useful
development patterns that you have.&lt;/p&gt;

&lt;h2 id=&quot;cautionary-tales-about-compiler-warnings-flags&quot;&gt;Cautionary tales about compiler warnings flags&lt;/h2&gt;

&lt;p&gt;Even though it might sound like a good idea to rush and fix all the
issues that these new compiler warning flags uncover, it might
actually cause some new bugs to pop up. Specifically
&lt;a href=&quot;https://www.sqlite.org/&quot;&gt;SQLite&lt;/a&gt; database engine has had its own take
on
&lt;a href=&quot;https://www.sqlite.org/testing.html#staticanalysis&quot;&gt;compiler warnings and their fixing&lt;/a&gt;
and they have concluded that fixing compiler warnings actually has
produced some extra bugs that would not have come into light if there
would have not been tries to fix compiler warnings.&lt;/p&gt;

&lt;p&gt;I have also had my own take on compiler warning fixes and sometimes I
have screwed up and messed up with a perfectly working code while
fixing a misleading warning. But generally my own experience has lead
to more fixes than what there have been bugs. And the coolest thing
is, that having these warnings enabled as the standard development
process prevent some bugs from ever creeping up to the application in
the first place.&lt;/p&gt;
</description>
        <pubDate>Sun, 08 May 2016 19:00:06 +0300</pubDate>
        <link>https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/</link>
        <guid isPermaLink="true">https://barro.github.io/2016/05/static-code-analysis-and-compiler-warnings/</guid>
        
        <category>c/c++</category>
        
        <category>static-analysis</category>
        
        
      </item>
    
      <item>
        <title>Being a good CPU neighbor</title>
        <description>&lt;p&gt;Very often computational tasks are
roughly &lt;a href=&quot;https://en.wikipedia.org/wiki/Processing_modes&quot;&gt;divided&lt;/a&gt; into
&lt;a href=&quot;https://en.wikipedia.org/wiki/Real-time_computing&quot;&gt;real-time&lt;/a&gt; and
&lt;a href=&quot;https://en.wikipedia.org/wiki/Batch_processing&quot;&gt;batch processing&lt;/a&gt;
tasks. Sometimes you might want to run some tasks that take a
large amount of computation resources, get the result as fast as
possible, but you don’t really care exactly when you get the result
out.&lt;/p&gt;

&lt;p&gt;In larger organizations there are shared computers that usually have a
lot of CPU power and memory available and that are mostly idle. But
they are also used by other users that will be quite annoyed if they
suffer from long delays to key presses or from similar issues because
your batch processing tasks take all the resources that are available
away from the system. Fortunately *nix systems provide different
mechanisms available to non-root users to avoid these kind of issues.&lt;/p&gt;

&lt;p&gt;These issue can also raise in situations where you have a system that
can only allocate static resource requirements to tasks, like in
&lt;a href=&quot;https://jenkins-ci.org/&quot;&gt;Jenkins&lt;/a&gt;. As an example, you might have some
test jobs that need to finish within certain time limit mixed
with compilation jobs that should finish as soon as possible, but that
can yield some resources to these higher priority test jobs, as they
don’t have as strict time limitation requirements. And you usually
don’t want to limit the resources that compilation jobs can use, if
they are run on otherwise idle machine.&lt;/p&gt;

&lt;p&gt;Here I’m specifically focusing on process priority settings and other
CPU scheduling settings provided by Linux, as it currently happens to
be probably the most used operating system kernel for multi-user
systems. These settings affect how much CPU time a process gets
relative to other processes and are especially useful on shared
overloaded systems where there are more processes running than what
there are CPU cores available.&lt;/p&gt;

&lt;h2 id=&quot;different-process-scheduling-priorities-in-linux&quot;&gt;Different process scheduling priorities in Linux&lt;/h2&gt;

&lt;p&gt;Linux and &lt;a href=&quot;http://pubs.opengroup.org/onlinepubs/9699919799/&quot;&gt;POSIX&lt;/a&gt;
interfaces provide different
&lt;a href=&quot;http://man7.org/linux/man-pages/man7/sched.7.html&quot;&gt;scheduling policies&lt;/a&gt;
that define how
&lt;a href=&quot;https://www.kernel.org/doc/Documentation/scheduler/&quot;&gt;Linux scheduler&lt;/a&gt;
allocates CPU time to a process. There are two main scheduling policies
for processes: real-time priority policies and normal scheduling
policies. Real-time policies are usually accessible only to root user
and are not the point of interest of here, as they can not usually be
used by normal users on shared systems.&lt;/p&gt;

&lt;p&gt;At the time of the writing this article there are three normal
scheduling policies available to normal users for process priorities:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_OTHER&lt;/code&gt;: the default scheduling policy in Linux with the
default
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/setpriority.2.html&quot;&gt;dynamic priority&lt;/a&gt;
of 0.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_BATCH&lt;/code&gt;: policy for scheduling batch processes. This
schedules processes in similar fashion as &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_OTHER&lt;/code&gt; and is
affected by the dynamic priority of a process. This makes the
scheduler assume that the process is CPU intensive and makes it
harder to wake up from a sleep.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_IDLE&lt;/code&gt;: the lowest priority scheduling policy. Not affected
by dynamic priorities. This equals to
&lt;a href=&quot;https://github.com/torvalds/linux/blob/v4.4/kernel/sched/core.c#L3860&quot;&gt;nice level priority of 20&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The standard *nix way to change process priorities is to use
&lt;a href=&quot;http://man7.org/linux/man-pages/man1/nice.1.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nice&lt;/code&gt;&lt;/a&gt; command. By
default in Linux, process can get
&lt;a href=&quot;http://man7.org/linux/man-pages/man2/getpriority.2.html&quot;&gt;nice values&lt;/a&gt;
of -20–19 where the default nice value for a process is 0. When
process is started with &lt;code class=&quot;highlighter-rouge&quot;&gt;nice&lt;/code&gt; command, the nice value will be&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Values 0–19 are available to a normal user and -20–-1
are available to the root user. The lowest priority nice value of 19
gives process
&lt;a href=&quot;https://www.kernel.org/doc/Documentation/scheduler/sched-nice-design.txt&quot;&gt;5% of CPU time&lt;/a&gt;
with the default scheduler in Linux.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href=&quot;http://man7.org/linux/man-pages/man1/chrt.1.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;chrt&lt;/code&gt;&lt;/a&gt;
command can be used to give a process access to &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_BATCH&lt;/code&gt; and
&lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_IDLE&lt;/code&gt; scheduling policies. &lt;code class=&quot;highlighter-rouge&quot;&gt;chrt&lt;/code&gt; can be used with combination
of &lt;code class=&quot;highlighter-rouge&quot;&gt;nice&lt;/code&gt; command to lower the priority of &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_BATCH&lt;/code&gt; scheduling
policy. And using &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_IDLE&lt;/code&gt; (= nice level 20) policy should give
around 80% of the CPU time that nice level of 19 has, as nice level
weights
&lt;a href=&quot;https://github.com/torvalds/linux/blob/v4.4/kernel/sched/sched.h#L1116&quot;&gt;increase the process priority by 1.25 compared to lower priority level&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;benchmarking-with-different-competing-workloads&quot;&gt;Benchmarking with different competing workloads&lt;/h2&gt;

&lt;p&gt;I wanted to benchmark the effect of different scheduling policies on a
work done by a specific benchmark program. I used a system with Linux
3.17.0 kernel with
&lt;a href=&quot;http://ark.intel.com/products/65523/Intel-Core-i7-3770K-Processor-8M-Cache-up-to-3_90-GHz&quot;&gt;Intel Core i7-3770K CPU at 3.5 GHz&lt;/a&gt;
processor with hyperthreading and  frequency scaling turned on and 32
gigabytes of RAM. I didn’t manage to make the CPU frequency constant,
so results vary a little between runs. I used John the Ripper’s bcrypt
benchmark started with following command as the test program for
useful work:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;/usr/sbin/john &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;bcrypt &lt;span class=&quot;nt&quot;&gt;-test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I benchmarked 1 and 7 instances of John the Ripper for 9 iterations
(9 * 5 = 45 seconds) with various amounts of non-benchmarking
processes running at the same time. 1 benchmarking process should by
default not have any cache contention resulting from other
benchmarking processes happening and 7 benchmarking processes saturate
all but 1 logical CPU core and can have cache and computational unit
contention with each other.&lt;/p&gt;

&lt;p&gt;Non-bechmarking processes were divided into different categories and
there were 0–7 times CPU cores instances of them started to make
them fight for CPU time with benchmarking processes. The results of
running different amounts of non-benchmarking processes with different
scheduling policies can be found from tables &lt;a href=&quot;#cpu-looper-table-cpus-1&quot;&gt;1&lt;/a&gt;,
&lt;a href=&quot;#cpu-looper-table-cpus-7&quot;&gt;2&lt;/a&gt;, &lt;a href=&quot;#mem-looper-table-cpus-1&quot;&gt;3&lt;/a&gt;, and
&lt;a href=&quot;#mem-looper-table-cpus-7&quot;&gt;4&lt;/a&gt;. Different scheduling policies visible in
those tables are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;default&lt;/em&gt;: default scheduling policy. Command started without any
wrappers. Corresponds to &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_OTHER&lt;/code&gt; with nice value of 0.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;chrt-batch&lt;/em&gt;: the default &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_BATCH&lt;/code&gt; scheduling policy. Command
started with &lt;code class=&quot;highlighter-rouge&quot;&gt;chrt --batch 0&lt;/code&gt; prefix.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;nice 10&lt;/em&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_OTHER&lt;/code&gt; scheduling policy with the default nice value
 of 10. Command started with &lt;code class=&quot;highlighter-rouge&quot;&gt;nice&lt;/code&gt; prefix.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;nice 19&lt;/em&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_OTHER&lt;/code&gt; scheduling policy with nice value of 19.
Command started with &lt;code class=&quot;highlighter-rouge&quot;&gt;nice -n 19&lt;/code&gt; prefix. This should theoretically
take around 5 % of CPU time out from the useful work.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;nice 19 batch&lt;/em&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_BATCH&lt;/code&gt; scheduling policy with nice value of 19.
 Command started with &lt;code class=&quot;highlighter-rouge&quot;&gt;nice -n 19 chrt --batch 0&lt;/code&gt; prefix.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;sched idle&lt;/em&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_IDLE&lt;/code&gt; scheduling policy. Command started with
&lt;code class=&quot;highlighter-rouge&quot;&gt;chrt --idle 0&lt;/code&gt; prefix. This should theoretically take around 80 % of
CPU time compared to nice level 19 out from useful work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The results in those tables reflect the relative average percentage of
work done compared to the situation when there are no additional
processes disturbing the benchmark. These only show the average value
and do not show, for example, variance that could be useful to
determine how close those values are of each other. You can download
get the raw benchmarking data and the source code to generate and
analyze this data from following links:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;cpu-neighbor-source-code.tar.xz&quot;&gt;Source code for test programs and generating and analyzing the data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;cpu-neighbor-benchmarks.tar.xz&quot;&gt;Raw benchmarking data&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cpu-looper&quot;&gt;CPU looper&lt;/h3&gt;

&lt;p&gt;CPU looper applications consists purely of an application that causes
CPU load. Its main purpose is just to test the scheduling policies
without forcing &lt;a href=&quot;https://en.wikipedia.org/wiki/CPU_cache&quot;&gt;CPU cache&lt;/a&gt;
misses. Of course there will be
&lt;a href=&quot;https://en.wikipedia.org/wiki/CPU_cache&quot;&gt;context switches&lt;/a&gt; that can
replace data cache entries related to
&lt;a href=&quot;https://en.wikipedia.org/wiki/Context_(computing)&quot;&gt;process state&lt;/a&gt; and
instruction cache entries for the process with another, but there
won’t be any extra intentional cache flushing happening here.&lt;/p&gt;

&lt;p&gt;The actual CPU looper application consists code shown in
&lt;a href=&quot;#cpu-neighbor-figure-1&quot;&gt;figure 1&lt;/a&gt; compiled without any optimizations:&lt;/p&gt;

&lt;figure id=&quot;cpu-neighbor-figure-1&quot;&gt;

  &lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;figcaption&gt;Figure 1: source code for CPU looper program.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;The results for starting 0–7 times CPU cores of CPU looper
processes with the default priority and then running benchmark with 1
or 7 cores can be found from tables &lt;a href=&quot;#cpu-looper-table-cpus-1&quot;&gt;1&lt;/a&gt; and
&lt;a href=&quot;#cpu-looper-table-cpus-7&quot;&gt;2&lt;/a&gt;.&lt;/p&gt;

&lt;figure id=&quot;cpu-looper-table-cpus-1&quot;&gt;
  &lt;table style=&quot;margin: 0 auto;&quot;&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th style=&quot;text-align: left&quot;&gt;1 worker&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;0&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;1&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;2&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;3&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;4&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;5&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;6&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;7&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;default&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;64.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;36.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;25.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;18.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;15.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;12.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;11.0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;66.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;37.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;24.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;16.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;14.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;12.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;10.9&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 10&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;93.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;82.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;75.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;75.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;75.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;74.9&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;92.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;89.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;89.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.9&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;94.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;89.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;89.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;86.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;89.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.7&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;95.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;91.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.2&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.6&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;91.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.4&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;80.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;74.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;68.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;67.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;67.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;64.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;60.7&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.5&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;83.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;75.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;75.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;74.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;74.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;69.8&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;89.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;89.7&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;90.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;89.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;87.8&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;87.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;87.2&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 19&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;77.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;69.7&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;66.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;66.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;64.6&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;63.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;58.1&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;figcaption&gt;Table 1: the relative percentage of average work done for
one benchmarking worker when there are 0&amp;ndash;7 times the logical CPU
cores of non-benchmarking CPU hogging jobs running with different
scheduling policies.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure id=&quot;cpu-looper-table-cpus-7&quot;&gt;

  &lt;table style=&quot;margin: 0 auto;&quot;&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th style=&quot;text-align: left&quot;&gt;7 workers&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;0&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;1&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;2&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;3&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;4&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;5&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;6&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;7&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;default&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;49.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;33.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;24.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;19.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;16.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;13.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;12.2&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;51.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;34.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;25.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;20.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;16.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;14.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;12.4&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 10&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;92.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;87.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;80.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;75.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;71.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;66.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;61.1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;94.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;94.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;96.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;95.7&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;96.0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;94.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.4&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;96.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;95.7&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;96.2&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;95.6&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;96.7&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;95.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;96.7&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;93.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;84.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;78.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;71.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;65.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;60.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;56.2&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;92.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;84.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;77.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;69.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;65.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;60.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;56.4&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;95.5&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;94.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;94.5&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;93.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;94.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;93.7&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;91.9&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 19&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;91.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;80.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;71.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;64.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;58.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;52.5&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;48.5&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;figcaption&gt;Table 2: the relative percentage of average work done for
seven benchmarking workers when there are 0&amp;ndash;7 times the logical
CPU cores of non-benchmarking CPU hogging jobs running with different
scheduling policies.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Tables &lt;a href=&quot;#cpu-looper-table-cpus-1&quot;&gt;1&lt;/a&gt; and
&lt;a href=&quot;#cpu-looper-table-cpus-7&quot;&gt;2&lt;/a&gt; show that
the effect is not consistent between different scheduling policies and
when there is 1 benchmarking worker running it suffers more from the
lower priority processes than what happens when there are 7
benchmarking workers running. But with higher priority scheduling
policies for background processes the average amount of work done for
1 process remains higher for light loads than with 7 worker
processes. These discrepancies can be probably explained by how
hyperthreading works by sharing the same physical CPU cores and by
caching issues.&lt;/p&gt;

&lt;h3 id=&quot;memory-looper&quot;&gt;Memory looper&lt;/h3&gt;

&lt;p&gt;Processors nowadays have multiple levels of cache and no cache
isolation and memory access from one core can
&lt;a href=&quot;https://www.youtube.com/watch?v=QBu2Ae8-8LM#t=41m14s&quot;&gt;wreak havoc for other cores&lt;/a&gt;
with just moving data from and to memory. So I wanted to see what
happens with different scheduling policies when running multiple
instances of a simple program that run on the background when John the
Ripper is trying to do some real work.&lt;/p&gt;

&lt;figure id=&quot;cpu-neighbor-figure-2&quot;&gt;

  &lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;stdlib.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 2 * 20 megabytes should be enough to spill all caches.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area_source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area_target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;calloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Just do some memory operations that access the whole memory area.
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;area_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area_target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;size_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;area_target&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

  &lt;figcaption&gt;Figure 2: source code for memory bandwidth hogging program.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Program shown in &lt;a href=&quot;#cpu-neighbor-figure-2&quot;&gt;figure 2&lt;/a&gt; is compiled
without any optimizations and it basically reads one word from memory,
adds 1 to it and stores the result to some other memory area and then
&lt;a href=&quot;https://en.wikipedia.org/wiki/Exclusive_or&quot;&gt;XORs&lt;/a&gt; the read memory
area with the written memory area. So it basically does not do
anything useful, but reads and writes a lot of data into memory every
time the program gets some execution time.&lt;/p&gt;

&lt;p&gt;Tables &lt;a href=&quot;#mem-looper-table-cpus-1&quot;&gt;3&lt;/a&gt; and &lt;a href=&quot;#mem-looper-table-cpus-7&quot;&gt;4&lt;/a&gt; show the
relative effect on John the Ripper benchmarking program when there are
various amounts of the program shown in
&lt;a href=&quot;#cpu-neighbor-figure-2&quot;&gt;figure 2&lt;/a&gt; running at the same time. If you
compare these numbers to values shown in tables
&lt;a href=&quot;#cpu-looper-table-cpus-1&quot;&gt;1&lt;/a&gt; and &lt;a href=&quot;#cpu-looper-table-cpus-7&quot;&gt;2&lt;/a&gt; a program that
only uses CPU cycles is running, the numbers for useful work can be in
some cases around 10 percentage points lower. So there is apparently
some cache contention ongoing with this benchmarking program and the
effect of lower priority scheduling policies is not the same that
could be theoretically expected just from the allocated time slices.&lt;/p&gt;

&lt;figure id=&quot;mem-looper-table-cpus-1&quot;&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th style=&quot;text-align: left&quot;&gt;1 worker&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;0&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;1&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;2&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;3&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;4&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;5&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;6&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;7&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;default priority&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;61.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;32.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;21.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;16.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;13.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;11.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;9.8&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;60.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;32.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;22.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;16.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;12.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;10.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;10.2&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 10&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;85.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;82.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;75.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;70.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;69.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;70.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;68.1&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;85.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;83.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;79.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;81.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;78.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;81.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;84.7&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;83.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;81.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;80.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;83.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;80.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;79.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;84.3&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;82.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;80.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;81.2&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;82.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;80.6&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;82.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;81.8&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;80.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;74.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;68.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;67.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;67.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;64.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;60.7&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;80.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;74.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;67.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;67.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;67.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;65.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;63.3&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;83.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;81.6&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;79.2&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;77.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;75.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;76.8&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;77.1&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 19&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;77.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;69.7&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;66.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;66.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;64.6&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;63.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;58.1&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;figcaption&gt;Table 3: the relative percentage of average work done for
one benchmarking worker when there are 0&amp;ndash;7 times the logical
CPU cores of non-benchmarking CPU and memory bandwidth hogging jobs
running with different scheduling policies.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure id=&quot;mem-looper-table-cpus-7&quot;&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th style=&quot;text-align: left&quot;&gt;7 workers&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;0&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;1&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;2&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;3&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;4&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;5&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;6&lt;/th&gt;
        &lt;th style=&quot;text-align: right&quot;&gt;7&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;default&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;48.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;32.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;24.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;19.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;16.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;14.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;12.3&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;48.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;32.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;23.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;19.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;16.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;14.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;12.6&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 10&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;89.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;81.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;74.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;69.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;64.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;60.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;56.3&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;92.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.6&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;90.5&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.5&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;91.8&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;92.1&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.9&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 0&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.1&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;91.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.9&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;91.5&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;92.1&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;85.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;77.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;70.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;63.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;58.3&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;54.2&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;50.3&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;nice 19 batch&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;86.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;77.7&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;70.0&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;63.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;58.8&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;54.4&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;50.6&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 10&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;90.6&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;89.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;88.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;88.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;88.0&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;87.4&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;86.3&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;—  &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt;&lt;em&gt;nice 19&lt;/em&gt; vs. &lt;em&gt;sched idle&lt;/em&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;100&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;82.8&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;72.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;62.9&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;57.3&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;52.2&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;48.2&lt;/strong&gt;&lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt;&lt;strong&gt;44.1&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;text-align: left&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
        &lt;td style=&quot;text-align: right&quot;&gt; &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;figcaption&gt;Table 4: the relative percentage of average work done for
seven benchmarking workers when there are 0&amp;ndash;7 times the logical
CPU cores of non-benchmarking CPU and memory bandwidth hogging jobs
running with different scheduling policies.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;These are just results of one specific benchmark with two specific
workloads on one specific machine with 4 hyperthreaded CPU cores. They
should anyways give you some kind of an idea how different CPU
scheduling policies under Linux affect the load that you do not want
to disturb when your machine is more or less overloaded. Clearly when
you are reading and writing data from and to memory, the lower
priority background process has bigger impact on the actual worker
process than what the allocated time slices would predict. But,
unsurprisingly, a single user can have quite a large impact on how
much their long running CPU hogging processes affect rest of the
machine.&lt;/p&gt;

&lt;p&gt;I did not do any investigation how much work those processes that are
supposed to disturb the benchmarking get done. In this case
&lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_BATCH&lt;/code&gt; with nice value of 19 could probably be the best
scheduling policy if we want to get the most work done and at the same
time avoid disturbing other users. Otherwise, it looks like the
&lt;code class=&quot;highlighter-rouge&quot;&gt;SCHED_IDLE&lt;/code&gt; policy, taken into use with &lt;code class=&quot;highlighter-rouge&quot;&gt;chrt --idle 0&lt;/code&gt; command, that
is promised to have the lowest impact on other processes has the
lowest impact. Especially when considering processes started with
lower nice values than the default one.&lt;/p&gt;
</description>
        <pubDate>Sun, 28 Feb 2016 18:00:05 +0200</pubDate>
        <link>https://barro.github.io/2016/02/being-a-good-cpu-neighbor/</link>
        <guid isPermaLink="true">https://barro.github.io/2016/02/being-a-good-cpu-neighbor/</guid>
        
        <category>cpu-priority</category>
        
        <category>nice</category>
        
        <category>chrt</category>
        
        
      </item>
    
      <item>
        <title>C, for(), and signed integer overflow</title>
        <description>&lt;p&gt;Signed integer overflow is
&lt;a href=&quot;https://en.wikipedia.org/wiki/Undefined_behavior&quot;&gt;undefined behavior&lt;/a&gt;
in C language. This enables compilers to do all kinds of
&lt;a href=&quot;http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html&quot;&gt;optimization tricks&lt;/a&gt;
that can lead to surprising and unexpected behavior between different
compilers, compiler versions, and optimization levels.&lt;/p&gt;

&lt;p&gt;I encountered something interesting when I tried different versions of
&lt;a href=&quot;https://gcc.gnu.org/&quot;&gt;GCC&lt;/a&gt; and &lt;a href=&quot;http://clang.llvm.org/&quot;&gt;clang&lt;/a&gt; with
following piece of code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include &amp;lt;limits.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INT_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;iterations&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;%d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When compiling this with GCC 4.7, GCC 4.9, and clang 3.4 and
compilation options for x86_64 architecture, we get following
output variations:&lt;/p&gt;

&lt;figure&gt;&lt;pre&gt;&lt;code&gt;$ gcc-4.9 --std=c11 -O0 tst.c &amp;amp;&amp;amp; ./a.out&lt;/code&gt;
3
$ gcc-4.9 --std=c11 -O3 tst.c &amp;amp;&amp;amp; ./a.out
2
$ clang-3.4 --std=c11 -O3 tst.c &amp;amp;&amp;amp; ./a.out
4
$ gcc-4.7 --std=c11 -O3 tst.c &amp;amp;&amp;amp; ./a.out asdf
&amp;lt;infinite loop...&amp;gt;&amp;lt;/code&amp;gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So let’s analyze these results. The loop &lt;code class=&quot;highlighter-rouge&quot;&gt;for (int i = INT_MAX - 2; i &amp;gt; 0; i++) {&lt;/code&gt;
should only iterate &lt;code class=&quot;highlighter-rouge&quot;&gt;3&lt;/code&gt; times until variable &lt;code class=&quot;highlighter-rouge&quot;&gt;i&lt;/code&gt; wraps around to
negative value due to
&lt;a href=&quot;https://en.wikipedia.org/wiki/Two%27s_complement&quot;&gt;two’s complement arithmetic&lt;/a&gt;. Therefore
we would expect &lt;code class=&quot;highlighter-rouge&quot;&gt;iterations&lt;/code&gt; variable to be &lt;code class=&quot;highlighter-rouge&quot;&gt;3&lt;/code&gt;. But this only happens
when optimizations are turned off. So let’s see why these outputs
result in these different values. Is there some clever loop unrolling
that completely breaks here or what?&lt;/p&gt;

&lt;h2 id=&quot;gcc-49--o0&quot;&gt;GCC 4.9 -O0&lt;/h2&gt;

&lt;p&gt;There is nothing really interesting going in the assembly code
produced by GCC without optimizations. It looks like what you would
expect from this kind of loop &lt;code class=&quot;highlighter-rouge&quot;&gt;for()&lt;/code&gt; on the lower level. So the main
interest is in optimizations that different compilers do.&lt;/p&gt;

&lt;h2 id=&quot;gcc-49--o3-andclang-34--o3&quot;&gt;GCC 4.9 -O3 and clang 3.4 -O3&lt;/h2&gt;

&lt;p&gt;GCC 4.9 and clang 3.4 both seem to result in similar machine
code. They both optimize the &lt;code class=&quot;highlighter-rouge&quot;&gt;for()&lt;/code&gt; loop out and replace the result of
it with a (different) constant. GCC 4.9 is just creating code that
assigns value &lt;code class=&quot;highlighter-rouge&quot;&gt;2&lt;/code&gt; to the second parameter for &lt;code class=&quot;highlighter-rouge&quot;&gt;printf()&lt;/code&gt; function
(see &lt;a href=&quot;http://www.x86-64.org/documentation/abi.pdf&quot;&gt;System V Application Binary Interface AMD64 Architecture Processor Supplement&lt;/a&gt; section
3.2.3 about parameter passing). Similarly clang 3.4 assigns value &lt;code class=&quot;highlighter-rouge&quot;&gt;4&lt;/code&gt; to
the second parameter for &lt;code class=&quot;highlighter-rouge&quot;&gt;printf()&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;gcc-49--o3-assembler-code-for-main&quot;&gt;GCC 4.9 -O3 assembler code for main()&lt;/h3&gt;

&lt;p&gt;Here we can see how value &lt;code class=&quot;highlighter-rouge&quot;&gt;2&lt;/code&gt; gets passed as &lt;code class=&quot;highlighter-rouge&quot;&gt;iterations&lt;/code&gt; variable:&lt;/p&gt;

&lt;figure&gt;&lt;pre&gt;&lt;code&gt;Dump of assembler code for function main:
5 {
0x00000000004003f0 &amp;lt;+0&amp;gt;: sub $0x8,%rsp

6     int iterations = 0;
7     for (int i = INT_MAX - 2; i &amp;gt; 0; i++) {
8         iterations++;
9     }
10     printf(&quot;%d\n&quot;, &lt;strong&gt;iterations&lt;/strong&gt;);
&lt;strong&gt;0x00000000004003f4 &amp;lt;+4&amp;gt;: mov $0x2,%esi&lt;/strong&gt;
0x00000000004003f9 &amp;lt;+9&amp;gt;: mov $0x400594,%edi
0x00000000004003fe &amp;lt;+14&amp;gt;: xor %eax,%eax
0x0000000000400400 &amp;lt;+16&amp;gt;: callq 0x4003c0 &amp;lt;printf@plt&amp;gt;

11     return 0;
12 }
0x0000000000400405 &amp;lt;+21&amp;gt;: xor %eax,%eax
0x0000000000400407 &amp;lt;+23&amp;gt;: add $0x8,%rsp
0x000000000040040b &amp;lt;+27&amp;gt;: retq
&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;clang-34--o3-assembler-code-for-main&quot;&gt;clang 3.4 -O3 assembler code for main()&lt;/h3&gt;

&lt;p&gt;Here we can see how value &lt;code class=&quot;highlighter-rouge&quot;&gt;4&lt;/code&gt; gets passed as &lt;code class=&quot;highlighter-rouge&quot;&gt;iterations&lt;/code&gt; variable:&lt;/p&gt;

&lt;figure&gt;&lt;pre&gt;&lt;code&gt;Dump of assembler code for function main:
5 {

6     int iterations = 0;
7     for (int i = INT_MAX - 2; i &amp;gt; 0; i++) {
8         iterations++;
9     }
10     printf(&quot;%d\n&quot;, &lt;strong&gt;iterations&lt;/strong&gt;);
0x00000000004004e0 &amp;lt;+0&amp;gt;: push %rax
0x00000000004004e1 &amp;lt;+1&amp;gt;: mov $0x400584,%edi
&lt;strong&gt;0x00000000004004e6 &amp;lt;+6&amp;gt;: mov $0x4,%esi&lt;/strong&gt;
0x00000000004004eb &amp;lt;+11&amp;gt;: xor %eax,%eax
0x00000000004004ed &amp;lt;+13&amp;gt;: callq 0x4003b0 &amp;lt;printf@plt&amp;gt;
0x00000000004004f2 &amp;lt;+18&amp;gt;: xor %eax,%eax

11     return 0;
0x00000000004004f4 &amp;lt;+20&amp;gt;: pop %rdx
0x00000000004004f5 &amp;lt;+21&amp;gt;: retq
&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;gcc-47--o3&quot;&gt;GCC 4.7 -O3&lt;/h2&gt;

&lt;p&gt;GCC 4.7 has an interesting result from optimizer that is completely
different that could be expected to happen. It basically replaces
&lt;code class=&quot;highlighter-rouge&quot;&gt;main()&lt;/code&gt; function with just one instruction that does nothing else than
jumps at the same address that it resides in and thus creates an
infinite loop:&lt;/p&gt;

&lt;figure&gt;&lt;pre&gt;&lt;code&gt;Dump of assembler code for function main:
5 {
0x0000000000&lt;strong&gt;400400&lt;/strong&gt; &amp;lt;+0&amp;gt;: jmp &lt;strong&gt;0x400400&lt;/strong&gt; &amp;lt;main&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This is an excellent example of
&lt;a href=&quot;http://www.catb.org/jargon/html/N/nasal-demons.html&quot;&gt;nasal demons&lt;/a&gt;
happening when there is undefined behavior ongoing and compilers have
free hands to do anything they want. Especially as GCC 4.7
produces really harmful machine code that instead of producing
unexpected value as a result, it just makes the program
unusable. Other compilers and other architectures could result in
different behavior, but let that be something for the future
investigation.&lt;/p&gt;
</description>
        <pubDate>Sun, 21 Feb 2016 18:00:04 +0200</pubDate>
        <link>https://barro.github.io/2016/02/c-for-and-signed-integer-overflow/</link>
        <guid isPermaLink="true">https://barro.github.io/2016/02/c-for-and-signed-integer-overflow/</guid>
        
        <category>c/c++</category>
        
        <category>undefined-behavior</category>
        
        
      </item>
    
      <item>
        <title>Shell script patterns for bash</title>
        <description>&lt;p&gt;I write a lot of shell scripts using bash to glue together existing
programs and their data. I have noticed that some patterns have
emerged that I very often use when writing these scripts nowadays. Let
the following script to demonstrate:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Exit if undefined variable is used.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Exit after first command failure.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; pipefail  &lt;span class=&quot;c&quot;&gt;# Exit if any part of the pipe fails.&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;ITERATIONS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Notice that there are no quotes here.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;shift
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMMAND&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Create arrays from commands.&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;dirname &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;readlink &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Get the script directory.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Running &#39;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMMAND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[*]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&#39; in &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; for &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ITERATIONS&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; iterations&quot;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;mktemp &lt;span class=&quot;nt&quot;&gt;--directory&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;cleanup&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    rm &lt;span class=&quot;nt&quot;&gt;-rf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$WORKDIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;trap &lt;/span&gt;cleanup EXIT  &lt;span class=&quot;c&quot;&gt;# Make sure that we clean up in any situation.&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;_ &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;seq 1 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ITERATIONS&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;  &lt;span class=&quot;c&quot;&gt;# Avoid the effect of &quot;cd&quot; command from propagating.&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$WORKDIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;COMMAND&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Execute command from an array.&lt;/span&gt;
            | &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;fail-fast-in-case-of-errors&quot;&gt;Fail fast in case of errors&lt;/h2&gt;

&lt;p&gt;Lines &lt;code class=&quot;highlighter-rouge&quot;&gt;3&lt;/code&gt;–&lt;code class=&quot;highlighter-rouge&quot;&gt;5&lt;/code&gt; are related to handling erroneous situations. If
any of the situations happen that these settings have effect on, they
will exit the shell script and prevent it running further. They can be
combined to &lt;code class=&quot;highlighter-rouge&quot;&gt;set -ueo pipefail&lt;/code&gt; as a shorthand notation.&lt;/p&gt;

&lt;p&gt;A very common mistake is to have an undefined variable, by just
forgetting to set the value, or mistyping a variable name. &lt;code class=&quot;highlighter-rouge&quot;&gt;set -u&lt;/code&gt; at
line &lt;code class=&quot;highlighter-rouge&quot;&gt;3&lt;/code&gt;prevents these kind of issues from happening. Other very
common situation in shell scripts is that some program is used
incorrectly, it fails, and then rest of the shell script just
continues execution. This then causes hard to notice failures later
on. &lt;code class=&quot;highlighter-rouge&quot;&gt;set -e&lt;/code&gt; at line &lt;code class=&quot;highlighter-rouge&quot;&gt;4&lt;/code&gt; prevents these issues from happening. And
because life is not easy in bash, we need to ensure that such program
execution failures that are part of pipelines are also caught. This is
done by &lt;code class=&quot;highlighter-rouge&quot;&gt;set -o pipefail&lt;/code&gt; on line &lt;code class=&quot;highlighter-rouge&quot;&gt;5&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;clean-up-after-yourself-even-in-unexpected-situations&quot;&gt;Clean up after yourself even in unexpected situations&lt;/h2&gt;

&lt;p&gt;It’s always a good idea to use unique temporary files or directories
for anything that can be created during runtime that is not a specific
target of the script. This makes sure that even if many instances of
the script are executed in parallel, there won’t be any race condition
issues.  &lt;code class=&quot;highlighter-rouge&quot;&gt;mktemp&lt;/code&gt; command on line &lt;code class=&quot;highlighter-rouge&quot;&gt;14&lt;/code&gt; shows how to create such
temporary files.&lt;/p&gt;

&lt;p&gt;Creating temporary files and directories poses a problem where they
may not be deleted if the script is exited too early or if you forget
to do a manual cleanup. &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup()&lt;/code&gt; function shown at lines
&lt;code class=&quot;highlighter-rouge&quot;&gt;15&lt;/code&gt;–&lt;code class=&quot;highlighter-rouge&quot;&gt;18&lt;/code&gt; includes code that makes sure that the script cleans
up after itself and &lt;code class=&quot;highlighter-rouge&quot;&gt;trap cleanup EXIT&lt;/code&gt; makes sure that &lt;code class=&quot;highlighter-rouge&quot;&gt;cleanup()&lt;/code&gt; is
implicitly called in any situation where this script may exit.&lt;/p&gt;

&lt;h2 id=&quot;executing-commands&quot;&gt;Executing commands&lt;/h2&gt;

&lt;p&gt;Something that is often seen in shell scripts that when you need to
create a variable that has a command with arguments, you then execute
the variable as it is (&lt;code class=&quot;highlighter-rouge&quot;&gt;$COMMAND&lt;/code&gt;) without using any safety mechanisms
against &lt;a href=&quot;http://www.golemtechnologies.com/articles/shell-injection&quot;&gt;input that can lead into unexpected results in the shell
script&lt;/a&gt;. Lines
&lt;code class=&quot;highlighter-rouge&quot;&gt;9&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;COMMAND=(&quot;$@&quot;)&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;24&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;${COMMAND[@]}&quot;&lt;/code&gt; show a way to assign a
command into an array and run such array as command and its
parameters. Line &lt;code class=&quot;highlighter-rouge&quot;&gt;25&lt;/code&gt; then includes a pipe just to demonstrate that
&lt;code class=&quot;highlighter-rouge&quot;&gt;set -o pipefail&lt;/code&gt; works if you pass a command that fails.&lt;/p&gt;

&lt;h2 id=&quot;script-directory-reference&quot;&gt;Script directory reference&lt;/h2&gt;

&lt;p&gt;Sometimes it’s very useful to access other files in the
same directory where the executed shell script resides in. Line &lt;code class=&quot;highlighter-rouge&quot;&gt;11&lt;/code&gt;
&lt;code class=&quot;highlighter-rouge&quot;&gt;DIR=$(dirname &quot;$(readlink -f &quot;$0&quot;)&quot;)&lt;/code&gt; basically gives the absolute
path to the current shell script directory. The order of &lt;code class=&quot;highlighter-rouge&quot;&gt;readlink&lt;/code&gt;
and &lt;code class=&quot;highlighter-rouge&quot;&gt;dirname&lt;/code&gt; commands can be changed depending if you want to access
the directory where the command to execute this script points to or
where the script actually resides in. These can be different locations
if there is a symbolic link to the script. The order shown above
points to the directory where the script is physically located at.&lt;/p&gt;

&lt;h2 id=&quot;quotes-are-not-always-needed&quot;&gt;Quotes are not always needed&lt;/h2&gt;

&lt;p&gt;Normally in bash if you reference variables without enclosing them
into quotes, you risk of shell injection attacks. But when assigning
variables in bash, you don’t need to have quotes in the assignment as
long as you don’t use spaces. The same applies to
&lt;a href=&quot;https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html&quot;&gt;command substitution&lt;/a&gt;
(&lt;a href=&quot;https://google.github.io/styleguide/shell.xml?showone=Use_Local_Variables#Use_Local_Variables&quot;&gt;some caveats with variable declarations apply&lt;/a&gt;). This style
is demonstrated on lines &lt;code class=&quot;highlighter-rouge&quot;&gt;7&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;ITERATIONS=$1&lt;/code&gt;and &lt;code class=&quot;highlighter-rouge&quot;&gt;11&lt;/code&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;DIR=$(...)&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;shellcheck-your-scripts&quot;&gt;Shellcheck your scripts&lt;/h2&gt;

&lt;p&gt;One cool program that will make you a better shell script writer is
&lt;a href=&quot;http://www.shellcheck.net/&quot;&gt;ShellCheck&lt;/a&gt;. It basically has a list of
issues in shell scripts that it detects and can notify you whenever it
notices issues that should be fixed. If you are writing shell scripts
as part of some version controlled project, you should add an
automatic ShellCheck verification step for all shell scripts that you
put into your repository.&lt;/p&gt;
</description>
        <pubDate>Sun, 14 Feb 2016 18:00:03 +0200</pubDate>
        <link>https://barro.github.io/2016/02/shell-script-patterns-for-bash/</link>
        <guid isPermaLink="true">https://barro.github.io/2016/02/shell-script-patterns-for-bash/</guid>
        
        <category>bash</category>
        
        <category>shell-scripts</category>
        
        
      </item>
    
      <item>
        <title>A succesful Git branching model considered harmful</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;Update 2018-07. The branching model described here is called trunk
based development. I and other people who I collaborated with did
not know about the articles that used this name. Nowadays there are
excellent web resources about the subject, like &lt;a href=&quot;https://trunkbaseddevelopment.com/&quot;&gt;trunkbaseddevelopment.com&lt;/a&gt;.
They have a lot of material about this and other key subjects
revolving around the area of efficient software development.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When people start to use &lt;a href=&quot;https://git-scm.com/&quot;&gt;git&lt;/a&gt; and get
introduced to branches and to the ease of branching, they may do
couple of Google searches and very often end up on a blog post about
&lt;a href=&quot;http://nvie.com/posts/a-successful-git-branching-model/&quot;&gt;A successful Git branching model&lt;/a&gt;. The
biggest issue with this article is that it comes up as one of the
first ones in many git branching related searches when it should serve
as a warning how not to use branches in software development.&lt;/p&gt;

&lt;h2 id=&quot;what-is-wrong-with-a-successful-git-branching-model&quot;&gt;What is wrong with “A successful Git branching model”?&lt;/h2&gt;

&lt;p&gt;To put it bluntly, this type of development approach where you use
shared remote branches for everything and merge them back as they are
is much more complicated than it should be. The basic principle in
making usable systems is to have sane defaults. This branching model
makes that mistake from the very beginning by not using the &lt;code class=&quot;highlighter-rouge&quot;&gt;master&lt;/code&gt;
branch for something that a developer who clones the repository would
expect it to be used, development.&lt;/p&gt;

&lt;p&gt;Using individual (long lived) branches for features also make it
harder to ensure that everything works together when changes are
merged back together. This is especially pronounced in today’s world
where
&lt;a href=&quot;http://www.martinfowler.com/articles/continuousIntegration.html&quot;&gt;continuous integration&lt;/a&gt;
should be the default practice of software development regardless how
big the project is. By integrating all changes together regularly
you’ll avoid big integration issues that waste a lot of time to
resolve, especially for bigger projects with hundreds or thousands of
developers. This type of development practice where every feature is
developed in its own shared remote branch drives the process naturally
towards big integration issues instead of avoiding them.&lt;/p&gt;

&lt;p&gt;Also in “A successful Git branching model” merge commits are
encouraged as the main method for integrating changes. I will explain
next why merge commits are bad and what you will lose by using them.&lt;/p&gt;

&lt;h3 id=&quot;what-is-wrong-with-merge-commits&quot;&gt;What is wrong with merge commits?&lt;/h3&gt;

&lt;p&gt;“A successful Git branching model” talks how non-fast-forward merge
commits can be thought as a way to keep all commits related to a
certain feature nicely in one group. Then if you decide that a feature
is not for you, you can just revert that one commit and have the whole
feature removed. I would argue that this is a really rare situation
that you revert a feature or that you even get it done completely
right on the first try.&lt;/p&gt;

&lt;p&gt;Merges in git very often create additional commits that begin with the
message that looks like following: “&lt;code class=&quot;highlighter-rouge&quot;&gt;Merge branch &#39;some-branch&#39; of
git://git.some.domain/repository/&lt;/code&gt;”. That does not
provide any value when you want to see what has actually changed. You
need go to the commit message and read what happens there, probably in
the second paragraph. Not to mention going back in history to the
branch and trying to see what happens in that branch.&lt;/p&gt;

&lt;p&gt;Having non-linear history also makes
&lt;a href=&quot;https://git-scm.com/docs/git-bisect&quot;&gt;git bisect&lt;/a&gt; harder to do when
issues are only revealed during integration. You may have both of the
branches good individually but then the merge commit fails because
your changes don’t conflict. This is not even that hard to encounter
when one developer changes some internal interface and other developer
builds something new based on the old interface definition. These kind
of can be easy or hard to figure out, but having the history linear
without any merge commits could immediately point out the commit that
causes issues.&lt;/p&gt;

&lt;h2 id=&quot;something-more-simple&quot;&gt;Something more simple&lt;/h2&gt;

&lt;figure class=&quot;pull-right text-center&quot; id=&quot;figure-cactus-model&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model.pdf&quot;&gt;
&lt;img src=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model-100.png&quot; alt=&quot;The cactus model&quot; width=&quot;190px&quot; height=&quot;538px&quot; title=&quot;The cactus model&quot; class=&quot;figure-image&quot; srcset=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model-100.png 1.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model-125.png 1.25x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model-150.png 1.5x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model-200.png 2.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model-300.png 3.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/cactus-model-400.png 4.0x&quot; /&gt;
&lt;/a&gt;
&lt;figcaption&gt;Figure 1: The cactus model&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Let me show a much more simple alternative, that we can call the
cactus model. It gets the name from the fact that all branches branch
out from a wide trunk (&lt;code class=&quot;highlighter-rouge&quot;&gt;master&lt;/code&gt; branch) and never get merged
back. Cactus model should reflect much better the way that comes up
naturally when working with git and making sure that continuous
integration principles are used.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&quot;#figure-cactus-model&quot;&gt;figure 1&lt;/a&gt; you can see the principle how the
cactus branching model works and following sections explain the
reasoning behind it. Some principles shown here may need
&lt;a href=&quot;https://www.gerritcodereview.com&quot;&gt;Gerrit&lt;/a&gt; or similar integrated code
review and repository management system to be fully usable.&lt;/p&gt;

&lt;h3 id=&quot;all-development-happens-on-the-master-branch&quot;&gt;All development happens on the master branch&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;master&lt;/code&gt; branch is the default that is checked out after &lt;code class=&quot;highlighter-rouge&quot;&gt;git
clone&lt;/code&gt;. So why not also have all development also happen there? No
need to guess or needlessly document the development branch when it is
the default one. This only applies to the central repository that is
cloned and kept up to date by everyone. Individual developers are
encouraged to use local branches for development but avoid shared
remote branches.&lt;/p&gt;

&lt;p&gt;Developers should &lt;code class=&quot;highlighter-rouge&quot;&gt;git rebase&lt;/code&gt; their changes regularly so that their
local branches would follow the latest &lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt;. This is to
make sure that we do not develop on an outdated baseline.&lt;/p&gt;

&lt;h4 id=&quot;using-local-branches&quot;&gt;Using local branches&lt;/h4&gt;

&lt;p&gt;Cactus model does not to discourage using branches when they are
useful. Especially an individual developer should use short lived
feature branches in their local repository and integrate them with the
&lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; whenever there is something that can be shared with
everyone else. Local branches are just to make it more easy to move
between features while commits are tested or under code review.&lt;/p&gt;

&lt;p&gt;Figures &lt;a href=&quot;#figure-rebase-1&quot;&gt;2&lt;/a&gt; and &lt;a href=&quot;#figure-rebase-2&quot;&gt;3&lt;/a&gt; show the basic
principle of local branches and rebases by visualizing a tree
state. In &lt;a href=&quot;#figure-rebase-1&quot;&gt;figure 2&lt;/a&gt; we have a situation with two
active local development branches (fuchsia circles) and one branch
that is under code review (blue circles) and ready to be integrated to
&lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; (yellow circles). In
&lt;a href=&quot;#figure-rebase-2&quot;&gt;figure 3&lt;/a&gt; we have updated the &lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; with
two new commits (yellow-blue circles) and submitted two commits for
code review (blue circle) and consider them to be ready for
integration. As branches don’t automatically disappear from the
repository, the integrated commits are still in the local repository
(gray circles), but hopefully forgotten and ready to be
&lt;a href=&quot;https://git-scm.com/docs/git-gc&quot;&gt;garbage collected&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;text-center&quot;&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;figure-rebase-1&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1.pdf&quot;&gt;
&lt;img src=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1-100.png&quot; alt=&quot;Local cactus branches&quot; width=&quot;265&quot; height=&quot;190&quot; title=&quot;Local cactus branches&quot; class=&quot;figure-image&quot; srcset=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1-100.png 1.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1-125.png 1.25x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1-150.png 1.5x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1-200.png 2.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1-300.png 3.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-1-400.png 4.0x&quot; /&gt;
&lt;/a&gt;
&lt;figcaption&gt;Figure 2: Local development branches&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;inline-figure&quot; id=&quot;figure-rebase-2&quot;&gt;
&lt;a href=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2.pdf&quot;&gt;
&lt;img src=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2-100.png&quot; alt=&quot;Local cactus after integration and rebase&quot; width=&quot;328&quot; height=&quot;190&quot; class=&quot;figure-image&quot; title=&quot;Local cactus after integration and rebase&quot; srcset=&quot;https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2-100.png 1.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2-125.png 1.25x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2-150.png 1.5x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2-200.png 2.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2-300.png 3.0x, https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/rebase-2-400.png 4.0x&quot; /&gt;
&lt;/a&gt;
&lt;figcaption&gt;Figure 3: Local branches after integration and rebase&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;

&lt;h4 id=&quot;shared-remote-branches&quot;&gt;Shared remote branches&lt;/h4&gt;

&lt;p&gt;As a main principle, shared remote branches should be avoided. All
changes should be made available on &lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; and other
developers should build their changes on top of that by continuously
updating their working copies. This ensures that we do not end up in
&lt;a href=&quot;http://c2.com/xp/IntegrationHell.html&quot;&gt;integration hell&lt;/a&gt; that will
happen when many feature branches need to be combined at once.&lt;/p&gt;

&lt;p&gt;If you use staged code review system, like Gerrit or github, then you
can just &lt;code class=&quot;highlighter-rouge&quot;&gt;git fetch&lt;/code&gt; the commit chain and build on top of that. Then
&lt;code class=&quot;highlighter-rouge&quot;&gt;git push&lt;/code&gt; your changes to your own repository to some specific
branch, that you have hopefully rebased on top of the &lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt;
before pushing.&lt;/p&gt;

&lt;h3 id=&quot;releases-are-branched-out-from-originmaster&quot;&gt;Releases are branched out from origin/master&lt;/h3&gt;

&lt;p&gt;Releases get their own tags or branches that are branched out from
&lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt;. In case we need a hotfix, just add that to the
release branch and cherry-pick it to the master branch, if
applicable. By using some specific tagging and branching naming scheme
should enable for automatic releases but this should be completely
invisible to developers in their daily work.&lt;/p&gt;

&lt;h3 id=&quot;there-are-only-fast-forward-merges&quot;&gt;There are only fast-forward merges&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;git merge&lt;/code&gt; is not used. Changes go to &lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; by using &lt;code class=&quot;highlighter-rouge&quot;&gt;git
rebase&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;git cherry-pick&lt;/code&gt;. This avoids cluttering the repository
with merge commits that do not really provide any real value and
avoids
&lt;a href=&quot;http://stackoverflow.com/questions/14023648/why-does-my-git-history-look-like-a-christmas-tree&quot;&gt;christmas tree look&lt;/a&gt;
on the repository. Rebasing also makes the history linear, so that
&lt;code class=&quot;highlighter-rouge&quot;&gt;git bisect&lt;/code&gt; is really easy to use for finding regressions.&lt;/p&gt;

&lt;p&gt;If you are using Gerrit, you can also use cherry-pick submit
strategy. This simply enables putting a collection of commits to
&lt;code class=&quot;highlighter-rouge&quot;&gt;origin/master&lt;/code&gt; at any desired order instead of having to settle for
the order decided when commits were first put for a code review.&lt;/p&gt;

&lt;h2 id=&quot;concluding-remarks&quot;&gt;Concluding remarks&lt;/h2&gt;

&lt;p&gt;Git is really cool as a version control system. You can do all kinds
of nifty stuff with it really easily that was hard or impossible to
do. Branches are just
&lt;a href=&quot;https://git-scm.com/book/en/v1/Git-Internals-Git-References&quot;&gt;pointers to certain commits&lt;/a&gt;
and that way you can create a branch really cheaply from
anything. Also you can do all kinds of
&lt;a href=&quot;https://git-scm.com/docs/git-merge#_merge_strategies&quot;&gt;fancy merges&lt;/a&gt;
and this makes using and mixing branches very easy. But as with all
tools, branches should be used appropriately to make it more easy for
developers to their daily development tasks, not harder by default.&lt;/p&gt;

&lt;p&gt;I have also seen these kind of scary development practices to be used
in projects with hundreds of developers when moving to git from some
other version control systems. Some organizations even take this as
far as they fully remove the &lt;code class=&quot;highlighter-rouge&quot;&gt;master&lt;/code&gt; branch from the central repository
and create all kinds of questions and obstacles by not having a sane
default that is expected by anyone who has used git anywhere else.&lt;/p&gt;
</description>
        <pubDate>Sun, 07 Feb 2016 18:00:01 +0200</pubDate>
        <link>https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/</link>
        <guid isPermaLink="true">https://barro.github.io/2016/02/a-succesful-git-branching-model-considered-harmful/</guid>
        
        <category>git</category>
        
        <category>version-control</category>
        
        
      </item>
    
      <item>
        <title>Starting a software development blog</title>
        <description>&lt;p&gt;Isn’t it a nice way to start a software development related blog by
talking about how to start a software development related blog? Or at
least it goes one up in the meta blogging level where there is an
article about what needs taken care of when creating a software
development related blog that starts with how meta this is.&lt;/p&gt;

&lt;h2 id=&quot;arent-there-tons-of-articles-regarding-this-already&quot;&gt;Aren’t there tons of articles regarding this already?&lt;/h2&gt;

&lt;p&gt;There are tons of articles about how to establish a blog. Some of them
are very good at giving generic advice on topics and blogging
platform selection, and you should use your favorite search engine to
search for those. I’m just going to explain my reasoning for choices I
have made when establishing this blog with my current understanding
and background research.&lt;/p&gt;

&lt;h2 id=&quot;why-blog-at-all&quot;&gt;Why blog at all?&lt;/h2&gt;

&lt;p&gt;Why should I blog at all? Blogging takes time and effort and I will
probably lose interest in it after some weeks/months/years. The
biggest reason for me to start blogging is that I find myself very
often explaining things through email discussions, wikis, or chats,
sometimes the same things multiple times. Also sometimes I just do
benchmarks and other types of digging and comparison, and I would
like to have a place to present these findings where I can easily link
to.&lt;/p&gt;

&lt;p&gt;What I’m not after here is being a part of some specific blogging
community. The second thing that I try to avoid is discussing topics
that are not software development related, or just share some links
with a very short comment on them. Those things I leave for Facebook
and Internet relay chat type of communication platforms.&lt;/p&gt;

&lt;h3 id=&quot;coming-up-with-ideas&quot;&gt;Coming up with ideas&lt;/h3&gt;

&lt;p&gt;I have collected ideas and drafts that I could write about for almost
a year now. And there are over a dozen different smaller or larger
article ideas in my backlog. So at least in the beginning I have some
material available. The biggest question is that do I find this
interesting enough to continue doing and how often do I come up with
new ideas that I could blog about.&lt;/p&gt;

&lt;h2 id=&quot;deciding-the-language-i-write-articles-in&quot;&gt;Deciding the language I write articles in&lt;/h2&gt;

&lt;p&gt;I have decided to write my blog in English. It’s not my first, or even
my second language, so why write a blog in English? The reason
for this is that software development topics come up naturally for me
in English. Also people who may be interested in these topics
basically have to know English to have any competence in this
industry and I’m not aiming at complete beginners.&lt;/p&gt;

&lt;h2 id=&quot;selecting-a-blogging-platform&quot;&gt;Selecting a blogging platform&lt;/h2&gt;

&lt;p&gt;I had a couple of requirements for a blogging platform that it should
satisfy so it would fit my needs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Hosted by a third party. I have hosted my own web
server and it requires somewhat constant maintenance and I want to
avoid that. Especially I don’t want to have constant
&lt;a href=&quot;https://premium.wpmudev.org/blog/wordpress-security-exploits/&quot;&gt;security issues&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;To be able to write articles locally on my computer and then
easily export the result to the blog. Also as articles generally
take quite a few trials and errors, they should be easy to modify.&lt;/li&gt;
  &lt;li&gt;Support source code listings and syntax coloring.&lt;/li&gt;
  &lt;li&gt;Be able to upload files of any type to the platform and link to
them. I know that I would like to produce source code, so why not
give out larger programs directly as files without having to list
all the source code in the article?
    &lt;ul&gt;
      &lt;li&gt;These files should be easy to modify as, as mentioned before,
articles take some iterations to be complete.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First I was thinking about using
&lt;a href=&quot;https://www.blogger.com/&quot;&gt;Blogger&lt;/a&gt; as my blogging platform, as quite
a few blogs that I follow use it as their platform. But I wasn’t
convinced that the transfer of files from local machine to Blogger
service would be the most convenient, especially with images and other
types of files. Then I remembered that some people have pages on
&lt;a href=&quot;https://pages.github.com/&quot;&gt;GitHub&lt;/a&gt; and stumbled upon
&lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; that creates static files and is aimed
specifically for this kind of content creation. So that’s what I
decided to use for now.&lt;/p&gt;

&lt;p&gt;Jekyll does require some work to be set up and probably to maintain,
but at least it frees me to do the content in any way I like to. Many
of the things that I also need to currently do manually would probably
have been taken care of by some plugins on third party blogging
services. But that’s the price of doing this in a more customizable
way.&lt;/p&gt;

&lt;h2 id=&quot;coming-up-with-some-basic-information&quot;&gt;Coming up with some basic information&lt;/h2&gt;

&lt;p&gt;Should I add a personal biography to the blog, or should people who
have not met me know me just by the name and the content that I
write? I have decided to write a little bit about myself that would
hopefully shed a light on who I am. But I have decided not to use
&lt;a href=&quot;https://barro.github.io/author/&quot;&gt;the author page&lt;/a&gt; as my curriculum
vitae, as it would get too long and boring.&lt;/p&gt;

&lt;h2 id=&quot;deciding-how-this-blog-should-look-and-feel&quot;&gt;Deciding how this blog should look and feel&lt;/h2&gt;

&lt;p&gt;As a general rule when making personal web pages, I try to make them
load fast and avoid images. And with this blog, I just took the
default Jekyll theme and started customizing it in certain aspects
where I want to have more information visible. As new devices with
different resolutions come into market and browsers get updated, I may
need to update this to something that better supports the reactive
nature of the website that I hope to have.&lt;/p&gt;

&lt;p&gt;One interesting direction where web development is going into
regarding the pages optimized for mobile devices is to have
&lt;a href=&quot;https://www.ampproject.org/&quot;&gt;accelerated mobile pages&lt;/a&gt; of the
content. Currently I have decided to write as much content as
possible in &lt;a href=&quot;https://daringfireball.net/projects/markdown/&quot;&gt;Markdown&lt;/a&gt;
that is processed by &lt;a href=&quot;http://kramdown.gettalong.org/&quot;&gt;kramdown&lt;/a&gt;
Markdown processor. It doesn’t natively support accelerated mobile
pages yet, so I have opted out from using accelerated mobile pages for
now. In the future it would be really nice to have lazy image loading
and support for
&lt;a href=&quot;https://css-tricks.com/responsive-images-youre-just-changing-resolutions-use-srcset/&quot;&gt;responsive images&lt;/a&gt;
with different sizes and device support.&lt;/p&gt;

&lt;h3 id=&quot;favicon&quot;&gt;Favicon&lt;/h3&gt;

&lt;p&gt;Favicon is a small image that should make a site stand out from
rest when you have multiple tabs open in a browser, bookmarks, and
when creating icons of websites/applications to a device or operating
system. I had made a favicon for my web site ages ago. I still have
the original high resolution version, so now I decided to see what
kind of different formats and sizes there are for these
icons. Fortunately I didn’t have to look too much, as I found a
website called
&lt;a href=&quot;http://realfavicongenerator.net/&quot;&gt;Real Favicon Generator.net&lt;/a&gt;
that would take care of converting this icon to different formats for
me.&lt;/p&gt;

&lt;p&gt;I was a little blown away by how many different targets there are for
these kinds of icons. The generated file collection included 27
different images and 2 metadata files in addition to code to add to a
website header. A current list of them looks like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Favicon&quot;&gt;Favicon&lt;/a&gt; for website in
different sizes and formats.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/pinnedTabs/pinnedTabs.html&quot;&gt;Safari’s pinned tabs&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Windows 8 and Windows 10
&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/dn455106(v=vs.85).aspx&quot;&gt;pinned website tiles&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://support.mozilla.org/en-US/kb/how-add-shortcut-website-android&quot;&gt;Android home screen icon&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html&quot;&gt;iOS home screen icon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a couple of years we probably have new systems and resolutions to
support. So I need to regenerate these favicons again to support those
new systems.&lt;/p&gt;

&lt;h3 id=&quot;responsive-images&quot;&gt;Responsive images&lt;/h3&gt;

&lt;p&gt;Some images that I produce are originally made with
&lt;a href=&quot;https://inkscape.org/&quot;&gt;Inkscape&lt;/a&gt; in vector graphics
format. Unfortunately the browser support for vector graphics formats
is appalling, the next best option is to use
&lt;a href=&quot;https://responsiveimages.org/&quot;&gt;responsive images&lt;/a&gt; that provide
different resolution versions of the image based on the display device
capabilities. Every vector graphic image has 6 versions (100%, 125%,
150%, 200%, 300%, 400%, and PDF) of it generated, which can then be
used in
&lt;a href=&quot;https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-srcset&quot;&gt;srcset&lt;/a&gt;
image attribute which enables devices with higher density screens to
get more crisp images. Higher density images are also used in modern
browsers when the page is zoomed. PDF versions are just used in
clickable links, as PDF files as images don’t really have that good of
a browser support yet.&lt;/p&gt;

&lt;h2 id=&quot;optimize-everything&quot;&gt;Optimize everything!&lt;/h2&gt;

&lt;p&gt;When writing content or doing anything with the layout, I naturally
want to have them as easy to edit as possible. That also means that if
I don’t minify HTML, CSS, images and other often rendered resources on
the page, I will lose on page load time. I would like the Jekyll
plugins to optimize everything that is produced, but unfortunately
only &lt;a href=&quot;http://jekyllrb.com/docs/assets/&quot;&gt;Sass/SCSS assets&lt;/a&gt; provide
easy minifying options. So page HTML is not minified, even though in
the front page’s case it could reduce its size by some percents.&lt;/p&gt;

&lt;p&gt;Every PNG image on this blog is optimized by using
&lt;a href=&quot;https://github.com/google/zopfli&quot;&gt;ZopfliPNG&lt;/a&gt;. It produces around 10%
smaller images than &lt;a href=&quot;http://optipng.sourceforge.net/&quot;&gt;OptiPNG&lt;/a&gt;, that is
the standard open source PNG optimizer. ZopfliPNG takes its time,
especially on larger images, but as the optimization only needs to be
done just before publishing, it’s worth doing, as it can easily save
10–50% in image size. Also if PNG images are not meant to be as
high quality representations as possible of something, they have their
color space reduced by &lt;a href=&quot;https://pngquant.org/&quot;&gt;pngquant&lt;/a&gt; if the
color space reduction does not result in a significant quality
deterioration. This can result in savings excess of 50% while still
keeping the image format appropriate for line drawings and other high
frequency image data.&lt;/p&gt;

&lt;p&gt;Every article has its own
&lt;a href=&quot;https://en.wikipedia.org/wiki/Identicon&quot;&gt;identicon&lt;/a&gt; and that would
result in an extra request if I were to add its as a simple
image. Instead I embed it to the page source by using
&lt;a href=&quot;https://en.wikipedia.org/wiki/Base64&quot;&gt;base64 encoded&lt;/a&gt;
&lt;a href=&quot;https://en.wikipedia.org/wiki/Data_URI_scheme&quot;&gt;data URI scheme&lt;/a&gt; for
the around 200 bytes that these page identifier images result in. I
could shave off some bytes by selecting between image formats that
take the least space to encode the same information. I don’t think
that I need to go that far, as I usually have far more text on a page
than what images usually take.&lt;/p&gt;

&lt;p&gt;Another place that I can optimize is to move all the content that is
not required for initial page rendering at the end of the page. This
it also possible to load some content asynchronously after the page
has initially loaded itself. This mostly means that I have moved all
Javascript this page has to the end of the page. Also
&lt;a href=&quot;https://developers.google.com/speed/pagespeed/insights/&quot;&gt;Google’s PageSpeed Insights&lt;/a&gt;
gives good hints on what else to optimize and one place to optimize is
to either inline or load CSS asynchronously. Unfortunately Jekyll has not
made it easy to include the generated CSS file as a part of the
document so instead of fighting it, I have opted to have it as a
separate file. The second option to load that CSS file asynchronously
unfortunately creates an annoying effect when the page is loaded and
then the style sheets are applied due to
&lt;a href=&quot;https://en.wikipedia.org/wiki/Hamburger_button&quot;&gt;the hamburger button&lt;/a&gt;,
so I left the main style sheet to be synchronously loaded in the
header.&lt;/p&gt;

&lt;p&gt;One place to still optimize would be the style sheets that these pages
have, but as this layout should be lightweight enough already, I hope
that I can survive without having to optimize the things that affect
layout rendering.&lt;/p&gt;

&lt;p&gt;The front page of this blog has 5 articles with full content
visible. I have opted for that option simply because I have noticed
that I like reading blogs where I don’t need to open any pages to get
to the content. Having less articles per page would make the front
page load faster and more articles would help in avoiding page
switches, so I hope that this is a decent compromise.&lt;/p&gt;

&lt;p&gt;All size optimizations are, in the end, pretty much overwhelmed by
just adding &lt;a href=&quot;https://disqus.com/&quot;&gt;Disqus&lt;/a&gt; as a commenting platform, as
it loads much more data than an average article and also includes
dozens of different files that a browser needs to fetch.&lt;/p&gt;

&lt;h2 id=&quot;two-way-communication&quot;&gt;Two-way communication&lt;/h2&gt;

&lt;p&gt;One of the powerful features of any blogging platform is that they
enable context related two-way communication between the author and
the readers. This means that some blogs have comments. As I’m using static
pages, the easiest solution is just to leave the commenting options
out. But I decided to opt in for &lt;a href=&quot;https://disqus.com/&quot;&gt;Disqus&lt;/a&gt; as a
commenting system for now, especially because there is
&lt;a href=&quot;http://www.perfectlyrandom.org/2014/06/29/adding-disqus-to-your-jekyll-powered-github-pages/&quot;&gt;a nice post explaining what you need to do with Jekyll to use Disqus on GitHub pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Disqus has its haters and issues, but I think that it’s the best bet
for now. If I spend most of my time deleting spammy comments, I will
then probably just abandon commenting features altogether and let
people comment on Twitter or by using some other means, if they feel
that’s necessary and are interested enough.&lt;/p&gt;

&lt;h2 id=&quot;linking-to-myself&quot;&gt;Linking to myself&lt;/h2&gt;

&lt;p&gt;As I have some presence on multiple social media sites and some
personal project resources, I have decided to include the most current
ones in the footer of the page.&lt;/p&gt;

&lt;h2 id=&quot;is-there-actually-anyone-who-reads-my-blog&quot;&gt;Is there actually anyone who reads my blog?&lt;/h2&gt;

&lt;p&gt;As I have opted to use a third party web hosting service with this, I
don’t have access to their logs and therefore can’t really know how
many page loads I get. So I take the second option and use full blown
&lt;a href=&quot;http://www.google.com/analytics/&quot;&gt;Google Analytics&lt;/a&gt; service for this
blog. It also provides much better data analysis features than any of
the web service log analyzers that I have used, so at least by using it I
should have some kind of an idea how many people actually visit this blog.&lt;/p&gt;

&lt;p&gt;Also using &lt;a href=&quot;https://www.feedburner.com/&quot;&gt;FeedBurner&lt;/a&gt; should provide me
statistics on how many people have subscribed to my blog.&lt;/p&gt;

&lt;h2 id=&quot;article-feeds&quot;&gt;Article feeds&lt;/h2&gt;

&lt;p&gt;For me article feeds have two purposes: to provide the subscribers of
this blog an easy access to new articles and for me some kind of an
idea how many people are regularly reading this blog. Displaying the
full article content in the feed is the approach that I like when
reading my feed subscriptions, as I can read the whole article in the
feed reader. I decided to use a third party feed service,
&lt;a href=&quot;https://www.feedburner.com/&quot;&gt;FeedBurner&lt;/a&gt; to get feed subscriber
statistics. FeedBurner also provides services I can use to further
modify my feed, like making it more compatible with different devices
and feed readers.&lt;/p&gt;

&lt;h2 id=&quot;adding-a-search&quot;&gt;Adding a search&lt;/h2&gt;

&lt;p&gt;One thing with a website with a lot of content is that it should be
possible to find the content. One way is to add a search to the
website, but it’s not that easy to do if the website is a collection
of static pages. I have now decided to opt out of adding a separate
search widget and hope that
&lt;a href=&quot;https://barro.github.io/archive/&quot;&gt;the article list&lt;/a&gt; is enough. If there are
any specific articles which interest people, web search engines would
bring those up.&lt;/p&gt;

&lt;h2 id=&quot;link-all-the-social-media&quot;&gt;Link all the social media!&lt;/h2&gt;

&lt;p&gt;Adding share buttons for social media services seems like a no-brainer
today. I was already exploring &lt;a href=&quot;https://www.addtoany.com/&quot;&gt;AddToAny&lt;/a&gt;
service to add such buttons to my site, but then I decided to do a
little bit of background research and think about the effects of such
buttons.&lt;/p&gt;

&lt;p&gt;A quick search returns articles that suggest avoiding social media
share buttons
(&lt;a href=&quot;http://solomon.io/why-im-done-with-social-media-buttons/&quot;&gt;1&lt;/a&gt;,
&lt;a href=&quot;http://exisweb.net/truth-about-share-buttons&quot;&gt;2&lt;/a&gt;,
&lt;a href=&quot;http://scottwhyoung.com/social-media/measuring-value-of-social-media-buttons/&quot;&gt;3&lt;/a&gt;)
and question their actual value for the website. I checked that
AddToAny creates 3 extra requests on a page load. Although such
requests are probably cached in the desktop browser, mobile browsers
don’t necessarily have such luck with caching and they will then
suffer quite a large extra delay while loading those resources.&lt;/p&gt;

&lt;p&gt;Also the share buttons would needlessly clutter my otherwise minimalistic
layout, even if I’m not a graphically talented designer to give a
professional opinion about this. And also I have had horrible
experiences browsing web on a phone where these kinds of social media
sharing buttons actually take real estate on the screen and contribute
more to already slow mobile experience.&lt;/p&gt;

&lt;p&gt;These things taken into account, I won’t be adding social media
sharing buttons here, as their downsides seem to be bigger than the
upsides.&lt;/p&gt;

&lt;h2 id=&quot;adding-metadata&quot;&gt;Adding metadata&lt;/h2&gt;

&lt;p&gt;Adding metadata to pages should make it more easy to share these
articles around, as different services are able to bring out the
relevant content on those pages. Major metadata collections for blog
posts used all over the web
&lt;a href=&quot;http://www.iacquire.com/blog/18-meta-tags-every-webpage-should-have-in-2013&quot;&gt;seem to be&lt;/a&gt;
Facebook’s
&lt;a href=&quot;https://developers.facebook.com/docs/sharing/opengraph/using-objects&quot;&gt;Open Graph objects&lt;/a&gt;,
&lt;a href=&quot;https://dev.twitter.com/cards/overview&quot;&gt;Twitter Cards&lt;/a&gt;, and
&lt;a href=&quot;https://developers.google.com/structured-data/rich-snippets/articles&quot;&gt;Rich Snippets for Articles&lt;/a&gt;
that Google uses. To use all of these, you need to have the following
information available:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Information about the author:
    &lt;ul&gt;
      &lt;li&gt;Name&lt;/li&gt;
      &lt;li&gt;Web page&lt;/li&gt;
      &lt;li&gt;Twitter handle&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Information about the organization that produces this content:
    &lt;ul&gt;
      &lt;li&gt;Name&lt;/li&gt;
      &lt;li&gt;Logo&lt;/li&gt;
      &lt;li&gt;Twitter handle&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Information about the article:
    &lt;ul&gt;
      &lt;li&gt;Title&lt;/li&gt;
      &lt;li&gt;Publishing date&lt;/li&gt;
      &lt;li&gt;Modified date&lt;/li&gt;
      &lt;li&gt;Unique per article image, different sizes&lt;/li&gt;
      &lt;li&gt;Article URL&lt;/li&gt;
      &lt;li&gt;Description/excerpt&lt;/li&gt;
      &lt;li&gt;Tags/keywords&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not all of this information is used in all metadata collections, but
you need to have that much data available if you want to use all these
three services. Fortunately these services provide metadata
validators:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developers.facebook.com/tools/debug/og/object/&quot;&gt;Open Graph Object Debugger&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cards-dev.twitter.com/validator&quot;&gt;Twitter Card Validator&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developers.google.com/structured-data/testing-tool/&quot;&gt;Structured Data Testing Tool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;unique-article-images&quot;&gt;Unique article images&lt;/h3&gt;

&lt;p&gt;The thing that resulted in the most issues was to get an unique per
article image done. That might make sense for news articles, but when
there are software development related articles about abstract
matters, it’s pretty hard to come up with images that do not look out
of place or are just completely made up. So I decided to completely
make up images that are generated automatically, if there is nothing
better specified.&lt;/p&gt;

&lt;p&gt;I’m using identicon type of approach by creating such 4 icons from
&lt;a href=&quot;https://en.wikipedia.org/wiki/SHA-1&quot;&gt;SHA-1&lt;/a&gt; of article’s path
(“/2016/01/software-development-blog” for this one). Then these icons are either combined
horizontally or to a 2x2 square grid and that way they are used to
create article images that are appropriate for different media. It’s a
crude trick, but at least with a very high probability it generates
a unique per article image that can be visually identified. For
example this article has these identifier images:&lt;/p&gt;

&lt;figure&gt;

  &lt;p&gt;&lt;img src=&quot;https://barro.github.io/2016/01/software-development-blog/id-square-400x400.png&quot; alt=&quot;400x400 square identicon for this article&quot; width=&quot;400px&quot; height=&quot;400px&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;400x400 square identicon for this article.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;

  &lt;p&gt;&lt;img src=&quot;https://barro.github.io/2016/01/software-development-blog/id-large-800x200.png&quot; alt=&quot;800x200 horizontal identicon for this article&quot; width=&quot;800px&quot; height=&quot;200px&quot; /&gt;&lt;/p&gt;
  &lt;figcaption&gt;800x200 horizontal identicon for this article.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;monetizing-blogging&quot;&gt;Monetizing blogging&lt;/h2&gt;

&lt;p&gt;There are various ways how one can monetize blogging, of which ads are
usually the most visible one. As I’m just starting and I don’t have
any established readership, it would be a waste of my time to add
any advertisements on these pages. If I get to 1000 readers monthly,
then I will probably add some very lightweight ads, as that way I
could use the money for one extra chocolate bar per month.&lt;/p&gt;

&lt;h2 id=&quot;how-timeless-is-this&quot;&gt;How timeless is this?&lt;/h2&gt;

&lt;p&gt;Probably in 5 years, I have lost interest in blogging. Most of the
pages that I’m now linking into are gone. Many of the subjects will
be outdated either by technology going forwards or development methods
going forward. Jekyll will be either in maintenance mode or a
completely abandoned project. If I continue blogging, I might even
have started using some real blogging service or some other blogging
platform.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I have not actively been involved in web development during the last
couple of years and this provided me an excellent opportunity to see
that what kind of web development related advances and changes there
have been. The biggest surprise comes from the metadata usage, and how
many different systems expect to have icons in different sizes and
formats.&lt;/p&gt;

&lt;p&gt;I generally try to put usability and speed before looking fancy. In
this blog, however the need for speed is not always satisfied, as
having the commenting system hosted outside adds a lot of extra data
to transfer and makes these pages more heavy for low power devices.&lt;/p&gt;
</description>
        <pubDate>Sun, 31 Jan 2016 18:00:00 +0200</pubDate>
        <link>https://barro.github.io/2016/01/software-development-blog/</link>
        <guid isPermaLink="true">https://barro.github.io/2016/01/software-development-blog/</guid>
        
        <category>meta</category>
        
        <category>blogging</category>
        
        
      </item>
    
  </channel>
</rss>
