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 <[email protected]>
> > ---
> >   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,
> >
> 


Reply via email to