[cfe-dev] [PATCH 1/1] StaticAnalyzer: fix memleak in CFRefCount
Ted Kremenek
kremenek at apple.com
Wed Apr 27 15:27:35 PDT 2011
Hi Jiri,
I think what you are seeing is code in transition.
BugTypes were previously deallocated by the BugReporter class. Now they aren't, because Checkers can outlive a BugReporter (since Checkers are now managed by CheckerManager). I think the right approach is to actually reference count BugTypes if we are concerned about BugReporter objects outliving a Checker object. Alternatively, we can have checkers own them, managing them with an llvm::OwningPtr<>. Note that this leak is not actually a big deal right now since Checkers stay persistent for the for the analysis of an entire translation unit (so we're not leaking on every function analyzed), but I agree we should clean this up.
Ted
On Apr 6, 2011, at 4:59 AM, Jiri Slaby wrote:
> CFRefCount doesn't free alocated bug types. Do this in the destructor
> if we allocated them in CherkerRegister.
>
> Note that this approach is racy. If somebody holds the old immutable
> map and iterates over that, they will encounter freed memory. The
> question is whether we want is race-free?
>
> Valgrind otherwise complains like:
> 172 (40 direct, 132 indirect) bytes in 1 blocks are definitely lost in loss record 27 of 27
> at 0x4C26337: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
> by 0x16DF42E: (anonymous namespace)::CFRefCount::RegisterChecks(clang::ento::ExprEngine&) (in /l/latest/r
> by 0x1711DC3: clang::ento::ExprEngine::ExprEngine(clang::ento::AnalysisManager&, clang::ento::TransferFun
> by 0x16323BC: ActionExprEngine((anonymous namespace)::AnalysisConsumer&, clang::ento::AnalysisManager&, c
> ...
>
> Signed-off-by: Jiri Slaby <jirislaby at gmail.com>
> Cc: Ted Kremenek <kremenek at apple.com>
> ---
> .../StaticAnalyzer/Core/BugReporter/BugReporter.h | 1 +
> lib/StaticAnalyzer/Core/BugReporter.cpp | 4 +++
> lib/StaticAnalyzer/Core/CFRefCount.cpp | 23 +++++++++++++++++++-
> 3 files changed, 27 insertions(+), 1 deletions(-)
>
> diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
> index 7c3c6bf..0d758d0 100644
> --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
> +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
> @@ -329,6 +329,7 @@ public:
> llvm::SmallVectorImpl<BugReport *> &bugReports) {}
>
> void Register(BugType *BT);
> + void Unregister(BugType *BT);
>
> void EmitReport(BugReport *R);
>
> diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
> index 74cd359..3d9e684 100644
> --- a/lib/StaticAnalyzer/Core/BugReporter.cpp
> +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
> @@ -1618,6 +1618,10 @@ void BugReporter::Register(BugType *BT) {
> BugTypes = F.add(BugTypes, BT);
> }
>
> +void BugReporter::Unregister(BugType *BT) {
> + BugTypes = F.remove(BugTypes, BT);
> +}
> +
> void BugReporter::EmitReport(BugReport* R) {
> // Compute the bug report's hash to determine its equivalence class.
> llvm::FoldingSetNodeID ID;
> diff --git a/lib/StaticAnalyzer/Core/CFRefCount.cpp b/lib/StaticAnalyzer/Core/CFRefCount.cpp
> index 416e120..c763c07 100644
> --- a/lib/StaticAnalyzer/Core/CFRefCount.cpp
> +++ b/lib/StaticAnalyzer/Core/CFRefCount.cpp
> @@ -1691,7 +1691,28 @@ public:
> leakWithinFunction(0), leakAtReturn(0), overAutorelease(0),
> returnNotOwnedForOwned(0), BR(0) {}
>
> - virtual ~CFRefCount() {}
> + virtual ~CFRefCount() {
> + if (BR) {
> + /* if we have BR, we have also the types */
> + BR->Unregister(useAfterRelease);
> + BR->Unregister(releaseNotOwned);
> + BR->Unregister(deallocGC);
> + BR->Unregister(deallocNotOwned);
> + BR->Unregister(leakWithinFunction);
> + BR->Unregister(leakAtReturn);
> + BR->Unregister(overAutorelease);
> + BR->Unregister(returnNotOwnedForOwned);
> +
> + delete useAfterRelease;
> + delete releaseNotOwned;
> + delete deallocGC;
> + delete deallocNotOwned;
> + delete leakWithinFunction;
> + delete leakAtReturn;
> + delete overAutorelease;
> + delete returnNotOwnedForOwned;
> + }
> + }
>
> void RegisterChecks(ExprEngine &Eng);
>
> --
> 1.7.4.2
>
>
More information about the cfe-dev
mailing list