Blame src/plugins/abrt-action-list-dsos

Packit Service 8a8a03
#!/usr/bin/python3 -u
Packit Service 8a8a03
# WARNING: python -u means unbuffered I/O. Without it the messages are
Packit Service 8a8a03
# passed to the parent asynchronously which looks bad in clients.
Packit Service 8a8a03
Packit Service 8a8a03
import sys
Packit Service 8a8a03
import os
Packit Service 8a8a03
import getopt
Packit Service 8a8a03
import rpm
Packit Service 8a8a03
Packit Service 8a8a03
def log_warning(s):
Packit Service 8a8a03
    sys.stderr.write("%s\n" % s)
Packit Service 8a8a03
Packit Service 8a8a03
def error_msg(s):
Packit Service 8a8a03
    sys.stderr.write("%s\n" % s)
Packit Service 8a8a03
Packit Service 8a8a03
def error_msg_and_die(s):
Packit Service 8a8a03
    sys.stderr.write("%s\n" % s)
Packit Service 8a8a03
    sys.exit(1)
Packit Service 8a8a03
Packit Service 8a8a03
def xopen(name, mode):
Packit Service 8a8a03
    try:
Packit Service 8a8a03
        r = open(name, mode)
Packit Service 8a8a03
    except IOError as e:
Packit Service 8a8a03
        error_msg_and_die("Can't open '%s': %s" % (name, e))
Packit Service 8a8a03
    return r
Packit Service 8a8a03
Packit Service 8a8a03
Packit Service 8a8a03
def parse_maps(maps_path):
Packit Service 8a8a03
    try:
Packit Service 8a8a03
        f = xopen(maps_path, "r")
Packit Service 8a8a03
        # We want to handle both /proc/PID/maps format:
Packit Service 8a8a03
        #  4f200000-4f215000 r-xp 00000000 08:03 1835520   /usr/lib64/libz.so.1.2.7
Packit Service 8a8a03
        # and Xorg backtrace format:
Packit Service 8a8a03
        #  [ 86985.880] 9: /usr/lib64/libdrm.so.2 (drmHandleEvent+0xa3) [0x376b407513]
Packit Service 8a8a03
        # To do that, we take only lines which have a / character,
Packit Service 8a8a03
        # then for each line we start at first /, then remove everything after first whitespace
Packit Service 8a8a03
        files = [x[x.find('/'):].split()[0] for x in f.readlines() if x.find('/') > -1]
Packit Service 8a8a03
        # set() uniqifies the list of filenames
Packit Service 8a8a03
        return set(files)
Packit Service 8a8a03
    except IOError as e:
Packit Service 8a8a03
        error_msg_and_die("Can't read '%s': %s" % (maps_path, e))
Packit Service 8a8a03
Packit Service 8a8a03
if __name__ == "__main__":
Packit Service 8a8a03
    progname = os.path.basename(sys.argv[0])
Packit Service 8a8a03
    help_text = ("Usage: %s [-o OUTFILE] -m PROC_PID_MAP_FILE") % progname
Packit Service 8a8a03
    try:
Packit Service 8a8a03
        opts, args = getopt.getopt(sys.argv[1:], "o:m:h", ["help"])
Packit Service 8a8a03
    except getopt.GetoptError as err:
Packit Service 8a8a03
        error_msg(err) # prints something like "option -a not recognized"
Packit Service 8a8a03
        error_msg_and_die(help_text)
Packit Service 8a8a03
Packit Service 8a8a03
    opt_o = None
Packit Service 8a8a03
    memfile = None
Packit Service 8a8a03
Packit Service 8a8a03
    for opt, arg in opts:
Packit Service 8a8a03
        if opt in ("-h", "--help"):
Packit Service 8a8a03
            print(help_text)
Packit Service 8a8a03
            exit(0)
Packit Service 8a8a03
        #elif opt == "-v":
Packit Service 8a8a03
        #    verbose += 1
Packit Service 8a8a03
        elif opt == "-o":
Packit Service 8a8a03
            opt_o = arg
Packit Service 8a8a03
        elif opt == "-m":
Packit Service 8a8a03
            memfile = arg
Packit Service 8a8a03
Packit Service 8a8a03
    if not memfile:
Packit Service 8a8a03
        error_msg("MAP_FILE is not specified")
Packit Service 8a8a03
        error_msg_and_die(help_text)
Packit Service 8a8a03
Packit Service 8a8a03
    try:
Packit Service 8a8a03
        # Note that we open -o FILE only when we reach the point
Packit Service 8a8a03
        # when we are definitely going to write something to it
Packit Service 8a8a03
        outfile = sys.stdout
Packit Service 8a8a03
        outname = opt_o
Packit Service 8a8a03
        try:
Packit Service 8a8a03
            dso_paths = parse_maps(memfile)
Packit Service 8a8a03
            for path in dso_paths:
Packit Service 8a8a03
                ts = rpm.TransactionSet()
Packit Service 8a8a03
                mi = ts.dbMatch('basenames', path)
Packit Service 8a8a03
                if len(mi):
Packit Service 8a8a03
                    for h in mi:
Packit Service 8a8a03
                        if outname:
Packit Service 8a8a03
                            outfile = xopen(outname, "w")
Packit Service 8a8a03
                            outname = None
Packit Service 8a8a03
Packit Service 8a8a03
                        vendor = h[rpm.RPMTAG_VENDOR]
Packit Service 8a8a03
                        rpmtag_nevra = h[rpm.RPMTAG_NEVRA]
Packit Service 8a8a03
Packit Service 8a8a03
                        outfile.write("%s %s (%s) %s\n" %
Packit Service 8a8a03
                                      (path,
Packit Service 8a8a03
                                       rpmtag_nevra,
Packit Service 8a8a03
                                       vendor,
Packit Service 8a8a03
                                       h[rpm.RPMTAG_INSTALLTIME])
Packit Service 8a8a03
                                      )
Packit Service 8a8a03
Packit Service 8a8a03
        except Exception as ex:
Packit Service 8a8a03
            error_msg_and_die("Can't get the DSO list: %s" % ex)
Packit Service 8a8a03
Packit Service 8a8a03
        outfile.close()
Packit Service 8a8a03
    except:
Packit Service 8a8a03
        if not opt_o:
Packit Service 8a8a03
            opt_o = "<stdout>"
Packit Service 8a8a03
        error_msg_and_die("Error writing to '%s'" % opt_o)