<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Made of Bugs &#187; software</title>
	<atom:link href="http://blog.nelhage.com/tag/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nelhage.com</link>
	<description>It's software. It's made of bugs.</description>
	<lastBuildDate>Thu, 18 Aug 2011 21:57:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Write yourself an strace in 70 lines of code</title>
		<link>http://blog.nelhage.com/2010/08/write-yourself-an-strace-in-70-lines-of-code/</link>
		<comments>http://blog.nelhage.com/2010/08/write-yourself-an-strace-in-70-lines-of-code/#comments</comments>
		<pubDate>Sun, 29 Aug 2010 16:33:26 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ptrace]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[strace]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=300</guid>
		<description><![CDATA[Basically anyone who&#8217;s used Linux for any amount of time eventually comes to know and love the strace command. strace is the system-call tracer, which traces the calls that a program makes into the kernel in order to interact with the outside world. If you&#8217;re not already familiar with this incredibly versatile tool, I suggest [...]]]></description>
			<content:encoded><![CDATA[<p>Basically anyone who&#8217;s used Linux for any amount of time eventually
comes to know and love the <a href="http://linux.die.net/man/1/strace"><code>strace</code></a> command. <code>strace</code> is the
system-call tracer, which traces the calls that a program makes into
the kernel in order to interact with the outside world. If you&#8217;re not
already familiar with this incredibly versatile tool, I suggest you go
check out my friend and coworker Greg Price&#8217;s excellent <a href="http://blog.ksplice.com/2010/08/strace-the-sysadmins-microscope/">blog
post</a> on the subject, and then come back here.</p>

<p>We all love strace, but have you ever wondered how it works? How does
it interject itself between the kernel and the userspace program? This
post will walk through a minimal implementation of <code>strace</code> in about
70 lines of C. It won&#8217;t be nearly as functional as the real thing, but
in the process you&#8217;ll learn most of what you need to know about the
core interfaces it uses.</p>

<p>On Linux (and probably some other UNIXes) <code>strace</code> uses a somewhat
arcane interface known as <a href="http://linux.die.net/man/2/ptrace"><code>ptrace</code></a>, the process-tracing
interface. <code>ptrace</code> allows one proccess to monitor the status of
another process, and to inspect (or even manipulate) its internal
state.</p>

<p><code>ptrace</code> is a complex system call, taking a magic &#8220;request&#8221; first
parameter, and doing completely different things depending on its
value. Its general prototype looks like:</p>

<pre><code>long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
</code></pre>

<p>However, because different values of <code>request</code> use anywhere from zero
to three of the remaining parameters, <code>glibc</code> prototypes it as a
varargs function, allowing a a developer to only list as many
parameters as a given call needs.</p>

<p>In order for one process to trace another, it attaches to that
process, and temporarily becomes that process&#8217;s parent. When a process
is <code>ptrace</code>d, the tracer can ask for the child to stop whenever
various events happen, such as the child making a system call. When
this happens, the kernel will stop the child with <code>SIGTRAP</code>. Since the
tracer is now the child&#8217;s parent, it can thus watch for this using the
standard UNIX <code>waitpid</code> system call.</p>

<p>Our miniature <code>strace</code> will only support the <code>strace COMMAND</code> form of
<code>strace</code> (as opposed to <code>strace -p</code>), and we&#8217;ll only print syscall
numbers and return values &#8212; no decoding of names or arguments or
anything. So a sample run might look like:</p>

<pre><code>$ ./ministrace ls
…
syscall(6) = 0
syscall(54) = 0
syscall(54) = 0
syscall(5) = 3
syscall(221) = 1
syscall(220) = 272
syscall(220) = 0
syscall(6) = 0
syscall(197) = 0
syscall(192) = -1219706880
…
</code></pre>

<p>Not the most useful thing in the world, but it shows off the core
tracing tools. So, let&#8217;s see the code:</p>

<pre><code>#include &lt;sys/ptrace.h&gt;
#include &lt;sys/reg.h&gt;
#include &lt;sys/wait.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;errno.h&gt;
#include &lt;string.h&gt;
</code></pre>

<p>We start with the necessary headers. <code>sys/ptrace.h</code> defines <code>ptrace</code>
and the <code>__ptrace_request</code> constants, and we&#8217;ll need <code>sys/reg.h</code> to
help decode system calls. More about that later. Everything else you
should probably recognize.</p>

<pre><code>int do_child(int argc, char **argv);
int do_trace(pid_t child);

int main(int argc, char **argv) {
    if (argc &lt; 2) {
        fprintf(stderr, "Usage: %s prog args\n", argv[0]);
        exit(1);
    }

    pid_t child = fork();
    if (child == 0) {
        return do_child(argc-1, argv+1);
    } else {
        return do_trace(child);
    }
}
</code></pre>

<p>We&#8217;ll start with the entry point. We check that we were passed a
command, and then we <code>fork()</code> to create two processes &#8212; one to
execute the program to be traced, and the other to trace it.</p>

<pre><code>int do_child(int argc, char **argv) {
    char *args [argc+1];
    memcpy(args, argv, argc * sizeof(char*));
    args[argc] = NULL;
</code></pre>

<p>The child starts with some trivial marshalling of arguments, since
<code>execvp</code> wants a <code>NULL</code>-terminated argument array.</p>

<pre><code>    ptrace(PTRACE_TRACEME);
    kill(getpid(), SIGSTOP);
    return execvp(args[0], args);
}
</code></pre>

<p>Next, we just execute the provided argument list, but first, we need
to start the tracing process, so that the parent can start tracing the
newly-executed program from the very start.</p>

<p>If a child knows that it wants to be traced, it can make the
<code>PTRACE_TRACEME</code> <code>ptrace</code> request, which starts tracing. In addition,
it means that the next signal sent to this process wil stop it and
notify the parent (via <code>wait</code>), so that the parent knows to start
tracing. So, after doing a <code>TRACEME</code>, we <code>SIGSTOP</code> ourselves, so that
the parent can continue our execution with the <code>exec</code> call.</p>

<p>(You might have noticed that <code>strace COMMAND</code> output always starts
with an <code>execve</code> call. Now you should understand why &#8212; we&#8217;re actually
going to start tracing immediately after the <code>kill</code> returns, so we see
the <code>execve</code> call that starts the new program).</p>

<pre><code>int wait_for_syscall(pid_t child);

int do_trace(pid_t child) {
    int status, syscall, retval;
    waitpid(child, &amp;status, 0);
</code></pre>

<p>In the parent, meanwhile, we prototype a function we&#8217;ll need later,
and start tracing. We immediately <code>waitpid</code> on the child, which will
return once the child has sent itself the <code>SIGSTOP</code> above, and is
ready to be traced.</p>

<pre><code>    ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACESYSGOOD);
</code></pre>

<p>I mentioned earliar that <code>ptrace</code> turns basically all events into a
<code>SIGTRAP</code> on the child. This is inconvenient because it means that
when you see the child has stopped due to <code>SIGTRAP</code>, there&#8217;s no good
way to know which of several possible reasons it stopped for.</p>

<p><code>PTRACE_SETOPTIONS</code> lets us set a number of options for how we want to
trace the child. We use it here to set <code>PTRACE_O_TRACESYSGOOD</code>, which
means that when the child stops for a syscall-related reason, we&#8217;ll
actually see it stopped with signal number <code>SIGTRAP | 0x80</code>, so we can
easily distinguish syscall stops from other stops. Since (for the
purposes of this demo), we only care about syscalls, this is very
convenient.</p>

<pre><code>    while(1) {
        if (wait_for_syscall(child) != 0) break;
</code></pre>

<p>Now we enter the tracing loop. <code>wait_for_syscall</code>, defined below, will
run the child until either entry to or exit from a system call. If it
returns non-zero, the child has exited and we end the loop.</p>

<pre><code>        syscall = ptrace(PTRACE_PEEKUSER, child, sizeof(long)*ORIG_EAX);
        fprintf(stderr, "syscall(%d) = ", syscall);
</code></pre>

<p>Otherwise, though, we know that the child is entering a system call,
and so we need to decode the system call number (and potentially
arguments, if this were a less toy example). The <code>PTRACE_PEEKUSER</code>
<code>ptrace</code> request reads a word of data from the child&#8217;s &#8220;user area&#8221;,
which is a logical area that holds all of its registers and other
internal non-memory state. On i386, the syscall number lives in
<code>%eax</code>. For various technical reasons, however, the kernel has already
clobbered the child&#8217;s <code>%eax</code> at this point, but it saves the original
value at a different offset, <code>ORIG_EAX</code>, which comes from
`sys/regs.h&#8217;.</p>

<pre><code>        if (wait_for_syscall(child) != 0) break;
</code></pre>

<p>Once we have the syscall number, we <code>wait_for_syscall</code> again, which
should leave us stopped at the syscall return.</p>

<pre><code>        retval = ptrace(PTRACE_PEEKUSER, child, sizeof(long)*EAX);
        fprintf(stderr, "%d\n", retval);
</code></pre>

<p>Return values on i386 are also passed in <code>%eax</code>, so this time we can
read it directly and print the return value, and then return to the
top of the loop to wait for the next syscall.</p>

<pre><code>     }
    return 0;
}
</code></pre>

<p>And once the child exits, we just return.</p>

<pre><code>int wait_for_syscall(pid_t child) {
    int status;
    while (1) {
        ptrace(PTRACE_SYSCALL, child, 0, 0);
</code></pre>

<p><code>wait_for_syscall</code> is a simple helper function. We continue the child
using <code>PTRACE_SYSCALL</code>, which allows a stopped child to continue
executing until the next entry to or exit from a system call.</p>

<pre><code>        waitpid(child, &amp;status, 0);
</code></pre>

<p>We then <code>waitpid</code> to wait for something interesting to happen in the
child.</p>

<pre><code>        if (WIFSTOPPED(status) &amp;&amp; WSTOPSIG(status) &amp; 0x80)
            return 0;
</code></pre>

<p>Because of the <code>PTRACE_O_SYSGOOD</code> we set above, we can detect a
syscall stop by checking if the child was stopped by a signal with the
high bit set. If so, we return.</p>

<pre><code>        if (WIFEXITED(status))
            return 1;
    }
}
</code></pre>

<p>If the child exited, we&#8217;re done here; Otherwise, it stopped for some
reason we don&#8217;t care about (like an <code>execve</code>, for instance), and so we
loop to start it again until it hits a syscall.</p>

<p>And that&#8217;s all there is to it. You can find the version I just posted on
<a href="http://github.com/nelhage/ministrace/tree/for-blog">github</a> if you want to download and try it out.</p>

<h2>Making it more useful</h2>

<p>While it works, the previous version isn&#8217;t exactly what I&#8217;d call particularly
helpful. You have to decode the syscall numbers by hand, and you don&#8217;t get any
syscall arguments.</p>

<p>It&#8217;s a little long to include in the post, but I&#8217;ve pushed a slightly more
functional version to <a href="http://github.com/nelhage/ministrace/tree/master">master</a> in the same github repository. It
includes a Python script to scan the Linux source to pick up syscall numbers and
argument counts and types, and it knows how to decode string arguments, so that
you can see filenames and <code>read</code> and <code>write</code> data.</p>

<p>Reading arguments is easy &#8212; on i386, they&#8217;re passed in registers, so it&#8217;s just
another <code>PTRACE_GETUSER</code> for each argument. Perhaps the most interesting piece
is the <code>read_string</code> function, which is used to read a NULL-terminated string
from the child process. (Of course, NULL-terminated isn&#8217;t quite right &#8212; the
real strace knows about the <code>count</code> arguments to <code>read()</code> and <code>write()</code>, for
instance. But it&#8217;s close enough for a demo):</p>

<pre><code>char *read_string(pid_t child, unsigned long addr) {
</code></pre>

<p><code>read_string</code> takes a child to read from, and the address of the string it&#8217;s
going to read.</p>

<pre><code>    char *val = malloc(4096);
    int allocated = 4096, read;
    unsigned long tmp;
</code></pre>

<p>We need some variables. A buffer to copy the string into, counters of how much
data we&#8217;ve copied and allocated, and a temporary variable for reading memory.</p>

<pre><code>    while (1) {
        if (read + sizeof tmp &gt; allocated) {
            allocated *= 2;
            val = realloc(val, allocated);
        }
</code></pre>

<p>We grow the buffer if necessary. We read data one word at a time.</p>

<pre><code>        tmp = ptrace(PTRACE_PEEKDATA, child, addr + read);
        if(errno != 0) {
            val[read] = 0;
            break;
        }
</code></pre>

<p><code>PTRACE_PEEKDATA</code> returns a work of data from the child at the specified
offset. Because it uses its return for the value, we need to check <code>errno</code> to
tell if it failed. If it did (perhaps because the child passed an invalid
pointer), we just return the string we&#8217;ve got so far, making sure to add our own
NULL at the end.</p>

<pre><code>        memcpy(val + read, &amp;tmp, sizeof tmp);
        if (memchr(&amp;tmp, 0, sizeof tmp) != NULL)
            break;
        read += sizeof tmp;
</code></pre>

<p>Then it&#8217;s a simple matter of appending the data we read, and breaking out if we
found a terminating NULL, or else looping to read another word.</p>

<pre><code>    }
    return val;
}
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/08/write-yourself-an-strace-in-70-lines-of-code/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Implementing a declarative mini-language in the C preprocessor</title>
		<link>http://blog.nelhage.com/2010/07/implementing-an-edsl-in-cpp/</link>
		<comments>http://blog.nelhage.com/2010/07/implementing-an-edsl-in-cpp/#comments</comments>
		<pubDate>Sun, 04 Jul 2010 19:54:55 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[check]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[dsl]]></category>
		<category><![CDATA[preprocessor]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=272</guid>
		<description><![CDATA[Last time, I announced Check Plus, a declarative language for defining Check tests in C. This time, I want to talk about the tricks I used to implement a declarative minilanguage using the C preprocessor (and some GCC extensions). The Problem We want to write some toplevel declarations that look like: #define SUITE_NAME example BEGIN_SUITE("Example [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/">Last time</a>, I announced Check Plus, a declarative language for
defining <a href="http://check.sourceforge.net/">Check</a> tests in C. This time, I want to talk about the tricks I
used to implement a declarative minilanguage using the C preprocessor (and some
GCC extensions).</p>

<h2>The Problem</h2>

<p>We want to write some toplevel declarations that look like:</p>

<pre><code>#define SUITE_NAME example
BEGIN_SUITE("Example test suite");

#define TEST_CASE core
BEGIN_TEST_CASE("Core tests");
…
</code></pre>

<p>and so on, and somehow translate them into code that does the equivalent of:</p>

<pre><code>Suite *s = suite_create ("Example test suite");
TCase *tc_core = tcase_create ("Core tests");
…
</code></pre>

<h2>First steps</h2>

<p>Instead of having our macros somehow lay down code directly, we&#8217;ll use them to
define some global data structures, which we will then loop across at runtime,
and make the appropriate Check library calls. We&#8217;ll define some structs that
we&#8217;re going to use for this purpose:</p>

<pre><code>typedef void (*test_func)(int);
typedef void (*test_hook)(void);

struct test_case {
    test_func  *funcs, *end_funcs;
    const char *test_name;
    test_hook *setup_hooks, *end_setup_hooks;
    test_hook *teardown_hooks, *end_teardown_hooks;
};

struct test_suite {
    struct test_case *cases, *end_cases;
    const char *suite_name;
};
</code></pre>

<p>Since tests and test fixtures are code, we&#8217;re going to need to keep function
pointers to them. We use typedefs to keep thos readable, and then we define
structs to represent a test suite, and a test case. We&#8217;re going to represent
arrays (of test cases, fixture hooks, or test functions) using a pair of
pointers, to the start and end of the array. There&#8217;s a specific reason for this
representation, which I&#8217;ll get to shortly.</p>

<h2>ELF Sections</h2>

<p>We can easily define global instances of these structs, but the problem is how
to get the pointers to the child arrays correctly. These macros are going to be
interspersed with other code, so we can&#8217;t just use a literal array, like</p>

<pre><code>struct test_suite s = {
 .suite_name = "Example test suite",
 .cases = {
   …
 }
};
</code></pre>

<p>because that &#8220;…&#8221; is going to have arbitrary code shoved in it.</p>

<p>The solution is to take advantage of a feature of the ELF object file format,
and some GCC extensions that let us take advantage of it.</p>

<p>ELF object files can contain an arbitary set of named sections, each
of which can contain code or data (or both, but that&#8217;s not
typical). GCC allows us to specify that a given variable should live
in a given section using
<code>__attribute__((section("section_name"))</code>. So, by placing all our
<code>struct test_case</code>s for a given <code>test_suite</code> into a separate section,
we can cause them to get placed contiguously, which means we just need
to get pointers to the start and end. That we can accomplish by
declaring a zero-length array in the appropriate section, which (being
of size zero) won&#8217;t generate any data, but will have the appropriate
address.</p>

<p>So, the code we&#8217;re going to generate for the above will look something
like:</p>

<pre><code>struct test_case _begin_example_cases[];
struct test_case _end_example_cases[];
struct test_suite _suite_example = {
  .cases = _begin_example_cases,
  .end_cases = _end_example_cases,
  .suite_name = "Example test suite"
};
struct test_case _begin_example_cases[0]
  __attribute__((section(".data.example.cases")));

struct test_case _test_example_core
  __attribute__((section(".data.example.cases"))) = {
  .test_name = "Core tests",
  …
};

…

struct test_case _end_example_cases[0]
  __attribute__((section(".data.example.cases")));
</code></pre>

<h2>Preprocessor tricks</h2>

<p>So far, I haven&#8217;t actually talked about the preprocessor at all. I&#8217;ve
just shown the code we want our macros to generate. So now let&#8217;s get
to the business of actually generating this code. I&#8217;ll walk through
the definition of `BEGIN_SUITE&#8217;, which expands to the code above. The
other definitions are all essentially analagous.</p>

<p>My first version of this library didn&#8217;t use the <code>SUITE_NAME</code> and
<code>TEST_CASE</code> macros, instead requiring those arguments to be passed to
every macro. I like the decreased repetition that this method gives,
but we&#8217;ll start with the explicit version, since it requires less
trickery to understand.</p>

<p>From the above example, we can see that <code>BEGIN_SUITE(example,
"Example")' is given the</code>example&#8217; token, and needs to construct both
symbols (<code>_suite_example</code>) and strings (<code>".data.example.cases"</code>)
containing that symbol. To do the first, we need to the processor
operator <code>##</code>, which concatenates two tokens into one. For example,
given</p>

<pre><code>#define PASTE(x,y) x##_##y
</code></pre>

<p>`PASTE(foo, bar)&#8217; is equivalent to just having written &#8220;foo_bar&#8221;
literally in your code.</p>

<p>Secondly, to construct strings, we need the <code>#x' preprocessor
operator. This operator, when applied to an argument to a macro,
returns a string literal containing the tokens passed to the macro. A
common usage of this is for an</code>assert` macro, that can print the
failed expression:</p>

<pre><code>#define assert(x) if (!(x)) { die("Assertion failed: %s\n", #x); }
</code></pre>

<p>And finally, we&#8217;re going to need the implicit concatenation feature of
the C language, which lets you type <code>"foo" "bar"</code> with the same
meaning as &#8220;foobar&#8221;.</p>

<p>Putting it all together, and we get:</p>

<pre><code>#define BEGIN_SUITE(sym, name)                                          \
    struct test_case _begin_ ## sym ## _cases[];                        \
    struct test_case _end_ ## sym ## _cases[];                          \
    struct test_suite _suite_ ## sym = {                                \
        .cases       = (struct test_case*)_begin_ ## sym ## _cases,     \
        .end_cases   = (struct test_case*)_end_ ## sym ## _cases,       \
        .suite_name  = name,                                            \
    };                                                                  \
    struct test_case _begin_ ## sym ## _cases[0]                        \
    __attribute__((section(".data." #sym ".cases")))
</code></pre>

<p>Two last things to note: we deliberately leave off a trailing
semicolon, requiring the user to provide one, and we need to end every
line with a <code>\</code>, to include the entire body in the macro definition.</p>

<h2>Another layer of indirection</h2>

<p>The one final bit is to get rid of that explicit <code>sym</code> argument
everywhere, in favor of the <code>SUITE_NAME</code> define. Our first try might
look something like:</p>

<pre><code>#define BEGIN_SUITE(name)                                               \
    struct test_case _begin_ ## SUITE_NAME ## _cases[];                 \
    …
</code></pre>

<p>You&#8217;ll quickly realize, however, that since <code>##</code> is applied at the
same time as function-like macro expansion, this will always give you
the symbol <code>_begin_SUITE_NAME_cases</code>. The solution is to force the
preprocessor to perform multiple phases of macro expansion, to cause
the <code>##</code> to be applied only after <code>SUITE_NAME</code> is expanded. In this
case, we require three layers of macros to get the order right:</p>

<pre><code>#define BEGIN_SUITE(name) _BEGIN_SUITE(SUITE_NAME, name)
#define _BEGIN_SUITE(sym, name) __BEGIN_SUITE(sym, name)
#define __BEGIN_SUITE(sym, name)                                        \
    struct test_case _begin_ ## sym ## _cases[];                        \
</code></pre>

<p>This causes the following sequence of expansions for
<code>BEGIN_SUITE("Example");</code>:</p>

<pre><code>BEGIN_SUITE("Example");                     // (a)
_BEGIN_SUITE(SUITE_NAME, "Example");        // (b)
__BEGIN_SUITE(sym, "Example");              // (c)
</code></pre>

<p>The key here is that when expanding a function-like macro, the
preprocessor performs the following steps, in order:</p>

<ol>
<li>Apply any <code>#</code> or <code>##</code> operators.</li>
<li>Macro-expand any arguments to the call</li>
<li>Perform the substitution</li>
<li>Macro-expand the result of the substitution</li>
</ol>

<p>In going from (a) to (b), only step (3) applies. When going from (b)
to (c), rule (2) means that <code>SUITE_NAME</code> gets expanded first, leaving
(c). Rule (1) means that the <code>_BEGIN_SUITE</code> macro is necessary, since
a call to <code>__BEGIN_SUITE(SUITE_NAME, "Example")</code> will get the <code>#</code> and
<code>##</code> applied to <code>SUITE_NAME</code> before it can be expanded.</p>

<h2>Conclusions</h2>

<p>So, that&#8217;s basically all there is to the Check-Plus implementation. If
you&#8217;re comfortable with that, you can try your hand at unravelling the
implementation of the Linux kernel&#8217;s <a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=include/trace/define_trace.h;h=1dfab54015113b83bce9f3302470c3a5ed95b5e7;hb=HEAD">tracing</a>
<a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=include/trace/ftrace.h;h=5a64905d7278a47fb683a0aceb63cef029dd467b;hb=HEAD">macros</a>, next (<a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=include/trace/events/kmem.h;h=3adca0ca9dbee10479d34d5a3e3562609ef89e86;hb=HEAD">sample usage</a>)!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/07/implementing-an-edsl-in-cpp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lab Notebooking for the Software Engineer</title>
		<link>http://blog.nelhage.com/2010/06/lab-notebooking-for-the-software-engineer/</link>
		<comments>http://blog.nelhage.com/2010/06/lab-notebooking-for-the-software-engineer/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 02:53:07 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[lab notebooks]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=254</guid>
		<description><![CDATA[A few weeks ago, I wrote that software engineers should keep lab notebooks as they work, in addition to just documenting things after the fact. Today, I&#8217;m going to share the techniques that I&#8217;ve found useful to try to get in the habit of lab-notebooking my work, even though I still feel like I could [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago, I <a href="http://blog.nelhage.com/2010/05/software-and-lab-notebooks/">wrote</a> that software engineers should keep
lab notebooks as they work, in addition to just documenting things
after the fact. Today, I&#8217;m going to share the techniques that I&#8217;ve
found useful to try to get in the habit of lab-notebooking my work,
even though I still feel like I could be better at writing things
down.</p>

<p>Here&#8217;s my advice for keeping a lab notebook as a computer scientist:</p>

<dl>
<dt>Use a text file</dt>

<dd> <p>There&#8217;s no need to use anything fancier. And if you&#8217;re writing
code all day, you can just keep your log file open in your editor of
choice, so that you don&#8217;t need to leave your hacking environment to
make a note of something. I&#8217;m an emacs junkie and use
<a href="http://orgmode.org/">org-mode</a> to keep all my notes, but use whatever you&#8217;re
comfortable with.</p>


<p>You could use a physical notebook, but unless you expect to want
documentation of what you were working on for some legal reason, I
don&#8217;t see the point. And most programmers I know hate writing things
out by hand.</p>
</dd>

<dt>Treat your file as append-only</dt>

<dd>One of the downsides of just using a text file is that you need to
enforce some discipline on yourself. It&#8217;s tempting to go back and fix
up things that have changed, or to keep editing a desgin description
as it evolved. But creating a perfect finished piece of documentation
is a different task. The point here is to have a log of everything you
do, not a single finished document. You can work on one side-by-side
with the (dated or even timestampped) append-only log.</dd>

<dt>Keep automatic backups.</dt>

<dd>Do this any way you want. I keep my log files in git, and have a
cron job that commits and pushes to a server every five minutes. This
provides at least two benefits. First, it applies an automatic timestamp (to
within five minutes) on anything I type, and second, it serves to make
sure that a recent version is available on my server, in case I switch
machines and want to keep working on a project.
</dd>

<dt>Train yourself to make regular entries.</dt>

<dd>

<p>Keeping this nice text file, regularly backed up, is useless if you
don&#8217;t record relevant things into it. Getting yourself into the habit
of writing enough down is tricky. One strategy I&#8217;ve found helpful is
to write down a list of &#8220;triggers&#8221; for situations that you promise to
always record. With an explict list of these that you&#8217;ve decided to
always record, you can get good at making a note whenever you perform
one of these tasks, which gets you into the habit of writing things
down. Here&#8217;s a partial list of some of the sorts of things I make a
point of writing down:</p>

<ul>

<li>Whenever I take a measurement. That is, any time I run
<tt>time</tt>, or look at <tt>top</tt> to figure out how much memory a
program under development is using, or similar, I&#8217;ll write down the
number and the circumstances under which it was recorded. I&#8217;ve found
that I almost always would like to have a better record of such things
later.</li>

<li>Whenever I do a non-trivial search and find a result. This can be
anything from googling for a solution to some problem where it takes
me several tries to find the right keywords, or grepping a large
codebase searching for the function that performs some task, or
tracking down some API function in documentation. If I wanted it once,
I&#8217;ll often want it later, and if it was hard to find, I&#8217;ll feel stupid
if I didn&#8217;t write it down.</li>

<li>Whenever I make an explicit design decision. If I&#8217;m thinking about
how to design some function, system, process, or whatever, I&#8217;ll stop
and take a moment to write down the options I was considering, and why
I made the choice I did. This ensures I can go back and remember why I
built a system the way it is.
</li>


<li>Whenever I wish I had written something down last time. This
should be obvious, but if you find yourself thinking &#8220;I know I did
this before; Why didn&#8217;t I take notes?&#8221;, you should
<strong>always</strong> make a point of writing it down this time, no
matter what excuse you come up with for why you really won&#8217;t need that
information a third time.
</li>

</ul>

<p>These categories are deliberately broad, but at the same time
well-defined. It&#8217;s fairly easy to train yourself to notice whenever
any of these points triggers, and remember to stop and write something
down. And that&#8217;s the first step to getting in the habit of writing
down everything that you&#8217;ll later wish you had written down.</p>

</dd>

</dl>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/06/lab-notebooking-for-the-software-engineer/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Confessions of a programmer: I hate code review</title>
		<link>http://blog.nelhage.com/2010/06/i-hate-code-review/</link>
		<comments>http://blog.nelhage.com/2010/06/i-hate-code-review/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 00:21:11 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[code review]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[ksplice]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=241</guid>
		<description><![CDATA[Most of the projects I&#8217;ve been working on today have fairly strict code review policies. My work requires code review on most of our code, and as we bring on an army of interns for the summer, I&#8217;ve been responsible for reviewing lots of code. Additionally, about five months ago BarnOwl, the console-based IM client [...]]]></description>
			<content:encoded><![CDATA[<div id="text-1">

<p>
Most of the projects I&#8217;ve been working on today have fairly strict
code review policies. My <a href="http://www.ksplice.com">work</a> requires code review on most of our
code, and as we bring on <a href="http://blog.ksplice.com/2010/03/quadruple-productivity-with-an-intern-army/">an army of interns</a> for the summer, I&#8217;ve been
responsible for reviewing lots of code. Additionally, about five
months ago <a href="http://barnowl.mit.edu/">BarnOwl</a>, the console-based IM client I develop, adopted an
official pre-commit review policy. And I have a confession to make: I
hate mandatory code review.
</p>
<p>

I should be clear that I think I still <b>believe</b> in code review
as a useful tool for developers working together on a project. A
reviewer will flag as bad style or inefficient or ugly things that you
let slide working for yourself. A reviewer comes at code without the
assumptions of how it&#8217;s supposed to work that you made, and can often
spot errors you made because mixed up a mental model of your intent
with the code you actually wrote.
</p>

<p> In addition, code review is a great way to ensure that at least
two people are familiar with each piece of your infrastructure. There
is often a natural tendency for different developers to take ownership
of specific pieces of code or infrastructure, and be the only ones who
touch or maintain it. But then it breaks while they&#8217;re on vacation,
and everyone else is left trying to figure out how this code was ever
supposed to work. A mandatory code review policy is often a great way
to mitigate that class of problem.
</p>

<p> But, theoretical and observed benefits of code review aside,
speaking personally, as both a developer and as a reviewer, I&#8217;ve been
finding it a really frustrating process.  </p>

</div>

<div id="outline-container-1.1" class="outline-3">
<h3 id="sec-1.1">As an author </h3>
<div id="text-1.1">


<p>
As a developer, I hate that code review adds unpredictably long
latencies into my development workflow. Once I&#8217;ve finished and tested
a feature to my satisfaction, and sent it off for code review, I have
to wait for a potentially long time before I can actually mark it as
done. This means that, when deciding what to do next, I have
essentially three choices:
</p>
<ol>
<li>
Busy-wait. Get coffee, read reddit, and check my mail until the
review request comes back.

</li>
<li>
Continue development on top of the code I just sent for code
review.

</li>
<li>
Work on something completely different.

</li>
</ol>

<p>All three of these options suck. (1) is convenient if I can expect the
review to come back shortly, since doing something idle like reading
reddit or checking mail lets me keep the code in the back of my mind,
so I don&#8217;t have to page it back in when the review response comes
back. But obviously it&#8217;s inefficient, wasted time, and unacceptable if
I don&#8217;t expect a reply within an hour at most.
</p>
<p>
(2) is often what I want to be doing. I&#8217;ll often be working on a
project with several logically distinct but related stages. It often
makes sense to send out a review request for each, since they can be
deployed and reviewed separately.
</p>
<p>
However, if a reviewer comes back with significant comments on the
code I sent out, I now not only need to update that code, but I also
need to rebase the work I&#8217;ve done since then on top of the result,
which may be a real pain if I&#8217;m working on something closely related
(e.g. if my work used APIs I built previously, and the reviewer asks
for changes in those APIs in some way).
</p>
<p>
Option (3) avoids both problems, but means that I&#8217;m continually
swapping different projects in and out of focus. This slows me down,
since I have to constantly re-remember where I was in each project,
which APIs I was using, and so on. Any developer can tell you that
they hate switching between different projects too frequently.
</p>
<p>
Option (3) might be more tolerable with large projects, where
development/review cycles are on the order of weeks. But those aren&#8217;t
the projects I&#8217;m working on.
</p>
</div>

</div>

<div id="outline-container-1.2" class="outline-3">
<h3 id="sec-1.2">As a reviewer </h3>
<div id="text-1.2">


<p>
Reviewing code is one of those things that I would enjoy if I had
infinite time, but that I find a nuisance when I don&#8217;t. I do enjoy
reading other peoples&#8217; code and figuring out how it could be better,
and giving feedback to help get it there.
</p>
<p>
But doing so well takes a lot of time, and a lot of time is something
I rarely have these days. In addition, because of my above complaints
about dealing with code review as a developer, I&#8217;m always acutely
aware that someone is probably waiting on my reply in order to get
work done. So I always feel rushed to reply to code review requests,
as well.
</p>
<p>
So, even though I always feel like code review should be something I&#8217;m
enjoying, I tend to find it a frustrating experience where it just
feels like a task I have to do before I can get back to real work.
</p>
<p>

This is, of course, in part just a symptom of being too busy, but code
review makes it a task that bugs me more than other time drains. If a
customer reports a critical bug that I have to drop everything to
investigate, I&#8217;ll be annoyed, but I at least feel like I&#8217;m doing
something important that fixes a real problem and hopefully ends with
a happy customer. If I spend a day doing nothing but reading code
reviews, I&#8217;ll end up feeling unsatisfied and unproductive. Because
code review feels fundamentally optional &#8212; even though I believe it&#8217;s
beneficial, it&#8217;s something we&#8217;ve chosen to do, not something that we
absolutely have to do in order for the project or business to keep
operating &#8212; it&#8217;s more frustrating to find myself spending a large
amount of time on.

</p>
</div>

</div>

<div id="outline-container-1.3" class="outline-3">
<h3 id="sec-1.3">In conclusion </h3>
<div id="text-1.3">


<p>
I believe in code review as a powerful tool. But in practice, I&#8217;ve
found it frustrating to work with. I&#8217;d like to hear your thoughts:
Does code review work for you? Am I doing it wrong, in some ways? Is
it just a question of changing my attitude in some way?
</p>
<p>
I know that a lot has been written about doing code review
effectively. I&#8217;d appreciate pointers to anything you&#8217;ve found
particularly compelling.
</p></div>
</div>

<p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/06/i-hate-code-review/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Software Engineers should keep lab notebooks</title>
		<link>http://blog.nelhage.com/2010/05/software-and-lab-notebooks/</link>
		<comments>http://blog.nelhage.com/2010/05/software-and-lab-notebooks/#comments</comments>
		<pubDate>Mon, 03 May 2010 03:14:14 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[lab notebooks]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=217</guid>
		<description><![CDATA[Software engineers, as a rule, suck at writing things down. Part of this is training &#8211; unlike chemists and biologists who are trailed to obsessively document everything they do in their lab notebooks, computer scientists are taught to document the end results of their work, but aren&#8217;t, in general, taught to take notes as they [...]]]></description>
			<content:encoded><![CDATA[<div id="text-1">

<p>
Software engineers, as a rule, suck at writing
things down. Part of this is training &ndash; unlike chemists and
biologists who are trailed to obsessively document everything they do
in their lab notebooks, computer scientists are taught to document the
end results of their work, but aren&#8217;t, in general, taught to take
notes as they go, and document the steps they take in building a
system. 6.005, MIT&#8217;s new introductory software engineering class,
attempted to require its students to keep lab notebooks for a few
semesters, and was met with near-universal complaints and ridicule
from the students (“Lab notebooks? For a software engineering class?
What the hell?”). (To be fair, I suspect they did a horrible job of
it, but I&#8217;m not sure that students would have been any less confused
at the idea).
</p>
<p>
Part of the reason is probably also the nature of software that makes
it very easy to record certain things as part of our tools, and that
makes experiments cheaply reproducible. Version control lets us
document the process of developing a piece of code, so it feels
superfluous to be taking additional notes on the side. Computers are
mostly deterministic, and cycles are cheap, so why bother meticuously
recording the results of a test run somewhere when you can just run it
again later, any time you want? Computers feel much neater and simpler
than messy bio or chem labs, and software is much simpler than
complicated biology experiments or chemical syntheses, and so no one
feels the need to be nearly as careful.
</p>
<p>
However, I am increasingly of the opinion that most software
engineers&#8217; total inability to work in a lab-notebook style, where you
meticulously document your work, is unfortunate and often seriously
detrimental to their work. While it&#8217;s true that things like commit
logs do a good job of documenting certain processes, here are some
types of situations where I&#8217;ve found working with meticulous notes at
every step can be invaluable:
</p>
<dl>
<dt>Debugging subtle problems</dt><dd>
Debugging is very much a problem of
gathering data and making and testing hypotheses. For subtle bugs
in large programs, the amount of state you need to keep track of
can rapidly get out of hand. And good luck when a bug is tricky
enough that your debugging gets spread across multiple days, or
even across a lunch break.

<p>
If you&#8217;ve ever found yourself wondering &#8220;Wait &ndash; did I see the
bug after I made $CHANGE to my code or test environment?&#8221;, you
should have been writing more things down.
</p>
<p>
This is especially important for non-deterministic bugs, such as
rare race conditions. If it takes you half a hour on average to
reproduce a bug, and you are experimenting with a dozen different
variables in your test environment that might affect the bug, you
can&#8217;t afford to forget the results of a single test, or to forget
a single detail of what you did to test. This is the point at
which you should be writing down every single command you type in
any relevant prompts, and every single code change (or, since we
have technology, obsessively saving the output of `history`,
making commits to test branches, and recording the correlation
between them).
</p></dd>
<dt>Profiling and optimization</dt><dd>
This is a process similar in many ways
to debugging, but even more data-driven. When you&#8217;re done with a
session of optimizing a piece of code or a system, if you can&#8217;t
show documented evidence of exactly how much faster you&#8217;ve made
it, where that speedup came from, and all the things you tried
and how much they helped, perhaps you should be writing more
things down. And if you (or ideally, even someone else) can&#8217;t go
back and reproduce the experiments you did, with approximately
the same results, you probably haven&#8217;t been documenting your work
well enough.

<p>
Even if you&#8217;re happy with the performance improvements you&#8217;ve
made, you may need to come back and wring even more performance
out of the system, and it&#8217;d be nice not to start from scratch. Or
maybe future testing will reveal that or more of your
optimizations was invalid, and you need to go back and consider
alternate options.
</p>
<p>
This is critically important when you&#8217;re optimizing not just a
piece of code, but some kind of system with lots of configuration
and setup, that you&#8217;ll later have to duplicate somewhere else,
instead of just checking the result into source control.
</p></dd>
<dt>Understanding a new project&#8217;s code or documentation</dt><dd>
Whenever I&#8217;m
first diving into a large code-base or first playing with a large
new API, I find it invaluable to take notes as I go about what I
look for and where I find it. I&#8217;ll often need to look up half a
dozen different API calls or pieces of code to understand
something, often too many to keep in my head as I go and dive
through more and more pieces of code or docs.

<p>
And when the documentation is ambiguous, I&#8217;ll often drop into a
REPL or build test programs to make various calls and understand
what happens. Again, after more than two or three of these, it&#8217;s
vital that I&#8217;ve been writing down my findings.
</p>
<p>
This is one example where a chronological style documenting
exactly in what order I found things is less critical, but that
detailed notes as I go are still vital.
</p></dd>
<dt>Designing things</dt><dd>
Whenever you&#8217;re designing something &ndash; be it an
API, a protocol, an interface, some kind of system, or something
else &ndash; it&#8217;s worth taking notes on the process you took to get to
your final decisions, and the choices you considered and
rejected, and why.

<p>
You&#8217;ll presumably end up a producing a piece of code or a design
document that indicates what you ended up deciding, but
understanding why you made the decisions you made is often
important to understanding how your system is supposed to work,
and how to best use or extend it in the future. Hopefully, when
you&#8217;re done, you&#8217;d do this writeup in brief somewhere anyways,
but the best way to make sure you don&#8217;t forget is to take good
notes as your thought process happens.
</p>
<p>
And nothing in software is ever complete. If you have to revise
the design for some reason, because someone points out problems
or new requirements come up, you&#8217;ll probably want to remember the
other possibilities you came up with &ndash; maybe one of them is now
more right.
</p>
</dd>
</dl>

<p>So, if you&#8217;re a software engineer, I strongly encourage you to try to
get better at writing things down. In a future post, I&#8217;ll hopefully
write up the techniques I&#8217;ve started using to take notes as I code,
debug, and design, but in the meanwhile, I encourage you to just grab
a text editor or a physical lab notebook, whichever is more
comfortable for you, and start taking more notes on what you&#8217;re doing.
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/05/software-and-lab-notebooks/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

