about summary refs log tree commit diff homepage
path: root/www/TestingCoreutils.html
blob: 7ae49302e15e84992f6177f9fcd6f0ae1da66d34 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 
          "http://www.w3.org/TR/html4/strict.dtd">
<!-- Material used from: HTML 4.01 specs: http://www.w3.org/TR/html401/ -->
<html>
<head>
  <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
  <title>KLEE - Coreutils Case Study</title>
  <link type="text/css" rel="stylesheet" href="menu.css">
  <link type="text/css" rel="stylesheet" href="content.css">
</head>
<body>
<!--#include virtual="menu.html.incl"-->
<div id="content">
  <!--*********************************************************************-->
  <h1>Coreutils Case Study</h1>

  <p>
    As a more detailed explanation of using KLEE, we will look at how we did our
    testing of <a href="http://www.gnu.org/software/coreutils/">GNU
    Coreutils</a> using KLEE.
  </p>

  <p>This tutorial assumes that you have configured and built KLEE
    with <tt>uclibc</tt> and <tt>POSIX</tt> runtime support.
  <p>

  <p>These tests were done on a 32-bit Linux machine.  On a 64-bit
  machine, we needed to also set the <tt>LD_LIBRARY_PATH</tt> environment
  variable:
    <pre>
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64 (Fedora)
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu (Ubuntu)
    </pre>
  </p>
  
  <!--*********************************************************************-->
  
  <h2>Step 1: Build coreutils with gcov</h2>

  <p>
    First you will need to download and unpack the source
    for <a href="http://www.gnu.org/software/coreutils/">coreutils</a>. In this
    example we use version 6.11 (one version later than what was used for our
    OSDI paper).
  </p>

  <p>
    Before we build with LLVM, let's build a version of <i>coreutils</i>
    with <em>gcov</em> support. We will use this later to get coverage
    information on the test cases produced by KLEE.
  </p>

  <p>
    From inside the <i>coreutils</i> directory, we'll do the usual
    configure/make steps inside a subdirectory (<tt>obj-gcov</tt>). Here are the
    steps:
  </p>

  <div class="instr">
    <pre>
<b>coreutils-6.11$ mkdir obj-gcov</b>
<b>coreutils-6.11$ cd obj-gcov</b>
<b>obj-gcov$ ../configure --disable-nls CFLAGS="-g -fprofile-arcs -ftest-coverage"</b>
<i>... verify that configure worked ...</i>
<b>obj-gcov$ make</b>
<b>obj-gcov$ make -C src arch hostname</b>
<i>... verify that make worked ...</i> </pre>
  </div>

  <p>
    We build with <tt>--disable-nls</tt> because this adds a lot of extra
    initialization in the C library which we are not interested in testing. Even
    though these aren't the executables that KLEE will be running on, we want to
    use the same compiler flags so that the test cases KLEE generates are most
    likely to work correctly when run on the uninstrumented binaries.
  </p>

  <p>
    You should now have a set of <tt>coreutils</tt> in
    the <tt>objc-gcov/src</tt> directory. For example:
  </p>

  <div class="instr">
    <pre>
