예제 #1
0
    def varprint_start_no_create(self,
                                 rank,
                                 varobj,
                                 name,
                                 max_depth=gdbconf.varprint_max_depth,
                                 max_children=gdbconf.varprint_max_children,
                                 reset_maxes=False):
        """Start a varprint sequence where we have already created the variable object."""
        v_id = self.varprint_id
        self.varprint_id += 1
        self.varprint_stacks[v_id] = [(varobj, 0)]
        branch_depth = max_depth = VariableObjectManager.get_name_depth(name)

        def _list_handler(record):
            return self.varprint_dfs(record,
                                     rank,
                                     v_id,
                                     name,
                                     max_depth=max_depth,
                                     max_children=max_children,
                                     reset_maxes=reset_maxes,
                                     branch_depth=branch_depth,
                                     branch_name=name)

        tokens = self.run_gdb_command(
            Command("var-list-children", args=("1", '"' + varobj.name + '"')),
            rank)
        self.be.add_token_handler(tokens[rank], _list_handler)
예제 #2
0
파일: gdbfe.py 프로젝트: thaolt/PGDB
 def do_help(self, cmd, targets=None):
     """Run the help command."""
     if not targets:
         # Because this makes the most sense, unless told otherwise, we run this on one processor.
         targets = 0
     self.comm.send(
         GDBMessage(CMD_MSG,
                    command=Command("interpreter-exec",
                                    args=("console", '"help ' + cmd + '"')),
                    ranks=targets), targets)
예제 #3
0
    def varprint_update(self, name, rank):
        """Check for updates on any of our variable objects."""
        def _update_handler(record):
            if "changelist" not in record.results:
                print "Got a bad update record."
                return True
            for change in record.results["changelist"]:
                varobj = self.varobjs[rank].get_var_obj(change["name"])
                if varobj:
                    # Potentially, a variable object could be manually created that we're not tracking.
                    if "in_scope" in change:
                        if change["in_scope"] in ["false", "invalid"]:
                            self.varobjs[rank].del_var_obj(varobj)
                            del varobj  # This probably isn't necessary.
                            return False
                    if "type_changed" in change and change[
                            "type_changed"] == "true":
                        self.varobjs[rank].del_var_obj(varobj)
                        del varobj
                        return False
                    if "value" in change:
                        varobj.value = change["value"]
                    if "dynamic" in change:
                        varobj.is_dynamic = change["dynamic"]
                    if "displayhint" in change:
                        varobj.display_hint = change["displayhint"]
                    if "num_new_children" in change:
                        new_num = int(change["new_num_children"])
                        if new_num < len(varobj.children):
                            # There has been a removal, so we no longer have child information.
                            varobj.children = []
                            varobj.listed = False
                            varobj.has_more = False
                        else:
                            if "new_children" in change:
                                for child in change["new_children"]:
                                    varobj = VariableObjectManager.create_var_obj(
                                        child)
                                    if not varobj:
                                        print "Could not create child varobj!"
                                        return True
                                    if not self.varobjs[rank].add_var_obj(
                                            varobj):
                                        print "Could not add child varobj!"
                                        return True
            self.varprint_handler2(name, rank)

        tokens = self.run_gdb_command(Command("var-update", args=("1", "*")),
                                      rank)
        self.be.add_token_handler(tokens[rank], _update_handler)
예제 #4
0
    def varprint_start(self,
                       rank,
                       name,
                       max_depth=gdbconf.varprint_max_depth,
                       max_children=gdbconf.varprint_max_children,
                       reset_maxes=False):
        """Start a varprint command sequence by creating the varobj in GDB."""
        v_id = self.varprint_id
        self.varprint_id += 1
        base_name = VariableObjectManager.get_base_name(name)
        branch_depth = max_depth + VariableObjectManager.get_name_depth(name)

        def _list_handler(record):
            return self.varprint_dfs(record,
                                     rank,
                                     v_id,
                                     name,
                                     max_depth=max_depth,
                                     max_children=max_children,
                                     reset_maxes=False,
                                     branch_depth=branch_depth,
                                     branch_name=name)

        def _create_handler(record):
            varobj = VariableObjectManager.create_var_obj(record.results)
            if not varobj:
                # Bad variable name.
                return True
            if not self.varobjs[rank].add_var_obj(varobj):
                print "Could not add varobj."
            if int(varobj.num_child) > 0 or varobj.is_dynamic:
                # Set up our stack.
                self.varprint_stacks[v_id] = [(varobj, 0)]
                tokens = self.run_gdb_command(
                    Command("var-list-children",
                            args=("1", record.results["name"])), rank)
                self.be.add_token_handler(tokens[rank], _list_handler)
            else:
                self.comm.send(
                    GDBMessage(VARPRINT_RES_MSG,
                               varobj=varobj,
                               rank=rank,
                               err=False), self.comm.frontend)

        tokens = self.run_gdb_command(
            Command("var-create", args=(base_name, "*", base_name)), rank)
        self.be.add_token_handler(tokens[rank], _create_handler)
