Files
clang-p2996/lldb/test/API/functionalities/step-avoids-regexp/TestStepAvoidsRegexp.py
Michael Buch 3cc9884500 [lldb][CPlusPlus] Add abi_tag support to the CPlusPlusNameParser
This patch teaches the `CPlusPlusNameParser` to parse the
demangled/prettified [[gnu::abi_tag(...)]] attribute. The demangled format
isn't standardized and the additions to the parser were mainly driven
using Clang (and the limited information on this from the official
Clang docs).

This change is motivated by multiple failures around step-in
behaviour for libcxx APIs (many of which have ABI tags as of recently).
LLDB determines whether the `step-avoid-regexp` matches the current
frame by parsing the scope-qualified name out of the demangled
function symbol. On failure, the `CPlusPlusNameParser` will simply
return the fully demangled name (which can include the return type)
to the caller, which in `FrameMatchesAvoidCriteria` means we will
not correctly decide whether we should stop at a frame or not if
the function has an abi_tag.

Ideally we wouldn't want to rely on the non-standard format
of demangled attributes. Alternatives would be:

1. Use the mangle tree API to do the parsing for us
2. Reconstruct the scope-qualified name from DWARF instead of parsing
   the demangled name

(1) isn't feasible without a significant refactor of `lldb_private::Mangled`,
if we want to do this efficiently.

(2) could be feasible in cases where debug-info for a frame is
available. But it does mean we certain operations (such as step-in regexp,
and frame function names) won't work with/won't show ABI tags.

**Testing**

* Un-XFAILed step-in API test
* Added parser unit-tests

Differential Revision: https://reviews.llvm.org/D136306
2022-10-21 14:00:50 +01:00

49 lines
1.7 KiB
Python

"""
Test thread step-in ignores frames according to the "Avoid regexp" option.
"""
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class StepAvoidsRegexTestCase(TestBase):
def hit_correct_function(self, pattern):
name = self.thread.frames[0].GetFunctionName()
self.assertTrue(
pattern in name, "Got to '%s' not the expected function '%s'." %
(name, pattern))
def setUp(self):
TestBase.setUp(self)
self.dbg.HandleCommand(
"settings set target.process.thread.step-avoid-regexp ^ignore::")
@skipIfWindows
@skipIf(compiler="clang", compiler_version=['<', '11.0'])
def test_step_avoid_regex(self):
"""Tests stepping into a function which matches the avoid regex"""
self.build()
(_, _, self.thread, _) = lldbutil.run_to_source_breakpoint(self, "main", lldb.SBFileSpec('main.cpp'))
# Try to step into ignore::auto_ret
self.thread.StepInto()
self.hit_correct_function("main")
# Try to step into ignore::with_tag
self.thread.StepInto()
self.hit_correct_function("main")
# Try to step into ignore::decltype_auto_ret
self.thread.StepInto()
self.hit_correct_function("main")
# Try to step into ignore::with_tag_template
self.thread.StepInto()
self.hit_correct_function("main")
# Step into with_tag_template_returns_ignore which is outside the 'ignore::'
# namespace but returns a type from 'ignore::'
self.thread.StepInto()
self.hit_correct_function("with_tag_template_returns_ignore")