Пример #1
0
    def __getitem__(self, name):
        """ Accessing variables by name.

Search order:
- current subprogram local data (variables, arguments, ...)
- global variables for compile unit of current subprogram
TODO: public global variables across all CUs
TODO: current CU's subprograms
TODO: public global subprograms
TODO: target registers

    :param name:
        of a variable

    :returns:
        corresponding runtime descriptor `Value`

        """

        prog = self.subprogram
        _locals = prog.data
        bname = bstr(name)

        try:
            datum = _locals[bname]
        except KeyError:
            cu = prog.die.cu
            _globals = self.dic.get_CU_global_variables(cu)
            try:
                datum = _globals[bname]
            except KeyError:
                raise KeyError("No name '%s' found in runtime" % name)

        return Value(datum, runtime = self, version = self.version)
Пример #2
0
 def set_br_by_line(self, lineno, cb):
     line_map = self.rt.dic.find_line_map(bstr(basename(self.srcfile)))
     line_descs = line_map[lineno]
     for desc in line_descs:
         # TODO: set a breakpoint at one address by line number?
         # if desc.state.is_stmt:
         addr = self.rt.target.reg_fmt % desc.state.address
         self.addr2line[addr] = lineno
         self.rt.add_br(addr, cb)
Пример #3
0
    def failback(self):
        """ Raises exception and displays the closest mung commits for all
breakpoint positions.
        """

        msg = []
        re_log = compile(b"<@>(.+?)</@>", flags=S)
        log_args = ("--pretty=format:</@><@>%H", "--no-merges", "-U0")

        for fname, lineno, version, delta_intervals in self.failures:
            log = self.curr_commit.repo.git.log(
                log_args, "HEAD..%s" % version, "--", fname,
                p=True)[4:] + "</@>"

            obstructive_commit = self.find_obstructive_commit(
                lineno, bstr(log), re_log)

            if obstructive_commit is None:
                if delta_intervals[lineno] is not None:
                    new_lineno = self.calc_lineno(delta_intervals, lineno)

                    log = self.curr_commit.repo.git.log(
                        log_args, "%s..HEAD" % version, "--", fname,
                        p=True)[4:] + "</@>"

                    obstructive_commit = self.find_obstructive_commit(
                        new_lineno, bstr(log), re_log)
                else:
                    msg.append(
                        ("\nThe closest obstructive commit for '%s:%s %s' "
                         "NOT FOUND!"
                         "\nTry decreasing the epsilon (default epsilon = 3).")
                        % (fname, lineno, version))
                    continue

            msg.append("\nThe closest obstructive commit for '%s:%s %s': %s" %
                       (fname, lineno, version, obstructive_commit))
        raise RuntimeError('\n'.join(msg))
Пример #4
0
    def test_gitpython(self):
        repo_dir = join(test_dir, "line_adaptation_tests", "gitrepo", "_git")

        # gitpython launches git during diff obtaining
        environ["GIT_DIR"] = repo_dir
        repo = Repo(repo_dir)
        diff = repo.commit("curr").diff("base", create_patch=True, unified=0)
        file_name = split(self._new)[0]
        raw_file_name = bstr(file_name)
        for change in diff:
            if change.b_rawpath == raw_file_name:
                self._check(change.diff)
                break
        else:
            self.fail("No diff for file " + file_name)
Пример #5
0
    def __getitem__(self, name):
        if self.code == TYPE_CODE_TYPEDEF:
            return self.target_type[name]

        members = self.members

        bname = bstr(name)

        if bname in members:
            return members[bname]

        # A declaration is expected to do not contain members. Hence, try to
        # find definition and get the member from it.
        if not self.declaration:
            raise KeyError("No member '%s'" % name)

        definition = self.dic[self.name]
        return definition[name]
