[PATCH] [analyzer] Detect use-after-free scenarios in -dealloc after calling [super dealloc]
David Kilzer
ddkilzer at kilzer.net
Sat Aug 23 23:17:41 PDT 2014
> * Crash in ASTMatchers running `test/Analysis/PR2978.m` test, possibly due to invalid code in `-dealloc` method. Haven't figured out how to make a stand-alone test case yet.
Something is going horribly wrong dereferencing a `clang::Stmt *` into a `const clang::Stmt &` in this call:
Finder.match(*S, Ctx);
Changing the pointer type to `const clang::Stmt *` as passed into the method had no effect. I also tried this to no avail:
const Stmt &SRef = *S;
Finder.match(SRef, Ctx);
Here's an lldb session showing the badness. I know something is going wrong because the value of `Node.Aligner` in the `match()` method is the same value as the `S` pointer (`0x000000010a033ce0`) prior to the call:
```
(lldb) run
Process 6895 launched: '/Volumes/Data/clang.git/llvm/Debug+Asserts/bin/clang' (x86_64)
Process 6895 stopped
* thread #1: tid = 0x39e920, 0x00000001010a5250 clang`scan_dealloc_for_self_after_super_dealloc(S=0x000000010a033ce0, Callback=0x00007fff5fbfc410, Ctx=0x000000010a822000) + 624 at CheckObjCDealloc.cpp:70, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00000001010a5250 clang`scan_dealloc_for_self_after_super_dealloc(S=0x000000010a033ce0, Callback=0x00007fff5fbfc410, Ctx=0x000000010a822000) + 624 at CheckObjCDealloc.cpp:70
67 stmt(hasDescendant(declRefExpr(to(varDecl(hasName("self"))))
68 .bind("self"))).bind("stmt");
69 Finder.addMatcher(Matcher, &Callback);
-> 70 Finder.match(*S, Ctx);
71 if (Callback.FoundMatch())
72 return true;
73
(lldb) p *S
(clang::Stmt) $4 = {
= {
Aligner = 0x000000000000008d
StmtBits = (sClass = 141)
CompoundStmtBits = (NumStmts = 0)
ExprBits = {
ValueKind = 0
ObjectKind = 0
TypeDependent = 0
ValueDependent = 0
InstantiationDependent = 0
ContainsUnexpandedParameterPack = 0
}
CharacterLiteralBits = (Kind = 0)
FloatingLiteralBits = (Semantics = 0, IsExact = 0)
UnaryExprOrTypeTraitExprBits = (Kind = 0, IsType = 0)
DeclRefExprBits = {
HasQualifier = 0
HasTemplateKWAndArgsInfo = 0
HasFoundDecl = 0
HadMultipleCandidates = 0
RefersToEnclosingLocal = 0
}
CastExprBits = (Kind = 0, BasePathSize = 0)
CallExprBits = (NumPreArgs = 0)
ExprWithCleanupsBits = (NumObjects = 0)
PseudoObjectExprBits = (NumSubExprs = 0, ResultIndex = 0)
ObjCIndirectCopyRestoreExprBits = (ShouldCopy = 0)
InitListExprBits = (HadArrayRangeDesignator = 0)
TypeTraitExprBits = (Kind = 0, Value = 0, NumArgs = 0)
}
}
(lldb) p S->getStmtClassName()
(const char *) $5 = 0x00000001044ea946 "ReturnStmt"
(lldb) p (*S).getStmtClassName()
(const char *) $6 = 0x00000001044ea946 "ReturnStmt"
(lldb) s
Process 6895 stopped
* thread #1: tid = 0x39e920, 0x00000001010b0b7a clang`void clang::ast_matchers::MatchFinder::match<clang::Stmt>(this=0x00007fff5fbfbe38, Node=0x000000010a033ce0, Context=0x000000010a822000) + 42 at ASTMatchFinder.h:160, queue = 'com.apple.main-thread', stop reason = step in
frame #0: 0x00000001010b0b7a clang`void clang::ast_matchers::MatchFinder::match<clang::Stmt>(this=0x00007fff5fbfbe38, Node=0x000000010a033ce0, Context=0x000000010a822000) + 42 at ASTMatchFinder.h:160
157 ///
158 /// @{
159 template <typename T> void match(const T &Node, ASTContext &Context) {
-> 160 match(clang::ast_type_traits::DynTypedNode::create(Node), Context);
161 }
162 void match(const clang::ast_type_traits::DynTypedNode &Node,
163 ASTContext &Context);
(lldb) p Node.getStmtClassName()
(const char *) $7 = 0x0000002000000000
(lldb) p Node
(const clang::Stmt) $8 = {
= {
Aligner = 0x000000010a033ce0
StmtBits = (sClass = 224)
CompoundStmtBits = (NumStmts = 656188)
ExprBits = {
ValueKind = 0
ObjectKind = 3
TypeDependent = 1
ValueDependent = 1
InstantiationDependent = 0
ContainsUnexpandedParameterPack = 0
}
CharacterLiteralBits = (Kind = 3)
FloatingLiteralBits = (Semantics = 3, IsExact = 0)
UnaryExprOrTypeTraitExprBits = (Kind = 3, IsType = 0)
DeclRefExprBits = {
HasQualifier = 1
HasTemplateKWAndArgsInfo = 1
HasFoundDecl = 0
HadMultipleCandidates = 0
RefersToEnclosingLocal = 0
}
CastExprBits = (Kind = 3, BasePathSize = 40)
CallExprBits = (NumPreArgs = 1)
ExprWithCleanupsBits = (NumObjects = 2563)
PseudoObjectExprBits = (NumSubExprs = 3, ResultIndex = 10)
ObjCIndirectCopyRestoreExprBits = (ShouldCopy = 1)
InitListExprBits = (HadArrayRangeDesignator = 1)
TypeTraitExprBits = (Kind = 3, Value = 0, NumArgs = 5)
}
}
(lldb)
```
One thing I can't tell is if `make` is compiling with the trunk clang I'm building, or whether it's using the clang I have installed with Xcode.
http://reviews.llvm.org/D5042
More information about the cfe-commits
mailing list