[cfe-commits] r55442 - in /cfe/trunk: Driver/AnalysisConsumer.cpp Driver/AnalysisConsumer.h Driver/clang.cpp utils/ubiviz

Ted Kremenek kremenek at apple.com
Wed Aug 27 15:31:43 PDT 2008


Author: kremenek
Date: Wed Aug 27 17:31:43 2008
New Revision: 55442

URL: http://llvm.org/viewvc/llvm-project?rev=55442&view=rev
Log:
Added Ubigraph visualization for the static analyzer (this is pretty alpha quality).

Added:
    cfe/trunk/utils/ubiviz   (with props)
Modified:
    cfe/trunk/Driver/AnalysisConsumer.cpp
    cfe/trunk/Driver/AnalysisConsumer.h
    cfe/trunk/Driver/clang.cpp

Modified: cfe/trunk/Driver/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/AnalysisConsumer.cpp?rev=55442&r1=55441&r2=55442&view=diff

==============================================================================
--- cfe/trunk/Driver/AnalysisConsumer.cpp (original)
+++ cfe/trunk/Driver/AnalysisConsumer.cpp Wed Aug 27 17:31:43 2008
@@ -31,11 +31,13 @@
 #include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
 #include "clang/Analysis/PathSensitive/GRExprEngine.h"
 #include "llvm/Support/Streams.h"
-
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
 #include <vector>
 
 using namespace clang;
 
+static ExplodedNodeImpl::Auditor* CreateUbiViz();
   
 //===----------------------------------------------------------------------===//
 // Basic type definitions.
@@ -59,7 +61,8 @@
     Actions ObjCImplementationActions;
     
   public:
-    const bool Visualize;
+    const bool VisGraphviz;
+    const bool VisUbigraph;
     const bool TrimGraph;
     const LangOptions& LOpts;
     Diagnostic &Diags;
@@ -76,8 +79,9 @@
                      const LangOptions& lopts,
                      const std::string& fname,
                      const std::string& htmldir,
-                     bool visualize, bool trim, bool analyzeAll) 
-      : Visualize(visualize), TrimGraph(trim), LOpts(lopts), Diags(diags),
+                     bool visgraphviz, bool visubi, bool trim, bool analyzeAll) 
+      : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim),
+        LOpts(lopts), Diags(diags),
         Ctx(0), PP(pp), PPF(ppf),
         HTMLDir(htmldir),
         FName(fname),
@@ -168,8 +172,16 @@
       return liveness.get();
     }
     
+    bool shouldVisualizeGraphviz() const {
+      return C.VisGraphviz;
+    }
+    
+    bool shouldVisualizeUbigraph() const {
+      return C.VisUbigraph;
+    }
+    
     bool shouldVisualize() const {
-      return C.Visualize;
+      return C.VisGraphviz || C.VisUbigraph;
     }
     
     bool shouldTrimGraph() const {
@@ -319,15 +331,26 @@
     Eng.RegisterInternalChecks();
     RegisterAppleChecks(Eng);
   }
+
+  // Set the graph auditor.
+  llvm::OwningPtr<ExplodedNodeImpl::Auditor> Auditor;
+  if (mgr.shouldVisualizeUbigraph()) {
+    Auditor.reset(CreateUbiViz());
+    ExplodedNodeImpl::SetAuditor(Auditor.get());
+  }
   
   // Execute the worklist algorithm.
   Eng.ExecuteWorkList();
   
+  // Release the auditor (if any) so that it doesn't monitor the graph
+  // created BugReporter.
+  ExplodedNodeImpl::SetAuditor(0);
+  
   // Display warnings.
   Eng.EmitWarnings(mgr);
   
   // Visualize the exploded graph.
-  if (mgr.shouldVisualize())
+  if (mgr.shouldVisualizeGraphviz())
     Eng.ViewGraph(mgr.shouldTrimGraph());
 }
 
@@ -418,12 +441,13 @@
                                            const LangOptions& lopts,
                                            const std::string& fname,
                                            const std::string& htmldir,
-                                           bool visualize, bool trim,
+                                           bool VisGraphviz, bool VisUbi,
+                                           bool trim,
                                            bool analyzeAll) {
   
   llvm::OwningPtr<AnalysisConsumer>
   C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir,
-                         visualize, trim, analyzeAll));
+                         VisGraphviz, VisUbi, trim, analyzeAll));
   
   for ( ; Beg != End ; ++Beg)
     switch (*Beg) {
@@ -438,3 +462,75 @@
   return C.take();
 }
 
