@@ -45,7 +45,13 @@ <h1>Checker Developer Manual</h1>
45
45
< li > < a href ="#bugs "> Bug Reports</ a > </ li >
46
46
< li > < a href ="#ast "> AST Visitors</ a > </ li >
47
47
< li > < a href ="#testing "> Testing</ a > </ li >
48
- < li > < a href ="#commands "> Useful Commands/Debugging Hints</ a > </ li >
48
+ < li > < a href ="#commands "> Useful Commands/Debugging Hints</ a >
49
+ < ul >
50
+ < li > < a href ="#attaching "> Attaching the Debugger</ a > </ li >
51
+ < li > < a href ="#narrowing "> Narrowing Down the Problem</ a > </ li >
52
+ < li > < a href ="#visualizing "> Visualizing the Analysis</ a > </ li >
53
+ < li > < a href ="#debugprints "> Debug Prints and Tricks</ a > </ li >
54
+ </ ul > </ li >
49
55
< li > < a href ="#additioninformation "> Additional Sources of Information</ a > </ li >
50
56
< li > < a href ="#links "> Useful Links</ a > </ li >
51
57
</ ul >
@@ -115,6 +121,8 @@ <h2 id=analyzer>Static Analyzer Overview</h2>
115
121
</ ul >
116
122
117
123
< h3 id =interaction > Interaction with Checkers</ h3 >
124
+
125
+ < p >
118
126
Checkers are not merely passive receivers of the analyzer core changes - they
119
127
actively participate in the < tt > ProgramState</ tt > construction through the
120
128
< tt > GenericDataMap</ tt > which can be used to store the checker-defined part
@@ -123,9 +131,12 @@ <h3 id=interaction>Interaction with Checkers</h3>
123
131
opportunity to either report a bug or modify the state. (As a rule of thumb,
124
132
the checker itself should be stateless.) The checkers are called one after another
125
133
in the predefined order; thus, calling all the checkers adds a chain to the
126
- < tt > ExplodedGraph</ tt > .
134
+ < tt > ExplodedGraph</ tt > .
135
+ </ p >
127
136
128
137
< h3 id =values > Representing Values</ h3 >
138
+
139
+ < p >
129
140
During symbolic execution, < a href ="http://clang.llvm.org/doxygen/classclang_1_1ento_1_1SVal.html "> SVal</ a >
130
141
objects are used to represent the semantic evaluation of expressions.
131
142
They can represent things like concrete
@@ -142,15 +153,17 @@ <h3 id=values>Representing Values</h3>
142
153
This represents a case that is outside the realm of the analyzer's reasoning
143
154
capabilities. < tt > SVals</ tt > are value objects and their values can be viewed
144
155
using the < tt > .dump()</ tt > method. Often they wrap persistent objects such as
145
- symbols or regions.
156
+ symbols or regions.
157
+ </ p >
158
+
146
159
< p >
147
160
< a href ="http://clang.llvm.org/doxygen/classclang_1_1ento_1_1SymExpr.html "> SymExpr</ a > (symbol)
148
161
is meant to represent abstract, but named, symbolic value. Symbols represent
149
162
an actual (immutable) value. We might not know what its specific value is, but
150
163
we can associate constraints with that value as we analyze a path. For
151
164
example, we might record that the value of a symbol is greater than
152
165
< tt > 0</ tt > , etc.
153
- < p >
166
+ </ p >
154
167
155
168
< p >
156
169
< a href ="http://clang.llvm.org/doxygen/classclang_1_1ento_1_1MemRegion.html "> MemRegion</ a > is similar to a symbol.
@@ -163,9 +176,12 @@ <h3 id=values>Representing Values</h3>
163
176
< a href ="http://clang.llvm.org/doxygen/classclang_1_1ento_1_1SymbolicRegion.html "> SymbolicRegion</ a >
164
177
is for. It is a < tt > MemRegion</ tt > that has an associated symbol. Since the
165
178
symbol is unique and has a unique name; that symbol names the region.
179
+ </ p >
166
180
167
- < P >
181
+ < p >
168
182
Let's see how the analyzer processes the expressions in the following example:
183
+ </ p >
184
+
169
185
< p >
170
186
< pre class ="code_example ">
171
187
int foo(int x) {
@@ -174,6 +190,8 @@ <h3 id=values>Representing Values</h3>
174
190
...
175
191
}
176
192
</ pre >
193
+ </ p >
194
+
177
195
< p >
178
196
Let's look at how < tt > x*2</ tt > gets evaluated. When < tt > x</ tt > is evaluated,
179
197
we first construct an < tt > SVal</ tt > that represents the lvalue of < tt > x</ tt > , in
@@ -193,13 +211,15 @@ <h3 id=values>Representing Values</h3>
193
211
The second line is similar. When we evaluate < tt > x</ tt > again, we do the same
194
212
dance, and create an < tt > SVal</ tt > that references the symbol < tt > $0</ tt > . Note, two < tt > SVals</ tt >
195
213
might reference the same underlying values.
214
+ </ p >
196
215
197
216
< p >
198
217
To summarize, MemRegions are unique names for blocks of memory. Symbols are
199
218
unique names for abstract symbolic values. Some MemRegions represents abstract
200
219
symbolic chunks of memory, and thus are also based on symbols. SVals are just
201
220
references to values, and can reference either MemRegions, Symbols, or concrete
202
221
values (e.g., the number 1).
222
+ </ p >
203
223
204
224
<!--
205
225
TODO: Add a picture.
@@ -511,75 +531,139 @@ <h2 id=testing>Testing</h2>
511
531
live in < tt > clang/test/Analysis</ tt > folder. To run all of the analyzer tests,
512
532
execute the following from the < tt > clang</ tt > build directory:
513
533
< pre class ="code ">
514
- $ < b > TESTDIRS=Analysis make test</ b >
534
+ $ < b > bin/llvm-lit -sv ../llvm/tools/clang/ test/Analysis </ b >
515
535
</ pre >
516
536
517
537
< h2 id =commands > Useful Commands/Debugging Hints</ h2 >
518
- < ul >
519
- < li >
520
- While investigating a checker-related issue, instruct the analyzer to only
538
+
539
+ < h3 id =attaching > Attaching the Debugger</ h3 >
540
+
541
+ < p > When your command contains the < tt > < b > -cc1</ b > </ tt > flag, you can attach the
542
+ debugger to it directly:</ p >
543
+
544
+ < pre class ="code ">
545
+ $ < b > gdb --args clang -cc1 -analyze -analyzer-checker=core test.c</ b >
546
+ $ < b > lldb -- clang -cc1 -analyze -analyzer-checker=core test.c</ b >
547
+ </ pre >
548
+
549
+ < p >
550
+ Otherwise, if your command line contains < tt > < b > --analyze</ b > </ tt > ,
551
+ the actual clang instance would be run in a separate process. In
552
+ order to debug it, use the < tt > < b > -###</ b > </ tt > flag for obtaining
553
+ the command line of the child process:
554
+ </ p >
555
+
556
+ < pre class ="code ">
557
+ $ < b > clang --analyze test.c -\#\#\#</ b >
558
+ </ pre >
559
+
560
+ < p >
561
+ Below we describe a few useful command line arguments, all of which assume that
562
+ you are running < tt > < b > clang -cc1</ b > </ tt > .
563
+ </ p >
564
+
565
+ < h3 id =narrowing > Narrowing Down the Problem</ h3 >
566
+
567
+ < p > While investigating a checker-related issue, instruct the analyzer to only
521
568
execute a single checker:
522
- < br > < tt >
523
- $ < b > clang -cc1 -analyze -analyzer-checker=osx.KeychainAPI test.c</ b >
524
- </ tt >
525
- </ li >
526
- < li >
527
- To dump AST:
528
- < br > < tt >
529
- $ < b > clang -cc1 -ast-dump test.c</ b >
530
- </ tt >
531
- </ li >
532
- < li >
533
- To view/dump CFG use < tt > debug.ViewCFG</ tt > or < tt > debug.DumpCFG</ tt > checkers:
534
- < br > < tt >
535
- $ < b > clang -cc1 -analyze -analyzer-checker=debug.ViewCFG test.c</ b >
536
- </ tt >
537
- </ li >
538
- < li >
539
- To see all available debug checkers:
540
- < br > < tt >
541
- $ < b > clang -cc1 -analyzer-checker-help | grep "debug"</ b >
542
- </ tt >
543
- </ li >
544
- < li >
545
- To see which function is failing while processing a large file use
546
- < tt > -analyzer-display-progress</ tt > option.
547
- </ li >
548
- < li >
549
- While debugging execute < tt > clang -cc1 -analyze -analyzer-checker=core</ tt >
550
- instead of < tt > clang --analyze</ tt > , as the later would call the compiler
551
- in a separate process.
552
- </ li >
553
- < li >
554
- To view < tt > ExplodedGraph</ tt > (the state graph explored by the analyzer) while
555
- debugging, goto a frame that has < tt > clang::ento::ExprEngine</ tt > object and
556
- execute:
557
- < br > < tt >
558
- (gdb) < b > p ViewGraph(0)</ b >
559
- </ tt >
560
- </ li >
561
- < li >
562
- To see the < tt > ProgramState</ tt > while debugging use the following command.
563
- < br > < tt >
564
- (gdb) < b > p State-> dump()</ b >
565
- </ tt >
566
- </ li >
567
- < li >
568
- To see < tt > clang::Expr</ tt > while debugging use the following command. If you
569
- pass in a SourceManager object, it will also dump the corresponding line in the
570
- source code.
571
- < br > < tt >
572
- (gdb) < b > p E-> dump()</ b >
573
- </ tt >
574
- </ li >
575
- < li >
576
- To dump AST of a method that the current < tt > ExplodedNode</ tt > belongs to:
577
- < br > < tt >
578
- (gdb) < b > p C.getPredecessor()-> getCodeDecl().getBody()-> dump()</ b >
579
- (gdb) < b > p C.getPredecessor()-> getCodeDecl().getBody()-> dump(getContext().getSourceManager())</ b >
580
- </ tt >
581
- </ li >
582
- </ ul >
569
+ </ p >
570
+ < pre class ="code ">
571
+ $ < b > clang -cc1 -analyze -analyzer-checker=osx.KeychainAPI test.c</ b >
572
+ </ pre >
573
+
574
+ < p > If you are experiencing a crash, to see which function is failing while
575
+ processing a large file use the < tt > < b > -analyzer-display-progress</ b > </ tt >
576
+ option.</ p >
577
+
578
+ < p > You can analyze a particular function within the file, which is often useful
579
+ because the problem is always in a certain function:</ p >
580
+ < pre class ="code ">
581
+ $ < b > clang -cc1 -analyze -analyzer-checker=core test.c -analyzer-display-progress</ b >
582
+ ANALYZE (Syntax): test.c foo
583
+ ANALYZE (Syntax): test.c bar
584
+ ANALYZE (Path, Inline_Regular): test.c bar
585
+ ANALYZE (Path, Inline_Regular): test.c foo
586
+ $ < b > clang -cc1 -analyze -analyzer-checker=core test.c -analyzer-display-progress -analyze-function=foo</ b >
587
+ ANALYZE (Syntax): test.c foo
588
+ ANALYZE (Path, Inline_Regular): test.c foo
589
+ </ pre >
590
+
591
+ < p > The bug reporter mechanism removes path diagnostics inside intermediate
592
+ function calls that have returned by the time the bug was found and contain
593
+ no interesting pieces. Usually it is up to the checkers to produce more
594
+ interesting pieces by adding custom < tt > BugReporterVisitor</ tt > objects.
595
+ However, you can disable path pruning while debugging with the
596
+ < tt > < b > -analyzer-config prune-paths=false</ b > </ tt > option.
597
+
598
+ < h3 id =visualizing > Visualizing the Analysis</ h3 >
599
+
600
+ < p > To dump the AST, which often helps understanding how the program should
601
+ behave:</ p >
602
+ < pre class ="code ">
603
+ $ < b > clang -cc1 -ast-dump test.c</ b >
604
+ </ pre >
605
+
606
+ < p > To view/dump CFG use < tt > debug.ViewCFG</ tt > or < tt > debug.DumpCFG</ tt >
607
+ checkers:</ p >
608
+ < pre class ="code ">
609
+ $ < b > clang -cc1 -analyze -analyzer-checker=debug.ViewCFG test.c</ b >
610
+ </ pre >
611
+
612
+ < p > < tt > ExplodedGraph</ tt > (the state graph explored by the analyzer) can be
613
+ visualized with another debug checker:</ p >
614
+ < pre class ="code ">
615
+ $ < b > clang -cc1 -analyze -analyzer-checker=debug.ViewExplodedGraph test.c</ b >
616
+ </ pre >
617
+ < p > Or, equivalently, with < tt > < b > -analyzer-viz-egraph-graphviz</ b > </ tt >
618
+ option, which does the same thing - dumps the exploded graph in graphviz
619
+ < tt > < b > .dot</ b > </ tt > format.</ p >
620
+
621
+ < p > You can convert < tt > < b > .dot</ b > </ tt > files into other formats - in
622
+ particular, converting to < tt > < b > .svg</ b > </ tt > and viewing in your web
623
+ browser might be more comfortable than using a < tt > < b > .dot</ b > </ tt > viewer:</ p >
624
+ < pre class ="code ">
625
+ $ < b > dot -Tsvg ExprEngine-501e2e.dot -o ExprEngine-501e2e.svg</ b >
626
+ </ pre >
627
+
628
+ < p > The < tt > < b > -trim-egraph</ b > </ tt > option removes all paths except those
629
+ leading to bug reports from the exploded graph dump. This is useful
630
+ because exploded graphs are often huge and hard to navigate.</ p >
631
+
632
+ < p > Viewing < tt > ExplodedGraph</ tt > is your most powerful tool for understanding
633
+ the analyzer's false positives, because it gives comprehensive information
634
+ on every decision made by the analyzer across all analysis paths.</ p >
635
+
636
+ < p > There are more debug checkers available. To see all available debug checkers:
637
+ </ p >
638
+ < pre class ="code ">
639
+ $ < b > clang -cc1 -analyzer-checker-help | grep "debug"</ b >
640
+ </ pre >
641
+
642
+ < h3 id =debugprints > Debug Prints and Tricks</ h3 >
643
+
644
+ < p > To view "half-baked" < tt > ExplodedGraph</ tt > while debugging, jump to a frame
645
+ that has < tt > clang::ento::ExprEngine</ tt > object and execute:</ p >
646
+ < pre class ="code ">
647
+ (gdb) < b > p ViewGraph(0)</ b >
648
+ </ pre >
649
+
650
+ < p > To see the < tt > ProgramState</ tt > while debugging use the following command.
651
+ < pre class ="code ">
652
+ (gdb) < b > p State-> dump()</ b >
653
+ </ pre >
654
+
655
+ < p > To see < tt > clang::Expr</ tt > while debugging use the following command. If you
656
+ pass in a < tt > SourceManager</ tt > object, it will also dump the corresponding line in the
657
+ source code.</ p >
658
+ < pre class ="code ">
659
+ (gdb) < b > p E-> dump()</ b >
660
+ </ pre >
661
+
662
+ < p > To dump AST of a method that the current < tt > ExplodedNode</ tt > belongs
663
+ to:</ p >
664
+ < pre class ="code ">
665
+ (gdb) < b > p C.getPredecessor()-> getCodeDecl().getBody()-> dump()</ b >
666
+ </ pre >
583
667
584
668
< h2 id =additioninformation > Additional Sources of Information</ h2 >
585
669
0 commit comments