<b>obj-gcov$ cd src</b>
src$ ls -l ls echo cat
-rwxr-xr-x 1 ddunbar ddunbar 164841 2009-07-25 20:58 cat
-rwxr-xr-x 1 ddunbar ddunbar 151051 2009-07-25 20:59 echo
-rwxr-xr-x 1 ddunbar ddunbar 439712 2009-07-25 20:58 ls
<b>src$ ./cat --version</b>
cat (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Torbjorn Granlund and Richard M. Stallman.</pre>
  </div>

  <p>
    In addition, these executables should be built with <tt>gcov</tt> support,
    so if you run one it will write a <tt>.gcda</tt> into the current
    directory. That file contains information about exactly what code was
    executed when the program ran. See
    the <a href="http://gcc.gnu.org/onlinedocs/gcc/Gcov.html">Gcov
    Documentation</a> for more information. We can use the <tt>gcov</tt> tool
    itself to produce a human readable form of the coverage information. For
    example:
  </p>

  <div class="instr">
    <pre>
<b>src$ rm -f *.gcda</b> <i># Get rid of any stale gcov files</i>
<b>src$ ./echo</b>

<b>src$ ls -l echo.gcda</b>
-rw-r--r-- 1 ddunbar ddunbar 1832 2009-08-04 21:14 echo.gcda
<b>src$ gcov echo</b>
File '../../src/system.h'
Lines executed:0.00% of 47
../../src/system.h:creating 'system.h.gcov'

File '../../lib/timespec.h'
Lines executed:0.00% of 2
../../lib/timespec.h:creating 'timespec.h.gcov'

File '../../lib/gettext.h'
Lines executed:0.00% of 32
../../lib/gettext.h:creating 'gettext.h.gcov'

File '../../lib/openat.h'
Lines executed:0.00% of 8
../../lib/openat.h:creating 'openat.h.gcov'

File '../../src/echo.c'
Lines executed:18.81% of 101
../../src/echo.c:creating 'echo.c.gcov' </pre>
  </div>

  <p>
    By default <tt>gcov</tt> will show the number of lines executed in the
    program (the <tt>.h</tt> files include code which was compiled
    into <tt>echo.c</tt>).
  </p>

  <!--*********************************************************************-->
  
  <h2>Step 2: Build <tt>coreutils</tt> with LLVM</h2>

  <p>
    One of the difficult parts of testing real software using KLEE is that it
    must be first compiled so that the final program is an LLVM bitcode file and
    not a linked executable. The software's build system may be set up to use
    tools such as 'ar', 'libtool', and 'ld', which do not in general understand
    LLVM bitcode files.
  </p>
  
  <p>
    It depends on the actual project what the best way to do this is. For
    coreutils, we use a helper script <tt>klee-gcc</tt>, which acts
    like <tt>llvm-gcc</tt> but adds additional arguments to cause it to emit
    LLVM bitcode files and to call <tt>llvm-ld</tt> to link executables. This
    is <b>not</b> a general solution, and your mileage may vary.
  </p>

    <!-- Discuss building other projects, the ./configure CC=llvm-gcc; make
    LD=llvm-ld CFLAGS="-emit-llvm" trick works frequently. -->

  <p>
    As before, we will build in a separate directory so we can easily access
    both the native executables and the LLVM versions. Here are the steps:
  </p>

  <div class="instr">
    <pre>
<b>coreutils-6.11$ mkdir obj-llvm</b>
<b>coreutils-6.11$ cd obj-llvm</b>
<b>obj-llvm$ ../configure --disable-nls CFLAGS="-g"</b>
<i>... verify that configure worked ...</i>
<b>obj-llvm$ make CC=/full/path/to/klee/scripts/klee-gcc</b>
<b>obj-llvm$ make -C src arch hostname CC=/full/path/to/klee/scripts/klee-gcc</b>
<i>... verify that make worked ...</i> </pre>
  </div>
  
  <p>
    Notice that we made two changes. First, we don't want to add <em>gcov</em>
    instrumentation in the binary we are going to test using KLEE, so we left of
    the <tt>-fprofile-arcs -ftest-coverage</tt> flags. Second, when running
    make, we set the <tt>CC</tt> variable to point to our <tt>klee-gcc</tt>
    wrapper script.
  </p>

  <p>
    If all went well, you should now have LLVM bitcode versions of coreutils! For
    example:
  </p>

  <div class="instr">
    <pre>
<b>obj-llvm$ cd src</b>
src$ ls -l ls echo cat
-rwxr-xr-x 1 ddunbar ddunbar 65 2009-07-25 23:40 cat
-rwxr-xr-x 1 ddunbar ddunbar 66 2009-07-25 23:43 echo
-rwxr-xr-x 1 ddunbar ddunbar 94 2009-07-25 23:38 ls
<b>src$ ./cat --version</b>
cat (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

LLVM ERROR: JIT does not support inline asm! </pre>
  </div>

  <p>
    You may notice some funny things going on. To start with, the files are way
    too small! Since we are actually producing LLVM bitcode files, the operating
    system can't run them directly. What <tt>llvm-ld</tt> does to make it so we
    can still run the resulting outputs is write a little shell script which
    uses the LLVM interpreter to run the binaries; the actual LLVM bitcode
    files have <tt>.bc</tt> appended. If we look a little closer:
  </p>

  <div class="instr">
    <pre>
<b>src$ cat ls</b>
#!/bin/sh
lli=${LLVMINTERP-lli}
exec $lli \
    -load=/usr/lib/librt.so \
    ls.bc ${1+"$@"}
<b>src$ ls -l ls.bc</b>
-rwxr-xr-x 1 ddunbar ddunbar 643640 2009-07-25 23:38 ls.bc </pre>
  </div>

  <p>
    The other funny thing is that the version message doesn't all print out, the
    LLVM interpreter emits a message about not supporting inline assembly. The
    problem here is that <tt>glibc</tt> occasionally implements certain
    operations using inline assembly, which the LLVM interpreter (<tt>lli</tt>)
    doesn't understand. KLEE works around this problem by specially recognizing
    certain common inline assembly sequences and turning them back into the
    appropriate LLVM instructions before executing the binary.
  </p>

  <!--*********************************************************************-->
  
  <h2>Step 3: Using KLEE as an interpreter</h2>

  <p>
    At its core, KLEE is just an interpreter for LLVM bitcode. For example, here
    is how to run the same <tt>cat</tt> command we did before, using KLEE. Note,
    this step requires that you configured and built KLEE with <tt>uclibc</tt>
    and <tt>POSIX</tt> runtime support (if you didn't, you'll need to go do that
    now).
  </p>

  <div class="instr">
    <pre>
<b>src$ klee --libc=uclibc --posix-runtime ./cat.bc --version</b>
KLEE: NOTE: Using model: /home/ddunbar/public/klee/Release/lib/libkleeRuntimePOSIX.bca
KLEE: output directory = "klee-out-3"
KLEE: WARNING: undefined reference to function: __signbitl
KLEE: WARNING: executable has module level assembly (ignoring)
KLEE: WARNING: calling external: syscall(54, 0, 21505, 177325672)
KLEE: WARNING: calling __user_main with extra arguments.
KLEE: WARNING: calling external: getpagesize()
KLEE: WARNING: calling external: vprintf(177640072, 183340048)
cat (GNU coreutils) 6.11

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Torbjorn Granlund and Richard M. Stallman.
KLEE: WARNING: calling close_stdout with extra arguments.
Copyright (C) 2008 Free Software Foundation, Inc.
KLEE: done: total instructions = 259357
KLEE: done: completed paths = 1
KLEE: done: generated tests = 1
  </div>

  <p>
    We got a lot more output this time! Let's step through it, starting with the
    KLEE command itself. The general form of a KLEE command line is first the
    arguments for KLEE itself, then the LLVM bitcode file to execute
    (<tt>cat.bc</tt>), and then any arguments to pass to the application
    (<tt>--version</tt> in this case, as before).
  </p>
  
  <p>
    If we were running a normal native application, it would have been linked
    with the C library, but in this case KLEE is running the LLVM bitcode file
    directly. In order for KLEE to work effectively, it needs to have
    definitions for all the external functions the program may call. We have
    modified the <a href="http://www.uclibc.org">uClibc</a> C library
    implementation for use with KLEE; the <tt>--libc=uclibc</tt> KLEE argument
    tells KLEE to load that library and link it with the application before it
    starts execution.
  </p>

  <p>
    Similarly, a native application would be running on top of an operating
    system that provides lower level facilities like <tt>write()</tt>, which the
    C library uses in its implementation. As before, KLEE needs definitions for
    these functions in order to fully understand the program. We provide a POSIX
    runtime which is designed to work with KLEE and the uClibc library to
    provide the majority of operating system facilities used by command line
    applications -- the <tt>--posix-runtime</tt> argument tells KLEE to link
    this library in as well.
  </p>

  <p>
    As before, <tt>cat</tt> prints out its version information (note that this
    time all the text is written out), but we now have a number of additional
    information output by KLEE. In this case, most of these warnings are
    innocuous, but for completeness here is what they mean:
  </p>
  
  <ul>
    <li><i>undefined reference to function: __signbitl</i>: This warning means
      that the program contains a call to the function <tt>__signbitl</tt>,
      but that function isn't defined anywhere (we would have seen a lot more
      of these if we had not linked with uClibc and the POSIX runtime). If the
      program actually ends up making a call to this function while it is
      executing, KLEE won't be able to interpret it and may terminate the
      program.</li>
    
    <li><i>executable has module level assembly (ignoring)</i>: Some file
      compiled in to the application had file level inline-assembly, which KLEE
      can't understand. In this case this comes from uClibc and is unused, so
      this is safe.</li>
    
    <li><i>calling __user_main with extra arguments</i>: This indicates that
      the function was called with more arguments than it expected, it is
      almost always innocuous. In this case <tt>__user_main</tt> is actually
      the <tt>main()</tt> function for <tt>cat</tt>, which KLEE has renamed it
      when linking with uClibc. <tt>main()</tt> is being called with
      additional arguments by uClibc itself during startup, for example the
      environment pointer.</li>
    
    <li><i>calling external: getpagesize()</i>: This is an example of KLEE
      calling a function which is used in the program but is never
      defined. What KLEE actually does in such cases is try to call the native
      version of the function, if it exists. This is sometimes safe, as long
      as that function does write to any of the programs memory or attempt to
      manipulate symbolic values. <tt>getpagesize()</tt>, for example, just
      returns a constant.</li>
  </ul>

  <p>
    In general, KLEE will only emit a given warning once. The warnings are also
    logged to <tt>warnings.txt</tt> in the KLEE output directory.
  </p>

  <!--*********************************************************************-->
  
  <h2>Step 4: Introducing symbolic data to an application </h2>

  <p>
    We've seen that KLEE can interpret a program normally, but the real purpose
    of KLEE is to explore programs more exhaustively by making parts of their
    input symbolic. For example, lets look at running KLEE on the <tt>echo</tt>
    application.
  </p>
  
  <p>
    When using uClibc and the POSIX runtime, KLEE replaces the
    program's <tt>main()</tt> function with a special function
    (<tt>klee_init_env</tt>) provided inside the runtime library. This
    function alters the normal command line processing of the
    application, in particular to support construction of symbolic
    arguments. For example, passing <tt>--help</tt> yields:
  </p>

  <div class="instr">
    <pre>
<b>src$ klee --libc=uclibc --posix-runtime ./echo.bc --help</b>
<i>...</i>

usage: (klee_init_env) [options] [program arguments]
  -sym-arg <N>              - Replace by a symbolic argument with length N
  -sym-args <MIN> <MAX> <N> - Replace by at least MIN arguments and at most
                              MAX arguments, each with maximum length N
  -sym-files <NUM> <N>      - Make stdin and up to NUM symbolic files, each
                              with maximum size N.
  -sym-stdout               - Make stdout symbolic.
  -max-fail <N>             - Allow up to <N> injected failures
  -fd-fail                  - Shortcut for '-max-fail 1'
<i>...</i>
  </div>

  <p>
    As an example, lets run <tt>echo</tt> with a symbolic argument of 3
    characters.
  </p>

  <div class="instr">
    <pre>
<b>src$ klee --libc=uclibc --posix-runtime ./echo.bc --sym-arg 3</b>
KLEE: NOTE: Using model: /home/ddunbar/public/klee/Release/lib/libkleeRuntimePOSIX.bca
KLEE: output directory = "klee-out-16"
KLEE: WARNING: undefined reference to function: __signbitl
KLEE: WARNING: executable has module level assembly (ignoring)
KLEE: WARNING: calling external: syscall(54, 0, 21505, 189414856)
KLEE: WARNING: calling __user_main with extra arguments.
..
KLEE: WARNING: calling close_stdout with extra arguments.
...
KLEE: WARNING: calling external: printf(183664896, 183580400)
Usage: ./echo.bc [OPTION]... [STRING]...
Echo the STRING(s) to standard output.

  -n             do not output the trailing newline
  -e             enable interpretation of backslash escapes
  -E             disable interpretation of backslash escapes (default)
      --help     display this help and exit
      --version  output version information and exit

If -e is in effect, the following sequences are recognized:

  \0NNN   the character whose ASCII code is NNN (octal)
  \\     backslash
  \a     alert (BEL)
  \b     backspace
  \c     suppress trailing newline
  \f     form feed
  \n     new line
  \r     carriage return
  \t     horizontal tab
  \v     vertical tab

NOTE: your shell may have its own version of echo, which usually supersedes
the version described here.  Please refer to your shell's documentation
for details about the options it supports.

Report bugs to <bug-coreutils@gnu.org>.
KLEE: WARNING: calling external: vprintf(183956664, 190534360)
echo (GNU coreutils) 6.11

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by FIXME unknown.
...
...
...




..


.

.
..
...
Copyright (C) 2008 Free Software Foundation, Inc.
KLEE: done: total instructions = 300193
KLEE: done: completed paths = 25
KLEE: done: generated tests = 25<pre>
  </div>

  <p>
    The results here are slightly more interesting, KLEE has explored 25 paths
    through the program. The output from all the paths is intermingled, but you
    can see that in addition to echoing various random characters, some blocks
    of text also were output. You may be suprised to learn that
    coreutils' <tt>echo</tt> takes some arguments, in this case the
    options <tt>--v</tt> (short for <tt>--version</tt>) and <tt>--h</tt> (short
    for <tt>--help</tt>) were explored. We can get a short summary of KLEE's
    internal statistics by running <tt>klee-stats</tt> on the output directory
    (remember, KLEE always makes a symlink called <tt>klee-last</tt> to the most
    recent output directory).
  </p>

  <div class="instr">
    <pre>
<b>src$ klee-stats klee-last</b>
-------------------------------------------------------------------------
| Path      | Instrs | Time(s) | ICov(%) | BCov(%) | ICount | Solver(%) |
-------------------------------------------------------------------------
| klee-last | 300673 |    1.47 |   28.18 |   17.37 |  28635 |      5.65 |
-------------------------------------------------------------------------</pre>
  </div>

  <p>
    Here <em>ICov</em> is the percentage of LLVM instructions which were
    covered, and <em>BCov</em> is the percentage of branches that were
    covered. You may be wondering why the percentages are so low -- how much
    more code can echo have! The main reason is that these numbers are computed
    using all the instructions or branches in the bitcode files; that includes a
    lot of library code which may not even be executable. We can help with that
    problem (and others) by passing the <tt>--optimize</tt> option to KLEE. This
    will cause KLEE to run the LLVM optimization passes on the bitcode module
    before executing it; in particular they will remove any dead code. When
    working with non-trivial applications, it is almost always a good idea to
    use this flag. Here are the results from running again
    with <tt>--optimze</tt> enabled:
  </p>

  <div class="instr">
    <pre>
<b>src$ klee --optimize --libc=uclibc --posix-runtime ./echo.bc --sym-arg 3</b>
<i>...</i>
KLEE: done: total instructions = 123251
KLEE: done: completed paths = 25
KLEE: done: generated tests = 25
src$ klee-stats klee-last
-------------------------------------------------------------------------
| Path      | Instrs | Time(s) | ICov(%) | BCov(%) | ICount | Solver(%) |
-------------------------------------------------------------------------
| klee-last | 123251 |    0.32 |   38.02 |   25.43 |   9531 |     29.66 |
-------------------------------------------------------------------------</pre>
  </div>

  <p>
    This time the instruction coverage went up by about ten percent, and you can
    see that KLEE also ran faster and executed less instructions. Most of the
    remaining code is still in library functions, just in places that the
    optimizers aren't smart enough to remove. We can verify this -- and look for
    uncovered code inside <tt>echo</tt> -- by using KCachegrind to visualize the
    results of a KLEE run.
  </p>

  <!--*********************************************************************-->
  
  <h2>Step 5: Visualizing KLEE's progress with <tt>kcachegrind</tt> </h2>

  <p>
    <a href="http://kcachegrind.sourceforge.net">KCachegrind</a> is an excellent
    profiling visualization tool, originally written for use with the callgrind
    plugin for valgrind. If you don't have it already, it is usually easily
    available on a modern Linux distribution via your platforms' software
    installation tool (e.g., <tt>apt-get</tt> or <tt>yum</tt>).
  </p>

  <p>
    KLEE by default writes out a <tt>run.istats</tt> file into the test output
    directory which is actually a KCachegrind file. In this example,
    the <tt>run.istats</tt> is from a run without <tt>--optimize</tt>, so the
    results are easier to understand. Assuming you have KCachegrind installed,
    just run:
  </p>

  <div class="instr">
    <pre> <b>src$ kcachegrind klee-last/run.istats</b> </pre>
  </div>

  <p>
    After KCachegrind opens, you should see a window that looks something like
    the one below. You should make sure that the "Instructions" statistic is
    selected by choosing "View" &gt; "Primary Event Type" &gt; "Instructions"
    from the menu, and make sure the "Source Code" view is selected (the right
    hand pane in the screenshot below).
  </p>
  
    <a href="content/coreutils_kc_0.png">
      <img src="content/coreutils_kc_0.png" height=500></a>

  <p>
    KCachegrind is a complex application in itself, and interested users should
    see the KCachegrind website for more information and documentation. However,
    the basics are that the one pane shows the "Flat Profile"; this is a list of
    which how many instructions were executed in each function. The "Self"
    column is the number of instructions which were executed in the function
    itself, and the "Incl" (inclusive) column is the number of instructions
    which were executed in the function, or any of the functions it called (or
    its callees called, and so on).
  </p>

  <p>
    KLEE includes quite a few statistics about execution. The one we are
    interested in now is "Uncovered Instructions", which will show which
    functions have instructions which were never executed. If you select that
    statistic and resort the list of functions, you should see something like
    this:
  </p>
  
    <a href="content/coreutils_kc_1.png">
      <img src="content/coreutils_kc_1.png" height=500></a>

  <p>
    Notice that most of the uncovered instructions are in library code as we
    would expect. However, if we select the <tt>__user_main</tt> function, we
    can look for code inside <tt>echo</tt> itself that was uncovered. In this
    case, most of the uncovered instructions are inside a large <tt>if</tt>
    statement guarded by the variable <tt>do_v9</tt>. If you look a bit more,
    you can see that this is a flag set to true when <tt>-e</tt> is passed. The
    reason that KLEE never explored this code is because we only passed one
    symbolic argument -- hitting this code requires a command line like <tt>$
    echo -e \a</tt>.
  </p>

  <p>
    One subtle thing to understand if you are trying to actually make sense of
    the KCachegrind numbers is that they include events accumulated across all
    states. For example, consider the following code:
  </p>

  <div class="instr">
    <pre>
Line 1:      a = 1;
Line 2:      if (...)
Line 3:        printf("hello\n");
Line 4:      b = c; </pre>
  </div>

  <p>
    In a normal application, if the statement on Line 1 was only executed once,
    then the statement on Line 4 could be (at most) executed once. When KLEE is
    running an application, however, it could fork and generate separate
    processes at Line 2. In that case, Line 4 may be executed more times than
    Line 1!
  </p>

  <p>
    Another useful tidbit: KLEE actually writes the <tt>run.istats</tt> file
    periodically as the application is running. This provides one way to monitor
    the status of long running applications (another way is to use the
    klee-stats tool).
  </p>

  <!--*********************************************************************-->
  
  <h2>Step 6: Replaying KLEE generated test cases </h2>

  <p>
    Let's step away from KLEE for a bit and look at just the test cases KLEE
    generated. If we look inside the <tt>klee-last</tt> we should see
    25 <tt>.ktest</tt> files.
  </p>

  <div class="instr">
    <pre>
<b>src$ ls klee-last</b>
assembly.ll	  test000004.ktest  test000012.ktest  test000020.ktest
info		  test000005.ktest  test000013.ktest  test000021.ktest
messages.txt	  test000006.ktest  test000014.ktest  test000022.ktest
run.istats	  test000007.ktest  test000015.ktest  test000023.ktest
run.stats	  test000008.ktest  test000016.ktest  test000024.ktest
test000001.ktest  test000009.ktest  test000017.ktest  test000025.ktest
test000002.ktest  test000010.ktest  test000018.ktest  warnings.txt
test000003.ktest  test000011.ktest  test000019.ktest </pre>
  </div>

  <p>
    These files contain the actual values to use for the symbolic data in order
    to reproduce the path that KLEE followed (either for obtaining code
    coverage, or for reproducing a bug). They also contain additional metadata
    generated by the POSIX runtime in order to track what the values correspond
    to and the version of the runtime. We can look at the individual contents of
    one file using <tt>ktest-tool</tt>:
  </p>

  <div class="instr">
    <pre>
<b>$ ktest-tool klee-last/test000001.ktest</b>
ktest file : 'klee-last/test000001.ktest'
args       : ['./echo.bc', '--sym-arg', '3']
num objects: 2
object    0: name: 'arg0'
object    0: size: 4
object    0: data: '@@@\x00'
object    1: name: 'model_version'
object    1: size: 4
object    1: data: '\x01\x00\x00\x00' </pre>
  </div>

  <p>
    In this case, the test case indicates that values "@@@\x00" should be passed
    as the first argument. However, <tt>.ktest</tt> files generally aren't
    really meant to be looked at directly. For the POSIX runtime, we provide a
    tool <tt>klee-replay</tt> which can be used to read the <tt>.ktest</tt> file
    and invoke the native application, automatically passing it the data
    necessary to reproduce the path that KLEE followed. 
  </p>

  <p>
    To see how it works, go back to the directory where we built the native
    executables:
  </p>

  <div class="instr">
    <pre>
<b>src$ cd ..</b>
<b>obj-llvm$ cd ..</b>
<b>coreutils-6.11$ cd obj-gcov</b>
<b>obj-gcov$ cd src</b>
<b>src$ ls -l echo</b>
-rwxr-xr-x 1 ddunbar ddunbar 151051 2009-07-25 20:59 echo </pre>
  </div>

  <p>
    To use the <tt>klee-replay</tt> tool, we just tell it the executable to run
    and the <tt>.ktest</tt> file to use. The program arguments, input files,
    etc. will all be constructed from the data in the <tt>.ktest</tt> file.
  </p>

  <div class="instr">
    <pre>
<b>src$ klee-replay ./echo ../../obj-llvm/src/klee-last/test000001.ktest </b>
klee-replay: TEST CASE: ../../obj-llvm/src/klee-last/test000001.ktest
klee-replay: ARGS: "./echo" "@@@" 
@@@
klee-replay: EXIT STATUS: NORMAL (0 seconds) </pre>
  </div>

  <p>
    The first two and last lines here come from the <tt>klee-replay</tt> tool
    itself. The first two lines list the test case being run, and the concrete
    values for arguments that are being passed to the application (notice this
    matches what we saw in the <tt>.ktest</tt> file earlier). The last line is
    the exit status of the program and the elapsed time to run.
  </p>
  
  <p>
    We can also use the <tt>klee-replay</tt> tool to run a set of test cases at
    once, one after the other. Let's do this and compare the <tt>gcov</tt>
    coverage to the numbers we got from <tt>klee-stats</tt>:
  </p>

  <div class="instr">
    <pre>
<b>src$ rm -f *.gcda</b> <i># Get rid of any stale gcov files</i>
<b>src$ klee-replay ./echo ../../obj-llvm/src/klee-last/*.ktest </b>
klee-replay: TEST CASE: ../../obj-llvm/src/klee-last/test000001.ktest
klee-replay: ARGS: "./echo" "@@@" 
@@@
klee-replay: EXIT STATUS: NORMAL (0 seconds)
<i>...</i>
klee-replay: TEST CASE: ../../obj-llvm/src/klee-last/test000022.ktest
klee-replay: ARGS: "./echo" "--v" 
echo (GNU coreutils) 6.11
Copyright (C) 2008 Free Software Foundation, Inc.
<i>...</i>

<b>src$ gcov echo</b>
File '../../src/system.h'
Lines executed:6.38% of 47
../../src/system.h:creating 'system.h.gcov'

File '../../lib/timespec.h'
Lines executed:0.00% of 2
../../lib/timespec.h:creating 'timespec.h.gcov'

File '../../lib/gettext.h'
Lines executed:0.00% of 32
../../lib/gettext.h:creating 'gettext.h.gcov'

File '../../lib/openat.h'
Lines executed:0.00% of 8
../../lib/openat.h:creating 'openat.h.gcov'

File '../../src/echo.c'
Lines executed:50.50% of 101
../../src/echo.c:creating 'echo.c.gcov' </pre>
  </div>

  <p>
    The number for <tt>echo.c</tt> here significantly higher than
    the <tt>klee-stats</tt> number because <tt>gcov</tt> is only considering
    lines in that one file, not the entire application. As with <tt>kcachegrind</tt>, we can inspect the coverage file output by <tt>gcov</tt> to see exactly what lines were covered and which weren't. Here is a fragment from the output:
  </p>

  <div class="instr">
    <pre>
        -:  193:      }
        -:  194:
       23:  195:just_echo:
        -:  196:
       23:  197:  if (do_v9)
        -:  198:    {
       10:  199:      while (argc > 0)
        -:  200:	{
    #####:  201:	  char const *s = argv[0];
        -:  202:	  unsigned char c;
        -:  203:
    #####:  204:	  while ((c = *s++))
        -:  205:	    {
    #####:  206:	      if (c == '\\' && *s)
        -:  207:		{
    #####:  208:		  switch (c = *s++)
        -:  209:		    {
    #####:  210:		    case 'a': c = '\a'; break;
    #####:  211:		    case 'b': c = '\b'; break;
    #####:  212:		    case 'c': exit (EXIT_SUCCESS);
    #####:  213:		    case 'f': c = '\f'; break;
    #####:  214:		    case 'n': c = '\n'; break; </pre>
  </div>
        
  <p>
    The far left hand column is the number of times each line was
    executed; <b>-</b> means the line has no executable code, and <b>#####</b>
    means the line was never covered. As you can see, the uncovered lines here
    correspond exactly to the uncovered lines as reported
    in <tt>kcachegrind</tt>.
  </p>

  <p>
    Before moving on to testing more complex applications, lets make sure we can
    get decent coverage of the simple <tt>echo.c</tt>. The problem before was
    that we weren't making enough data symbolic, providing echo with two
    symbolic arguments should be plenty to cover the entire program. We can use
    the POSIX runtime <tt>--sym-args</tt> option to pass multiple options. Here
    are the steps, after switching back to the <tt>obj-llvm/src</tt> directory:
  </p>

  <div class="instr">
    <pre>
<b>src$ klee --only-output-states-covering-new --optimize --libc=uclibc --posix-runtime ./echo.bc --sym-args 0 2 4</b>
<i> ... </i>
KLEE: done: total instructions = 7437521
KLEE: done: completed paths = 9963
KLEE: done: generated tests = 55 </pre>
</div>

  <p>
    The format of the <tt>--sym-args</tt> option actually specifies a minimum
    and a maximum number of arguments to pass and the length to use for each
    argument. In this case <tt>--sym-args 0 2 4</tt> says to pass between 0 and
    2 arguments (inclusive), each with a maximum length of four characters.
  </p>
  
  <p>
    We also added the <tt>--only-output-states-covering-new</tt> option to the
    KLEE command line. By default KLEE will write out test cases for every path
    it explores. This becomes less useful <!-- and should become not the default
    --> once the program becomes larger, because many test cases will end up
    exercise the same paths, and computing (or even reexecuting) each one wastes
    time. Using this option tells KLEE to only output test cases for paths which
    covered some new instruction in the code (or hit an error). The final lines
    of the output show that even though KLEE explored almost ten thousand paths
    through the code, it only needed to write 55 test cases.
  </p>

  <p>
    If we go back to the <tt>obj-gcov/src</tt> directory and rerun the latest
    set of test cases, we finally have reasonable coverage of <tt>echo.c</tt>:
  </p>

  <div class="instr">
    <pre>
<b>src$ rm -f *.gcda</b> <i># Get rid of any stale gcov files</i>
<b>src$ klee-replay ./echo ../../obj-llvm/src/klee-last/*.ktest </b>
klee-replay: TEST CASE: ../../obj-llvm/src/klee-last/test000001.ktest
klee-replay: ARGS: "./echo" 

<i> ... </i>

<b>src$ gcov echo</b>
File '../../src/system.h'
Lines executed:6.38% of 47
../../src/system.h:creating 'system.h.gcov'

File '../../lib/timespec.h'
Lines executed:0.00% of 2
../../lib/timespec.h:creating 'timespec.h.gcov'

File '../../lib/gettext.h'
Lines executed:0.00% of 32
../../lib/gettext.h:creating 'gettext.h.gcov'

File '../../lib/openat.h'
Lines executed:0.00% of 8
../../lib/openat.h:creating 'openat.h.gcov'

File '../../src/echo.c'
Lines executed:97.03% of 101
../../src/echo.c:creating 'echo.c.gcov' </pre>
</div>

  <p>
    The reasons for not getting perfect 100% line coverage are left as an
    exercise to the reader. :) <!-- FIXME: Technically, it's just cause I haven't
    bothered to figure it out... figure it out! -->
  </p>

  <!--*********************************************************************-->
    
  <h2>Step 7: Using <tt>zcov</tt> to analyze coverage </h2>

  <p>
  For visualizing the coverage results, you might want to use the <a href="http://minormatter.com/zcov/">zcov</a> tool.
  </p>
  <br/>

</div>
</body>
</html>