Skip to content

Commit

Permalink
perf: Correctly parse frames with " (" in them (#753)
Browse files Browse the repository at this point in the history
Closes: #673

Co-authored-by: Marcin Olszewski <[email protected]>
  • Loading branch information
Jongy and marcin-ol authored Jun 25, 2023
1 parent 9e3c08d commit e3d865a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
13 changes: 11 additions & 2 deletions gprofiler/profilers/perf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,16 @@
# ffffffff81082227 mmput+0x57 ([kernel.kallsyms])
# 0 [unknown] ([unknown])
# 7fe48f00faff __poll+0x4f (/lib/x86_64-linux-gnu/libc-2.31.so)
FRAME_REGEX = re.compile(r"^\s*[0-9a-f]+ (.*?) \(\[?(.*?)\]?\)$")
FRAME_REGEX = re.compile(
r"""
^\s*[0-9a-f]+[ ] # first a hexadecimal offset
(?P<symbol>.*)[ ] # a symbol name followed by a space
\( (?: # dso name is either:
\[ (?P<dso_brackets> [^]]+) \] # - text enclosed in square brackets, e.g.: [vdso]
| (?P<dso_plain> [^)]+(?:[ ]\(deleted\))? ) # - OR library name, optionally followed by " (deleted)" tag
) \)$""",
re.VERBOSE,
)
SAMPLE_REGEX = re.compile(
r"\s*(?P<comm>.+?)\s+(?P<pid>[\d-]+)/(?P<tid>[\d-]+)(?:\s+\[(?P<cpu>\d+)])?\s+(?P<time>\d+\.\d+):\s+"
r"(?:(?P<freq>\d+)\s+)?(?P<event_family>[\w\-_/]+):(?:(?P<event>[\w-]+):)?(?P<suffix>[^\n]*)(?:\n(?P<stack>.*))?",
Expand Down Expand Up @@ -120,7 +129,7 @@ def _collapse_stack(comm: str, stack: str, insert_dso_name: bool = False) -> str
for line in reversed(stack.splitlines()):
m = FRAME_REGEX.match(line)
assert m is not None, f"bad line: {line}"
sym, dso = m.groups()
sym, dso = m.group("symbol"), m.group("dso_brackets") or m.group("dso_plain")
sym = sym.split("+")[0] # strip the offset part.
if sym == "[unknown]" and dso != "unknown":
sym = f"({dso})"
Expand Down
8 changes: 8 additions & 0 deletions tests/test_perf.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,14 @@ def test_get_average_frame_count(samples: str, count: float) -> None:
),
id="mixed_java_stack",
),
pytest.param(
" 1234 std::__1::__function::__func<Envoy::Event::DispatcherImpl::createFileEvent(int, std::__1::function<void (unsigned int)>, Envoy::Event::FileTriggerType, unsigned int)::$_5, std::__1::allocator<Envoy::Event::DispatcherImpl::createFileEvent(int, std::__1::function<void (unsigned int)>, Envoy::Event::FileTriggerType, unsigned int)::$_5>, void (unsigned int)>::operator() (/path/to/envoy)\n", # noqa
dict(
dso_true="std::__1::__function::__func<Envoy::Event::DispatcherImpl::createFileEvent(int, std::__1::function<void (unsigned int)>, Envoy::Event::FileTriggerType, unsigned int)::$_5, std::__1::allocator<Envoy::Event::DispatcherImpl::createFileEvent(int, std::__1::function<void (unsigned int)>, Envoy::Event::FileTriggerType, unsigned int)::$_5>, void (unsigned int)>::operator() (/path/to/envoy)", # noqa
dso_false="std::__1::__function::__func<Envoy::Event::DispatcherImpl::createFileEvent(int, std::__1::function<void (unsigned int)>, Envoy::Event::FileTriggerType, unsigned int)::$_5, std::__1::allocator<Envoy::Event::DispatcherImpl::createFileEvent(int, std::__1::function<void (unsigned int)>, Envoy::Event::FileTriggerType, unsigned int)::$_5>, void (unsigned int)>::operator()", # noqa
),
id="frame_with_space_parenthesis",
),
],
)
def test_collapse_stack_consider_dso(stack: str, insert_dso_name: bool, outcome_dict: Dict[str, str]) -> None:
Expand Down

0 comments on commit e3d865a

Please sign in to comment.