299 Commits

Author SHA1 Message Date
Jonas Devlieghere
f866ef202c
[lldb] Bring more diagnostics in compliance with our coding standards (#190410)
The LLVM Coding Standards [1] specify that:

> [T]o match error message styles commonly produced by other tools,
> start the first sentence with a lowercase letter, and finish the last
> sentence without a period, if it would end in one otherwise.

Historically, that hasn't been something we've enforced in LLDB, but in
the past year or so I've started to pay more attention to this in code
reviews. This PR brings more error messages in compliance, further
increasing consistency.

I also adopted `createStringErrorV` where it improved the code as a
drive-by for lines I was already touching.

[1] https://llvm.org/docs/CodingStandards.html#error-and-warning-messages

Assisted-by: Claude Code
2026-04-05 10:41:47 -07:00
Jason Molenda
fb36a54ef6
[lldb] Rename formatv verbose log call, misc log cleanups [NFC] (#186951)
lldb had three preprocessor defines for logging,

LLDB_LOG  - formatv style argument
LLDB_LOGF - printf style argument
LLDB_LOGV - formatv style argument, only when verbose enabled

If you weren't looking at Log.h and the definition of these three, and
wanted to log something with formatv, it was easy to use LLDB_LOGV by
accident. We just had a situation where an important log statement
wasn't logging and it turned out to be this. This is fragile if you
aren't looking at the header directly, so I'd like to make this more
explicit. My proposal:

LLDB_LOG  - formatv style argument
LLDB_LOG_VERBOSE - formatv style argument, only when verbose enabled 
LLDB_LOGF - printf style argument
LLDB_LOGF_VERBOSE - printf style argument, only when verbose enabled

The new fouth one is to remove several places where we do `if (log &&
log->GetVerbose()) LLDB_LOGF (...)` in the sources today, and make both
styles consistent.

This PR implements that change, mechanically changing all LLDB_LOGV's to
LLDB_LOG_VERBOSE.

It also updates many of the `if (log && log->GetVerbose()) LLDB_LOGF`'s.
Some uses of this conditional expression do extra calculations in
addition to logging, and so those were left as-is so we're not doing
throwaway work when running without verbose logging.

There were many instances throughout lldb where callers are still doing
`if (log) LLDB_LOG*(...)`, a remnant of when all calls were to the `Log`
object's `Printf()` method, and you had to check if your local Log*
pointer was non-nullptr before calling the method. I removed those,
again keeping ones where work for logging is done in the block of code.

The code changes are all mechanical and uninteresting, but the question
of whether this naming change is widely agreed on is maybe worth
discussing.
2026-03-18 16:31:33 -07:00
Jonas Devlieghere
c5e5d5b282
[lldb] When LLDB_ENABLE_MTE is ON always run the driver with MTE (#186322)
When LLDB_ENABLE_MTE is set to ON, we should always run the driver with
MTE by signing with the checked-allocations entitlement.
2026-03-16 18:11:58 +00:00
Jonas Devlieghere
c182ca3e3a
[lldb] Assert & fix missing calls to UnregisterPlugin (#185162)
Fix missing calls to UnregisterPlugin and add an assert in the
PluginManager that ensures all plugins have been unregistered by the
time the plugin manager is destroyed.
2026-03-09 13:04:08 -07:00
Jonas Devlieghere
c4ea6cc3f7
[lldb] Remove call_once wrappers around PluginManager::RegisterPlugin (#184273)
Remove call_once wrappers around PluginManager::RegisterPlugin. Plugins
can be registered and unregistered in Initialize and Terminate
respectively. In its current state, after having called Terminate, a
plugin can never be re-initialized.
2026-03-03 13:17:21 -08:00
Jonas Devlieghere
329c52c100
[lldb] Change the way the shlib directory helper is set (#183637)
This PR changes the way we set the shlib directory helper. Instead of
setting it while initializing the Host plugin, we register it when
initializing the Python plugin. The motivation is that the current
approach is incompatible with the dynamically linked script
interpreters, as they will not have been loaded at the time the Host
plugin is initialized.

The downside of the new approach is that we set the helper after having
initialized the Host plugin, which theoretically introduces a small
window where someone could query the helper before it has been set.
Fortunately the window is pretty small and limited to when we're
initializing plugins, but it's less "pure" than what we had previously.
That said, I think it balances out with removing the plugin include.
2026-02-27 15:27:02 -08:00
Jonas Devlieghere
863813cace
[lldb] Merge interfaces into lldbPluginScriptInterpreterPython (NFC) (#182962)
Make the interfaces part of lldbPluginScriptInterpreterPython instead of
putting them into their own static library. This avoids the need for an
extra static archive and more importantly a bunch of code duplication
between the two CMakeLists.txt.
2026-02-23 21:33:38 -08:00
Jonas Devlieghere
11af80c3ec
[lldb] Go through the plugin interface to obtain the scripting path (#182400)
Avoid directly including `ScriptInterpreterPython.h` in `SBHostOS`, and
instead go through the plugin interface to obtain the scripting path.
This also deprecates the ``SBHostOS::GetLLDBPythonPath`` method in favor
of the more generic GetScriptPath variant.
2026-02-19 16:41:00 -08:00
Jonas Devlieghere
fece61b281
[lldb] Remove check for LLDB_ENABLE_PYTHON in SWIGPythonBridge.h (#182326)
The header guard is redundant because
`source/Plugins/ScriptInterpreter/CMakeLists.txt` already gates the
entire `Python/` subdirectory behind `LLDB_ENABLE_PYTHON`.
2026-02-19 11:05:45 -08:00
Med Ismail Bennani
15cf81b13f [lldb] Fix wrong log formatting for script callbacks (NFC)
Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2026-02-17 20:43:51 -08:00
Jonas Devlieghere
091296f3e3
[lldb] Revert scripted symbol locator (#181945)
This revert #181334 and its follow-up PRs (including #181488, #181492,
#181493, #181494 and #181498) as well as Ismail's documentation changes
(#181594, #181717). The original commit causes a test failure in CI
(https://github.com/llvm/llvm-project/issues/181938) but the more I look
at the patch, the more I'm convinced it was not ready to land. It will
be easier to iterate on the feedback by re-landing this than by using
post-commit review.
2026-02-17 16:52:21 -08:00
rchamala
1ee03d1e09
[lldb] Add ScriptedSymbolLocator plugin for source file resolution (#181334)
## Summary                                                        
                                                                    
Based on discussion from
[RFC](https://discourse.llvm.org/t/rfc-python-callback-for-source-file-resolution/83545),
this PR adds a new `SymbolLocatorScripted` plugin that allows Python
scripts to implement custom symbol and source file resolution logic.
This enables downstream users to build custom symbol servers, source
file remapping, and build artifact resolution entirely in Python.
                                                                    
  ### Changes

- Adds `LocateSourceFile()` to the SymbolLocator plugin interface,
called during source path resolution with a fully loaded `ModuleSP`, so
the plugin has access to the module's UUID, file paths, and symbols.
- Adds `SymbolLocatorScripted` plugin that delegates all four
SymbolLocator methods (`LocateExecutableObjectFile`,
`LocateExecutableSymbolFile`, `DownloadObjectAndSymbolFile`,
`LocateSourceFile`) to a user-provided Python class.
- Adds `ScriptedSymbolLocatorPythonInterface` to bridge C++ calls to
Python, with proper GIL management and error handling.
- Results for `LocateSourceFile` are cached per (module UUID, source
file) pair.
- The Python class is configured via: `settings set
plugin.symbol-locator.scripted.script-class module.ClassName`

  ### Python class interface

  ```python
  class MyLocator:
      def __init__(self, exe_ctx, args): ...
      def locate_source_file(self, module, original_source_file):
  ...
      def locate_executable_object_file(self, module_spec): ...
      def locate_executable_symbol_file(self, module_spec,
  default_search_paths): ...
      def download_object_and_symbol_file(self, module_spec,
  force_lookup, copy_executable): ...
```

  ### Test plan
```
  Added TestScriptedSymbolLocator.py with 3 test cases:
  - test_locate_source_file — verifies the locator resolves source
  files, receives a valid SBModule with UUID, and remaps paths correctly
  - test_locate_source_file_none_fallthrough — verifies returning
None falls through to default LLDB resolution, and that having no script
  class set works normally
  - test_invalid_script_class — verifies graceful handling of
  invalid class names without crashing
```

Co-authored-by: Rahul Reddy Chamala <rachamal@fb.com>
2026-02-14 07:39:00 -08:00
Jonas Devlieghere
18b5e2a726
[lldb] Push down the SWIG module to avoid an import cycle (#166265)
This is a reland of #129135 (by dingxiangfei2009) with Vladislav
(dzhidzhoev) fix on top.

Fixes #92603
2025-11-17 10:56:28 -08:00
Med Ismail Bennani
4cd17eeaeb
[lldb/Interpreter] Implement ScriptedFrameProvider{,Python}Interface (#166662)
This patch implements the base and python interface for the
ScriptedFrameProvider class.

This is necessary to call python APIs from the ScriptedFrameProvider
that will come in a follow-up.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-11-06 11:54:17 -08:00
Ebuka Ezike
d87c80bd46
[lldb] Do not narrow GetIndexOfChildWithName return type to int (#165453)
Modify the python wrapper to return uint32_t,
which prevents incorrect child name-to-index mapping and avoids
performing redundant operations on non-existent SBValues.
2025-10-29 18:22:54 +00:00
Med Ismail Bennani
84b56202fb
[lldb] Introduce ScriptedFrame affordance (#149622)
This patch introduces a new scripting affordance in lldb:
`ScriptedFrame`.

This allows user to produce mock stackframes in scripted threads and
scripted processes from a python script.

With this change, StackFrame can be synthetized from different sources:
- Either from a dictionary containing a load address, and a frame index,
  which is the legacy way.
- Or by creating a ScriptedFrame python object.

One particularity of synthezising stackframes from the ScriptedFrame
python object, is that these frame have an optional PC, meaning that
they don't have a report a valid PC and they can act as shells that just
contain static information, like the frame function name, the list of
variables or registers, etc. It can also provide a symbol context.

rdar://157260006

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-09-04 15:07:11 -07:00
Jonas Devlieghere
b62b65a95f
[lldb] Use (only) PyImport_AppendInittab to patch readline (#153329)
The current implementation tries to (1) patch the existing readline
module definition if it's already present in the inittab and (2) append
our patched readline module to the inittab. The former (1) uses the
non-stable Python API and I can't find a situation where this is
necessary. 

We do this work before initialization, so for the readline
module to exist, it either needs to be added by Python itself (which
doesn't seem to be the case), or someone would have had to have added it
without initializing.
2025-08-14 13:47:48 -05:00
Jonas Devlieghere
ac0ad5093a
[lldb] Use PyThread_get_thread_ident instead of accessing PyThreadState (#153460)
Use `PyThread_get_thread_ident`, which is part of the Stable API,
instead of accessing a member of the PyThreadState, which is opaque when
using the Stable API.
2025-08-14 12:41:49 -05:00
Jonas Devlieghere
bcdc80828b
[lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is enabled (#152588)
PyConfig and friends are not part of the stable API. We could switch
back to Py_SetPythonHome, which has been deprecated, but still part of
the stable API. For now, limit the use of PyConfig to when
LLDB_EMBED_PYTHON_HOME is enabled, which essentially means Windows.
Changing the order doesn't seem to matter.
2025-08-08 11:49:43 -05:00
Jonas Devlieghere
ad623a813e
[lldb] Eliminate PyGILState_Check (NFC) (#152006)
Eliminate calls to PyGILState_Check, which is not part of the Python
Limited C API. In the Locker, we can use PyGILState_Ensure directly. We
could do something similar to replace the assert, but I don't think it's
worth it. We don't assert that we hold the GIL anywhere else.
2025-08-04 10:44:32 -07:00
Jonas Devlieghere
8f77fa7026
[lldb] Simplify Python Locker log messages (NFC)
Eliminate the `log` variable by inlining the GetLog call and use
"locked" and "unlocked" directly, as requested by Ismail in #151780.
2025-08-04 09:37:37 -07:00
Jonas Devlieghere
0ee1811624
[lldb] Eliminate InitializePythonRAII::InitializeThreadsPrivate (NFC) (#151780)
The behavior of thread initialization changed in Python 3.7. The minimum
supported Python version is now 3.8. That means that
`PyEval_ThreadsInitialized` always returns true and `PyEval_InitThreads`
is never called.

The helper function existed to coordinate initializing the threads and
acquiring the GIL, which is no longer necessary. With that, there's no
point in having the helper at all. This PR eliminates the function and
inlines to GIL acquisition into the caller.
2025-08-04 09:08:20 -07:00
Jonas Devlieghere
4d1ae58d9e
[lldb] Reimplment PyRun_SimpleString using the Python stable C API (#151777)
Reimplment `PyRun_SimpleString` using the Python stable C API and the
`RunString` helper.

Part of https://github.com/llvm/llvm-project/issues/151617
2025-08-01 16:18:24 -07:00
jimingham
4c8e79f815
Switch the ScriptedBreakpointResolver over to the ScriptedInterface form (#150720)
This is NFC, I'm modernizing the interface before I add to it in a
subsequent commit.
2025-07-28 15:11:22 -07:00
Jonas Devlieghere
cf6a4bbc42
[lldb] Use std::make_shared where possible (NFC) (#150714)
This is a continuation of 68fd102, which did the same thing but only for
StopInfo. Using make_shared is both safer and more efficient:

- With make_shared, the object and the control block are allocated
  together, which is more efficient.
- With make_shared, the enable_shared_from_this base class is properly
  linked to the control block before the constructor finishes, so
  shared_from_this() will be safe to use (though still not recommended
  during construction).
2025-07-25 15:55:21 -07:00
Kazu Hirata
61714c16be
[lldb] Remove unused local variables (NFC) (#138457) 2025-05-04 11:56:22 -07:00
Charles Zablit
b3d130279f
[lldb] Upgrade GetIndexOfChildWithName to use llvm::Expected (#136693)
This patch replaces the use of `UINT32_MAX` as the error return value of
`GetIndexOfChildWithName` with `llvm::Expected`.


# Tasks to do in another PR

1. Replace `CalculateNumChildrenIgnoringErrors` with
`CalculateNumChildren`. See [this
comment](https://github.com/llvm/llvm-project/pull/136693#discussion_r2056319358).
2. Update `lldb_private::formatters::ExtractIndexFromString` to use
`llvm::Expected`. See [this
comment](https://github.com/llvm/llvm-project/pull/136693#discussion_r2054217536).
3. Create a new class which carries both user and internal errors. See
[this
comment](https://github.com/llvm/llvm-project/pull/136693#discussion_r2056439608).
2025-04-30 11:44:19 +01:00
Vladislav Dzhidzhoev
058992ea9f
[lldb] Fix Python GIL-not-held issue in CreateStructuredDataFromScriptObject (#136309)
TestStructuredDataAPI.py fails with Python debug build ver. 3.12+ due to
call to Py_XINCREF while GIL is not held.
2025-04-18 22:16:35 +02:00
jimingham
347c5a7af5
Add a new affordance that the Python module in a dSYM (#133290)
So the dSYM can be told what target it has been loaded into.

When lldb is loading modules, while creating a target, it will run
"command script import" on any Python modules in Resources/Python in the
dSYM. However, this happens WHILE the target is being created, so it is
not yet in the target list. That means that these scripts can't act on
the target that they a part of when they get loaded.

This patch adds a new python API that lldb will call:

__lldb_module_added_to_target

if it is defined in the module, passing in the Target the module was
being added to, so that code in these dSYM's don't have to guess.
2025-04-01 09:54:06 -07:00
jimingham
870463519b
Fix the managing of the session dictionary when you have nested wrappers (#132846)
Since the inner wrapper call might have removed one of the entries from
the global dict that the outer wrapper ALSO was going to delete, make
sure that we check that the key is still in the global dict before
trying to act on it.
2025-03-25 09:56:58 -07:00
Jonas Devlieghere
57bac14f4b
[lldb] Fix header include order in ScriptInterpreterPython.cpp
Should fix the following compile error on Windows:

  C:\Python312\include\pyconfig.h(225): error C2371: 'pid_t': redefinition; different basic types
  C:\buildbot\as-builder-10\lldb-x-aarch64\llvm-project\lldb\include\lldb/Host/windows/PosixApi.h(80): note: see declaration of 'pid_t'
2025-02-19 21:09:32 -08:00
Jonas Devlieghere
58279d1ee1
[lldb] Synchronize the debuggers output & error streams
This patch improves the synchronization of the debugger's output and error
streams using two new abstractions: `LockableStreamFile` and
`LockedStreamFile`.

 - `LockableStreamFile` is a wrapper around a `StreamFile` and a mutex. Client
   cannot use the `StreamFile` without calling `Lock`, which returns a
   `LockedStreamFile`.

 - `LockedStreamFile` is an RAII object that locks the stream for the duration
   of its existence.  As long as you hold on to the returned object you are
   permitted to write to the stream. The destruction of the object
   automatically flush the output stream.
2025-02-19 20:32:00 -08:00
Jonas Devlieghere
eff3c343b0
[lldb] Remove Debugger::Get{Output,Error}Stream (NFC) (#126821)
Remove Debugger::GetOutputStream and Debugger::GetErrorStream in
preparation for replacing both with a new variant that needs to be
locked and hence can't be handed out like we do right now.

The patch replaces most uses with GetAsyncOutputStream and
GetAsyncErrorStream respectively. There methods return new StreamSP
objects that automatically get flushed on destruction.

See #126630 for more details.
2025-02-12 08:29:06 -08:00
David Spickett
db567eaca0 [lldb][NFC] Format part of ScriptInterpreterPython.cpp
Was flagged in https://github.com/llvm/llvm-project/pull/124735
but done separately so it didn't get in the way of that.
2025-01-29 09:59:34 +00:00
David Spickett
9ea64dd878
[lldb] Make Python >= 3.8 required for LLDB 21 (#124735)
As decided on
https://discourse.llvm.org/t/rfc-lets-document-and-enforce-a-minimum-python-version-for-lldb/82731.

LLDB 20 recommended `>= 3.8` but did not remove support for anything
earlier. Now we are in what will become LLDB 21, so I'm removing that
support and making
`>= 3.8` required.

See https://docs.python.org/3/c-api/apiabiversion.html#c.PY_VERSION_HEX
for the format of PY_VERSION_HEX.
2025-01-29 09:56:41 +00:00
Jonas Devlieghere
9ce0a61bdb
[lldb] Use PY_VERSION_HEX to simplify conditional compilation (NFC) (#114346)
Use PY_VERSION_HEX to simplify conditional compilation depending on the
Python version.

This also adds a static_assert to lldb-python to error out with a
meaningful diagnostic when you try building LLDB with an older Python
version in preparation for [1].

[1]
https://discourse.llvm.org/t/rfc-lets-document-and-enforce-a-minimum-python-version-for-lldb/82731/15
2024-10-31 08:46:35 -07:00
Jonas Devlieghere
75aaa312ff
[lldb] Fix formatting and whitespace in ScriptInterpreterPython (NFC) 2024-10-30 20:33:28 -07:00
Jonas Devlieghere
de7ad6b682
[lldb] Use Py_InitializeFromConfig with Python >= 3.8 (NFC) (#114112)
This fixes the deprecation warning for Py_SetPythonHome, which was
deprecated in Python 3.11. With this patch, when building against Python
3.8 or later, we now use Py_InitializeFromConfig instead.

Fixes #113475
2024-10-30 18:48:43 -07:00
Jonas Devlieghere
2bc5302706
Revert "[lldb] Use Py_InitializeFromConfig with Python >= 3.8 (NFC)" (#114290)
Reverts llvm/llvm-project#114112 because this triggers a compile error:

```
no known conversion from 'str_type' (aka 'wchar_t *') to 'const char *' for 3rd argument
  221 | PyAPI_FUNC(PyStatus) PyConfig_SetBytesString(
      |                      ^
  222 |     PyConfig *config,
  223 |     wchar_t **config_str,
  224 |     const char *str);
      |     ~~~~~~~~~~~~~~~
1 error generated.

```
2024-10-30 11:36:10 -07:00
Jonas Devlieghere
45f420e344
[lldb] Use Py_InitializeFromConfig with Python >= 3.8 (NFC) (#114112)
This fixes the deprecation warning for Py_SetPythonHome, which was
deprecated in Python 3.11. With this patch, when building against Python
3.8 or later, we now use Py_InitializeFromConfig instead.

Fixes #113475
2024-10-30 08:41:30 -07:00
Jonas Devlieghere
b852fb1ec5
[lldb] Move ValueObject into its own library (NFC) (#113393)
ValueObject is part of lldbCore for historical reasons, but conceptually
it deserves to be its own library. This does introduce a (link-time) circular
dependency between lldbCore and lldbValueObject, which is unfortunate
but probably unavoidable because so many things in LLDB rely on
ValueObject. We already have cycles and these libraries are never built
as dylibs so while this doesn't improve the situation, it also doesn't
make things worse.

The header includes were updated with the following command:

```
find . -type f -exec sed -i.bak "s%include \"lldb/Core/ValueObject%include \"lldb/ValueObject/ValueObject%" '{}' \;
```
2024-10-24 20:20:48 -07:00
jimingham
04b443e778
Add the ability to define custom completers to the parsed_cmd template. (#109062)
If your arguments or option values are of a type that naturally uses one
of our common completion mechanisms, you will get completion for free.
But if you have your own custom values or if you want to do fancy things
like have `break set -s foo.dylib -n ba<TAB>` only complete on symbols
in foo.dylib, you can use this new mechanism to achieve that.
2024-09-24 10:00:00 -07:00
Med Ismail Bennani
f732157a9d
[lldb/Interpreter] Introduce ScriptedStopHook{,Python}Interface & make use of it (#109498)
This patch re-lands #105449 and fixes the various test failures.

---------

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-09-20 16:55:47 -07:00
David Spickett
801046e330 Revert "[lldb] Fix SWIG wrapper compilation error"
...and "[lldb/Interpreter] Introduce `ScriptedStopHook{,Python}Interface` & make use of it (#105449)"

This reverts commit 76b827bb4d5b4cc4d3229c4c6de2529e8b156810, and commit 1e131ddfa8f1d7b18c85c6e4079458be8b419421
because the first commit caused the test command-stop-hook-output.test to fail.
2024-09-20 09:57:07 +00:00
Med Ismail Bennani
1e131ddfa8
[lldb/Interpreter] Introduce ScriptedStopHook{,Python}Interface & make use of it (#105449)
This patch introduces new `ScriptedStopHook{,Python}Interface` classes
that make use of the Scripted Interface infrastructure and makes use of
it in `StopHookScripted`.

It also relax the requirement on the number of argument for initializing
scripting extension if the size of the interface parameter pack contains
1 less element than the extension maximum number of positional arguments
for this initializer.
This addresses the cases where the embedded interpreter session
dictionary is passed to the extension initializer which is not used most
of the time.

---------

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-09-19 23:35:34 -07:00
Adrian Prantl
a0dd90eb7d
[lldb] Make conversions from llvm::Error explicit with Status::FromEr… (#107163)
…ror() [NFC]
2024-09-05 12:19:31 -07:00
Adrian Prantl
0642cd768b
[lldb] Turn lldb_private::Status into a value type. (#106163)
This patch removes all of the Set.* methods from Status.

This cleanup is part of a series of patches that make it harder use the
anti-pattern of keeping a long-lives Status object around and updating
it while dropping any errors it contains on the floor.

This patch is largely NFC, the more interesting next steps this enables
is to:
1. remove Status.Clear()
2. assert that Status::operator=() never overwrites an error
3. remove Status::operator=()

Note that step (2) will bring 90% of the benefits for users, and step
(3) will dramatically clean up the error handling code in various
places. In the end my goal is to convert all APIs that are of the form

`    ResultTy DoFoo(Status& error)
`
to

`    llvm::Expected<ResultTy> DoFoo()
`
How to read this patch?

The interesting changes are in Status.h and Status.cpp, all other
changes are mostly

` perl -pi -e 's/\.SetErrorString/ = Status::FromErrorString/g' $(git
grep -l SetErrorString lldb/source)
`
plus the occasional manual cleanup.
2024-08-27 10:59:31 -07:00
Adrian Prantl
3c0fba4f24 Revert "Revert "[lldb] Extend frame recognizers to hide frames from backtraces (#104523)""
This reverts commit 547917aebd1e79a8929b53f0ddf3b5185ee4df74.
2024-08-23 11:06:01 -07:00
Dmitri Gribenko
547917aebd Revert "[lldb] Extend frame recognizers to hide frames from backtraces (#104523)"
This reverts commit f01f80ce6ca7640bb0e267b84b1ed0e89b57e2d9.

This commit introduces an msan violation. See the discussion on https://github.com/llvm/llvm-project/pull/104523.
2024-08-22 13:24:57 +02:00
Adrian Prantl
f01f80ce6c
[lldb] Extend frame recognizers to hide frames from backtraces (#104523)
Compilers and language runtimes often use helper functions that are
fundamentally uninteresting when debugging anything but the
compiler/runtime itself. This patch introduces a user-extensible
mechanism that allows for these frames to be hidden from backtraces and
automatically skipped over when navigating the stack with `up` and
`down`.

This does not affect the numbering of frames, so `f <N>` will still
provide access to the hidden frames. The `bt` output will also print a
hint that frames have been hidden.

My primary motivation for this feature is to hide thunks in the Swift
programming language, but I'm including an example recognizer for
`std::function::operator()` that I wished for myself many times while
debugging LLDB.

rdar://126629381


Example output. (Yes, my proof-of-concept recognizer could hide even
more frames if we had a method that returned the function name without
the return type or I used something that isn't based off regex, but it's
really only meant as an example).

before:
```
(lldb) thread backtrace --filtered=false
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000100001f04 a.out`foo(x=1, y=1) at main.cpp:4:10
    frame #1: 0x0000000100003a00 a.out`decltype(std::declval<int (*&)(int, int)>()(std::declval<int>(), std::declval<int>())) std::__1::__invoke[abi:se200000]<int (*&)(int, int), int, int>(__f=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:149:25
    frame #2: 0x000000010000399c a.out`int std::__1::__invoke_void_return_wrapper<int, false>::__call[abi:se200000]<int (*&)(int, int), int, int>(__args=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:216:12
    frame #3: 0x0000000100003968 a.out`std::__1::__function::__alloc_func<int (*)(int, int), std::__1::allocator<int (*)(int, int)>, int (int, int)>::operator()[abi:se200000](this=0x000000016fdff280, __arg=0x000000016fdff224, __arg=0x000000016fdff220) at function.h:171:12
    frame #4: 0x00000001000026bc a.out`std::__1::__function::__func<int (*)(int, int), std::__1::allocator<int (*)(int, int)>, int (int, int)>::operator()(this=0x000000016fdff278, __arg=0x000000016fdff224, __arg=0x000000016fdff220) at function.h:313:10
    frame #5: 0x0000000100003c38 a.out`std::__1::__function::__value_func<int (int, int)>::operator()[abi:se200000](this=0x000000016fdff278, __args=0x000000016fdff224, __args=0x000000016fdff220) const at function.h:430:12
    frame #6: 0x0000000100002038 a.out`std::__1::function<int (int, int)>::operator()(this= Function = foo(int, int) , __arg=1, __arg=1) const at function.h:989:10
    frame #7: 0x0000000100001f64 a.out`main(argc=1, argv=0x000000016fdff4f8) at main.cpp:9:10
    frame #8: 0x0000000183cdf154 dyld`start + 2476
(lldb) 
```

after

```
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000100001f04 a.out`foo(x=1, y=1) at main.cpp:4:10
    frame #1: 0x0000000100003a00 a.out`decltype(std::declval<int (*&)(int, int)>()(std::declval<int>(), std::declval<int>())) std::__1::__invoke[abi:se200000]<int (*&)(int, int), int, int>(__f=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:149:25
    frame #2: 0x000000010000399c a.out`int std::__1::__invoke_void_return_wrapper<int, false>::__call[abi:se200000]<int (*&)(int, int), int, int>(__args=0x000000016fdff280, __args=0x000000016fdff224, __args=0x000000016fdff220) at invoke.h:216:12
    frame #6: 0x0000000100002038 a.out`std::__1::function<int (int, int)>::operator()(this= Function = foo(int, int) , __arg=1, __arg=1) const at function.h:989:10
    frame #7: 0x0000000100001f64 a.out`main(argc=1, argv=0x000000016fdff4f8) at main.cpp:9:10
    frame #8: 0x0000000183cdf154 dyld`start + 2476
Note: Some frames were hidden by frame recognizers
```
2024-08-20 16:01:22 -07:00