Source code for mcgdb.model.task.interaction.components

"""
Module extending GDB's CLI with commands related to component handling.
"""

import gdb

from mcgdb.toolbox import my_gdb
from mcgdb import representation

[docs]class cmd_info_compo (gdb.Command): """ info components List the components currently existing in the inferior. The component currently selected in GDB will be denoted with a '*'. Component[s] not bound to a processors will be denoted with a '~'. Usage: info components [ID*|.] [interfaces|itf|endpoints|ep] [full|+] Optional arguments are - component IDs (all components if no argument) or '.' for the current component - interfaces to list component interfaces - 'full' or '+' for all of the above. e.g.: info components 1 #1 CommHost[2591] """ def __init__ (self): gdb.Command.__init__ (self, "info components", gdb.COMMAND_OBSCURE)
[docs] def invoke (self, arg, from_tty): print_endpoints = False print_work = False print_cpp_obj = False print_newline = False print_name = False print_state = False current = False selected = [] rest = str(arg) while rest != "": first, part, rest = rest.partition(" ") if first in ("+name"): print_name = True if first in ("+work"): print_work = True elif first in ("+cpp_obj", "+cpp", "+this"): print_cpp_obj = True elif first in ("+interfaces", "+itf", "+ifaces"): print_endpoints = True elif first in ("+state"): print_state = True elif first in ("+nl"): print_newline = True elif first in ("full", "+"): print_endpoints = True print_cpp_obj = True print_work = True print_name = True print_newline = True elif first == '.': current_compo = p2012_mon.CommComponent.get_selected_component(silent=True) if current_compo: selected.append(current_compo.numbers[p2012_mon.CommComponent]) elif first.isdigit(): selected.append(int(first)) else: my_gdb.log.warning("argument '%s' not recognized", first) i = 0 for comm_comp in p2012_mon.CommComponent.list_: number = comm_comp.numbers[p2012_mon.CommComponent] i += 1 if len(selected) != 0 and number not in selected: continue idx = -1 mark = comm_comp.get_mark() print ("%s #%d %s " % (mark, number, comm_comp)) if print_endpoints and comm_comp.endpoints: print ("\t%s" \ % "\n\t".join(["%s [> #%s]" % (str(ep), str(ep.get_other_side().comm_entity.numbers[p2012_mon.CommComponent])) for ep in comm_comp.endpoints])) print ("\t--") if print_work and not isinstance(comm_comp, pedf_mon.Module): print ("\tWork method: %s" % comm_comp.work_method) if comm_comp.work_breakpoint is not None: if not comm_comp.work_breakpoint.enabled: print ("\tWork breakpoint disabled") print ("\tWork count: %d" % comm_comp.work_count) #print ("\tFire tokens: %d (max: %d)" % (comm_comp.fire_tokens, comm_comp.max_tokens)) print ("\t--") if print_cpp_obj: print ("\tthis: (%s) %s" % (comm_comp.instance.type, comm_comp.instance)) print ("\t--") if print_name: print ("\tname: %s" % (comm_comp.name)) print ("\t--") if print_state: print ("\tstate: %s" % (comm_comp.state)) #print ("\thread: (RtThread *) %s" % (comm_comp.thread)) if print_newline: print ("")
[docs]class cmd_compo (gdb.Command): def __init__ (self): gdb.Command.__init__ (self, "component", gdb.COMMAND_OBSCURE) self.subcommands = {}
[docs] def get_cli_component(self, arg, silent=False): str_id, part, rest = arg.partition(" ") if str_id.isdigit(): arg = rest int_id = int(str_id) for comm_comp in p2012_mon.CommComponent.list_: if comm_comp.numbers[p2012_mon.CommComponent] == int_id: compo = comm_comp break else: if not silent: my_gdb.log.warning("Couldn't find a component " \ "with the ID #%d", int_id) return None, arg elif str_id == '.': compo = p2012_mon.CommComponent.get_selected_component(silent=True) else: compo = None ret = rest if compo is not None else arg return compo, ret
[docs] def invoke (self, arg, from_tty): compo, arg = self.get_cli_component(arg) subcmd_name, part, rest = arg.partition(" ") if subcmd_name in self.subcommands: subcmd = self.subcommands[subcmd_name] elif (None in self.subcommands and (not self.subcommands[None].__class__.must_have or compo is not None)): subcmd = self.subcommands[None] rest = arg subcmd_name = self.default_name else: my_gdb.log.warning("No subcommand associated with keyword '%s'.", subcmd_name) return if compo is None and subcmd.__class__.must_have: my_gdb.log.warning("Subcommand '%s' requires a valid component.", subcmd_name) return return subcmd.invoke(compo, rest, from_tty)
[docs] def complete(self, text, word): compo, text = self.get_cli_component(text, silent=True) subcmd_name, part, rest = text.partition(" ") if subcmd_name in self.subcommands: if (compo is None and self.subcommands[subcmd_name].__class__.must_have): return [] return self.subcommands[subcmd_name].complete(compo, rest, word) return [name for (name, subcmd) in self.subcommands.items() if name is not None and name.startswith(word) and (not subcmd.__class__.must_have or compo is not None)]
[docs] def sub_command(self, subcmd, name, default=False): self.subcommands[name] = subcmd if default: self.default_name = name self.subcommands[None] = subcmd
cmd_component = None
[docs]class subcmd_compo_switch: must_have = True def __init__ (self): cmd_component.sub_command(self, name="switch", default=True)
[docs] def invoke (self, compo, arg, from_tty): force = False rest = arg while rest != "": first, part, rest = rest.partition(" ") if first in ("force"): force = True else: my_gdb.log.warning("argument '%s' not recognized.", first) try: ret = compo.switch(force) except Exception as e: my_gdb.log.warning("Error: %s", e) ret = False if ret is None: my_gdb.log.warning("No task associated with this component.") elif not ret: my_gdb.log.warning("An error occured during task switching ...") else: my_gdb.log.info("[Switching to component %s]", compo) gdb.execute("where 1")
[docs]class subcmd_compo_catch: must_have = False def __init__ (self): cmd_component.sub_command(self, "catch")
[docs] def invoke (self, compo, arg, from_tty): if len(arg) == 0 or len(arg) == 1: for name, state in p2012_mon.catchable_values(): if compo is None: if p2012_mon.ALL_ENTITIES in state: str_comp = "all" else: str_comp = ", ".join([str(comp) for comp in state]) print ("%s\t\t-->\t%s" % (name, str_comp)) return first_arg, part, rest = arg.partition(" ") if len(rest) == 0 or rest == "on": enable = True else: enable = False if first_arg in p2012_mon.catch.keys(): p2012_mon.catchable_addRemove(first_arg, compo, enable) if compo is None: str_comp = "all components." else: str_comp = "Component #%d." % (compo.numbers[p2012_mon.CommComponent]) if enable: print ("Catching components' '%s' method for %s" % (first_arg, str_comp)) else: print ("Catching components' '%s' " \ "method disabled" % first_arg) else: print ("Argument '%s' not recognized" % first_arg )
[docs] def complete(self, compo, text, word): complete = [] for name in p2012_mon.catchable_keys(): if name.startswith(text): complete.append(name) return complete
[docs]class subcmd_compo_break: must_have = True def __init__ (self): cmd_component.sub_command(self, name="break")
[docs] def invoke (self, compo, arg, from_tty): assert compo is not None if len(arg) == 0 or len(arg) == 1: print ("Please specify a linespec.") return p2012_mon.UserComponentBreakpoint(compo, arg)
[docs] def complete(self, compo, text, word): complete = [] for name in p2012_mon.breakable_keys(): if name.startswith(text): complete.append(name) return complete
[docs]class subcmd_compo_interface: must_have = True def __init__ (self): cmd_component.sub_command(self, name="interface")
[docs] def invoke(self, compo, arg, from_tty): itf_name, part, rest = arg.partition(" ") if len(itf_name) == 0: print ("Please provide an interface name." \ "Available interfaces: %s." \ % ", ".join([str(i) for i in compo.interfaces])) return itf = compo.get_interface(itf_name) if itf is None: #check if we can determine the interface name compl = self.complete(compo, itf_name, None) if len(compl) != 1: if len(compl) == 0: print ("No interface named '%s' in the selected component." % itf_name) else: print ("Please select one of the interfaces (%s)." % ",".join([str(c) for c in compl])) return itf = compo.get_interface(compl[0]) if itf.link is None: print ("Interface '%s' is not connected." % itf_name) return action, part, rest = rest.partition(" ") if action in self.__class__.actions: self.__class__.actions[action](self, itf, rest) else: if len(action) != 0: print ("Unknown action: '%s'" % action) print ("Valid actions: %s" % ", ".join(self.__class__.actions.keys()))
[docs] def switch(self, itf, arg): other_side = itf.link.get_other_endpoints(itf) if len(other_side) == 0: print ("No other endpoint connected to interface '%s'." % itf.name) return rmt_itf = None if len(other_side) == 1: rmt_itf = other_side[0] else: if len(arg) == 0: idx = 1 print ("Multiple destinations possible for interface '%s':" % itf.name) for rmtItf in other_side: print ("\t[%d] %s" % (idx, rmt_itf) ) return try: rmt_itf_idx = int(arg) except ValueError: print ("Invalid interface index ('%s')" % arg) return try: rmt_itf = other_side[rmt_itf_idx] except KeyError: print ("No such interface index ('%d')" % rmt_itf_idx) return ret = rmt_itf.comm_entity.switch() if ret is None: print ("No inferior associated with component %s." % rmt_itf) elif not ret: print ("Impossible to switch to component %s." % rmt_itf)
[docs] def tbreak(self, itf, arg, permanent=False): string = "[New message%%s on %s/%s%s]" % (itf.comm_entity, itf.name, " (%s)" % arg if arg else "") def cb(msg): return string % (" #"+str(msg.numbers[connection_mon.Message]) if msg is not None else "") ret = itf.stop_next(permanent=permanent, cb=cb) if permanent: print ("Breakpoint set on %s/%s's events." % \ (itf.comm_entity, itf.name)) else: print ("Temporary breakpoint set on %s/%s's next event." % \ (itf.comm_entity, itf.name)) return ret
[docs] def next_(self, itf, arg): self.tbreak(itf, arg) gdb.execute("cont")
[docs] def breakpoint(self, itf, arg): if arg == "off": if itf.breakpoint_rq is None: my_gdb.log.warning("No breakpoint set on this interface.") return itf.undo_request(itf.breakpoint_rq) itf.breakpoint_rq = None print ("Breakpoint removed from %s/%s." % (itf.comm_entity, itf.name)) else: if itf.breakpoint_rq is not None: msg = itf.breakpoint_rq.str is not None and \ itf.breakpoint_rq.str or "No message" my_gdb.log.warning("Breakpoint already set on this interface.") return itf.breakpoint_rq = self.tbreak(itf, arg, permanent=True)
actions = {"switch": switch, "tbreak": tbreak, "next": next_, "break":breakpoint}
[docs] def complete(self, compo, text, word): assert compo is not None complete = [] itf, part, rest = text.partition(" ") if itf not in compo.interfaces: for name in compo.interfaces: if name.startswith(itf): complete.append(name) return complete act, part, rest = rest.partition(" ") for action in self.__class__.actions.keys(): if action.startswith(act) and action != act: complete.append(action) return complete
[docs]class subcmd_compo_disable_work: must_have = True def __init__ (self): cmd_component.sub_command(self, name="track-work", default=True)
[docs] def invoke (self, compo, arg, from_tty): if compo is None: print ("Error: no component selected") return if compo.work_breakpoint is None: print ("Error: no work breakpoint for this component") return do_enable = arg in ("y", "yes", "o", "on") compo.work_breakpoint.enabled = do_enable print ("Tracking WORK method %s for component %s." % ("enabled" if do_enable else "disabled", str(compo)))
[docs]def initialize(): global cmd_component cmd_component = cmd_compo() subcmd_compo_switch() subcmd_compo_catch() subcmd_compo_break() subcmd_compo_disable_work() cmd_info_compo()
#subcmd_compo_interface()