3787 Commits

Author SHA1 Message Date
Charles Zablit
7fe5953a44
[lldb][windows] add Windows Virtual Console support (#168729) 2025-12-18 10:29:38 +00:00
Felipe de Azevedo Piovezan
566eb2b78f
[lldb] Respect max packet size limits for MultiMemRead in ProcessGDBRemote (#172022)
(ignore the first commit, it is the dependency of this PR)

Servers advertise what their maximum packet size is, MultiMemRead needs
to respect that.

Depends on:
*  https://github.com/llvm/llvm-project/pull/172020
2025-12-15 17:49:29 +00:00
Felipe de Azevedo Piovezan
66f2b6625e
[lldb][nfc] Change ProcessGDBRemote::ParseMultiMemReadPacket signature (#172020)
Instead of returning an `Expected<vector<...>>` it now returns an Error,
and receives a vector argument to fill in. This will be useful to
support a change were ParseMultiMemReadPacket will be called multiple
times in a loop with the same vector; without this change, we would have
to concatenate vectors and copy memory around.
2025-12-12 16:07:09 +00:00
Jason Molenda
e4c83b7b11
[lldb][NFC] Change ObjectFile argument type (#171574)
The ObjectFile plugin interface accepts an optional DataBufferSP
argument. If the caller has the contents of the binary, it can provide
this in that DataBufferSP. The ObjectFile subclasses in their
CreateInstance methods will fill in the DataBufferSP with the actual
binary contents if it is not set.
ObjectFile base class creates an ivar DataExtractor from the
DataBufferSP passed in.

My next patch will be a caller that creates a VirtualDataExtractor with
the binary data, and needs to pass that in to the ObjectFile plugin,
instead of the bag-of-bytes DataBufferSP. It builds on the previous
patch changing ObjectFile's ivar from DataExtractor to DataExtractorSP
so I could pass in a subclass in the shared ptr. And it will be using
the VirtualDataExtractor that Jonas added in
https://github.com/llvm/llvm-project/pull/168802

No behavior is changed by the patch; we're simply moving the creation of
the DataExtractor to the caller, instead of a DataBuffer that is
immediately used to set up the ObjectFile DataExtractor. The patch is a
bit complicated because all of the ObjectFile subclasses have to
initialize their DataExtractor to pass in to the base class.

I ran the testsuite on macOS and on AArch64 Ubutnu. (btw David, I ran it
under qemu on my M4 mac with SME-no-SVE again, Ubuntu 25.10, checked
lshw(1) cpu capabilities, and qemu doesn't seem to be virtualizing the
SME, that explains why the testsuite passes)

rdar://148939795

---------

Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-12-11 10:08:56 -08:00
David Spickett
5c98163246 [lldb] Log when we use fallback register information
These fallback layouts are essentially guesses. Used when there is
no other way to query register information from the debug server.

Therefore there is a risk that LLDB and the debug server disagree,
which can produce strange effects.

I have added a log message here so we have a clue when triaging
these problems.

Note that it's not wrong to assume a layout in some situations.
It's how some debug servers were built. However if you end up
using the fallback when the server expected you to use XML,
you're likely going to have a bad time.
2025-12-10 17:08:27 +00:00
Med Ismail Bennani
96c733e0db
[lldb] Add support for PC-less scripted frames (#170805)
Scripted frames that materialize Python functions or other non-native
code are PC-less by design, meaning they don't have valid program
counter values. Previously, these frames would display invalid addresses
(`0xffffffffffffffff`) in backtrace output.

This patch updates `FormatEntity` to detect and suppress invalid address
display for PC-less frames, adds fallback to frame methods when symbol
context is unavailable, and modifies `StackFrame::GetSymbolContext` to
skip PC-based symbol resolution for invalid addresses.

The changes enable PC-less frames to display cleanly with proper
function names, file paths, and line numbers, and allow for source
display of foreign sources (like Python). Includes comprehensive test
coverage demonstrating frames pointing to Python source files.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-12-05 23:57:54 +00:00
David Spickett
6b040b4b4f
[lldb] Issue a warning when Target XML should have been used but we do not have libxml2 (#170663)
If you connect lldb without libxml2 enabled, to a debug stub,
that server may offer Target XML but lldb will not use it. This
often causes incorrect or missing registers.

So much so that I think users should be made aware of this so
they can find an lldb with libxml2 enabled.

This warning will only be printed when:
* The debug server offered us Target XML but lldb does not have libxml2,
and -
* qRegisterInfo was not supported by the debug server.

This means that (lldb without libxml2) -> (lldb-server or debugserver)
will not warn as we'll fall back to qRegisterInfo. All that's
potentially
missing is advanced register formatting information, which most people
won't notice is missing anyway. If they do, the logs contain information
about this.

If you connect (lldb without libxml2) > (gdbserver, or a stub inspired
by it)
you will see this warning. As they do not support qRegisterInfo.

```
$ ./bin/lldb /tmp/test.o -o "gdb-remote 1234"
(lldb) target create "/tmp/test.o"
Current executable set to '/tmp/test.o' (aarch64).
(lldb) gdb-remote 1234
warning: the debug server supports Target Description XML but LLDB does not have XML parsing enabled. Using "qRegisterInfo" was also not possible. Register information may be incorrect or missing.
```

When qRegisterInfo is not supported, there are 4 possible situations.

1. The debug server offered Target XML and we do not have libxml2

We should warn the user so they can find an lldb with libxml2.

2. The debug server offered Target XML but it was not valid XML

Ideally we'd warn here too, but the error handling needs more
work to implement this, and there is logging for it if you know
where to look.

3. The debug server did not offer Target XML and we have libxml2
4. The debug server did not offer Target XML and we do have libxml2

There's no XML to parse, so no reason to warn. The user is not getting
a worse debug experience because we lack libxml2.

Their only course of action here would be to replace the debug stub.
Given that this occurs a lot with stubs embedded in kernels or debug
hardware, they may not have a choice either.
2025-12-05 13:55:05 +00:00
David Spickett
23173475c1
[lldb] Improve logging of failure to get register information from Target XML (#170478)
In
https://discourse.llvm.org/t/does-lldb-qemu-support-dumping-x64-control-registers-such-as-cr3/89031
a user was not seeing certain registers when connected to QEMU. Turns
out their LLDB build did not have libxml2 enabled.

While logging is not the first thing most users will think of, it is
something an expert can ask for to confirm whether they have XML support
enabled.

So in this PR I've shuffled the logic GetGDBServerRegisterInfo to better
report problems in the log.

The key one is when lldb does not have libxml2 but the server did say it
supports qxfer:features. In this case we would have used it if we could,
and the debug session will likely be degraded because we are not able
to.

https://sourceware.org/gdb/current/onlinedocs/gdb.html/General-Query-Packets.html#qXfer-target-description-read
2025-12-05 10:13:27 +00:00
Charles Zablit
fc1e91112b
[lldb] ensure comment conforms to LLVM guidelines (#170533)
This patch is a follow up to
https://github.com/llvm/llvm-project/pull/170471.
2025-12-03 20:14:05 +00:00
Charles Zablit
8b94997a47
[lldb][windows] fix invalid corefile error message (#170471) 2025-12-03 12:53:17 +00:00
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
Med Ismail Bennani
41a53c0a23
[lldb/Target] Add BorrowedStackFrame and make StackFrame methods virtual (#170191)
This change makes StackFrame methods virtual to enable subclass
overrides and introduces BorrowedStackFrame, a wrapper that presents an
existing StackFrame with a different frame index.

This enables creating synthetic frame views or renumbering frames
without copying the underlying frame data, which is useful for frame
manipulation scenarios.

This also adds a new borrowed-info format entity to show what was the
original frame index of the borrowed frame.

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-12-02 10:41:03 -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
GeorgeHuyubo
fce58897ce
[lldb] Enable locate module callback for all module loading (#160199)
Main executables were bypassing the locate module callback that shared 
libraries use, preventing custom symbol file location logic from working
consistently. 

This PR fix this by
*   Adding target context to ModuleSpec
* Leveraging that context to use target search path and platform's
locate module callback in ModuleList::GetSharedModule

This ensures both main executables and shared libraries get the same 
callback treatment for symbol file resolution.

---------

Co-authored-by: George Hu <hyubo@meta.com>
Co-authored-by: George Hu <georgehuyubo@gmail.com>
2025-11-06 12:48:21 -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
Odric Roux-Paris
23cc43d955
[lldb] print errors when the debug server is not found (#165157) 2025-10-27 22:51:28 +00:00
Felipe de Azevedo Piovezan
276bccda66
[lldb] Implement ProcessGDBRemote support for ReadMemoryRanges (#164311)
This commit makes use of the newly created MultiMemRead packet to
provide an efficient implementation of MultiMemRead inside
ProcessGDBRemote.

Testing is tricky, but it is accomplished two ways:

1. Some Objective-C tests would fail if this were implemented incorrectly,
as there is already an in-tree use of the base class implementation of
MultiMemRead, which is now getting replaced by the derived class.

2. One Objective-C test is modified so that we ensure the packet is
being sent by looking at the packet logs. While not the most elegant
solution, it is a strategy adopted in other tests as well. This gets
around the fact that we cannot instantiate / unittest a mock
ProcessGDBRemote.

Depends on https://github.com/llvm/llvm-project/pull/163651
2025-10-22 07:40:29 -07:00
Ebuka Ezike
097f1e7625
[lldb] Do not stop the process on SIGWINCH by default. (#163182)
SIGWINCH is sent when the terminal window size changes.. Most people
debugging do not want the process on this signal.

When using lldb-dap, the user may be using an integrated terminal and
may resize the pane/window mulitple times when debugging. this causes
the signal to be sent multiple times. It gets in the way.

The process ignores this signal by default
2025-10-15 17:19:51 +01:00
Felipe de Azevedo Piovezan
ccf6e0250b
[lldb] Parse qSupported MultiMemRead tag in GDB Remote Client (#163249)
This is in preparation for the new MultiMemRead packet discussed in the
RFC [1].

An alternative to using `qSupported` would be having clients send an
empty `MultiMemRead` packet. However, this is problematic because the
already-existing packet `M` is a prefix of `MultiMemRead`; an empty
reply would be ambiguous in this case. It is also risky that the stub
might interpret the `MultiMemRead` as a valid `M` packet.

Another advantage of `qSupported` is that this packet is already
exchanged, so parsing a new field is simpler than having to exchange one
extra packet.

[1]:
https://discourse.llvm.org/t/rfc-a-new-vectorized-memory-read-packet/88441
2025-10-15 07:34:06 -07:00
aokblast
c9b07f34d4
[LLDB, FreeBSD, x86] Fix empty register set when trying to get size of register (#162890)
The register set information is stored as a singleton in
GetRegisterInfo_i386. However, other functions later access this
information assuming it is stored in GetSharedRegisterInfoVector. To
resolve this inconsistency, we remove the original construction logic
and instead initialize the singleton using llvm::call_once within the
appropriate function (GetSharedRegisterInfoVector_i386).
2025-10-15 09:55:00 +01:00
Jonas Devlieghere
14a7c8a741
[lldb] Use the correct Wasm register context (#162942)
When implementing the WebAssembly Process Plugin, I initially added
WasmGDBRemoteRegisterContext as a placeholder in the UnwindWasm TU.

After implementing RegisterContextWasm (#151056), I forgot to switch
over to the new implementation. This meant we were using the wrong
register context for all frames, except frame 0. The register context
deals with the virtual registers, so this only becomes an issue when
trying to evaluate a `DW_OP_WASM_location`, which is why this went
unnoticed.

This PR removes the WasmGDBRemoteRegisterContext placeholder and updates
UnwindWasm to use RegisterContextWasm instead for all frames.

In terms of testing, I considered updating TestWasm but that would
require adding even more state to the already complicated GDB stub. This
doesn't scale and my focus over the next weeks/months will be coming up
with a comprehensive testing strategy that involves running (a subset of
the) API tests under a Wasm runtime, which will cover this and much
more.

rdar://159297244
2025-10-13 10:20:40 -07:00
David Spickett
fb17bc70ac
[lldb][Linux] Fix checking of error values when attach fails (#161673)
Relates to #161510

Fixes 6db44e52ce474bbeb66042073a6e3c6c586f78a2

(it's not fixing it, it's just making the error not be an unhandled
error)

When we fail to attach to a process we see if we can add more
information about why it happened:
```
  if (status.GetError() == EPERM) {
    // Depending on the value of ptrace_scope, we can return a different
    // error that suggests how to fix it.
    return AddPtraceScopeNote(status.ToError());
  }
```
ToError creates a new error value and leaves the one in `status`
unchecked. `status`'s error is ok because it will be checked by Status'
destructor.

The problem happens in `AddPtraceScopeNote`. If we take certain return
paths, this new error, or the one we get when trying to find the ptrace
scope, may be unchecked on destruction when the function returns.

To fix this, in AddPtraceScopeNote, consume any errors that we are not
going to return. Anything returned will be checked by some caller.

Reproducing this failure mode is difficult but it can be faked by
calling AddPtraceScopeNote earlier. Which is what I did to prove the
concept of the problem.
2025-10-07 09:41:51 +01:00
David Peixotto
44a1f7e7ca
[lldb] Fix unsafe map mutation in ProcessElfCore::FindModuleUUID (#159444)
The `ProcessElfCore::FindModuleUUID` function can be called by multiple
threads at the same time when `target.parallel-module-load` is true. We
were using the `operator[]` to lookup the UUID which will mutate the map
when the key is not present. This is unsafe in a multi-threaded contex
so we now use a read-only `find` operation and explicitly return an
invalid UUID when the key is not present.

The `m_uuids` map can follow a create-then-query pattern. It is
populated in the `DoLoadCore` function which looks like it is only
called in a single-threaded context so we do not need extra locking as
long as we keep the other accesses read-only.

Other fixes I considered

* Use a lock to protect access - We don't need to modify the map after
creation so we can allow concurrent read-only access.
* Store the map in a const pointer container to prevent accidental
mutation in other places.
     - Only accessed in one place currently so just added a comment.
* Store the UUID in the NT_FILE_Entry after building the mapping
correctly in `UpdateBuildIdForNTFileEntries`. - The map lets us avoid a
linear search in `FindModuleUUID`.

This commit also reverts the temporary workaround from #159395 which
disabled parallel module loading to avoid the test failure.

Fixes #159377
2025-09-18 08:20:09 -07:00
Vy Nguyen
09e0f1e035
[LLDB]Fix buffer-over-flow bug introduced in 157170 (#159588)
If `pr_name` is longer than 16, it would be a non-null terminated
string. Assigning it to `std::string m_executable_name` would cause an
overflow read. Instead, just copy the name from thread_data.name.

To repro, run the `elf-core/TestLinuxCore.py` with asan
(Question: why is the new variable needed in the first place? can't the
thread_data.name be used?)
2025-09-18 10:43:42 -04:00
Walter Erquinigo
4f72abd840
[LLDB] Add support for the structured data plugins in lldb-server (#159457)
The LLDB client has support for structured data plugins, but lldb-server
doesn't have corresponding support for it. This patch adds the missing
functionality in LLGS for servers to register their supported plugins
and send corresponding async messages.
2025-09-18 10:40:55 -04:00
nerix
a868f28c6e
[LLDB][ProcessWindows] Set exit status on instance rather than going through all targets (#159308)
When quitting LLDB on Windows while a process was still running, LLDB
would take unusually long to exit. This was due to a temporary deadlock:

The main thread was destroying the processes. In doing so, it iterated
over the target list:

88c64f76ed/lldb/source/Core/Debugger.cpp (L1095-L1098)

This locks the list for the whole iteration. Finalizing the process
would eventually lead to `DebuggerThread::StopDebugging`, which
terminates the process and waits for it to exit:

88c64f76ed/lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp (L196)
The debugger loop (on a separate thread) would see that the process
exited and call
[`ProcessWindows::OnExitProcess`](88c64f76ed/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (L656-L673)).
This calls the static function
[`Process::SetProcessExitStatus`](0a7a7d56fc/lldb/source/Target/Process.cpp (L1098-L1126)).
This tries to find the process by its ID from the debugger's target
list. Doing so requires locking the list, so the debugger thread would
then be stuck on

0a7a7d56fc/lldb/source/Target/TargetList.cpp (L403)

After 5s, the main thread would give up waiting. So every exit where the
process was still running would be delayed by about 5s.

Since `ProcessWindows` would find itself when calling
`SetProcessExitStatus`, we can call `SetExitStatus` directly.

This can also make some tests run faster. For example, the DIA PDB tests
previously took 15s to run on my PC (24 jobs) and now take 5s. For all
shell tests, the difference isn't that big (only about 3s), because most
don't run into this and the tests run in parallel.
2025-09-18 11:27:25 +02:00
David Spickett
88b5c7435e
[lldb] Correct 32-bit build failure in StopInfoMachException.cpp (#159523)
uintptr_t is usually a good idea when handling pointers, but lldb has to
handle 64-bit addresses that might be from a remote system, on a 32-bit
system.

So I've changed a few instances here to use addr_t which is 64-bit
everywhere.

Before we got:
https://lab.llvm.org/buildbot/#/builders/18/builds/21247

```
../llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp:81:28: error: constexpr variable 'g_mte_tag_mask' must be initialized by a constant expression
   81 | static constexpr uintptr_t g_mte_tag_mask = (uintptr_t)0x0f << g_mte_tag_shift;
      |                            ^                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp:81:61: note: shift count 56 >= width of type 'uintptr_t' (aka 'unsigned int') (32 bits)
   81 | static constexpr uintptr_t g_mte_tag_mask = (uintptr_t)0x0f << g_mte_tag_shift;
      |                                                             ^
1 error generated.
```

Original code added by #159117.
2025-09-18 09:59:02 +01:00
Jonas Devlieghere
def2020485
[lldb] Recognize MTE fault Mach exceptions (#159117)
Recognize an MTE tag fault Mach exception. A tag fault is an error
reported by Arm's Memory Tagging Extension (MTE) when a memory access
attempts to use a pointer with a tag that doesn't match the tag stored
with the memory. LLDB will print the tag and address to make the issue
easier to diagnose.

This was hand tested by debugging an MTE enabled binary on an iPhone 17
running iOS 26.

rdar://113575216
2025-09-17 11:20:52 -07:00
Martin Storsjö
4ff113f0aa
[lldb] Add unreachable after fully covered switches, avoid GCC warnings. NFC. (#159327)
This avoids the following kind of warning with GCC:

    warning: control reaches end of non-void function [-Wreturn-type]
2025-09-17 20:34:30 +03:00
GeorgeHuyubo
c087da4b18
[lldb][ElfCore] Improve main executable detection in core files (#157170)
This change improves how LLDB's ProcessElfCore plugin identifies the
main executable when loading ELF core files. Previously, the code would
simply use the first entry in the NT_FILE section, which is not
guaranteed to be the main executable, also the first entry might not
have a valid UUID.

1. **Storing executable name**: Extract the executable name from the ELF
NT_PRPSINFO note and store it in `m_executable_name`

2. **Preferential matching**: When selecting the main executable from
NT_FILE entries, prefer entries whose path ends with the stored
executable name

3. **UUID-based lookup**: Call `FindModuleUUID()` helper function to
properly match modules by path and retrieve a valid UUID

Co-authored-by: George Hu <hyubo@meta.com>
2025-09-10 15:15:59 -07:00
Jason Molenda
69511ae804
[lldb] Unwind through ARM Cortex-M exceptions automatically (#153922)
When a processor faults/is interrupted/gets an exception, it will stop
running code and jump to an exception catcher routine. Most processors
will store the pc that was executing in a system register, and the
catcher functions have special instructions to retrieve that & possibly
other registers. It may then save those values to stack, and the author
can add .cfi directives to tell lldb's unwinder where to find those
saved values.

ARM Cortex-M (microcontroller) processors have a simpler mechanism where
a fixed set of registers are saved to the stack on an exception, and a
unique value is put in the link register to indicate to the caller that
this has taken place. No special handling needs to be written into the
exception catcher, unless it wants to inspect these preserved values.
And it is possible for a general stack walker to walk the stack with no
special knowledge about what the catch function does.

This patch adds an Architecture plugin method to allow an Architecture
to override/augment the UnwindPlan that lldb would use for a stack
frame, given the contents of the return address register. It resembles a
feature where the LanguageRuntime can replace/augment the unwind plan
for a function, but it is doing it at offset by one level. The
LanguageRuntime is looking at the local register context and/or symbol
name to decide if it will override the unwind rules. For the Cortex-M
exception unwinds, we need to modify THIS frame's unwind plan if the
CALLER's LR had a specific value. RegisterContextUnwind has to retrieve
the caller's LR value before it has completely decided on the UnwindPlan
it will use for THIS stack frame.

This does mean that we will need one additional read of stack memory
than we currently do when unwinding, on Armv7 Cortex-M targets. The
unwinder walks the stack lazily, as stack frames are requested, and so
now if you ask for 2 stack frames, we will read enough stack to walk 2
frames, plus we will read one extra word of memory, the spilled LR value
from the stack. In practice, with 512-byte memory cache reads, this is
unlikely to be a real performance hit.

This PR includes a test with a yaml corefile description and a JSON
ObjectFile, incorporating all of the necessary stack memory and symbol
names from a real debug session I worked on. The architectural default
unwind plans are used for all stack frames except the 0th because
there's no instructions for the functions, and no unwind info. I may
need to add an encoding of unwind fules to ObjectFileJSON in the future
as we create more test cases like this.

This PR depends on the yaml2macho-core utility from
https://github.com/llvm/llvm-project/pull/153911 to run its API test.

rdar://110663219
2025-09-09 14:11:39 -07:00
Igor Kudrin
8ec4d87550
[lldb][elf-core][ARM] Add support for VFP registers (#155956)
This patch loads values of the VFP registers from the NT_ARM_VFP note.

Note that a CORE/NT_FPREGSET note is typically present in core dump
files and is used to store the FPA registers. The FPA unit is rare and
obsolete; however, Linux creates the note even if the unit is absent.
2025-09-08 14:55:54 -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
Jacob Lalonde
6505bc3db0
[LLDB][AArch64] Make TPIDR a generic tp register (#154444)
Unlike x86, ARM doesn't support a generic thread pointer for TLS data,
so things like
```
reg read tp
...
memory read tp
```

Don't work, and you need to specify tpidr. This works, especially
because that's the name GDB uses. But for ease of use, and at the
request of @aperez I've made it so we can reference it via `tp`.

I personally don't have an aarch machine, and all the arm examples in
`Shell/Register/Core` are freebsd and don't contain tpidr, so I was
unable to add a shell test for this. I added a test to the AARCH
register tests, but without an Aarch machine I'm hoping these work.
2025-09-04 10:37:52 -07:00
Med Ismail Bennani
6c10ab8a3c
[lldb] Mark scripted frames as synthetic instead of artificial (#153117)
This patch changes the way frames created from scripted affordances like
Scripted Threads are displayed. Currently, they're marked artificial
which is used usually for compiler generated frames.

This patch changes that behaviour by introducing a new synthetic
StackFrame kind and moves 'artificial' to be a distinct StackFrame
attribut.

On top of making these frames less confusing, this allows us to know
when a frame was created from a scripted affordance.

rdar://155949703

Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2025-09-03 15:58:14 -07:00
David Spickett
8d5deadb15
[lldb][ARM] Port Arm Linux to use NativeRegisterContextDBReg (#152284)
Which is also used by AArch64 and LoongArch.

To test this, I ran the test suite as usual on Arm and found no new 
failures, then ran it again with all test programs compiled with
`-mthumb`. This means the binaries will be entirely Thumb code.

Finally I tested it on AArch64, but this is mostly a build test,
as I did not run the entire test suite compiled to AArch32.

Prior to this change, these tests failed with `-mthumb`:
```
Failed Tests (14):
  lldb-api :: commands/process/reverse-continue/TestReverseContinue.py
  lldb-api :: functionalities/breakpoint/breakpoint_by_line_and_column/TestBreakpointByLineAndColumn.py
  lldb-api :: functionalities/data-formatter/data-formatter-cpp/TestDataFormatterCpp.py
  lldb-api :: functionalities/reverse-execution/TestReverseContinueBreakpoints.py
  lldb-api :: functionalities/reverse-execution/TestReverseContinueWatchpoints.py
  lldb-api :: functionalities/tail_call_frames/disambiguate_call_site/TestDisambiguateCallSite.py
  lldb-api :: functionalities/tail_call_frames/disambiguate_paths_to_common_sink/TestDisambiguatePathsToCommonSink.py
  lldb-api :: functionalities/tail_call_frames/disambiguate_tail_call_seq/TestDisambiguateTailCallSeq.py
  lldb-api :: functionalities/tail_call_frames/inlining_and_tail_calls/TestInliningAndTailCalls.py
  lldb-api :: functionalities/tail_call_frames/sbapi_support/TestTailCallFrameSBAPI.py
  lldb-api :: functionalities/tail_call_frames/thread_step_out_message/TestArtificialFrameStepOutMessage.py
  lldb-api :: functionalities/thread/jump/TestThreadJump.py
  lldb-api :: lang/c/vla/TestVLA.py
  lldb-api :: linux/sepdebugsymlink/TestTargetSymbolsSepDebugSymlink.py
```

After this change, no new failures occurred. So I am confident it is
correct / as bad as it always was.

Looking at those failures, it's a few things:
* Something in the reverse execution wrapper that I can't figure out,
but is
  likely nothing to do with the real breakpoints.
* The inability to tail call when building thumb code, because the call
goes
  via. a veneer that might do a mode switch.
* Assumptions about source locations being in specific places.

None of which are issues I feel like need fixing before doing this port.

I suspect there is redundant code in this, particularly aligning
addresses. I've not made an effort to remove it because A: I'm scared to
break Thumb support because it's not commonly used and B: it may be
there to handle clients other than LLDB, which don't align breakpoint
addresses before requesting them.
2025-08-27 14:05:38 +01:00
David Spickett
cdb18705fc [lldb] Fix spacing in "proccess plugin packet monitor" help 2025-08-26 10:35:54 +00:00
Julian Lettner
484d0408f9
[lldb] Fix source line annotations for libsanitizers traces (#154247)
When providing allocation and deallocation traces,
the ASan compiler-rt runtime already provides call
addresses (`TracePCType::Calls`).

On Darwin, system sanitizers (libsanitizers)
provides return address.  It also discards a few
non-user frames at the top of the stack, because
these internal libmalloc/libsanitizers stack
frames do not provide any value when diagnosing
memory errors.

Introduce and add handling for
`TracePCType::ReturnsNoZerothFrame` to cover this
case and enable libsanitizers traces line-level
testing.

rdar://157596927

---
Commit 1 is a mechanical refactoring to introduce
and adopt `TracePCType` enum to replace
`pcs_are_call_addresses` bool.  It preserve the
current behavior:
```
pcs_are_call_addresses:
  false  ->  TracePCType::Returns (default)
  true   ->  TracePCType::Calls
``` 

Best reviewed commit by commit.
2025-08-20 14:33:27 -07:00
David Tenty
63195d3d7a
[NFC][CMake] quote ${CMAKE_SYSTEM_NAME} consistently (#154537)
A CMake change included in CMake 4.0 makes `AIX` into a variable
(similar to `APPLE`, etc.)
ff03db6657

However, `${CMAKE_SYSTEM_NAME}` unfortunately also expands exactly to
`AIX` and `if` auto-expands variable names in CMake. That means you get
a double expansion if you write:

`if (${CMAKE_SYSTEM_NAME}  MATCHES "AIX")`
which becomes:
`if (AIX  MATCHES "AIX")`
which is as if you wrote:
`if (ON MATCHES "AIX")`

You can prevent this by quoting the expansion of "${CMAKE_SYSTEM_NAME}",
due to policy
[CMP0054](https://cmake.org/cmake/help/latest/policy/CMP0054.html#policy:CMP0054)
which is on by default in 4.0+. Most of the LLVM CMake already does
this, but this PR fixes the remaining cases where we do not.
2025-08-20 12:45:41 -04:00
Igor Kudrin
11e1d46586 [lldb] Fix UBSan complaints for #151460 2025-08-07 13:01:52 -07:00
David Spickett
49d5dd37f8 Reland "[lldb] Fix auto advance PC in EmulateInstructionARM64 if PC >= 4G (#151460)"
This reverts commit 600976f4bfb06526c283dcc4efc4801792f08ca5.

The test was crashing trying to access any element of the GPR struct.

(gdb) disas
Dump of assembler code for function _ZN7testing8internal11CmpHelperEQIyyEENS_15AssertionResultEPKcS4_RKT_RKT0_:
   0x00450afc <+0>:	push	{r4, r5, r6, r7, r8, r9, r10, r11, lr}
   0x00450b00 <+4>:	sub	sp, sp, #60	; 0x3c
   0x00450b04 <+8>:	ldr	r5, [sp, #96]	; 0x60
=> 0x00450b08 <+12>:	ldm	r3, {r4, r7}
   0x00450b0c <+16>:	ldm	r5, {r6, r9}
   0x00450b10 <+20>:	eor	r7, r7, r9
   0x00450b14 <+24>:	eor	r6, r4, r6
   0x00450b18 <+28>:	orrs	r7, r6, r7

(gdb) p/x r3
$3 = 0x3e300f6e

"However, load and store multiple instructions (LDM and STM) and load and store double-word (LDRD or STRD) must be aligned to at least a word boundary."

https://developer.arm.com/documentation/den0013/d/Porting/Alignment

>>> 0x3e300f6e % 4
2

Program received signal SIGBUS, Bus error.
0x00450b08 in testing::AssertionResult testing::internal::CmpHelperEQ<unsigned long long, unsigned long long>(char const*, char const*, unsigned long long const&, unsigned long long const&) ()

The struct is packed with 1 byte alignment, but it needs to start at an aligned address for us
to ldm from it. So I've done that with alignas.

Also fixed some compiler warnings in the test itself.
2025-08-06 09:25:48 +00:00
Kazu Hirata
40fbc76dc8 [lldb] Fix the build
This patch fixes:

  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:623:47:
  error: expected ';' after expression
2025-08-05 11:09:56 -07:00
Walter Erquinigo
9179b07981
[LLDB] Complete a missing register format mapping in the gdb-remote p… (#152170)
…rotocol

When writing a custom gdb-remote server I realized that the encoder and
decoder of register formats is incomplete.

- Add the encoder on the server side and add an llvm_unreachable is
there's a missing case.
- Add a decoder on the client side that doesn't fail. We have to keep it
flexible.

I couldn't figure out an easy way to test this but the changes seem very
straightforward to me.
2025-08-05 13:53:15 -04:00
Felipe de Azevedo Piovezan
c3b5f1cfe9
[lldb] Fix incorrect conversion from boolean in RegisterContextThreadMemory (#151767)
The method ConvertRegisterKindToRegisterNumber should return
INVALID_REGNUM, and not "false" upon failure: false would mean 0 which
is usually the number for generic PC.

Likewise, NumSupportedHardwareBreakpoints should return 0 instead of
false (though for this one they are equivalent).
2025-08-01 15:40:14 -07:00
Jonas Devlieghere
f62370290a
[lldb] Implement RegisterContextWasm (#151056)
This PR implements a register context for Wasm, which uses virtual
registers to resolve Wasm local, globals and stack values. The registers
are used to implement support for `DW_OP_WASM_location` in the DWARF
expression evaluator (#151010). This also adds a more comprehensive
test, showing that we can use this to show local variables.
2025-07-30 19:51:09 -07:00
David Spickett
10d7352c7a
[lldb][FreeBSD] Add Auxv numbers for HWCAP3 and HWCAP4 (#151152)
These entries serve the same purpose as the Linux HWCAPs but have been
assigned different numbers as FreeBSD had already used the Linux ones.

The numbers were assigned in:

85007872d1

In theory we can read these for the purposes of register field
detection, even on earlier versions of FreeBSD. As the aux data is a
key-value structure, we simply won't find the new numbers on older
systems.

However, FreeBSD has not defined any feature bits for HWACP3 and 4. It
is likley that they will match the Linux feature bits, but I have no
proof of that yet.

For instance, FEAT_MTE_STORE_ONLY is indicated by a HWCAP3 feature bit
on Linux. FreeBSD does not support this feature at all yet.

So for now, these values exist for future use and are not used for
register field detection on FreeBSD.
2025-07-30 11:24:35 +01:00
Kazu Hirata
c00e8dd9ea [lldb] Fix a warning
This patch fixes:

  lldb/source/Plugins/Process/wasm/ProcessWasm.cpp:107:25: error:
  format specifies type 'unsigned long long' but the argument has type
  'lldb::tid_t' (aka 'unsigned long') [-Werror,-Wformat]
2025-07-29 12:25:46 -07:00
Jonas Devlieghere
a28e7f1aad
[lldb] Add WebAssembly Process Plugin (#150143)
Extend support in LLDB for WebAssembly. This PR adds a new Process
plugin (ProcessWasm) that extends ProcessGDBRemote for WebAssembly
targets. It adds support for WebAssembly's memory model with separate
address spaces, and the ability to fetch the call stack from the
WebAssembly runtime.

I have tested this change with the WebAssembly Micro Runtime (WAMR,
https://github.com/bytecodealliance/wasm-micro-runtime) which implements
a GDB debug stub and supports the qWasmCallStack packet.

```
(lldb) process connect --plugin wasm connect://localhost:4567
Process 1 stopped
* thread #1, name = 'nobody', stop reason = trace
    frame #0: 0x40000000000001ad
wasm32_args.wasm`main:
->  0x40000000000001ad <+3>:  global.get 0
    0x40000000000001b3 <+9>:  i32.const 16
    0x40000000000001b5 <+11>: i32.sub
    0x40000000000001b6 <+12>: local.set 0
(lldb) b add
Breakpoint 1: where = wasm32_args.wasm`add + 28 at test.c:4:12, address = 0x400000000000019c
(lldb) c
Process 1 resuming
Process 1 stopped
* thread #1, name = 'nobody', stop reason = breakpoint 1.1
    frame #0: 0x400000000000019c wasm32_args.wasm`add(a=<unavailable>, b=<unavailable>) at test.c:4:12
   1    int
   2    add(int a, int b)
   3    {
-> 4        return a + b;
   5    }
   6
   7    int
(lldb) bt
* thread #1, name = 'nobody', stop reason = breakpoint 1.1
  * frame #0: 0x400000000000019c wasm32_args.wasm`add(a=<unavailable>, b=<unavailable>) at test.c:4:12
    frame #1: 0x40000000000001e5 wasm32_args.wasm`main at test.c:12:12
    frame #2: 0x40000000000001fe wasm32_args.wasm
```

This PR is based on an unmerged patch from Paolo Severini:
https://reviews.llvm.org/D78801. I intentionally stuck to the
foundations to keep this PR small. I have more PRs in the pipeline to
support the other features/packets.

My motivation for supporting Wasm is to support debugging Swift compiled
to WebAssembly:
https://www.swift.org/documentation/articles/wasm-getting-started.html
2025-07-29 10:07:13 -07:00
b10902118
9bf3e615a2
[lldb][AArch64] Fix arm64 hardware breakpoint/watchpoint to arm32 process. (#147198)
When debugging arm32 process on arm64 machine, arm64 lldb-server will
use `NativeRegisterContextLinux_arm`, but the server should keep using
64-bit ptrace commands for hardware watchpoint/breakpoint, even when
debugging a 32-bit tracee.

See:
5d220ff942

There have been many conditional compilation handling arm32 tracee on
arm64, but this one is missed out.

To reuse the 64-bit implementation, I separate the shared code from
`NativeRegisterContextLinux_arm64.cpp` to
`NativeRegisterContextLinux_arm64dbreg.cpp`, with other adjustments to
share data structures of debug registers.
2025-07-29 10:05:13 +01:00