Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception Handler: can't pickle traceback objects #17405

Open
andresriancho opened this issue Nov 13, 2018 · 0 comments
Open

Exception Handler: can't pickle traceback objects #17405

andresriancho opened this issue Nov 13, 2018 · 0 comments

Comments

@andresriancho
Copy link
Owner

The ExceptionHandler has a serious design flaw: it relies on ExceptionData having a self.traceback attribute, which is not serializable.

class ExceptionData(object):
    def __init__(self, current_status, e, tb, enabled_plugins):
        assert isinstance(e, Exception)
        assert isinstance(current_status, CoreStatus)

        #
        # According to [0] it is not a good idea to keep references to tracebacks:
        #
        #   > traceback refers to a linked list of frames, and each frame has references
        #   > to lots of other stuff like the code object, the global dict, local dict,
        #   > builtin dict, ...
        #
        # [0] https://bugs.python.org/issue13831
        #
        # TODO: Remove the next line:
        self.traceback = tb

This triggers:

Exception in thread AuditorController:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
    self.run()
  File "w3af/core/controllers/core_helpers/consumers/base_consumer.py", line 199, in run
    self._consume_wrapper(work_unit)
  File "w3af/core/controllers/core_helpers/consumers/base_consumer.py", line 58, in _wrapper
    result = method(self, function_id, *args, **kwds)
  File "w3af/core/controllers/core_helpers/consumers/base_consumer.py", line 227, in _consume_wrapper
    return self._consume(work_unit)
  File "w3af/core/controllers/core_helpers/consumers/audit.py", line 116, in _consume
    'audit.get_original_response()', e)
  File "w3af/core/controllers/core_helpers/consumers/base_consumer.py", line 424, in handle_exception
    self._out_queue.put(exception_data)
  File "/usr/lib/python2.7/Queue.py", line 136, in put
    self._put(item)
  File "w3af/core/data/misc/cached_queue.py", line 131, in _put
    self.disk[self.put_pointer] = item
  File "w3af/core/data/db/disk_dict.py", line 112, in __setitem__
    cpickle_dumps(value)))
  File "w3af/core/data/misc/cpickle_dumps.py", line 19, in cpickle_dumps
    return cPickle.dumps(obj, cPickle.HIGHEST_PROTOCOL)
TypeError: can't pickle traceback objects

The problem happens when one of the consumers gets an exception, the exception is handled like this:

  • ExceptionData instance is created and sent to the queue (crash happens here)
  • ExceptionData is read from the queue, deserialized and ExceptionHandler.handle_exception_data is called. One of the parameters used in this method is the traceback object (see: exception_data.traceback)
  • Then ExceptionHandler.handle is called, where in some cases the traceback is used to re-raise the exception using raise exception, None, tb.

AFAIK there is no way to have the feature of re-raising an exception with the original traceback without having the traceback instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant