|
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)
|