+//===----------------------------------------------------------------------===//
+// Ubigraph Visualization.  FIXME: Move to separate file.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  
+class UbigraphViz : public ExplodedNodeImpl::Auditor {
+  llvm::OwningPtr<llvm::raw_ostream> Out;
+  unsigned Cntr;
+
+  typedef llvm::DenseMap<void*,unsigned> VMap;
+  VMap M;
+  
+public:
+  UbigraphViz(llvm::raw_ostream* out) : Out(out), Cntr(0) {}  
+  virtual void AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst);  
+};
+  
+} // end anonymous namespace
+
+static ExplodedNodeImpl::Auditor* CreateUbiViz() {
+  std::string ErrMsg;
+  
+  llvm::sys::Path Filename = llvm::sys::Path::GetTemporaryDirectory(&ErrMsg);
+  if (!ErrMsg.empty())
+    return 0;
+
+  Filename.appendComponent("llvm_ubi");
+  Filename.makeUnique(true,&ErrMsg);
+
+  if (!ErrMsg.empty())
+    return 0;
+
+  llvm::cerr << "Writing '" << Filename << "'.\n";
+  
+  llvm::OwningPtr<llvm::raw_fd_ostream> Stream;
+  std::string filename = Filename.toString();
+  Stream.reset(new llvm::raw_fd_ostream(filename.c_str(), ErrMsg));
+
+  if (!ErrMsg.empty())
+    return 0;
+  
+  return new UbigraphViz(Stream.take());
+}
+
+void UbigraphViz::AddEdge(ExplodedNodeImpl* Src, ExplodedNodeImpl* Dst) {
+  // Lookup the Src.  If it is a new node, it's a root.
+  VMap::iterator SrcI= M.find(Src);
+  unsigned SrcID;
+  
+  if (SrcI == M.end()) {
+    M[Src] = SrcID = Cntr++;
+    *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
+  }
+  else
+    SrcID = SrcI->second;
+  
+  // Lookup the Dst.
+  VMap::iterator DstI= M.find(Dst);
+  unsigned DstID;
+
+  if (DstI == M.end()) {
+    M[Dst] = DstID = Cntr++;
+    *Out << "('vertex', " << DstID << ")\n";
+  }
+  else
+    DstID = DstI->second;
+
+  // Add the edge.
+  *Out << "('edge', " << SrcID << ", " << DstID << ")\n";
+}
+

Modified: cfe/trunk/Driver/AnalysisConsumer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/AnalysisConsumer.h?rev=55442&r1=55441&r2=55442&view=diff

==============================================================================
--- cfe/trunk/Driver/AnalysisConsumer.h (original)
+++ cfe/trunk/Driver/AnalysisConsumer.h Wed Aug 27 17:31:43 2008
@@ -28,8 +28,10 @@
                                     const LangOptions& lopts,
                                     const std::string& fname,
                                     const std::string& htmldir,
-                                    bool visualize, bool trim,
-                                    bool analyzeAll);
+                                    bool VisualizeGraphViz,
+                                    bool VisualizeUbi,
+                                    bool VizTrimGraph,
+                                    bool AnalyzeAll);
 } // end clang namespace
 
 #endif

Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=55442&r1=55441&r2=55442&view=diff

==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Wed Aug 27 17:31:43 2008
@@ -159,11 +159,15 @@
 //===----------------------------------------------------------------------===//
 
 static llvm::cl::opt<bool>
-VisualizeEG("visualize-egraph",
-            llvm::cl::desc("Display static analysis Exploded Graph"));
+VisualizeEGDot("analyzer-viz-egraph-graphviz",
+               llvm::cl::desc("Display exploded graph using GraphViz"));
 
 static llvm::cl::opt<bool>
-AnalyzeAll("checker-opt-analyze-headers",
+VisualizeEGUbi("analyzer-viz-egraph-ubigraph",
+               llvm::cl::desc("Display exploded graph using Ubigraph"));
+
+static llvm::cl::opt<bool>
+AnalyzeAll("analyzer-opt-analyze-headers",
     llvm::cl::desc("Force the static analyzer to analyze "
                    "functions defined in header files"));
 
@@ -964,8 +968,8 @@
                                     &AnalysisList[0]+AnalysisList.size(),
                                     Diag, PP, PPF, LangOpts,
                                     AnalyzeSpecificFunction,
-                                    OutputFile, VisualizeEG, TrimGraph,
-                                    AnalyzeAll);
+                                    OutputFile, VisualizeEGDot, VisualizeEGUbi,
+                                    TrimGraph, AnalyzeAll);
   }
 }
 

Added: cfe/trunk/utils/ubiviz
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/ubiviz?rev=55442&view=auto

==============================================================================
--- cfe/trunk/utils/ubiviz (added)
+++ cfe/trunk/utils/ubiviz Wed Aug 27 17:31:43 2008
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This script reads visualization data emitted by the static analyzer for
+# display in Ubigraph.
+#
+##===----------------------------------------------------------------------===##
+
+import xmlrpclib
+import sys
+
+def Error(message):
+    print >> sys.stderr, 'ubiviz: ' + message
+    sys.exit(1)
+    
+def StreamData(filename):
+  file = open(filename)
+  for ln in file:
+    yield eval(ln)
+  file.close()
+
+def Display(G, data):
+  action = data[0]
+  if action == 'vertex':
+    vertex = data[1]
+    G.new_vertex_w_id(vertex)
+    for attribute in data[2:]:
+      G.set_vertex_attribute(vertex, attribute[0], attribute[1])
+  elif action == 'edge':
+    src = data[1]
+    dst = data[2]
+    edge = G.new_edge(src,dst)
+    for attribute in data[3:]:
+      G.set_edge_attribute(edge, attribute[0], attribute[1])
+
+def main(args):
+  if len(args) == 0:
+    Error('no input files')    
+
+  server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2')
+  G = server.ubigraph
+            
+  for arg in args:
+    G.clear()
+    for x in StreamData(arg):
+      Display(G,x)
+
+if __name__ == '__main__':
+    main(sys.argv[1:])
+    
+    
\ No newline at end of file

Propchange: cfe/trunk/utils/ubiviz

------------------------------------------------------------------------------
    svn:executable = *





More information about the cfe-commits mailing list