diff options
author | Joshua Watt <JPEWhacker@gmail.com> | 2024-10-08 13:36:25 +0100 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2024-12-06 05:50:24 -0800 |
commit | d77302b2fe94db6c132310771b7b97c7b534edec (patch) | |
tree | 9dfca5b2686eb7a96d6c53e4920502a0581efed4 /bitbake/lib/bb/exceptions.py | |
parent | fd5231a5445f0a61d3a7678d1980a94dc1c80544 (diff) | |
download | poky-d77302b2fe94db6c132310771b7b97c7b534edec.tar.gz |
bitbake: Remove custom exception backtrace formatting
Removes the code in bitbake to show custom backtrace formatting for
exceptions. In particular, the bitbake exception code prints function
arguments, which while helpful is a security problem when passwords and
other secrets can be passed as function arguments.
As it turns out, the handling of the custom serialized exception stack
frames was pretty much made obsolete by d7db75020ed ("event/msg: Pass
formatted exceptions"), which changed the events to pass a preformatted
stacktrack list of strings, but the passing of the serialized data was
never removed.
Change all the code to use the python traceback API to format exceptions
instead of the custom code; conveniently traceback.format_exception()
also returns a list of stack trace strings, so it can be used as a drop
in replacement for bb.exception.format_exception()
(Bitbake rev: c25e7ed128b9fd5b53d28d678238e2f3af52ef8b)
Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'bitbake/lib/bb/exceptions.py')
-rw-r--r-- | bitbake/lib/bb/exceptions.py | 96 |
1 files changed, 0 insertions, 96 deletions
diff --git a/bitbake/lib/bb/exceptions.py b/bitbake/lib/bb/exceptions.py deleted file mode 100644 index 801db9c82f..0000000000 --- a/bitbake/lib/bb/exceptions.py +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | # | ||
2 | # Copyright BitBake Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: GPL-2.0-only | ||
5 | # | ||
6 | |||
7 | import inspect | ||
8 | import traceback | ||
9 | import bb.namedtuple_with_abc | ||
10 | from collections import namedtuple | ||
11 | |||
12 | |||
13 | class TracebackEntry(namedtuple.abc): | ||
14 | """Pickleable representation of a traceback entry""" | ||
15 | _fields = 'filename lineno function args code_context index' | ||
16 | _header = ' File "{0.filename}", line {0.lineno}, in {0.function}{0.args}' | ||
17 | |||
18 | def format(self, formatter=None): | ||
19 | if not self.code_context: | ||
20 | return self._header.format(self) + '\n' | ||
21 | |||
22 | formatted = [self._header.format(self) + ':\n'] | ||
23 | |||
24 | for lineindex, line in enumerate(self.code_context): | ||
25 | if formatter: | ||
26 | line = formatter(line) | ||
27 | |||
28 | if lineindex == self.index: | ||
29 | formatted.append(' >%s' % line) | ||
30 | else: | ||
31 | formatted.append(' %s' % line) | ||
32 | return formatted | ||
33 | |||
34 | def __str__(self): | ||
35 | return ''.join(self.format()) | ||
36 | |||
37 | def _get_frame_args(frame): | ||
38 | """Get the formatted arguments and class (if available) for a frame""" | ||
39 | arginfo = inspect.getargvalues(frame) | ||
40 | |||
41 | try: | ||
42 | if not arginfo.args: | ||
43 | return '', None | ||
44 | # There have been reports from the field of python 2.6 which doesn't | ||
45 | # return a namedtuple here but simply a tuple so fallback gracefully if | ||
46 | # args isn't present. | ||
47 | except AttributeError: | ||
48 | return '', None | ||
49 | |||
50 | firstarg = arginfo.args[0] | ||
51 | if firstarg == 'self': | ||
52 | self = arginfo.locals['self'] | ||
53 | cls = self.__class__.__name__ | ||
54 | |||
55 | arginfo.args.pop(0) | ||
56 | del arginfo.locals['self'] | ||
57 | else: | ||
58 | cls = None | ||
59 | |||
60 | formatted = inspect.formatargvalues(*arginfo) | ||
61 | return formatted, cls | ||
62 | |||
63 | def extract_traceback(tb, context=1): | ||
64 | frames = inspect.getinnerframes(tb, context) | ||
65 | for frame, filename, lineno, function, code_context, index in frames: | ||
66 | formatted_args, cls = _get_frame_args(frame) | ||
67 | if cls: | ||
68 | function = '%s.%s' % (cls, function) | ||
69 | yield TracebackEntry(filename, lineno, function, formatted_args, | ||
70 | code_context, index) | ||
71 | |||
72 | def format_extracted(extracted, formatter=None, limit=None): | ||
73 | if limit: | ||
74 | extracted = extracted[-limit:] | ||
75 | |||
76 | formatted = [] | ||
77 | for tracebackinfo in extracted: | ||
78 | formatted.extend(tracebackinfo.format(formatter)) | ||
79 | return formatted | ||
80 | |||
81 | |||
82 | def format_exception(etype, value, tb, context=1, limit=None, formatter=None): | ||
83 | formatted = ['Traceback (most recent call last):\n'] | ||
84 | |||
85 | if hasattr(tb, 'tb_next'): | ||
86 | tb = extract_traceback(tb, context) | ||
87 | |||
88 | formatted.extend(format_extracted(tb, formatter, limit)) | ||
89 | formatted.extend(traceback.format_exception_only(etype, value)) | ||
90 | return formatted | ||
91 | |||
92 | def to_string(exc): | ||
93 | if isinstance(exc, SystemExit): | ||
94 | if not isinstance(exc.code, str): | ||
95 | return 'Exited with "%d"' % exc.code | ||
96 | return str(exc) | ||