summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process
AgeCommit message (Collapse)Author
2025-11-12Revert "[lldb] Introduce ScriptedFrameProvider for real threads" (#167662)Michael Buch
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-11[lldb] Introduce ScriptedFrameProvider for real threads (#161870)Med Ismail Bennani
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-06[lldb] Enable locate module callback for all module loading (#160199)GeorgeHuyubo
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[lldb/Interpreter] Implement ScriptedFrameProvider{,Python}Interface (#166662)Med Ismail Bennani
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-10-27[lldb] print errors when the debug server is not found (#165157)Odric Roux-Paris
2025-10-22[lldb] Implement ProcessGDBRemote support for ReadMemoryRanges (#164311)Felipe de Azevedo Piovezan
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-15[lldb] Do not stop the process on SIGWINCH by default. (#163182)Ebuka Ezike
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[lldb] Parse qSupported MultiMemRead tag in GDB Remote Client (#163249)Felipe de Azevedo Piovezan
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[LLDB, FreeBSD, x86] Fix empty register set when trying to get size of ↵aokblast
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-13[lldb] Use the correct Wasm register context (#162942)Jonas Devlieghere
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-07[lldb][Linux] Fix checking of error values when attach fails (#161673)David Spickett
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-09-18[lldb] Fix unsafe map mutation in ProcessElfCore::FindModuleUUID (#159444)David Peixotto
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[LLDB]Fix buffer-over-flow bug introduced in 157170 (#159588)Vy Nguyen
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[LLDB] Add support for the structured data plugins in lldb-server (#159457)Walter Erquinigo
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[LLDB][ProcessWindows] Set exit status on instance rather than going through ↵nerix
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: https://github.com/llvm/llvm-project/blob/88c64f76ed2ca226da99b99f60d316b1519fc7d8/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: https://github.com/llvm/llvm-project/blob/88c64f76ed2ca226da99b99f60d316b1519fc7d8/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`](https://github.com/llvm/llvm-project/blob/88c64f76ed2ca226da99b99f60d316b1519fc7d8/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp#L656-L673). This calls the static function [`Process::SetProcessExitStatus`](https://github.com/llvm/llvm-project/blob/0a7a7d56fc882653335beba0d1f8ea9f26089c22/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 https://github.com/llvm/llvm-project/blob/0a7a7d56fc882653335beba0d1f8ea9f26089c22/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[lldb] Correct 32-bit build failure in StopInfoMachException.cpp (#159523)David Spickett
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-17[lldb] Recognize MTE fault Mach exceptions (#159117)Jonas Devlieghere
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[lldb] Add unreachable after fully covered switches, avoid GCC warnings. ↵Martin Storsjö
NFC. (#159327) This avoids the following kind of warning with GCC: warning: control reaches end of non-void function [-Wreturn-type]
2025-09-10[lldb][ElfCore] Improve main executable detection in core files (#157170)GeorgeHuyubo
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-09[lldb] Unwind through ARM Cortex-M exceptions automatically (#153922)Jason Molenda
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-08[lldb][elf-core][ARM] Add support for VFP registers (#155956)Igor Kudrin
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-04[lldb] Introduce ScriptedFrame affordance (#149622)Med Ismail Bennani
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[LLDB][AArch64] Make TPIDR a generic tp register (#154444)Jacob Lalonde
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-03[lldb] Mark scripted frames as synthetic instead of artificial (#153117)Med Ismail Bennani
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-08-27[lldb][ARM] Port Arm Linux to use NativeRegisterContextDBReg (#152284)David Spickett
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-26[lldb] Fix spacing in "proccess plugin packet monitor" helpDavid Spickett
2025-08-20[lldb] Fix source line annotations for libsanitizers traces (#154247)Julian Lettner
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[NFC][CMake] quote ${CMAKE_SYSTEM_NAME} consistently (#154537)David Tenty
A CMake change included in CMake 4.0 makes `AIX` into a variable (similar to `APPLE`, etc.) https://gitlab.kitware.com/cmake/cmake/-/commit/ff03db6657c38c8cf992877ea66174c33d0bcb0b 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-07[lldb] Fix UBSan complaints for #151460Igor Kudrin
2025-08-06Reland "[lldb] Fix auto advance PC in `EmulateInstructionARM64` if PC >= 4G ↵David Spickett
(#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-05[lldb] Fix the buildKazu Hirata
This patch fixes: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp:623:47: error: expected ';' after expression
2025-08-05[LLDB] Complete a missing register format mapping in the gdb-remote p… ↵Walter Erquinigo
(#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-01[lldb] Fix incorrect conversion from boolean in RegisterContextThreadMemory ↵Felipe de Azevedo Piovezan
(#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-07-30[lldb] Implement RegisterContextWasm (#151056)Jonas Devlieghere
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[lldb][FreeBSD] Add Auxv numbers for HWCAP3 and HWCAP4 (#151152)David Spickett
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: https://github.com/freebsd/freebsd-src/commit/85007872d1227006adf2ce119fe30de856cbe12d 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-29[lldb] Fix a warningKazu Hirata
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[lldb] Add WebAssembly Process Plugin (#150143)Jonas Devlieghere
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[lldb][AArch64] Fix arm64 hardware breakpoint/watchpoint to arm32 process. ↵b10902118
(#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: https://github.com/torvalds/linux/commit/5d220ff9420f8b1689805ba2d938bedf9e0860a4 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-28[lldb] support ieee_single and ieee_double gdbtypes for registers (#150268)satyanarayana reddy janga
Some gdb remote servers send target.xml that contains ``` <reg name='ft0' bitsize='32' type='ieee_single' dwarf_regnum='32'/> <reg name='ft1' bitsize='32' type='ieee_single' dwarf_regnum='33'/> <reg name='ft2' bitsize='32' type='ieee_single' dwarf_regnum='34'/> <reg name='ft3' bitsize='32' type='ieee_single' dwarf_regnum='35'/> <reg name='ft4' bitsize='32' type='ieee_single' dwarf_regnum='36'/> <reg name='ft5' bitsize='32' type='ieee_single' dwarf_regnum='37'/> <reg name='ft6' bitsize='32' type='ieee_single' dwarf_regnum='38'/> <reg name='ft7' bitsize='32' type='ieee_single' dwarf_regnum='39'/> ``` it seems like a valid and supported type in gdb. from gdb16.3/gdb/target_descriptions.c (could not find a way to link it). ``` case TDESC_TYPE_IEEE_SINGLE: m_type = init_float_type (alloc, -1, "builtin_type_ieee_single", floatformats_ieee_single); return; case TDESC_TYPE_IEEE_DOUBLE: m_type = init_float_type (alloc, -1, "builtin_type_ieee_double", floatformats_ieee_double); return; ``` ### Testplan updated unittest to test this. Reviewers: @clayborg , @jeffreytan81 , @Jlalond
2025-07-28[lldb][AArch64][Linux] Show MTE store only setting in mte_ctrl (#145033)David Spickett
This controls whether tag checking is performed for loads and stores, or stores only. It requires a specific architecture feature which we detect with a HWCAP3 and cpuinfo feature. Live process tests look for this and adjust expectations accordingly, core file tests are using an updated file with this feature enabled. The size of the core file has increased and there's nothing I can do about that. Could be the presence of new architecure features or kernel changes since I last generated them. I can generate a smaller file that has the tag segment, but that segment does not actually contain tag data. So that's no use.
2025-07-28[lldb][AArch64] Add HWCAP3 to register field detection (#145029)David Spickett
This will be used to detect the presence of Arm's new Memory Tagging store only checking feature. This commit just adds the plumbing to get that value into the detection function. FreeBSD has not allocated a number for HWCAP3 and already has AT_ARGV defined as 29. So instead of attempting to read from FreeBSD processes, I've explicitly passed 0. We don't want to be reading some other entry accidentally. If/when FreeBSD adds HWCAP3 we can handle it like we do for AUXV_FREEBSD_AT_HWCAP. No extra tests here, those will be coming with the next change for MTE support.
2025-07-28[lldb][NFC] Use IterationAction for ModuleList::ForEach callbacks (#150930)Michael Buch
2025-07-28[lldb][Arm32] Remove unused watchpoint refcount. (#150770)b10902118
Already removed in NativeRegisterContextDBReg.h
2025-07-17[LLDB] Process minidump better error messages (#149206)Jacob Lalonde
Prior, Process Minidump would return ``` Status::FromErrorString("could not parse memory info"); ``` For any unsuccessful memory read, with no differentiation between an error in LLDB and the data simply not being present. This lead to a lot of user confusion and overall pretty terrible user experience. To fix this I've refactored the APIs so we can pass an error back in an llvm expected. There were also no shell tests for memory read and process Minidump so I added one.
2025-07-02[lldb][NFC][MachO] Clean up LC_THREAD reading code, remove i386 corefile ↵Jason Molenda
(#146480) While fixing bugs in the x86_64 LC_THREAD parser in ObjectFileMachO, I noticed that the other LC_THREAD parsers are all less clear than they should be. To recap, a Mach-O LC_THREAD load command has a byte size for the entire payload. Within the payload, there will be one or more register sets provided. A register set starts with a UInt32 "flavor", the type of register set defined in the system headers, and a UInt32 "count", the number of UInt32 words of memory for this register set. After one register set, there may be additional sets. A parser can skip an unknown register set flavor by using the count field to get to the next register set. When the total byte size of the LC_THREAD load command has been parsed, it is completed. This patch fixes the riscv/arm/arm64 LC_THREAD parsers to use the total byte size as the exit condition, and to skip past unrecognized register sets, instead of stopping parsing. Instead of fixing the i386 corefile support, I removed it. The last macOS that supported 32-bit Intel code was macOS 10.14 in 2018. I also removed i386 KDP support, 32-bit intel kernel debugging hasn't been supported for even longer than that. It would be preferable to do these things separately, but I couldn't bring myself to update the i386 LC_THREAD parser, and it required very few changes to remove this support entirely.
2025-06-30[lldb][Mach-O] Fix several bugs in x86_64 Mach-O corefile (#146460)Jason Molenda
reading, and one bug in the new RegisterContextUnifiedCore class. The PR I landed a few days ago to allow Mach-O corefiles to augment their registers with additional per-thread registers in metadata exposed a few bugs in the x86_64 corefile reader when running under different CI environments. It also showed a bug in my RegisterContextUnifiedCore class where I wasn't properly handling lookups of unknown registers (e.g. the LLDB_GENERIC_RA when debugging an intel target). The Mach-O x86_64 corefile support would say that it had fpu & exc registers available in every corefile, regardless of whether they were actually present. It would only read the bytes for the first register flavor in the LC_THREAD, the GPRs, but it read them incorrectly, so sometimes you got more register context than you'd expect. The LC_THREAD register context specifies a flavor and the number of uint32_t words; the ObjectFileMachO method would read that number of uint64_t's, exceeding the GPR register space, but it was followed by FPU and then EXC register space so it didn't crash. If you had a corefile with GPR and EXC register bytes, it would be written into the GPR and then FPU register areas, with zeroes filling out the rest of the context.
2025-06-30[lldb][RISCV] fix LR/SC atomic sequence handling in lldb-server (#146072)dlav-sc
lldb-server had limited support for single-stepping through the lr/sc atomic sequence. This patch enhances that support for all possible atomic sequences. The previous version contained an incorrect regex pattern in the test, causing the riscv-specific test to run on other platforms. This reland fixes the regex (see lldb/test/API/riscv/step/TestSoftwareStep.py)
2025-06-27[lldb][Mach-O] Allow "process metadata" LC_NOTE to supply registers (#144627)Jason Molenda
The "process metadata" LC_NOTE allows for thread IDs to be specified in a Mach-O corefile. This extends the JSON recognzied in that LC_NOTE to allow for additional registers to be supplied on a per-thread basis. The registers included in a Mach-O corefile LC_THREAD load command can only be one of the register flavors that the kernel (xnu) defines in <mach/arm/thread_status.h> for arm64 -- the general purpose registers, floating point registers, exception registers. JTAG style corefile producers may have access to many additional registers beyond these that EL0 programs typically use, for instance TCR_EL1 on AArch64, and people developing low level code need access to these registers. This patch defines a format for including these registers for any thread. The JSON in "process metadata" is a dictionary that must have a `threads` key. The value is an array of entries, one per LC_THREAD in the Mach-O corefile. The number of entries must match the LC_THREADs so they can be correctly associated. Each thread's dictionary must have two keys, `sets`, and `registers`. `sets` is an array of register set names. If a register set name matches one from the LC_THREAD core registers, any registers that are defined will be added to that register set. e.g. metadata can add a register to the "General Purpose Registers" set that lldb shows users. `registers` is an array of dictionaries, one per register. Each register must have the keys `name`, `value`, `bitsize`, and `set`. It may provide additional keys like `alt-name`, that `DynamicRegisterInfo::SetRegisterInfo` recognizes. This `sets` + `registers` formatting is the same that is used by the `target.process.python-os-plugin-path` script interface uses, both are parsed by `DynamicRegisterInfo`. The one addition is that in this LC_NOTE metadata, each register must also have a `value` field, with the value provided in big-endian base 10, as usual with JSON. In RegisterContextUnifiedCore, I combine the register sets & registers from the LC_THREAD for a specific thread, and the metadata sets & registers for that thread from the LC_NOTE. Even if no LC_NOTE is present, this class ingests the LC_THREAD register contexts and reformats it to its internal stores before returning itself as the RegisterContex, instead of shortcutting and returning the core's native RegisterContext. I could have gone either way with that, but in the end I decided if the code is correct, we should live on it always. I added a test where we process save-core to create a userland corefile, then use a utility "add-lcnote" to strip the existing "process metadata" LC_NOTE that lldb put in it, and adds a new one from a JSON string. rdar://74358787 --------- Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-06-27[lldb] Extract debug server location code (#145706)Pavel Labath
.. from the guts of GDBRemoteCommunication to ~top level. This is motivated by #131519 and by the fact that's impossible to guess whether the author of a symlink intended it to be a "convenience shortcut" -- meaning it should be resolved before looking for related files; or an "implementation detail" -- meaning the related files should be located near the symlink itself. This debate is particularly ridiculous when it comes to lldb-server running in platform mode, because it also functions as a debug server, so what we really just need to do is to pass /proc/self/exe in a platform-independent manner. Moving the location logic higher up achieves that as lldb-platform (on non-macos) can pass `HostInfo::GetProgramFileSpec`, while liblldb can use the existing complex logic (which only worked on liblldb anyway as lldb-platform doesn't have a lldb_private::Platform instance). Another benefit of this patch is a reduction in dependency from GDBRemoteCommunication to the rest of liblldb (achieved by avoiding the Platform dependency).
2025-06-26[lldb] Remove child_process_inherit argument from Pipe (#145516)Pavel Labath
It's not necessary on posix platforms as of #126935 and it's ignored on windows as of #138896. For both platforms, we have a better way of inheriting FDs/HANDLEs.