On Thu, 2012-09-20 at 13:54 +0200, Jiri Moskovcak wrote:
- doesn't work
- the python exception are caught fine, but the file dso_list is not created
I've just tested it once more and it works on my F17 system. My test case is adding
import subprocess; subprocess.call("nonexisting_binary")
to the /usr/bin/phatch file followed by running phatch. This results in a directory in /var/spool/abrt that contains the dso_list file with python-libs package listed.
On 08/15/2012 03:05 PM, Vratislav Podzimek wrote:
Signed-off-by: Vratislav Podzimek vpodzime@redhat.com
src/hooks/abrt_exception_handler.py.in | 84 ++++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 4 deletions(-)
diff --git a/src/hooks/abrt_exception_handler.py.in b/src/hooks/abrt_exception_handler.py.in index 6c0659a..ecdb175 100644 --- a/src/hooks/abrt_exception_handler.py.in +++ b/src/hooks/abrt_exception_handler.py.in @@ -24,8 +24,22 @@ Module for the ABRT exception handling hook
import sys import os +import inspect
-def write_dump(tb): +try:
- import rpm
- HAVE_RPM = True
+except ImportError as imperr:
- HAVE_RPM = False
- import syslog
- syslog.syslog("RPM module not available, cannot query RPM db for package "\
"names")
+class RPMinfoError(Exception):
- """Exception class for RPMdb-querying related errors"""
- pass
+def write_dump(tb_text, tb): if sys.argv[0][0] == "/": executable = os.path.abspath(sys.argv[0]) else: @@ -33,6 +47,11 @@ def write_dump(tb): # (BTW, we *can't* assume the script is in current directory.) executable = sys.argv[0]
- if HAVE_RPM:
dso_list = get_dso_list(tb)
- else:
dso_list = None
# Open ABRT daemon's socket and write data to it try: import socket
@@ -48,8 +67,12 @@ def write_dump(tb): # This handler puts a short(er) crash descr in 1st line of the backtrace. # Example: # CCMainWindow.py:1:<module>:ZeroDivisionError: integer division or modulo by zero
s.sendall("REASON=%s\0" % tb.splitlines()[0])
s.sendall("BACKTRACE=%s\0" % tb)
s.sendall("REASON=%s\0" % tb_text.splitlines()[0])
s.sendall("BACKTRACE=%s\0" % tb_text)
if dso_list:
s.sendall("dso_list=%s\0" % "\n".join(dso_list))
s.shutdown(socket.SHUT_WR)
@@ -77,6 +100,59 @@ def write_dump(tb): import syslog syslog.syslog("can't communicate with ABRT daemon, is it running? %s" % str(ex))
+def get_package_for_file(fpath):
- """
- Returns package name for a given file.
- @param fpath: filename
- @type fpath: str
- @return: package name for the file
- @rtype: str
- @throws RPMinfoError: if package for the file cannot be found
- """
- ts = rpm.TransactionSet()
- mi = ts.dbMatch("basenames", fpath)
- try:
header = mi.next()
- except StopIteration:
raise RPMinfoError("Cannot get package and component for file "+
fpath)
- package = "{0}-{1}-{2}.{3}".format(header["name"], header["version"],
header["release"], header["arch"])
- return package
+def get_dso_list(tb):
- """
- Get the list of names of the packages whose files appear in the traceback.
- @param tb: traceback
- @type tb: traceback
- @return: list of package names
- @rtype: list
- """
- if inspect.istraceback(tb):
tb = inspect.getinnerframes(tb)
- packages = set()
- for (frame, fpath, lineno, func, ctx, idx) in tb:
try:
packages.add(get_package_for_file(fpath))
except RPMinfoError as rpmerr:
continue
- # remove the package name of the executable itself
- try:
packages.discard(get_package_for_file(sys.argv[0]))
- except RPMinfoError as rpmerr:
pass
- return list(packages)
- def conf_enabled(var_name): try: file = open(@CONF_DIR@ + "/plugins/python.conf", "r")
@@ -187,7 +263,7 @@ def handleMyException((etype, value, tb)): text += "".join(elist)
# Send data to the daemon
write_dump(text)
write_dump(text, tb) except: # Silently ignore any error in this hook,