-
Notifications
You must be signed in to change notification settings - Fork 623
Expand file tree
/
Copy pathgnu_backtrace.py
More file actions
96 lines (72 loc) · 2.72 KB
/
gnu_backtrace.py
File metadata and controls
96 lines (72 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import re
from typing import TYPE_CHECKING
import sentry_sdk
from sentry_sdk.integrations import Integration
from sentry_sdk.scope import add_global_event_processor
from sentry_sdk.utils import capture_internal_exceptions
if TYPE_CHECKING:
from typing import Any
from sentry_sdk._types import Event
# function is everything between index at @
# and then we match on the @ plus the hex val
FUNCTION_RE = r"[^@]+?"
HEX_ADDRESS = r"\s+@\s+0x[0-9a-fA-F]+"
_FRAME_RE_PATTERN = r"""
^(?P<index>\d+)\.\s+(?P<function>{FUNCTION_RE}){HEX_ADDRESS}(?:\s+in\s+(?P<package>.+))?$
""".format(
FUNCTION_RE=FUNCTION_RE,
HEX_ADDRESS=HEX_ADDRESS,
)
FRAME_RE = re.compile(_FRAME_RE_PATTERN, re.MULTILINE | re.VERBOSE)
class GnuBacktraceIntegration(Integration):
identifier = "gnu_backtrace"
@staticmethod
def setup_once() -> None:
@add_global_event_processor
def process_gnu_backtrace(event: "Event", hint: "dict[str, Any]") -> "Event":
with capture_internal_exceptions():
return _process_gnu_backtrace(event, hint)
def _process_gnu_backtrace(event: "Event", hint: "dict[str, Any]") -> "Event":
if sentry_sdk.get_client().get_integration(GnuBacktraceIntegration) is None:
return event
exc_info = hint.get("exc_info", None)
if exc_info is None:
return event
exception = event.get("exception", None)
if exception is None:
return event
values = exception.get("values", None)
if values is None:
return event
for exception in values:
frames = exception.get("stacktrace", {}).get("frames", [])
if not frames:
continue
msg = exception.get("value", None)
if not msg:
continue
additional_frames = []
new_msg = []
for line in msg.splitlines():
match = FRAME_RE.match(line)
if match:
additional_frames.append(
(
int(match.group("index")),
{
"package": match.group("package") or None,
"function": match.group("function") or None,
"platform": "native",
},
)
)
else:
# Put garbage lines back into message, not sure what to do with them.
new_msg.append(line)
if additional_frames:
additional_frames.sort(key=lambda x: -x[0])
for _, frame in additional_frames:
frames.append(frame)
new_msg.append("<stacktrace parsed and removed by GnuBacktraceIntegration>")
exception["value"] = "\n".join(new_msg)
return event