예제 #5
0
 def _create_handler(record):
     varobj = VariableObjectManager.create_var_obj(record.results)
     if not varobj:
         # Bad variable name.
         return True
     if not self.varobjs[rank].add_var_obj(varobj):
         print "Could not add varobj."
     if int(varobj.num_child) > 0 or varobj.is_dynamic:
         # Set up our stack.
         self.varprint_stacks[v_id] = [(varobj, 0)]
         tokens = self.run_gdb_command(
             Command("var-list-children",
                     args=("1", record.results["name"])), rank)
         self.be.add_token_handler(tokens[rank], _list_handler)
     else:
         self.comm.send(
             GDBMessage(VARPRINT_RES_MSG,
                        varobj=varobj,
                        rank=rank,
                        err=False), self.comm.frontend)
예제 #6
0
파일: gdbfe.py 프로젝트: thaolt/PGDB
 def do_varassign(self, cmd, targets=None):
     """Run the varassign command."""
     if not targets:
         targets = self.comm.get_mpiranks()
     split = cmd.split("=")
     if len(split) != 2:
         print "varassign format is: var = val"
         return
     var = split[0].strip()
     if var[0] == '"' and var[-1] == '"':
         var = var[1:-1]
     val = split[1].strip()
     for rank in targets.members():
         full_name = self.varobjs[rank].get_full_name(var)
         if not full_name:
             print "Variable not found on rank {0}.".format(rank)
             continue
         self.comm.send(
             GDBMessage(CMD_MSG,
                        command=Command("var-assign",
                                        args=('"' + full_name + '"',
                                              '"' + val + '"')),
                        ranks=rank), rank)
예제 #7
0
    def varprint_dfs(self,
                     record,
                     rank,
                     v_id,
                     name,
                     max_depth=gdbconf.varprint_max_depth,
                     max_children=gdbconf.varprint_max_children,
                     reset_maxes=False,
                     branch_depth=None,
                     branch_name=None):
        """Do the depth-first search for expanding a variable object's children."""
        cur_varobj, parent_depth = self.varprint_stacks[v_id].pop()
        cur_varobj.listed = True
        if "has_more" not in record.results:
            self.comm.send(
                GDBMessage(VARPRINT_RES_MSG,
                           rank=rank,
                           err=True,
                           msg="Got bad variable data."), self.comm.frontend)
        elif "children" in record.results:
            if len(record.results["children"]) > max_children:
                cur_varobj.more_children = True
            for child_tup in record.results["children"][:max_children]:
                child = child_tup[1]
                varobj = VariableObjectManager.create_var_obj(child)
                if not varobj:
                    print "Could not create child varobj!"
                    return True
                if not self.varobjs[rank].add_var_obj(varobj):
                    print "Could not add child varobj!"
                    return True
                if int(varobj.num_child) > 0 or varobj.is_dynamic:
                    # Only potentially push if the varobj can have children.
                    do_listing = True
                    if parent_depth > max_depth:
                        # If the depth of the parent of this node is greater than five,
                        # we want to terminate the search of this branch, unless this
                        # node is a pseduo-child, or we want to go deeper on one branch.
                        if branch_name and VariableObjectManager.same_branch(
                                varobj.name, branch_name):
                            if parent_depth > branch_depth and not VariableObjectManager.is_pseudochild(
                                    varobj):
                                do_listing = False
                        elif not VariableObjectManager.is_pseudochild(varobj):
                            do_listing = False
                    # Don't list null-pointers.
                    if varobj.vartype and varobj.value and varobj.vartype[
                            -1] == "*":
                        try:
                            if int(varobj.value, 0) == 0:
                                do_listing = False
                        except ValueError:
                            pass
                    # Do not evaluate children further when there's an excessive number.
                    if len(record.results["children"]) > 128:
                        do_listing = False
                    # Add to the stack to list if we meet the requirements.
                    if do_listing:
                        self.varprint_stacks[v_id].append(
                            (varobj, parent_depth + 1))
        if not self.varprint_stacks[v_id]:
            to_send = self.varobjs[rank].get_var_obj(name)
            if to_send:
                self.comm.send(
                    GDBMessage(VARPRINT_RES_MSG,
                               varobj=to_send,
                               rank=rank,
                               err=False), self.comm.frontend)
            else:
                self.comm.send(
                    GDBMessage(VARPRINT_RES_MSG,
                               rank=rank,
                               err=True,
                               msg="Variable does not exist."),
                    self.comm.frontend)
        else:
            to_list, depth = self.varprint_stacks[v_id][-1]
            if reset_maxes:

                def _list_handler(record):
                    return self.varprint_dfs(record,
                                             rank,
                                             v_id,
                                             name,
                                             branch_depth=branch_depth,
                                             branch_name=branch_name)
            else:

                def _list_handler(record):
                    return self.varprint_dfs(record,
                                             rank,
                                             v_id,
                                             name,
                                             max_depth=max_depth,
                                             max_children=max_children,
                                             reset_maxes=reset_maxes,
                                             branch_depth=branch_depth,
                                             branch_name=branch_name)

            tokens = self.run_gdb_command(
                Command("var-list-children",
                        args=("1", '"' + to_list.name + '"')), rank)
            self.be.add_token_handler(tokens[rank], _list_handler)
