diff options
Diffstat (limited to 'gdb/contrib/exsummary.py')
-rw-r--r-- | gdb/contrib/exsummary.py | 185 |
1 files changed, 0 insertions, 185 deletions
diff --git a/gdb/contrib/exsummary.py b/gdb/contrib/exsummary.py deleted file mode 100644 index f3f7c60..0000000 --- a/gdb/contrib/exsummary.py +++ /dev/null @@ -1,185 +0,0 @@ -# Copyright 2011-2019 Free Software Foundation, Inc. -# -# This is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# <http://www.gnu.org/licenses/>. - -import sys -import glob - -# Compute the summary information from the files created by -# excheck.py. Run in the build directory where you used the -# excheck.py plugin. - -class Function: - def __init__(self, name): - self.name = name - self.location = None - self.callers = [] - self.can_throw = False - self.marked_nothrow = False - self.reason = None - - def log(self, message): - print "%s: note: %s" % (self.location, message) - - def set_location(self, location): - self.location = location - - # CALLER is an Edge. - def add_caller(self, caller): - # self.log("adding call from %s" % caller.from_fn.name) - self.callers.append(caller) - # self.log("len = %d" % len(self.callers)) - - def consistency_check(self): - if self.marked_nothrow and self.can_throw: - print ("%s: error: %s marked as both 'throw' and 'nothrow'" - % (self.location, self.name)) - - def declare_nothrow(self): - self.marked_nothrow = True - self.consistency_check() - - def declare_throw(self): - result = not self.can_throw # Return True the first time - self.can_throw = True - self.consistency_check() - return result - - def print_stack(self, is_indirect): - if is_indirect: - print ("%s: error: function %s is marked nothrow but is assumed to throw due to indirect call" - % (self.location, self.name)) - else: - print ("%s: error: function %s is marked nothrow but can throw" - % (self.location, self.name)) - - edge = self.reason - while edge is not None: - print ("%s: info: via call to %s" - % (edge.location, edge.to_fn.name)) - edge = edge.to_fn.reason - - def mark_throw(self, edge, work_list, is_indirect): - if not self.can_throw: - # self.log("can throw") - self.can_throw = True - self.reason = edge - if self.marked_nothrow: - self.print_stack(is_indirect) - else: - # Do this in the 'else' to avoid extra error - # propagation. - work_list.append(self) - -class Edge: - def __init__(self, from_fn, to_fn, location): - self.from_fn = from_fn - self.to_fn = to_fn - self.location = location - -# Work list of known-throwing functions. -work_list = [] -# Map from function name to Function object. -function_map = {} -# Work list of indirect calls. -indirect_functions = [] -# Whether we should process cleanup functions as well. -process_cleanups = False -# Whether we should process indirect function calls. -process_indirect = False - -def declare(fn_name): - global function_map - if fn_name not in function_map: - function_map[fn_name] = Function(fn_name) - return function_map[fn_name] - -def define_function(fn_name, location): - fn = declare(fn_name) - fn.set_location(location) - -def declare_throw(fn_name): - global work_list - fn = declare(fn_name) - if fn.declare_throw(): - work_list.append(fn) - -def declare_nothrow(fn_name): - fn = declare(fn_name) - fn.declare_nothrow() - -def declare_cleanup(fn_name): - global process_cleanups - fn = declare(fn_name) - if process_cleanups: - fn.declare_nothrow() - -def function_call(to, frm, location): - to_fn = declare(to) - frm_fn = declare(frm) - to_fn.add_caller(Edge(frm_fn, to_fn, location)) - -def has_indirect_call(fn_name, location): - global indirect_functions - fn = declare(fn_name) - phony = Function("<indirect call>") - phony.add_caller(Edge(fn, phony, location)) - indirect_functions.append(phony) - -def mark_functions(worklist, is_indirect): - for callee in worklist: - for edge in callee.callers: - edge.from_fn.mark_throw(edge, worklist, is_indirect) - -def help_and_exit(): - print "Usage: exsummary [OPTION]..." - print "" - print "Read the .py files from the exception checker plugin and" - print "generate an error summary." - print "" - print " --cleanups Include invalid behavior in cleanups" - print " --indirect Include assumed errors due to indirect function calls" - sys.exit(0) - -def main(): - global work_list - global indirect_functions - global process_cleanups - global process_indirect - - for arg in sys.argv: - if arg == '--cleanups': - process_cleanups = True - elif arg == '--indirect': - process_indirect = True - elif arg == '--help': - help_and_exit() - - for fname in sorted(glob.glob('*.c.gdb_exc.py')): - execfile(fname) - print "================" - print "= Ordinary marking" - print "================" - mark_functions(work_list, False) - if process_indirect: - print "================" - print "= Indirect marking" - print "================" - mark_functions(indirect_functions, True) - return 0 - -if __name__ == '__main__': - status = main() - sys.exit(status) |