aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ScriptInterpreter/Python
AgeCommit message (Collapse)AuthorFilesLines
2025-09-04[lldb] Introduce ScriptedFrame affordance (#149622)Med Ismail Bennani9-1/+249
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-08-14[lldb] Use (only) PyImport_AppendInittab to patch readline (#153329)Jonas Devlieghere1-11/+1
The current implementation tries to (1) patch the existing readline module definition if it's already present in the inittab and (2) append our patched readline module to the inittab. The former (1) uses the non-stable Python API and I can't find a situation where this is necessary. We do this work before initialization, so for the readline module to exist, it either needs to be added by Python itself (which doesn't seem to be the case), or someone would have had to have added it without initializing.
2025-08-14[lldb] Use PyThread_get_thread_ident instead of accessing PyThreadState ↵Jonas Devlieghere1-2/+2
(#153460) Use `PyThread_get_thread_ident`, which is part of the Stable API, instead of accessing a member of the PyThreadState, which is opaque when using the Stable API.
2025-08-08[lldb] Support the Python stable C API in PythonString::AsUTF8 (#152599)Jonas Devlieghere1-5/+23
This conditionally reimplements PythonString::AsUTF8 using PyUnicode_AsUTF8String instead of PyUnicode_AsUTF8AndSize. PyUnicode_AsUTF8AndSize caches the UTF-8 representation of the string in the Unicode object, which makes it more efficient and ties the lifetime of the data to the Python string. However, it was only added to the Stable API in Python 3.10. Older versions that want to use the Stable API must use PyUnicode_AsUTF8String in combination with ConstString.
2025-08-08[lldb] Only use PyConfig when LLDB_EMBED_PYTHON_HOME is enabled (#152588)Jonas Devlieghere1-19/+21
PyConfig and friends are not part of the stable API. We could switch back to Py_SetPythonHome, which has been deprecated, but still part of the stable API. For now, limit the use of PyConfig to when LLDB_EMBED_PYTHON_HOME is enabled, which essentially means Windows. Changing the order doesn't seem to matter.
2025-08-06[lldb] Eliminate (_)Py_IsFinalizing (NFC) (#152226)Jonas Devlieghere1-16/+3
Looking at the implementation of `pylifecycle.c` in cpython, finalizing and initialized are set at the same time. Therefore we can eliminate the call to `Py_IsFinalizing` and only check `Py_IsInitialized`, which is part of the stable API. I converted the check to an assert and confirmed that during my test suite runs, we never got into the if block. Because we check before taking the lock, there is an opportunity for a race, but that exact same race exists with the original code.
2025-08-05[lldb] Workaround omission of PyBUF_READ in the stable API (#152214)Jonas Devlieghere1-0/+6
PyMemoryView_FromMemory is part of stable ABI but the flag constants such as PyBUF_READ are not. This was fixed in Python 3.11 [1], but still requires this workaround when using older versions. [1] https://github.com/python/cpython/issues/98680
2025-08-05[lldb] Drop PY_MINOR_VERSION >= 3 check (NFC)Jonas Devlieghere1-6/+1
The minimum supported Python version is now 3.8, so there's no supported configuration where the minor version is less than 3.
2025-08-05[lldb] Use Python Bytes instead of Buffer for Binary I/O (NFC) (#152031)Jonas Devlieghere1-40/+6
Binary I/O (also called buffered I/O) expects bytes-like objects and produces bytes objects [1]. Switch from using a Python buffer to using Python bytes to read the data. This eliminates calls to functions that aren't part of the Python stable C API. [1] https://docs.python.org/3/library/io.html#binary-i-o
2025-08-05[lldb] Reimplement PythonObject::Dump using the limited API (#152055)Jonas Devlieghere1-17/+25
This reimplements `PythonObject::Dump` using functions that are part of the limited API, instead of using `PyObject_Print`, which is not.
2025-08-05[lldb] Add a CMake option to build agains the Python limited API (#152034)Jonas Devlieghere1-1/+9
This adds a CMake option (which defaults to OFF) to force building against the Python limited API. This makes iterating on #151617 easier and eventually will prevent us from regressing this configuration.
2025-08-04[lldb] Eliminate PyGILState_Check (NFC) (#152006)Jonas Devlieghere2-3/+3
Eliminate calls to PyGILState_Check, which is not part of the Python Limited C API. In the Locker, we can use PyGILState_Ensure directly. We could do something similar to replace the assert, but I don't think it's worth it. We don't assert that we hold the GIL anywhere else.
2025-08-04[lldb] Simplify Python Locker log messages (NFC)Jonas Devlieghere1-11/+10
Eliminate the `log` variable by inlining the GetLog call and use "locked" and "unlocked" directly, as requested by Ismail in #151780.
2025-08-04[lldb] Use fully qualified name instead of namespace (NFC)Jonas Devlieghere1-8/+3
In #151761, both Alex and Pavel prefer to use a fully qualified name instead of opening a namespace. This PR addresses that post-commit feedback.
2025-08-04[lldb] Eliminate InitializePythonRAII::InitializeThreadsPrivate (NFC) (#151780)Jonas Devlieghere1-41/+10
The behavior of thread initialization changed in Python 3.7. The minimum supported Python version is now 3.8. That means that `PyEval_ThreadsInitialized` always returns true and `PyEval_InitThreads` is never called. The helper function existed to coordinate initializing the threads and acquiring the GIL, which is no longer necessary. With that, there's no point in having the helper at all. This PR eliminates the function and inlines to GIL acquisition into the caller.
2025-08-01[lldb] Remove unused PythonObject::Dump (NFC) (#151783)Jonas Devlieghere1-7/+0
PythonObject::Dump isn't called and uses `_PyObject_Dump`, which isn't part of the stable API. Part of https://github.com/llvm/llvm-project/issues/151617.
2025-08-01[lldb] Reimplment PyRun_SimpleString using the Python stable C API (#151777)Jonas Devlieghere4-25/+42
Reimplment `PyRun_SimpleString` using the Python stable C API and the `RunString` helper. Part of https://github.com/llvm/llvm-project/issues/151617
2025-08-01[lldb] Reimplment PyRun_String using the Python stable C API (#151761)Jonas Devlieghere2-13/+35
Reimplement `PyRun_String` using `Py_CompileString` and` PyEval_EvalCode`, which are part of the stable C API. Part of #151617
2025-08-01[lldb] Replace Python APIs with their stable equivalent (#151618)Jonas Devlieghere1-3/+3
2025-07-28Switch the ScriptedBreakpointResolver over to the ScriptedInterface form ↵jimingham10-89/+194
(#150720) This is NFC, I'm modernizing the interface before I add to it in a subsequent commit.
2025-07-25[lldb] Use std::make_shared where possible (NFC) (#150714)Jonas Devlieghere1-2/+2
This is a continuation of 68fd102, which did the same thing but only for StopInfo. Using make_shared is both safer and more efficient: - With make_shared, the object and the control block are allocated together, which is more efficient. - With make_shared, the enable_shared_from_this base class is properly linked to the control block before the constructor finishes, so shared_from_this() will be safe to use (though still not recommended during construction).
2025-06-04[lldb/cmake] Implicitly pass arguments to llvm_add_library (#142583)Pavel Labath2-6/+4
If we're not touching them, we don't need to do anything special to pass them along -- with one important caveat: due to how cmake arguments work, the implicitly passed arguments need to be specified before arguments that we handle. This isn't particularly nice, but the alternative is enumerating all arguments that can be used by llvm_add_library and the macros it calls (it also relies on implicit passing of some arguments to llvm_process_sources).
2025-05-22[lldb] Remove redundant control flow statements (NFC) (#141183)Kazu Hirata1-1/+0
2025-05-04[lldb] Remove unused local variables (NFC) (#138457)Kazu Hirata1-8/+0
2025-04-30[lldb] Upgrade `GetIndexOfChildWithName` to use `llvm::Expected` (#136693)Charles Zablit2-7/+10
This patch replaces the use of `UINT32_MAX` as the error return value of `GetIndexOfChildWithName` with `llvm::Expected`. # Tasks to do in another PR 1. Replace `CalculateNumChildrenIgnoringErrors` with `CalculateNumChildren`. See [this comment](https://github.com/llvm/llvm-project/pull/136693#discussion_r2056319358). 2. Update `lldb_private::formatters::ExtractIndexFromString` to use `llvm::Expected`. See [this comment](https://github.com/llvm/llvm-project/pull/136693#discussion_r2054217536). 3. Create a new class which carries both user and internal errors. See [this comment](https://github.com/llvm/llvm-project/pull/136693#discussion_r2056439608).
2025-04-18[lldb] Fix Python GIL-not-held issue in CreateStructuredDataFromScriptObject ↵Vladislav Dzhidzhoev1-1/+1
(#136309) TestStructuredDataAPI.py fails with Python debug build ver. 3.12+ due to call to Py_XINCREF while GIL is not held.
2025-04-01Add a new affordance that the Python module in a dSYM (#133290)jimingham3-2/+14
So the dSYM can be told what target it has been loaded into. When lldb is loading modules, while creating a target, it will run "command script import" on any Python modules in Resources/Python in the dSYM. However, this happens WHILE the target is being created, so it is not yet in the target list. That means that these scripts can't act on the target that they a part of when they get loaded. This patch adds a new python API that lldb will call: __lldb_module_added_to_target if it is defined in the module, passing in the Target the module was being added to, so that code in these dSYM's don't have to guess.
2025-03-25Fix the managing of the session dictionary when you have nested wrappers ↵jimingham1-5/+9
(#132846) Since the inner wrapper call might have removed one of the entries from the global dict that the outer wrapper ALSO was going to delete, make sure that we check that the key is still in the global dict before trying to act on it.
2025-02-19[lldb] Fix header include order in ScriptInterpreterPython.cppJonas Devlieghere1-4/+3
Should fix the following compile error on Windows: C:\Python312\include\pyconfig.h(225): error C2371: 'pid_t': redefinition; different basic types C:\buildbot\as-builder-10\lldb-x-aarch64\llvm-project\lldb\include\lldb/Host/windows/PosixApi.h(80): note: see declaration of 'pid_t'
2025-02-19[lldb] Synchronize the debuggers output & error streamsJonas Devlieghere1-16/+19
This patch improves the synchronization of the debugger's output and error streams using two new abstractions: `LockableStreamFile` and `LockedStreamFile`. - `LockableStreamFile` is a wrapper around a `StreamFile` and a mutex. Client cannot use the `StreamFile` without calling `Lock`, which returns a `LockedStreamFile`. - `LockedStreamFile` is an RAII object that locks the stream for the duration of its existence. As long as you hold on to the returned object you are permitted to write to the stream. The destruction of the object automatically flush the output stream.
2025-02-12[lldb] Remove Debugger::Get{Output,Error}Stream (NFC) (#126821)Jonas Devlieghere1-2/+2
Remove Debugger::GetOutputStream and Debugger::GetErrorStream in preparation for replacing both with a new variant that needs to be locked and hence can't be handed out like we do right now. The patch replaces most uses with GetAsyncOutputStream and GetAsyncErrorStream respectively. There methods return new StreamSP objects that automatically get flushed on destruction. See #126630 for more details.
2025-02-04[lldb] Support CommandInterpreter print callbacks (#125006)Jonas Devlieghere1-6/+7
Xcode uses a pseudoterminal for the debugger console. - The upside of this apporach is that it means that it can rely on LLDB's IOHandlers for multiline and script input. - The downside of this approach is that the command output is printed to the PTY and you don't get a SBCommandReturnObject. Adrian added support for inline diagnostics (#110901) and we'd like to access those from the IDE. This patch adds support for registering a callback in the command interpreter that gives access to the `(SB)CommandReturnObject` right before it will be printed. The callback implementation can choose whether it likes to handle printing the result or defer to lldb. If the callback indicated it handled the result, the command interpreter will skip printing the result. We considered a few other alternatives to solve this problem: - The most obvious one is using `HandleCommand`, which returns a `SBCommandReturnObject`. The problem with this approach is the multiline input mentioned above. We would need a way to tell the IDE that it should expect multiline input, which isn't known until LLDB starts handling the command. - To address the multiline issue,we considered exposing (some of the) IOHandler machinery through the SB API. To solve this particular issue, that would require reimplementing a ton of logic that already exists today in the CommandInterpeter. Furthermore that seems like overkill compared to the proposed solution. rdar://141254310
2025-01-29[lldb][NFC] Format part of ScriptInterpreterPython.cppDavid Spickett1-6/+8
Was flagged in https://github.com/llvm/llvm-project/pull/124735 but done separately so it didn't get in the way of that.
2025-01-29[lldb] Make Python >= 3.8 required for LLDB 21 (#124735)David Spickett3-86/+4
As decided on https://discourse.llvm.org/t/rfc-lets-document-and-enforce-a-minimum-python-version-for-lldb/82731. LLDB 20 recommended `>= 3.8` but did not remove support for anything earlier. Now we are in what will become LLDB 21, so I'm removing that support and making `>= 3.8` required. See https://docs.python.org/3/c-api/apiabiversion.html#c.PY_VERSION_HEX for the format of PY_VERSION_HEX.
2025-01-16[lldb] Add OS plugin property for reporting all threads (#123145)Felipe de Azevedo Piovezan2-0/+12
Currently, an LLDB target option controls whether plugins report all threads. However, it seems natural for this knowledge could come from the plugin itself. To support this, this commits adds a virtual method to the plugin base class, making the Python OS query the target option to preserve existing behavior.
2025-01-06[lldb][ResolveSourceFileCallback] Update SBModule (#120832)rchamala1-0/+1
Summary: RFC https://discourse.llvm.org/t/rfc-python-callback-for-source-file-resolution/83545 SBModule will be used for resolve source file callback as Python function arguments. This diff allows these things. Can be instantiated from SBPlatform. Can be passed to/from Python. Test Plan: N/A. The next set of diffs in the stack have unittests and shell test validation Co-authored-by: Rahul Reddy Chamala <rachamal@fb.com>
2024-10-31[lldb] Use PY_VERSION_HEX to simplify conditional compilation (NFC) (#114346)Jonas Devlieghere3-15/+19
Use PY_VERSION_HEX to simplify conditional compilation depending on the Python version. This also adds a static_assert to lldb-python to error out with a meaningful diagnostic when you try building LLDB with an older Python version in preparation for [1]. [1] https://discourse.llvm.org/t/rfc-lets-document-and-enforce-a-minimum-python-version-for-lldb/82731/15
2024-10-30[lldb] Fix formatting and whitespace in ScriptInterpreterPython (NFC)Jonas Devlieghere1-40/+35
2024-10-30[lldb] Use Py_InitializeFromConfig with Python >= 3.8 (NFC) (#114112)Jonas Devlieghere1-28/+35
This fixes the deprecation warning for Py_SetPythonHome, which was deprecated in Python 3.11. With this patch, when building against Python 3.8 or later, we now use Py_InitializeFromConfig instead. Fixes #113475
2024-10-30Revert "[lldb] Use Py_InitializeFromConfig with Python >= 3.8 (NFC)" (#114290)Jonas Devlieghere1-40/+28
Reverts llvm/llvm-project#114112 because this triggers a compile error: ``` no known conversion from 'str_type' (aka 'wchar_t *') to 'const char *' for 3rd argument 221 | PyAPI_FUNC(PyStatus) PyConfig_SetBytesString( | ^ 222 | PyConfig *config, 223 | wchar_t **config_str, 224 | const char *str); | ~~~~~~~~~~~~~~~ 1 error generated. ```
2024-10-30[lldb] Use Py_InitializeFromConfig with Python >= 3.8 (NFC) (#114112)Jonas Devlieghere1-28/+40
This fixes the deprecation warning for Py_SetPythonHome, which was deprecated in Python 3.11. With this patch, when building against Python 3.8 or later, we now use Py_InitializeFromConfig instead. Fixes #113475
2024-10-24[lldb] Move ValueObject into its own library (NFC) (#113393)Jonas Devlieghere2-1/+2
ValueObject is part of lldbCore for historical reasons, but conceptually it deserves to be its own library. This does introduce a (link-time) circular dependency between lldbCore and lldbValueObject, which is unfortunate but probably unavoidable because so many things in LLDB rely on ValueObject. We already have cycles and these libraries are never built as dylibs so while this doesn't improve the situation, it also doesn't make things worse. The header includes were updated with the following command: ``` find . -type f -exec sed -i.bak "s%include \"lldb/Core/ValueObject%include \"lldb/ValueObject/ValueObject%" '{}' \; ```
2024-09-24Add the ability to define custom completers to the parsed_cmd template. ↵jimingham3-0/+57
(#109062) If your arguments or option values are of a type that naturally uses one of our common completion mechanisms, you will get completion for free. But if you have your own custom values or if you want to do fancy things like have `break set -s foo.dylib -n ba<TAB>` only complete on symbols in foo.dylib, you can use this new mechanism to achieve that.
2024-09-23[lldb] Change the implementation of Status to store an llvm::Error (NFC) ↵Adrian Prantl1-10/+19
(#106774) (based on a conversation I had with @labath yesterday in https://github.com/llvm/llvm-project/pull/106442) Most APIs that currently vend a Status would be better served by returning llvm::Expected<> instead. If possibles APIs should be refactored to avoid Status. The only legitimate long-term uses of Status are objects that need to store an error for a long time (which should be questioned as a design decision, too). This patch makes the transition to llvm::Error easier by making the places that cannot switch to llvm::Error explicit: They are marked with a call to Status::clone(). Every other API can and should be refactored to use llvm::Expected. In the end Status should only be used in very few places. Whenever an unchecked Error is dropped by Status it logs this to the verbose API channel. Implementation notes: This patch introduces two new kinds of error_category as well as new llvm::Error types. Here is the mapping of lldb::ErrorType to llvm::Errors: ``` (eErrorTypeInvalid) eErrorTypeGeneric llvm::StringError eErrorTypePOSIX llvm::ECError eErrorTypeMachKernel MachKernelError eErrorTypeExpression llvm::ErrorList<ExpressionError> eErrorTypeWin32 Win32Error ``` Relanding with built-in cloning support for llvm::ECError, and support for initializing a Windows error with a NO_ERROR error code, and modifying TestGDBRemotePlatformFile.py to support different renderings of ENOSYS.
2024-09-23Revert "[lldb] Change the implementation of Status to store an llvm::Error ↵Adrian Prantl1-19/+10
(NFC) (#106774)" This reverts commit 40d8888f13fb54b0fe840deef23054de6544c184. One last Windows failure remaining.
2024-09-23[lldb] Change the implementation of Status to store an llvm::Error (NFC) ↵Adrian Prantl1-10/+19
(#106774) (based on a conversation I had with @labath yesterday in https://github.com/llvm/llvm-project/pull/106442) Most APIs that currently vend a Status would be better served by returning llvm::Expected<> instead. If possibles APIs should be refactored to avoid Status. The only legitimate long-term uses of Status are objects that need to store an error for a long time (which should be questioned as a design decision, too). This patch makes the transition to llvm::Error easier by making the places that cannot switch to llvm::Error explicit: They are marked with a call to Status::clone(). Every other API can and should be refactored to use llvm::Expected. In the end Status should only be used in very few places. Whenever an unchecked Error is dropped by Status it logs this to the verbose API channel. Implementation notes: This patch introduces two new kinds of error_category as well as new llvm::Error types. Here is the mapping of lldb::ErrorType to llvm::Errors: ``` (eErrorTypeInvalid) eErrorTypeGeneric llvm::StringError eErrorTypePOSIX llvm::ECError eErrorTypeMachKernel MachKernelError eErrorTypeExpression llvm::ErrorList<ExpressionError> eErrorTypeWin32 Win32Error ``` Relanding with built-in cloning support for llvm::ECError, and support for initializing a Windows error with a NO_ERROR error code.
2024-09-20Revert "[lldb] Change the implementation of Status to store an llvm::Error ↵Adrian Prantl1-19/+10
(NFC) (#106774)" This reverts commit b44da2446b17aaa847bf76f81a01870917f8736b.
2024-09-20[lldb] Change the implementation of Status to store an llvm::Error (NFC) ↵Adrian Prantl1-10/+19
(#106774) (based on a conversation I had with @labath yesterday in https://github.com/llvm/llvm-project/pull/106442) Most APIs that currently vend a Status would be better served by returning llvm::Expected<> instead. If possibles APIs should be refactored to avoid Status. The only legitimate long-term uses of Status are objects that need to store an error for a long time (which should be questioned as a design decision, too). This patch makes the transition to llvm::Error easier by making the places that cannot switch to llvm::Error explicit: They are marked with a call to Status::clone(). Every other API can and should be refactored to use llvm::Expected. In the end Status should only be used in very few places. Whenever an unchecked Error is dropped by Status it logs this to the verbose API channel. Implementation notes: This patch introduces two new kinds of error_category as well as new llvm::Error types. Here is the mapping of lldb::ErrorType to llvm::Errors: ``` (eErrorTypeInvalid) eErrorTypeGeneric llvm::StringError eErrorTypePOSIX llvm::ECError eErrorTypeMachKernel MachKernelError eErrorTypeExpression llvm::ErrorList<ExpressionError> eErrorTypeWin32 Win32Error ``` Relanding with built-in cloning support for llvm::ECError, and support for initializing a Windows error with a NO_ERROR error code.
2024-09-20[lldb/Interpreter] Introduce ScriptedStopHook{,Python}Interface & make use ↵Med Ismail Bennani10-77/+196
of it (#109498) This patch re-lands #105449 and fixes the various test failures. --------- Signed-off-by: Med Ismail Bennani <ismail@bennani.ma>
2024-09-20Revert "[lldb] Change the implementation of Status to store an llvm::Error ↵David Spickett1-19/+10
(NFC) (#106774)" This reverts commit 104b249c236578d298384416c495ff7310b97f4d because it has caused 2 test failures on Windows: https://lab.llvm.org/buildbot/#/builders/141/builds/2544 Failed Tests (2): lldb-api :: functionalities/gdb_remote_client/TestGDBRemotePlatformFile.py lldb-unit :: Utility/./UtilityTests.exe/StatusTest/ErrorWin32 I reckon the cause is the same, that we construct an error with the Win32 NO_ERROR value which means there was no error but we're assuming anything with an error code is a failure.