Пример #6
0
    def __init__(self, dic, line_adapter=None, verbose=False):
        """
    :type dic: DWARFInfoCache
    :param line_adapter:
        is object that specifically converts the line number of a file for some
        breakpoint position
        """
        self.dic = dic
        if line_adapter is None:
            line_adapter = IdentityAdapter()
        self.verbose = verbose

        # inspect methods getting those who is a breakpoint handler
        self.breakpoints = brs = []
        for _, cb in getmembers(self, predicate=is_breakpoint_cb):
            mi = None
            for mi in breakpoint_matches(cb.__doc__.splitlines()):
                file_name, lineno, opaque = mi.groups()
                raw_file_name = bstr(file_name)
                raw_file_name, line = line_adapter.adapt_lineno(
                    raw_file_name, lineno, opaque)
                if line is not None:
                    break
            else:
                if mi is None:
                    # No position specification was found.
                    # It's not a breakpoint handler.
                    continue
                try:
                    raw_file_name, line = line_adapter.failback()
                except Exception as e:
                    # This location format is compatible with PyDev (Eclipse)
                    # and same as one used in standard exception tracebacks.
                    loc_str = '  File "%s", line %d' % cb_loc(cb)
                    raise RuntimeError("Failed to set breakpoint %s\n%s\n%s" %
                                       (cb.__name__, loc_str, e))

            line_map = dic.find_line_map(raw_file_name)
            line_descs = line_map[line]

            for desc in line_descs:
                addr = desc.state.address
                brs.append((addr, cb, raw_file_name, line))
Пример #7
0
    def __init__(self, dic, line_adapter=None, verbose=False):
        """
    :type dic: DWARFInfoCache
    :param line_adapter:
        is object that specifically converts the line number of a file for some
        breakpoint position
        """
        self.dic = dic
        if line_adapter is None:
            line_adapter = IdentityAdapter()
        self.verbose = verbose

        # inspect methods getting those who is a breakpoint handler
        self.breakpoints = brs = []
        for _, cb in getmembers(self, predicate=is_breakpoint_cb):
            mi = None
            for mi in breakpoint_matches(cb.__doc__.splitlines()):
                file_name, lineno, opaque = mi.groups()
                raw_file_name = bstr(file_name)
                raw_file_name, line = line_adapter.adapt_lineno(
                    raw_file_name, lineno, opaque)
                if line is not None:
                    break
            else:
                if mi is None:
                    # No position specification was found.
                    # It's not a breakpoint handler.
                    continue
                raw_file_name, line = line_adapter.failback()

            line_map = dic.find_line_map(raw_file_name)
            line_descs = line_map[line]

            for desc in line_descs:
                addr = desc.state.address
                brs.append((addr, cb, raw_file_name, line))
Пример #8
0
    def __getitem__(self, name):
        sps = self.subprograms

        bname = bstr(name)

        if bname in sps:
            return sps[bname]

        types = self.types
        if bname in types:
            return types[bname]

        di = self.di

        # First, search in .debug_pubnames
        pubnames = self.pubnames
        if pubnames is None:
            offsets = None
        else:
            offsets = pubnames[name]

        # Second, search in .debug_pubtypes
        if offsets is None:
            pubtypes = self.pubtypes
            if pubtypes is None:
                offsets = None
            else:
                offsets = pubtypes[name]

        # Third, search in .symtab
        if offsets is None:
            symtab = self.symtab
            if symtab is None:
                raise KeyError(name)

            # Note that `bname` is not required there, `get_symbol_by_name`
            # can work with strings under both Py2 and Py3.
            symbols = symtab.get_symbol_by_name(name)
            if symbols is None:
                raise KeyError(name)

            for symbol in symbols:
                # Get CU that covers target address of current symbol
                address = symbol.entry.st_value
                cu = self.cu(address)

                # Search for a DIE with requested name
                # TODO: Only topmost DIEs are processed now. Is there a reason
                # for a deeper search?
                for die in cu.get_top_DIE().iter_children():
                    attrs = die.attributes
                    if "DW_AT_name" not in attrs:
                        continue
                    if attrs["DW_AT_name"].value == bname:
                        break
                else:
                    # No DIE with such name found in current CU
                    continue
                # A DIE with such name was found
                break
            else:
                # No DIE was found for each symbol with requested name
                raise KeyError(name)
            # Note that last cu and die variable definitions are looked for
        else:
            cu = di._parse_CU_at_offset(offsets[0])
            die = cu.get_DIE_at_offset(offsets[1] - offsets[0])

        tag = die.tag[7:]  # DW_TAG_*

        if tag == "subprogram":
            sym_name = die.attributes["DW_AT_name"].value
            symbol = Subprogram(self, die, name=sym_name)
            sps[sym_name] = [symbol]
        elif tag in TYPE_TAGS:
            symbol = self.type_by_die(die)
        else:
            raise NotImplementedError("Handling name '%s' of DIE tag"
                                      " 'DW_TAG_%s' is not implemented yet" %
                                      (name, tag))

        return symbol