[clang] 07a7fd3 - [analyzer] Print the offending function at EndAnalysis crash

Balazs Benics via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 10 03:21:51 PDT 2022


Author: Balazs Benics
Date: 2022-06-10T12:21:17+02:00
New Revision: 07a7fd314a118393e6ca5e4dbcc9c3d91ff96172

URL: https://github.com/llvm/llvm-project/commit/07a7fd314a118393e6ca5e4dbcc9c3d91ff96172
DIFF: https://github.com/llvm/llvm-project/commit/07a7fd314a118393e6ca5e4dbcc9c3d91ff96172.diff

LOG: [analyzer] Print the offending function at EndAnalysis crash

I've faced crashes in the past multiple times when some
`check::EndAnalysis` callback caused some crash.
It's really anoying that it doesn't tell which function triggered this
callback.

This patch adds the well-known trace for that situation as well.
Example:
  1.      <eof> parser at end of file
  2.      While analyzing stack:
          #0 Calling test11

Note that this does not have tests.
I've considered `unittests` for this purpose, by using the
`ASSERT_DEATH()` similarly how we check double eval called functions in
`ConflictingEvalCallsTest.cpp`, however, that the testsuite won't invoke
the custom handlers. Only the message of the `llvm_unreachable()` will
be printed. Consequently, it's not applicable for us testing this
feature.

I've also considered using an end-to-end LIT test for this.
For that, we would need to somehow overload the `clang_analyzer_crash()`
`ExprInspection` handler, to get triggered by other events than the
`EvalCall`. I'm not saying that we could not come up with a generic way
of causing crash in a specific checker callback, but I'm not sure if
that would worth the effort.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D127389

Added: 
    

Modified: 
    clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 6be33d488a9e3..89c0a121d95f9 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -228,6 +228,11 @@ class ExprEngine {
 
   const Stmt *getStmt() const;
 
+  const LocationContext *getRootLocationContext() const {
+    assert(G.roots_begin() != G.roots_end());
+    return (*G.roots_begin())->getLocation().getLocationContext();
+  }
+
   void GenerateAutoTransition(ExplodedNode *N);
   void enqueueEndOfPath(ExplodedNodeSet &S);
   void GenerateCallExitNode(ExplodedNode *N);

diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 55920c1a7566e..3e3feee9c31cb 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -613,6 +613,8 @@ void ExprEngine::printJson(raw_ostream &Out, ProgramStateRef State,
 }
 
 void ExprEngine::processEndWorklist() {
+  // This prints the name of the top-level function if we crash.
+  PrettyStackTraceLocationContext CrashInfo(getRootLocationContext());
   getCheckerManager().runCheckersForEndAnalysis(G, BR, *this);
 }
 


        


More information about the cfe-commits mailing list