Source code for mcgdb.interaction.my_gdb

"""
Module extending GDB's CLI with new general-purpose debugging commands.
"""

import gdb

import mcgdb
from mcgdb import toolbox
from mcgdb.toolbox import my_gdb, python_utils


import logging; log = logging.getLogger(__name__)
log_user = logging.getLogger("mcgdb.log.user.interaction")

@python_utils.refer_to(my_gdb.current_infthr)
[docs]class cmd_info_infthread (gdb.Command): def __init__ (self): gdb.Command.__init__ (self, "info infthreads", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): gdb.execute("info inferior %d" % gdb.selected_inferior().num) info_thr = "info thread " for thread in gdb.selected_inferior().threads(): info_thr += ("%d " % thread.num) gdb.execute(info_thr)
[docs]class cmd_AllInfBreakpoint(gdb.Command): def __init__(self): gdb.Command.__init__ (self, "break_spread", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): my_gdb.AllInfBreakpoint.spread_to_other_inferiors()
[docs]class cmd_sn(gdb.Command): def __init__(self): gdb.Command.__init__ (self, "sn", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): if my_gdb.strong_next(args): self.dont_repeat()
[docs]class cmd_strong_next(gdb.Command): def __init__(self): gdb.Command.__init__ (self, "strong_next", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): if my_gdb.strong_next(args): self.dont_repeat()
########################## start_time = []
[docs]class cmd_start_time(gdb.Command): def __init__(self): gdb.Command.__init__ (self, "start_time", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): start_time.append(time.time()) print ("Starting timer")
[docs]class cmd_stop_time(gdb.Command): def __init__(self): gdb.Command.__init__ (self, "stop_time", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): stop_time = time.time() print ("Stopping timer after %f" % (stop_time - start_time.pop()))
##########################
[docs]class cmd_info_semantics_levels(gdb.Command): """ List the semantic breakpoints currently activated. e.g.: * General * Definition ---> NPM_init_v01 (1/0 hits) '1/0 hits' means that the breakpoint has been hit once, and 0 FinishBreakpoints were used. See "communication semantics levels" to disable some of these breakpoints. """ def __init__(self): gdb.Command.__init__ (self, "info semantics levels", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): mcgdb.capture.FunctionBreakpoint.check_breakpoint_validity() current = mcgdb.capture.FunctionType.root cmd_info_semantics_levels.browse(current, 0)
@staticmethod
[docs] def browse(func_type, depth): print ("%s * %s%s" % ("\t"*depth, func_type, " (disabled)" if not func_type.enabled else "")) for bp in func_type.functions: if not bp.is_valid(): continue print ("%s %s %s (%d%s hits)" % ("\t"*depth, bp.enabled and "--->" or " ", bp.location, bp.hit_internal, "/%d" % bp.fhit_internal if bp.prepare_after.im_func is not mcgdb.capture.FunctionBreakpoint.prepare_after.im_func else "" )) for child in func_type.children: cmd_info_semantics_levels.browse(child, depth+1)
[docs]class cmd_comm_semantics_levels(gdb.Command): """ Enable or disable some of the programming-model breakpoint, for instance to improve the performances. Usage: communication semantics levels LEVEL {enable|disable} See "info semantics levels" for more details about the breakpoints related to each level. """ def __init__(self): gdb.Command.__init__ (self, "communication semantics levels", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): current = model.capture.FunctionType.root lst = [child for child in cmd_comm_semantics_levels.list(current)] complete = [] type_str, part, rest = args.partition(" ") if type_str not in [child.name for child in lst]: for name in [child.name for child in lst]: if name.startswith(type_str): complete.append(name) if len(complete) == 0: print ("Cannot select a semantic level."\ "Please choose one among: %s" \ % ', '.join([child.name for child in lst])) return elif len(complete) != 1: print ("Cannot select a semantic level."\ "Available levels are: %s" % ', '.join(complete)) return else: type_str = complete[0] print ("Type completed to '%s'"% type_str) type_ = [child for child in lst if child.name == type_str][0] act, part, rest = rest.partition(" ") if len(act) == 0: print ("Please select 'enable' or 'disable'") return elif "enable".startswith(act): do_enable = True do_enable_str = "Enabling" elif "disable".startswith(act): do_enable = False do_enable_str = "Disabling" else: print ("Please select 'enable' or 'disable'") return print ("%s function types '%s'" % (do_enable_str, type_str)) type_.to_enabled(do_enable)
[docs] def complete(self, text, word): current = model.capture.FunctionType.root lst = [elt for elt in cmd_comm_semantics_levels.list(current)] complete = [] type_, part, rest = text.partition(" ") if type_ not in [child.name for child in lst]: for name in [child.name for child in lst]: if name.startswith(type_): complete.append(name) return complete act, part, rest = rest.partition(" ") if act not in ["enable", "disable"]: for action in ["enable", "disable"]: if action.startswith(act): complete.append(action) return complete
@staticmethod
[docs] def list(func_type): stack = [func_type] while len(stack) != 0: current = stack.pop() yield current for child in current.children: stack.insert(0, child)
[docs]class cmd_cont(gdb.Command): def __init__(self, name): gdb.Command.__init__ (self, name, gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): my_gdb.events.cont.trigger() try: gdb.execute("continue") except gdb.error as e: print ("<>%s<>" % e) except KeyboardInterrupt: pass
###################
[docs]class cmd_mcgdb_load_by_name(gdb.Command): def __init__(self): gdb.Command.__init__ (self, "mcgdb load_model_by_name", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): toolbox.load_models_by_name(args)
[docs]class cmd_mcgdb_detect(gdb.Command): def __init__(self): gdb.Command.__init__ (self, "mcgdb detect_models", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty): toolbox.detect_models()
[docs]class cmd_mcgdb_autodetect(gdb.Command): autodetect_enabled = False def __init__(self): gdb.Command.__init__ (self, "mcgdb autodetect_models", gdb.COMMAND_NONE)
[docs] def invoke(self, args, from_tty): if not cmd_mcgdb_autodetect.autodetect_enabled: gdb.events.new_objfile.connect(toolbox.check_new_objfile_for_models) log_user.info("Model auto detection enabled") else: gdb.events.new_objfile.disconnect(toolbox.check_new_objfile_for_models) log_user.info("Model auto detection disabled") cmd_mcgdb_detect.autodetect_enabled = False
################### # disable start/run commands after first 'cont' event
[docs]class gdb_start_command (gdb.Command): def __init__ (self, cmd): super (gdb_start_command, self).__init__ (cmd, gdb.COMMAND_USER)
[docs] def invoke (self, arg, from_tty): log_user.warn("Cannot restart/run with mcgdb enabled, sorry.")
[docs]def cont(evt): #gdb_start_command("start") #gdb_start_command("run") gdb.events.cont.disconnect(cont)
###################
[docs]def postInitialize(): gdb.Command("info semantics", gdb.COMMAND_NONE, prefix=1) gdb.Command("communication semantics", gdb.COMMAND_NONE, prefix=1) cmd_cont("cont") cmd_cont("c") cmd_sn() cmd_strong_next() cmd_info_infthread() cmd_AllInfBreakpoint() cmd_info_semantics_levels() cmd_comm_semantics_levels() cmd_start_time() cmd_stop_time() cmd_mcgdb_autodetect() cmd_mcgdb_detect() cmd_mcgdb_load_by_name() gdb.events.cont.connect(cont) gdb.execute("py import mcgdb")