Presentation about code analysis framework for CDT which is C/C++ IDE based on Eclipse. How to write a good static analysis tool? How to integrate right where develop introduces bugs? Catch bugs as you type!
Unlocking the Future of AI Agents with Large Language Models
Eclipse Con 2015: Codan - a C/C++ Code Analysis Framework for CDT
1. Codan - a Code Analysis Framework
for CDT
Elena Laskavaia
2015 If (getuid()!=0 && geteuid==0) {
ErrorF(“only root”);
exit(1);
}
2. Why Static Analysis?
Defect
Detection
Potential
Problems
Code Style
Security
Violations
Defect
Detection
Unused
Code
Code
Patterns
Metrics
Violations
Reverse
Engineering
Model
Visualization
Cross-
Reference
Metrics
Forward
Engineering
Refactoring
Context-
Assist
Code
Generation
Analysis of source code without running the program
3. Cost of fixing one bug
Stage Bug Life Cost
As you type 1 s 1 cent
Developer build 10 sec 10 cent
Developer testing 10 min $3
SCM check in 4 h $10
Integration build 1 d $40
Integration testing 10 days $200
In the field 30 days $1000+
In outer space 3 years $100 million*
1
10
100
1000
10000
Dev Unit QA User Live
Cost
10. Codan Problem Markers
• Codan problem markers – categories, editor annotations
• Quick Fix
• Problem Details view
• Menu: Customize Problem...
• Menu: Show in -> Problem Details
13. Writing a Good Checker
Framework worth
nothing without checkers
Framework is bad if
checkers are bad
What does it take to write
a good checker?
14. Good Defect Detection Tool
• Be part of the processIntegrated
• Ignore defects, change severity, parameterizeCustomizable
• Fix the code - if canAuto-correcting
• Bad description damages tool reputationSelf-explaining
• No code modifications: exceptions, historyHide false positives
• Reconfigure itself based on defect densityAdaptable
• Not: laggy, annoying, noisy, wrongNot burden
15. Checker Design Cycle
• Unit tests
• “Field” test
•Profiling
•Customization
•Properties
•Checker
•Quick Fix
•Error Parsers
•Problem Details
•Idea
•Presentation
•Code Model
•Good fit?
Design Develop
TestTune
17. Problem Marker is a problem
Problem Marker – you blame developer
Defensive reaction – blame the tool
Too much red marks – turn it off
Too many f.p. – don't trust anymore
Unclear description – tool is wrong
21. dummy() {
return;
}
void some1();
void some() {
return some1();
}
int retindead() {
return 5;;
}
int infloop() {
while(1) { … }
}
void f() {
[](int r){return r;}(5);
}
int test() {
class A {
void m() { return; };
}
}
auto f() -> void
{
}
f.p. -
nobody cares
f.p. - void
expression
f.p. - missing
auto evaluation
f.p. - enclosed
functions
f.p. - lambda
f.p. - dead code
or unreachable
Return Mismatch Checker
History in bug reports…
• Return type of function does not match type of return expression
• Or return is missing for non-void function
22. Return Checker Uses Models
AST
Preprocessor
Comments
Tokens
Bindings
Control Flow
Graph
Data Flow
Graph*
Text
File Structure
C-Model
(Containment)
C-Index
(Cross Reference)
25. Checker Class
public class StatementHasNoEffectChecker extends AbstractIndexAstChecker {
private static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem";
public void processAst(IASTTranslationUnit ast) {
ast.accept(new CheckStmpVisitor());
}
class CheckStmpVisitor extends ASTVisitor {
CheckStmpVisitor() {
shouldVisitStatements = true;
}
public int visit(IASTStatement stmt) {
if (stmt instanceof IASTExpressionStatement) {
if (hasNoEffect(((IASTExpressionStatement) stmt).getExpression())) {
reportProblem(ER_ID, stmt);
}
return PROCESS_SKIP;
}
return PROCESS_CONTINUE;
}
…
See full code of this checker in codan subtree of project:
org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/StatementHasNoEffectChecker.java
26. External Tool Integration
• Triggers (choose one)
– Integrate into build system and parse output
– Invoke from checker and parse output
• Severity Mapping
• Problem Preference editor (or not)
• Extra details (hyperlinks)
• Tool configuration (preference page)
29. External Invoke Code
public void processUnit(ITranslationUnit unit) {
IScannerInfo scannerInfo = unit.getScannerInfo(true);
List<String> res = getCompilerOptionsList(scannerInfo); // -I.. –D…
res.add("-c");res.add("-o/dev/null");res.add("-O2");res.add("-Wall");// default flags
res.add(unit.getFile().getLocation().toPortableString());// file path
String args[] = res.toArray(new String[res.size()]);
try {
externalToolInvoker.launchOnBuildConsole(
unit.getResource().getProject(),
new IConsoleParser[] { getConsoleParser(unit) }, // parser converts patterns to markers
"check",
getToolPath(), args, new String[] {}, getWorkingDirectory(), // command line
new NullProgressMonitor());
} catch (CoreException | InvocationFailure e) {
Activator.log(e);
}
}
30. APIs
CDT
Codan
Base Checkers
Base Quick Fix
Problem Details
Control Flow Graph
Error Parser Utils
Launch Utils
CDT
C-AST
Comments
Includes
Marcos
Tokens
AST
Bindings
CDT
Core
C-Element
Containment
Cross References
Error Parsers
Scanner Discovery
AST-Rewrite
Eclipse
Platform
Property Change
Listeners
Problem Markers
Editor Annotations
Resources
31. Test
Run Static Analysis
• On checker’s code!
Write Junits
• True Positives
• True Negatives
• Error recovery
• Use Code Coverage
Field Testing
• Large Code Base
• C++ not only C
• Inspect for f.p.
32. Junit Test and Coverage
// main() {
// int a,b;
//
// b+a; // error here
// }
public void testBinaryExpression() {
checkSampleAbove();
}
// main() {
// int a,b;
//
// a=b+a; // no error here
// }
public void testNormalAssignment() {
checkSampleAbove();
}
34. Adding problem parameters
public void initPreferences(IProblemWorkingCopy problem) {
super.initPreferences(problem);
if (problem.getId().equals(RET_NO_VALUE_ID)) {
addPreference(problem, PARAM_IMPLICIT,
“Also check functions with implicit return value”,
Boolean.FALSE);
}
}
35. Creative Use
Quick Fix Only
• Error pattern to trigger quick fix from compiler errors
Problem Details Only
• Hyperlink to generic search
Compile as you type
• As computers getting faster… c++ compilers too!
Tool chain warning configuration
• Modify build configuration as user changes error profile
Editor Markup
• Use highlighting annotations instead of regular once
Headless
• Reuse checkers to run headless