Commit Graph

645 Commits

Author SHA1 Message Date
Med Ismail Bennani
c50802cbee Reland "[lldb] Introduce ScriptedFrameProvider for real threads (#161870)" (#170236)
This patch re-lands #161870 with fixes to the previous test failures.

rdar://161834688

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-12-02 18:59:40 +00:00
n2h9
a4d42775b9 [lldb] [scripting bridge] 167388 chore: add api to return arch name for target (#168273)
This pr fixes #167388 .

## Description

This pr adds new method `GetArchName` to `SBTarget` so that no need to
parse triple to get arch name in client code.

## Testing

### All from `TestTargetAPI.py`

run test with

```
./build/bin/lldb-dotest -v -p TestTargetAPI.py
```
<details>
<summary>existing tests (without newly added)</summary>
<img width="1425" height="804" alt="image"
src="https://github.com/user-attachments/assets/617e4c69-5c6b-44c4-9aeb-b751a47e253c"
/>
</details>

<details>
<summary>existing tests (with newly added)</summary>
<img width="1422" height="778" alt="image"
src="https://github.com/user-attachments/assets/746990a1-df88-4348-a090-224963d3c640"
/>

</details>

### Only `test_get_arch_name`

run test with 
```
./build/bin/lldb-dotest -v -p TestTargetAPI.py -f test_get_arch_name_dwarf -f test_get_arch_name_dwo -f test_get_arch_name_dsym lldb/test/API/python_api/target

```
<details>
<summary>only newly added</summary>
<img width="1422" height="778" alt="image"
src="https://github.com/user-attachments/assets/fcaafa5d-2622-4171-acee-e104ecee0652"
/>
</details>

---------

Signed-off-by: Nikita B <n2h9z4@gmail.com>
Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-11-26 11:36:19 -08:00
Michael Buch
b7bc4a2103 Revert "[lldb] Introduce ScriptedFrameProvider for real threads" (#167662)
The new test fails on x86 and arm64 public macOS bots:
```
09:27:59  ======================================================================
09:27:59  FAIL: test_append_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can add frames after real stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 122, in test_append_frames
09:27:59      self.assertEqual(new_frame_count, original_frame_count + 1)
09:27:59  AssertionError: 5 != 6
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_applies_to_thread (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that applies_to_thread filters which threads get the provider.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 218, in test_applies_to_thread
09:27:59      self.assertEqual(
09:27:59  AssertionError: 5 != 1 : Thread with ID 1 should have 1 synthetic frame
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_prepend_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can add frames before real stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 84, in test_prepend_frames
09:27:59      self.assertEqual(new_frame_count, original_frame_count + 2)
09:27:59  AssertionError: 5 != 7
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_remove_frame_provider_by_id (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that RemoveScriptedFrameProvider removes a specific provider by ID.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 272, in test_remove_frame_provider_by_id
09:27:59      self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59  AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_replace_all_frames (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that we can replace the entire stack.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 41, in test_replace_all_frames
09:27:59      self.assertEqual(thread.GetNumFrames(), 3, "Should have 3 synthetic frames")
09:27:59  AssertionError: 5 != 3 : Should have 3 synthetic frames
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ======================================================================
09:27:59  FAIL: test_scripted_frame_objects (TestScriptedFrameProvider.ScriptedFrameProviderTestCase)
09:27:59     Test that provider can return ScriptedFrame objects.
09:27:59  ----------------------------------------------------------------------
09:27:59  Traceback (most recent call last):
09:27:59    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/functionalities/scripted_frame_provider/TestScriptedFrameProvider.py", line 159, in test_scripted_frame_objects
09:27:59      self.assertEqual(frame0.GetFunctionName(), "custom_scripted_frame_0")
09:27:59  AssertionError: 'thread_func(int)' != 'custom_scripted_frame_0'
09:27:59  - thread_func(int)
09:27:59  + custom_scripted_frame_0
09:27:59  
09:27:59  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
09:27:59  ----------------------------------------------------------------------
09:27:59  Ran 6 tests in 14.242s
09:27:59  
09:27:59  FAILED (failures=6)
```

Reverts llvm/llvm-project#161870
2025-11-12 10:13:43 +00:00
Med Ismail Bennani
1e467e4485 [lldb] Introduce ScriptedFrameProvider for real threads (#161870)
This patch extends ScriptedFrame to work with real (non-scripted)
threads,
enabling frame providers to synthesize frames for native processes.

Previously, ScriptedFrame only worked within
ScriptedProcess/ScriptedThread
contexts. This patch decouples ScriptedFrame from ScriptedThread,
allowing
users to augment or replace stack frames in real debugging sessions for
use
cases like custom calling conventions, reconstructing corrupted frames
from
core files, or adding diagnostic frames.

Key changes:

- ScriptedFrame::Create() now accepts ThreadSP instead of requiring
ScriptedThread, extracting architecture from the target triple rather
than ScriptedProcess.arch

- Added SBTarget::RegisterScriptedFrameProvider() and
ClearScriptedFrameProvider() APIs, with Target storing a
SyntheticFrameProviderDescriptor template for new threads

- Added "target frame-provider register/clear" commands for CLI access

- Thread class gains LoadScriptedFrameProvider(),
ClearScriptedFrameProvider(),
and GetFrameProvider() methods for per-thread frame provider management

- New SyntheticStackFrameList overrides FetchFramesUpTo() to lazily
provide
frames from either the frame provider or the real stack

This enables practical use of the SyntheticFrameProvider infrastructure
in
real debugging workflows.

rdar://161834688

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

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-11-11 20:18:45 +00: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
Sergei Druzhkov
f4e77e9a74 [lldb] Fix StdUnorderedMapSynthProvider for GCC (#164251)
This patch adds small workaround for
[issue](https://github.com/llvm/llvm-project/issues/152504). It looks
like code compiled with gcc has lack of some important debug information
(e.g. DW_TAG_template_type_parameter for allocator).

Example code:
```cpp
#include <unordered_map>

int main() {
    std::unordered_map<int, int> map = {
        {1, 2}
    };
    return 0;
}
```

Output from `llvm-dwarfdump` for code compiled by GCC or Clang. I used
system GCC (13.3.0) and Clang (18.1.3) on Ubuntu 24.04 (WSL).

GCC:
```
0x00001fcd:     DW_TAG_class_type
                  DW_AT_name	("allocator<std::pair<int const, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)
                  DW_AT_decl_column	(11)
                  DW_AT_sibling	(0x0000207c)

0x00001fda:       DW_TAG_inheritance
                    DW_AT_type	(0x00001d0a "std::__new_allocator<std::pair<int const, int> >")
                    DW_AT_data_member_location	(0)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001fe0:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00001ff4)
                    DW_AT_sibling	(0x00001ffa)

0x00001ff4:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00001ff9:         NULL

0x00001ffa:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4ERKS2_")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x0000200e)
                    DW_AT_sibling	(0x00002019)

0x0000200e:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002013:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x00002018:         NULL

0x00002019:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_decl_column	(18)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_type	(0x00004ec8 "std::allocator<std::pair<int const, int> > &")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_defaulted	(DW_DEFAULTED_in_class)
                    DW_AT_object_pointer	(0x00002031)
                    DW_AT_sibling	(0x0000203c)

0x00002031:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002036:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x0000203b:         NULL

0x0000203c:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEED4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00002050)
                    DW_AT_sibling	(0x0000205b)

0x00002050:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002055:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004cab "int")
                      DW_AT_artificial	(true)

0x0000205a:         NULL
```

Clang:
```
0x00001a6e:     DW_TAG_class_type
                  DW_AT_calling_convention	(DW_CC_pass_by_reference)
                  DW_AT_name	("allocator<std::pair<const int, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)

0x00001a74:       DW_TAG_template_type_parameter
                    DW_AT_type	(0x00000dec "std::pair<const int, int>")
                    DW_AT_name	("_Tp")

0x00001a7a:       DW_TAG_inheritance
                    DW_AT_type	(0x00001ad5 "std::__allocator_base<std::pair<const int, int> >")
                    DW_AT_data_member_location	(0x00)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a81:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a86:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a8b:         NULL

0x00001a8c:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a91:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a96:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001a9b:         NULL

0x00001a9c:       DW_TAG_subprogram
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_type	(0x00002de0 "std::allocator<std::pair<const int, int> > &")
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001aa6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001aab:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001ab0:         NULL

0x00001ab1:       DW_TAG_subprogram
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001ab6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001abb:         NULL
```

I propose to add fallback implementation based on type of `_M_h`.
2025-10-29 09:04:22 +00:00
David Spickett
65c24e5022 [lldb][examples] Use "chr" in CFString.py
Python3 removed "unichr" when string encoding was changed,
so this code tried to import that then defaulted to "chr"
if it couldn't.

Since LLVM requires >=3.8 we can use "chr" directly.
2025-10-16 09:58:54 +00:00
David Spickett
7ab271cbd2 [lldb][examples] Use Python3 versions of types module in performance.py
2.x had ListType and StringTypes (https://docs.python.org/2.7/library/types.html),
3.x removed these (https://docs.python.org/3.0/library/types.html).

We can use "str" and "list" directly as in 3.x all strings are
just "str", and ListType was always an alias to "list".
2025-10-16 09:54:53 +00:00
David Spickett
c6e4a63295 [lldb][examples] Remove Python 2 compatibility code in lldbtk.py
The Tkinter module was renamed to tkinter in Python 3.0.

https://docs.python.org/2/library/tkinter.html
https://docs.python.org/3/library/tkinter.html

Rest of it appears to work when imported inside of LLDB:
```
$ ./bin/lldb /tmp/test.o
(lldb) target create "/tmp/test.o"
Current executable set to '/tmp/test.o' (x86_64).
(lldb) b main
Breakpoint 1: where = test.o`main + 8 at test.c:1:18, address = 0x0000000000001131
(lldb) run
Process 121572 launched: '/tmp/test.o' (x86_64)
Process 121572 stopped
* thread #1, name = 'test.o', stop reason = breakpoint 1.1
    frame #0: 0x0000555555555131 test.o`main at test.c:1:18
-> 1   	int main() { int a = 1; char b = '?'; return 0; }
(lldb) command script import <...>/llvm-project/lldb/examples/python/lldbtk.py
(lldb) tk-
Available completions:
        tk-process   -- For more information run 'help tk-process'
        tk-target    -- For more information run 'help tk-target'
        tk-variables -- For more information run 'help tk-variables'
(lldb) tk-process
(lldb) tk-target
(lldb) tk-variables
```
2025-10-13 13:13:07 +00:00
Christopher Di Bella
e8f61801c6 [libcxx] adds size-based __split_buffer representation to unstable ABI (#139632)
**tl;dr** We can significantly improve the runtime performance of
`std::vector` by changing its representation from three pointers to one
pointer and two integers. This document explains the details of this
change, along with the justifications for making it. See the [RFC] for
more information.

`vector` depends on `__split_buffer` for inserting elements. Changing
`__split_buffer` to match `vector`'s representation simplifies the
model, as it eliminates the need to convert between two different
representations of a contiguous buffer in the same configuration of
libc++.

[RFC]: https://discourse.llvm.org/t/adding-a-size-based-vector-to-libc-s-unstable-abi/86306

---------

Co-authored-by: Jorge Gorbe Moya <jgorbe@google.com>
2025-09-12 06:33:10 -07:00
jimingham
e2d9420272 Make flag-only options work in the ParsedCommand mode of adding commands (#157756)
I neglected to add a test when I was writing tests for this, so of
course it broke. This makes it work again and adds a test.

rdar://159459160
2025-09-10 09:27:29 -07: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
Med Ismail Bennani
595148ab76 [lldb/crashlog] Avoid StopAtEntry when launch crashlog in interactive mode (#154651)
In 88f409194, we changed the way the crashlog scripted process was
launched since the previous approach required to parse the file twice,
by stopping at entry, setting the crashlog object in the middle of the
scripted process launch and resuming it.

Since then, we've introduced SBScriptObject which allows to pass any
arbitrary python object accross the SBAPI boundary to another scripted
affordance.

This patch make sure of that to include the parse crashlog object into
the scripted process launch info dictionary, which eliviates the need to
stop at entry.

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

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-08-21 23:16:45 -07:00
David Spickett
f995bc802d [lldb] Improve setting of program for filtering disassembly (#148823)
This changes the example command added in
https://github.com/llvm/llvm-project/pull/145793 so that the fdis
program does not have to be a single program name.

Doing so also means we can run the test on Windows where the program
needs to be "python.exe script_name".

I've changed "fdis set" to treat the rest of the command as the program.
Then store that as a list to be passed to subprocess. If we just use a
string, Python will think that "python.exe foo" is the name of an actual
program instead of a program and an argument to it.

This will still break if the paths have spaces in, but I'm trying to do
just enough to fix the test here without rewriting all the option
handling.
2025-07-16 15:41:51 +01:00
nerix
f98cf07b7d [LLDB] Convert libstdc++ std::variant summary to C++ (#148929)
This PR converts the `std::variant` summary from Python to C++.

Split from #148554. MSVC's STL and libstdc++ use the same type name for
`std::variant`, thus they need one "dispatcher" function that checks the
type and calls the appropriate summary. For summaries, both need to be
implemented in C++.

This is mostly a 1:1 translation. The main difference is that in C++,
the summary returns `false` if it can't inspect the object properly
(e.g. a member could not be found). In Python, this wasn't possible.
2025-07-16 10:07:45 +01:00
tedwoodward
eb6da944af [lldb] Improve disassembly of unknown instructions (#145793)
LLDB uses the LLVM disassembler to determine the size of instructions and
to do the actual disassembly. Currently, if the LLVM disassembler can't
disassemble an instruction, LLDB will ignore the instruction size, assume
the instruction size is the minimum size for that device, print no useful
opcode, and print nothing for the instruction.

This patch changes this behavior to separate the instruction size and
"can't disassemble". If the LLVM disassembler knows the size, but can't
dissasemble the instruction, LLDB will use that size. It will print out
the opcode, and will print "<unknown>" for the instruction. This is much
more useful to both a user and a script.

The impetus behind this change is to clean up RISC-V disassembly when
the LLVM disassembler doesn't understand all of the instructions.
RISC-V supports proprietary extensions, where the TD files don't know
about certain instructions, and the disassembler can't disassemble them.
Internal users want to be able to disassemble these instructions.

With llvm-objdump, the solution is to pipe the output of the disassembly
through a filter program. This patch modifies LLDB's disassembly to look
more like llvm-objdump's, and includes an example python script that adds
a command "fdis" that will disassemble, then pipe the output through a
specified filter program. This has been tested with crustfilt, a sample
filter located at https://github.com/quic/crustfilt .

Changes in this PR:
- Decouple "can't disassemble" with "instruction size".
  DisassemblerLLVMC::MCDisasmInstance::GetMCInst now returns a bool for
    valid disassembly, and has the size as an out paramter.
  Use the size even if the disassembly is invalid.
  Disassemble if disassemby is valid.

- Always print out the opcode when -b is specified.
  Previously it wouldn't print out the opcode if it couldn't disassemble.

- Print out RISC-V opcodes the way llvm-objdump does.
  Code for the new Opcode Type eType16_32Tuples by Jason Molenda.

- Print <unknown> for instructions that can't be disassembled, matching
  llvm-objdump, instead of printing nothing.

- Update max riscv32 and riscv64 instruction size to 8.

- Add example "fdis" command script.

- Added disassembly byte test for x86 with known and unknown instructions.
- Added disassembly byte test for riscv32 with known and unknown instructions,
  with and without filtering.
- Added test from Jason Molenda to RISC-V disassembly unit tests.
2025-07-14 21:50:22 -05:00
Med Ismail Bennani
1db9afb102 [lldb/crashlog] Make registers always available & fix x29/x30 parsing (#145104)
This patch addresses 2 issues:
1. It makes registers available on non-crashed threads all the time
2. It fixes arm64 registers parsing for registers that don't use the `x`
prefix (`fp` -> `x29` / `lr` -> `x30`)

---------

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-06-20 15:26:14 -07:00
Med Ismail Bennani
58f48011b3 [lldb] Add support for x86_64h to scripted process (#145099)
This patch adds support to the haswell sub-architecture (x86_64h) to
scripted processes.

rdar://147208252

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-06-20 13:28:21 -07:00
Med Ismail Bennani
7b989ade35 [lldb/crashlog] Make interactive mode the new default (#144839)
This patch makes interactive mode as the default when using the crashlog
command. It replaces the existing `-i|--interactive` flag with a new
`-m|--mode` option, that can either be `interactive` or `batch`.

By default, when the option is not explicitely set by the user, the
interactive mode is selected, however, lldb will fallback to batch mode
if the command interpreter is not interactive or if stdout is not a tty.

This also adds some railguards to prevent users from using interactive
only options with the batch mode and updates the tests accordingly.

rdar://97801509

Differential Revision: https://reviews.llvm.org/D141658

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-06-18 22:49:21 -07:00
Eisuke Kawashima
24abf2c728 [lldb] fix(lldb/**.py): fix invalid escape sequences (#94034)
Co-authored-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
2025-02-28 14:59:35 +00:00
Dave Lee
354eb88285 [lldb] Also show session history in fzf_history (#128986)
lldb's history log file is written to at the end of a debugging session.
As a result, the log does not contain commands run during the current
session.

This extends the `fzf_history` to include the output of `session
history`.
2025-02-26 19:14:49 -08:00
Dave Lee
83c6b1a888 [lldb] Add fzf_history command to examples (#128571)
Adds a `fzf_history` to the examples directory.

This python command invokes [fzf](https://github.com/junegunn/fzf) to
select from lldb's command history.

Tighter integration is available on macOS, via commands for copy and
paste. The user's chosen history entry back is pasted into the lldb
console (via AppleScript). By pasting it, users have the opportunity to
edit it before running it. This matches how fzf's history search works.

Without copy and paste, the user's chosen history entry is printed to
screen and then run automatically.
2025-02-25 08:10:09 -08:00
Pavel Labath
0949330669 [lldb] Avoid expression evaluation in the std::deque formatter (#127071)
It's slower and it can fail in contexts where expression evaluation
doesn't work.
2025-02-14 08:51:32 +01:00
Greg Clayton
b7722fbcab [lldb] Fix std::unordered_* synthetic children when typedefs are used. (#123125)
There was a bug in both the GNU and libc++ library synthetic child
providers when a typedef was used in the type of the variable. Previous
code was looking at the top level typename to try and determine if
std::unordered_ was a map or set and this failed when typedefs were
being used. This patch fixes both C++ library synthetic child providers
with updated tests.
2025-01-15 16:30:45 -08:00
Med Ismail Bennani
833a17489d [lldb/crashlog] Fix typo in error message when creating a target (#122514)
This fixes a typo when creating a target from the crashlog script and
that we were not able to find a valid architecture from the crash
report.

rdar://137344016

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-01-10 11:44:50 -08:00
Adrian Prantl
ee1adc5aab [lldb] Add a return opcode to the formatter bytecode (#121602)
In LLVM we love our early exists and this opcode allows for simpler code
generation.
2025-01-03 15:26:40 -08:00
Adrian Prantl
9f98949c94 [lldb] Move the python module import workaround further up 2024-12-06 17:01:58 -08:00
Adrian Prantl
fffe8c6684 [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to examples
This PR adds a proof-of-concept for a bytecode designed to ship and
run LLDB data formatters. More motivation and context can be found in
the formatter-bytecode.rst file and on discourse.

https://discourse.llvm.org/t/a-bytecode-for-lldb-data-formatters/82696

Relanding with a fix for a case-sensitive path.
2024-12-06 16:27:16 -08:00
Adrian Prantl
b504c8771f Revert "[lldb] Add a compiler/interpreter of LLDB data formatter bytecode to examples"
This reverts commit 60380cd27c.
2024-12-06 16:26:55 -08:00
Adrian Prantl
60380cd27c [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to examples
This PR adds a proof-of-concept for a bytecode designed to ship and
run LLDB data formatters. More motivation and context can be found in
the formatter-bytecode.rst file and on discourse.

https://discourse.llvm.org/t/a-bytecode-for-lldb-data-formatters/82696

Relanding with a fix for a case-sensitive path.
2024-12-06 16:10:09 -08:00
Adrian Prantl
8ab76a47b2 Revert "[lldb] Add a compiler/interpreter of LLDB data formatter bytecode to examples"
This reverts commit 7e3da87ca896484a11ac09df297183147154ac91.

I managed to break the bots.
2024-12-06 15:34:12 -08:00
Adrian Prantl
0ee364d2a2 [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (#113398)
This PR adds a proof-of-concept for a bytecode designed to ship and run
LLDB data formatters. More motivation and context can be found in the
`formatter-bytecode.md` file and on discourse.

https://discourse.llvm.org/t/a-bytecode-for-lldb-data-formatters/82696
2024-12-06 15:11:21 -08:00
Jason Molenda
fda4a324a3 [lldb] Only run scripted process test on x86_64/arm64
The newly added
test/API/functionalities/scripted_process_empty_memory_region/dummy_scripted_process.py
imports
examples/python/templates/scripted_process.py
which only has register definitions for x86_64 and arm64.

Only run this test on those two architectures for now.
2024-11-15 00:56:34 -08:00
Peng Liu
c7df10643b Unify naming of internal pointer members in std::vector and std::__split_buffer (#115517)
Related to PR #114423, this PR proposes to unify the naming of the
internal pointer members in `std::vector` and `std::__split_buffer` for
consistency and clarity.

Both `std::vector` and `std::__split_buffer` originally used a
`__compressed_pair<pointer, allocator_type>` member named `__end_cap_`
to store an internal capacity pointer and an allocator. However,
inconsistent naming changes have been made in both classes:
- `std::vector` now uses `__cap_` and `__alloc_` for its internal
pointer and allocator members.
- In contrast, `std::__split_buffer` retains the name `__end_cap_` for
the capacity pointer, along with `__alloc_`.

This inconsistency between the names `__cap_` and `__end_cap_` has
caused confusions (especially to myself when I was working on both
classes). I suggest unifying these names by renaming `__end_cap_` to
`__cap_` in `std::__split_buffer`.
2024-11-13 11:08:08 +01: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
jimingham
615bd9ee60 Add docs and an example use of the scripted command get_flags API. (#109176)
The API is present, and we even have a test for it, but it isn't
documented so no one probably knows you can set requirements for your
scripted commands. This just adds docs and uses it appropriately in the
`framestats` example command.
2024-09-18 18:10:43 -07:00
Michael Buch
9e9b1178ca [lldb] Support new libc++ __compressed_pair layout (#96538)
This patch is in preparation for the `__compressed_pair` refactor in
https://github.com/llvm/llvm-project/pull/76756.

This is mostly reviewable now. With the new layout we no longer need to
unwrap the `__compressed_pair`. Instead, we just need to look for child
members. E.g., to get to the underlying pointer of `std::unique_ptr` we
no longer do,
```
GetFirstValueOfCXXCompressedPair(GetChildMemberWithName("__ptr_"))

```
but instead do
```
GetChildMemberWithName("__ptr_")
```

We need to be slightly careful because previously the
`__compressed_pair` had a member called `__value_`, whereas now
`__value_` might be a member of the class that used to hold the
`__compressed_pair`. So before unwrapping the pair, we added checks for
`isOldCompressedLayout` (not sure yet whether folding this check into
`GetFirstValueOfCXXCompressedPair` is better).
2024-09-16 10:11:49 +01:00
jeffreytan81
b6bf27ef3c Avoid expression evaluation in libStdC++ std::vector<bool> synthetic children provider (#108414)
Our customers is reporting a serious performance issue (expanding a this
pointer takes 70 seconds in VSCode) in a specific execution context.

Profiling shows the hot path is triggered by an expression evaluation
from libStdC++ synthetic children provider for `std::vector<bool>` since
it uses `CreateValueFromExpression()`.

This PR added a new `SBValue::CreateBoolValue()` API and switch
`std::vector<bool>` synthetic children provider to use the new API
without performing expression evaluation.

Note: there might be other cases of `CreateValueFromExpression()` in our
summary/synthetic children providers which I will sweep through in later
PRs.

With this PR, the customer's scenario reduces from 70 seconds => 50
seconds. I will add other PRs to further optimize the remaining 50
seconds (mostly from type/namespace lookup).

Testing:

`test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py`
passes with the PR

---------

Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
2024-09-13 10:26:01 -07:00
Pavel Labath
5ce9a86110 [lldb] Make variant formatter work with libstdc++-14 (#97568)
In this version the internal data member has grown an additional
template parameter (bool), which was throwing the summary provider off.

This patch uses the type of the entire variant object. This is part of
the API/ABI, so it should be more stable, but it means we have to
explicitly strip typedefs and references to get to the interesting bits,
which is why I've extended the test case with examples of those.
2024-07-08 12:06:10 +02:00
jimingham
77d131eddb Add the ability for Script based commands to specify their "repeat command" (#94823)
Among other things, returning an empty string as the repeat command
disables auto-repeat, which can be useful for state-changing commands.

There's one remaining refinement to this setup, which is that for parsed
script commands, it should be possible to change an option value, or add
a new option value that wasn't originally specified, then ask lldb "make
this back into a command string". That would make doing fancy things
with repeat commands easier.

That capability isn't present in the lldb_private side either, however.
So that's for a next iteration.

I haven't added this to the docs on adding commands yet. I wanted to
make sure this was an acceptable approach before I spend the time to do
that.
2024-07-03 10:39:34 -07:00
Med Ismail Bennani
622df0ee92 [lldb] Add scripted thread plan python base class to lldb & website (#97481)
Following a feedback request in #97262, I took out the scripted thread
plan python base class from it and make a separate PR for it.

This patch adds the scripted thread plan base python class to the lldb
python module as well as the lldb documentation website.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-07-02 15:20:18 -07:00
Med Ismail Bennani
59f4267c8e [lldb/docs] Add scripting extensions documentation to the website (#97262)
This patch adds the documentation for a subset of scripting extensions
such as scripted process, scripted thread, operating system threads &
scritped thread plans to the lldb website.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-07-02 12:52:50 -07:00
Eisuke Kawashima
586114510c [lldb] fix(lldb/**.py): fix comparison to None (#94017)
from PEP8
(https://peps.python.org/pep-0008/#programming-recommendations):

> Comparisons to singletons like None should always be done with is or
is not, never the equality operators.

Co-authored-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
2024-06-26 15:59:07 +01:00
Eisuke Kawashima
fd35a92300 [lldb] fix(lldb/**.py): fix comparison to True/False (#94039)
from PEP8
(https://peps.python.org/pep-0008/#programming-recommendations):

> Comparisons to singletons like None should always be done with is or
is not, never the equality operators.

Co-authored-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
2024-06-26 15:55:15 +01:00
Med Ismail Bennani
1373f7c714 Revert "[lldb/crashlog] Make interactive mode the new default" (#96263)
Reverts llvm/llvm-project#94575 since introduces test failure:


https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/6166/
2024-06-20 18:23:50 -07:00
Med Ismail Bennani
aafa0ef900 [lldb/crashlog] Make interactive mode the new default (#94575)
This patch makes interactive mode as the default when using the crashlog
command. It replaces the existing `-i|--interactive` flag with a new
`-m|--mode` option, that can either be `interactive` or `batch`.

By default, when the option is not explicitely set by the user, the
interactive mode is selected, however, lldb will fallback to batch mode
if the command interpreter is not interactive or if stdout is not a tty.

This also adds some railguards to prevent users from using interactive
only options with the batch mode and updates the tests accordingly.

rdar://97801509

Differential Revision: https://reviews.llvm.org/D141658

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-06-20 17:23:18 -07:00
Med Ismail Bennani
d09231a422 [lldb/crashlog] Remove aarch64 requirement on crashlog tests (#94553)
This PR removes the `target-aarch64` requirement on the crashlog tests
to exercice them on Intel bots and make image loading single-threaded
temporarily while implementing a fix for a deadlock issue when loading
the images in parallel.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-06-06 12:17:00 -07:00
Med Ismail Bennani
86dddbe3b5 [lldb/crashlog] Always load Application Specific Backtrace Thread images (#94259)
This patch changes the crashlog image loading default behaviour to not
only load images from the crashed thread but also for the application
specific backtrace thread.

This patch also move the Application Specific Backtrace / Last Exception
Backtrace tag from the thread queue field to the thread name.

rdar://128276576

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-06-05 20:22:36 -07:00
Med Ismail Bennani
68a9cb7995 [lldb/crashlog] Add --no-parallel-image-loading hidden flag (#94513)
This patch adds the `--no-parallel-image-loading` to the crashlog
command. By default, image loading will happen in parallel in the
crashlog script however, sometimes, when running tests or debugging the
crashlog script itself, it's better to load the images sequentially.

As its name suggests, this flag will disable the default image loading
behaviour to load all the images sequencially in the main thread.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-06-05 15:45:42 -07:00
Med Ismail Bennani
f8afa763c6 [lldb/crashlog] Use environment variable to manually set dsymForUUIDBinary (#94517)
In lldb, users can change the `dsymForUUID` binary using the
`LLDB_APPLE_DSYMFORUUID_EXECUTABLE` environment variable.

This patch changes the crashlog to support the same behaviour as lldb
and uses this environment variable to disable `dsymForUUID` lookups in
crashlog test by having it be empty. Since CI bots shoudn't have access
to images on build records, it doesn't make sense to make use of
`dsymForUUID` in tests.

rdar://128953725

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-06-05 13:21:27 -07:00