예제 #8
0
    def init_gdb(self):
        """Initialize GDB-related things, and launch the GDB process."""
        # Indexed by MPI rank.
        self.varobjs = {}
        # Maps tokens to MPI rank.
        self.token_rank_map = {}
        self.record_handler = GDBMIRecordHandler()
        self.record_handler.add_type_handler(
            self._watch_thread_created,
            set([mi.gdbmi_records.ASYNC_NOTIFY_THREAD_CREATED]))
        self.startup_stop_hid = self.record_handler.add_type_handler(
            self._watch_startup_stop,
            set([mi.gdbmi_records.ASYNC_EXEC_STOPPED]))
        gdb_env = {}
        if gdbconf.use_sbd:
            self.sbd = SBDBE(self.comm)
            gdb_env["LD_PRELOAD"] = gdbconf.sbd_bin
        else:
            self.sbd = None

        enable_pprint_cmd = Command("enable-pretty-printing")
        enable_target_async_cmd = Command("gdb-set",
                                          args=["target-async", "on"])
        disable_pagination_cmd = Command("gdb-set", args=["pagination", "off"])
        enable_non_stop_cmd = Command("gdb-set", args=["non-stop", "on"])
        add_inferior_cmd = Command("add-inferior")
        self.gdb = GDBMachineInterface(gdb=gdbconf.gdb_path,
                                       gdb_args=["-x", gdbconf.gdb_init_path],
                                       env=gdb_env)
        procs = self.comm.get_proctab()
        # Set up GDB.
        if not self.run_gdb_command(enable_pprint_cmd):
            raise RuntimeError("Could not enable pretty printing!")
        if not self.run_gdb_command(enable_target_async_cmd):
            raise RuntimeError("Could not enable target-async!")
        if not self.run_gdb_command(disable_pagination_cmd):
            raise RuntimeError("Could not disable pagination!")
        if not self.run_gdb_command(enable_non_stop_cmd):
            raise RuntimeError("Could not enable non-stop!")

        # Create inferiors and set up MPI rank/inferior map.
        # First inferior is created by default.
        self.rank_inferior_map = {procs[0].mpirank: 'i1'}
        self.inferior_rank_map = {'i1': procs[0].mpirank}
        i = 2
        for proc in procs[1:]:
            # Hackish: Assume that the inferiors follow the iN naming scheme.
            self.rank_inferior_map[proc.mpirank] = 'i' + str(i)
            self.inferior_rank_map['i' + str(i)] = proc.mpirank
            i += 1
            if not self.run_gdb_command(add_inferior_cmd, no_thread=True):
                raise RuntimeError('Cound not add inferior i{0}!'.format(i -
                                                                         1))

        # Maps MPI ranks to associated threads and vice-versa.
        self.rank_thread_map = {}
        self.thread_rank_map = {}

        if self.sbd:
            # Set up the list of executables for load file checking.
            self.sbd.set_executable_names(
                [os.path.basename(proc.pd.executable_name) for proc in procs])

        # Attach processes.
        for proc in procs:
            if not self.run_gdb_command(Command(
                    "target-attach",
                    opts={
                        '--thread-group': self.rank_inferior_map[proc.mpirank]
                    },
                    args=[proc.pd.pid]),
                                        proc.mpirank,
                                        no_thread=True):
                raise RuntimeError("Could not attach to rank {0}!".format(
                    proc.mpirank))
            self.varobjs[proc.mpirank] = VariableObjectManager()
            # Cludge to fix GDB not outputting records for the i1 attach.
            if self.rank_inferior_map[proc.mpirank] == 'i1':
                time.sleep(0.1)
예제 #9
0
파일: gdbfe.py 프로젝트: thaolt/PGDB
 def do_quit(self, cmd, targets=None):
     """Gracefully quit PGDB."""
     self.quit = True
     self.comm.send(GDBMessage(CMD_MSG, command=Command("gdb-exit")),
                    self.comm.broadcast)