• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Gallopsled / pwntools / 8912ca5a8c3a9725c3ba6d30561607150a6faebe-PR-2205

pending completion
8912ca5a8c3a9725c3ba6d30561607150a6faebe-PR-2205

Pull #2205

github-actions

web-flow
Merge 81f463e2c into 8b4cacf8b
Pull Request #2205: Fix stable Python 2 installation from a built wheel

3878 of 6371 branches covered (60.87%)

12199 of 16604 relevant lines covered (73.47%)

0.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

33.33
/pwnlib/atexception.py
1
"""
2
Analogous to atexit, this module allows the programmer to register functions to
3
be run if an unhandled exception occurs.
4
"""
5
from __future__ import absolute_import
1✔
6
from __future__ import division
1✔
7

8
import sys
1✔
9
import threading
1✔
10
import traceback
1✔
11

12
from pwnlib.context import context
1✔
13

14
__all__ = ['register', 'unregister']
1✔
15

16
_lock = threading.Lock()
1✔
17
_ident = 0
1✔
18
_handlers = {}
1✔
19

20
def register(func, *args, **kwargs):
1✔
21
    """register(func, *args, **kwargs)
22

23
    Registers a function to be called when an unhandled exception occurs.  The
24
    function will be called with positional arguments `args` and keyword
25
    arguments `kwargs`, i.e. ``func(*args, **kwargs)``.  The current `context`
26
    is recorded and will be the one used when the handler is run.
27

28
    E.g. to suppress logging output from an exception-handler one could write::
29

30
      with context.local(log_level = 'error'):
31
        atexception.register(handler)
32

33
    An identifier is returned which can be used to unregister the
34
    exception-handler.
35

36
    This function can be used as a decorator::
37

38
      @atexception.register
39
      def handler():
40
        ...
41

42
    Notice however that this will bind ``handler`` to the identifier and not the
43
    actual exception-handler.  The exception-handler can then be unregistered
44
    with::
45

46
      atexception.unregister(handler)
47

48
    This function is thread safe.
49

50
    """
51
    global _ident
52
    with _lock:
×
53
        ident = _ident
×
54
        _ident += 1
×
55
    _handlers[ident] = (func, args, kwargs, vars(context))
×
56
    return ident
×
57

58
def unregister(func):
1✔
59
    """unregister(func)
60

61
    Remove `func` from the collection of registered functions.  If `func` isn't
62
    registered this is a no-op.
63
    """
64
    if func in _handlers:
×
65
        del _handlers[func]
×
66

67
def _run_handlers():
1✔
68
    """_run_handlers()
69

70
    Run registered handlers.  They run in the reverse order of which they were
71
    registered.
72

73
    If a handler raises an exception, it will be printed but nothing else
74
    happens, i.e. other handlers will be run.
75
    """
76
    for _ident, (func, args, kwargs, ctx) in \
×
77
        sorted(_handlers.items(), reverse = True):
78
        try:
×
79
            with context.local():
×
80
                context.clear()
×
81
                context.update(**ctx)
×
82
                func(*args, **kwargs)
×
83
        except SystemExit:
×
84
            pass
×
85
        except Exception:
×
86
            # extract the current exception and rewind the traceback to where it
87
            # originated
88
            typ, val, tb = sys.exc_info()
×
89
            traceback.print_exception(typ, val, tb.tb_next)
×
90

91
# we rely on the existing excepthook to print exceptions
92
_oldhook = getattr(sys, 'excepthook', None)
1✔
93

94
def _newhook(typ, val, tb):
1✔
95
    """_newhook(typ, val, tb)
96

97
    Our excepthook replacement.  First the original hook is called to print the
98
    exception, then each handler is called.
99
    """
100
    if _oldhook:
×
101
        _oldhook(typ, val, tb)
×
102
    if _run_handlers:
×
103
        _run_handlers()
×
104

105
sys.excepthook = _newhook
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc