summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
AgeCommit message (Collapse)Author
2023-05-10[lldb] Mark most SBAPI methods involving private types as protected or privateAlex Langford
Many SB classes have public constructors or methods involving types that are private. Some are more obvious (e.g. containing lldb_private in the name) than others (lldb::FooSP is usually std::shared_pointer<lldb_private::Foo>). This commit explicitly does not address FileSP, so I'm leaving that one alone for now. Some of these were for other SB classes to use and should have been made protected/private with a friend class entry added. Some of these were public for some of the swig python helpers to use. I put all of those functions into a class and made them static methods. The relevant SB classes mark that class as a friend so they can access those private/protected members. I've also removed an outdated SBStructuredData test (can you guess which constructor it was using?) and updated the other relevant tests. Differential Revision: https://reviews.llvm.org/D150157
2023-05-03Allow scripted thread plans to modify the thread stop description whenJim Ingham
they are completed.
2023-04-26[lldb] Change return type of FileSpec::GetFileNameExtensionAlex Langford
These don't really need to be in ConstStrings. It's nice that comparing ConstStrings is fast (just a pointer comparison) but the cost of creating the ConstString usually already includes the cost of doing a StringRef comparison anyway, so this is just extra work and extra memory consumption for basically no benefit. Differential Revision: https://reviews.llvm.org/D149300
2023-02-28[lldb] Remove const qualifier on bool argument passed by valueMed Ismail Bennani
Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
2023-02-28[lldb] Fix {break,watch}point command function stopping behaviourMed Ismail Bennani
In order to run a {break,watch}point command, lldb can resolve to the script interpreter to run an arbitrary piece of code or call into a user-provided function. To do so, we will generate a wrapping function, where we first copy lldb's internal dictionary keys into the interpreter's global dictionary, copied inline the user code before resetting the global dictionary to its previous state. However, {break,watch}point commands can optionally return a value that would tell lldb whether we should stop or not. This feature was only implemented for breakpoint commands and since we inlined the user code directly into the wrapping function, introducing an early return, that caused lldb to let the interpreter global dictionary tinted with the internal dictionary keys. This patch fixes that issue while also adding the stopping behaviour to watchpoint commands. To do so, this patch refactors the {break,watch}point command creation method, to let the lldb wrapper function generator know if the user code is a function call or a arbitrary expression. Then the wrapper generator, if the user input was a function call, the wrapper function will call the user function and save the return value into a variable. If the user input was an arbitrary expression, the wrapper will inline it into a nested function, call the nested function and save the return value into the same variable. After resetting the interpreter global dictionary to its previous state, the generated wrapper function will return the varible containing the return value. rdar://105461140 Differential Revision: https://reviews.llvm.org/D144688 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
2023-02-15[lldb] Remove pydoc import during script interpreter initDave Lee
The Python script interpreter imports `pydoc` during initialization, but this can be slow in some cases, and doesn't seem to be necessary any more. This can be slow because pydoc may execute shell commands (for example `xcrun` on macOS). The shell commands may have variable performance, depending on their caches and search space. The 2012 bug report for the original commit (f71a8399997bfdc1ddeeb30c6a8897554a11c382) says the following: > "script help" in lldb pipes the help documentation through less(1) but there's some > problem with the key handling and often the keys you'd use to move in less (space to > move down a page, 'q' to quit) are not received by less (they're going to lldb > instead) This was resolved at the time by overriding `pydoc`'s pager to be the `plainpager` function. I have manually tested `script help(lldb.SBDebugger)` and found no issues with the pager, including using "space" for paging, "/" for searching, and "q" for quitting. The presumption is that lldb and/or Python have improved I/O handling that eliminates the original problem. The original bug report gave an ~/.lldbinit workaround: ``` script import pydoc; pydoc.pager = pydoc.plainpager ``` Note that calling Python's `help()` will import `pydoc`, but this will only happen for users who use `help()` from the `script` command. Differential Revision: https://reviews.llvm.org/D144138
2023-02-14Report a useful error when someone passes an incorrect python class name.Jim Ingham
2023-02-06[lldb/Plugins] Fix method dispatch bug when using multiple scripted processesMed Ismail Bennani
This patch should address a bug when a user have multiple scripted processes in the same debugging session. In order for the scripted process plugin to be able to call into the scripted object instance methods to fetch the necessary data to reconstruct its state, the scripted process plugin calls into a scripted process interface, that has a reference to the created script object instance. However, prior to this patch, we only had a single instance of the scripted process interface, living the script interpreter. So every time a new scripted process plugin was created, it would overwrite the script object instance that was held by the single scripted process interface in the script interpreter. That would cause all the method calls made to the scripted process interface to be dispatched by the last instanciated script object instance, which is wrong. In order to prevent that, this patch moves the scripted process interface reference to be help by the scripted process plugin itself. rdar://104882562 Differential Revision: https://reviews.llvm.org/D143308 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
2023-01-12[lldb/Interpreter] Introduce ScriptedPlatform{,Python}InterfaceMed Ismail Bennani
This patch introduces both the ScriptedPlatformInterface and the ScriptedPlatformPythonInterface. As the name suggests, these calls will be used to call into the Scripted Platform python implementation from the C++ Scripted Platform plugin instance. Differential Revision: https://reviews.llvm.org/D139251 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
2023-01-07[lldb] Use std::optional instead of llvm::Optional (NFC)Kazu Hirata
This patch replaces (llvm::|)Optional< with std::optional<. I'll post a separate patch to clean up the "using" declarations, #include "llvm/ADT/Optional.h", etc. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-07[lldb] Add #include <optional> (NFC)Kazu Hirata
This patch adds #include <optional> to those files containing llvm::Optional<...> or Optional<...>. I'll post a separate patch to actually replace llvm::Optional with std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-09Switch the "command script add" interactive input to use the new command form.Jim Ingham
We're suggesting people use the form of the command that takes an exe_ctx - it is both more convenient and more correct - since you should not be using GetSelected{Target, Process, etc.} in commands.
2022-11-18[lldb/Python] Make use of PythonObject and PythonFormat in callbacks (NFC)Med Ismail Bennani
This patch extends the template specialization of PythonFormat structs and makes use of the pre-existing PythonObject class to format arguments and pass them to the right method, before calling it. This is a preparatory patch to merge PythonFormat with SWIGPythonBridge's GetPythonValueFormatString methods. Differential Revision: https://reviews.llvm.org/D138248 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
2022-10-19[lldb] Add matching based on Python callbacks for data formatters.Jorge Gorbe Moya
This patch adds a new matching method for data formatters, in addition to the existing exact typename and regex-based matching. The new method allows users to specify the name of a Python callback function that takes a `SBType` object and decides whether the type is a match or not. Here is an overview of the changes performed: - Add a new `eFormatterMatchCallback` matching type, and logic to handle it in `TypeMatcher` and `SBTypeNameSpecifier`. - Extend `FormattersMatchCandidate` instances with a pointer to the current `ScriptInterpreter` and the `TypeImpl` corresponding to the candidate type, so we can run registered callbacks and pass the type to them. All matcher search functions now receive a `FormattersMatchCandidate` instead of a type name. - Add some glue code to ScriptInterpreterPython and the SWIG bindings to allow calling a formatter matching callback. Most of this code is modeled after the equivalent code for watchpoint callback functions. - Add an API test for the new callback-based matching feature. For more context, please check the RFC thread where this feature was originally discussed: https://discourse.llvm.org/t/rfc-python-callback-for-data-formatters-type-matching/64204/11 Differential Revision: https://reviews.llvm.org/D135648
2022-09-06[lldb] [Core] Split read thread support into ThreadedCommunicationMichał Górny
Split the read thread support from Communication into a dedicated ThreadedCommunication subclass. The read thread support is used only by a subset of Communication consumers, and it adds a lot of complexity to the base class. Furthermore, having a dedicated subclass makes it clear whether a particular consumer needs to account for the possibility of read thread being running or not. The modules currently calling `StartReadThread()` are updated to use `ThreadedCommunication`. The remaining modules use the simplified `Communication` class. `SBCommunication` is changed to use `ThreadedCommunication` in order to avoid changing the public API. `CommunicationKDP` is updated in order to (hopefully) compile with the new code. However, I do not have a Darwin box to test it, so I've limited the changes to the bare minimum. `GDBRemoteCommunication` is updated to become a `Broadcaster` directly. Since it does not inherit from `ThreadedCommunication`, its event support no longer collides with the one used for read thread and can be implemented cleanly. The support for `eBroadcastBitReadThreadDidExit` is removed from the code -- since the read thread was not used, this event was never reported. Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.llvm.org/D133251
2022-08-27[lldb] Use nullptr instead of NULL (NFC)Kazu Hirata
Identified with modernize-use-nullptr.
2022-08-27[lldb] Remove a redundaunt return statement (NFC)Kazu Hirata
Identified with readability-redundant-control-flow.
2022-08-11[lldb] Remove uses of six module (NFC)Dave Lee
With lldb (& llvm) requiring Python 3.6+, use of the `six` module can be removed. Differential Revision: https://reviews.llvm.org/D131304
2022-08-09[lldb/crashlog] Surface error using SBCommandReturnObject argumentMed Ismail Bennani
This patch allows the crashlog script to surface its errors to lldb by using the provided SBCommandReturnObject argument. rdar://95048193 Differential Revision: https://reviews.llvm.org/D129614 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
2022-07-28[NFC] Improve FileSpec internal APIs and usage in preparation for adding ↵Greg Clayton
caching of resolved/absolute. Resubmission of https://reviews.llvm.org/D130309 with the 2 patches that fixed the linux buildbot, and new windows fixes. The FileSpec APIs allow users to modify instance variables directly by getting a non const reference to the directory and filename instance variables. This makes it impossible to control all of the times the FileSpec object is modified so we can clear cached member variables like m_resolved and with an upcoming patch caching if the file is relative or absolute. This patch modifies the APIs of FileSpec so no one can modify the directory or filename instance variables directly by adding set accessors and by removing the get accessors that are non const. Many clients were using FileSpec::GetCString(...) which returned a unique C string from a ConstString'ified version of the result of GetPath() which returned a std::string. This caused many locations to use this convenient function incorrectly and could cause many strings to be added to the constant string pool that didn't need to. Most clients were converted to using FileSpec::GetPath().c_str() when possible. Other clients were modified to use the newly renamed version of this function which returns an actualy ConstString: ConstString FileSpec::GetPathAsConstString(bool denormalize = true) const; This avoids the issue where people were getting an already uniqued "const char *" that came from a ConstString only to put the "const char *" back into a "ConstString" object. By returning the ConstString instead of a "const char *" clients can be more efficient with the result. The patch: - Removes the non const GetDirectory() and GetFilename() get accessors - Adds set accessors to replace the above functions: SetDirectory() and SetFilename(). - Adds ClearDirectory() and ClearFilename() to replace usage of the FileSpec::GetDirectory().Clear()/FileSpec::GetFilename().Clear() call sites - Fixed all incorrect usage of FileSpec::GetCString() to use FileSpec::GetPath().c_str() where appropriate, and updated other call sites that wanted a ConstString to use the newly returned ConstString appropriately and efficiently. Differential Revision: https://reviews.llvm.org/D130549
2022-07-23Revert "[NFC] Improve FileSpec internal APIs and usage in preparation for ↵Nico Weber
adding caching of resolved/absolute." and follow-ups This reverts commit 9429b67b8e300e638d7828bbcb95585f85c4df4d. It broke the build on Windows, see comments on https://reviews.llvm.org/D130309 It also reverts these follow-ups: Revert "Fix buildbot breakage after https://reviews.llvm.org/D130309." This reverts commit f959d815f4637890ebbacca379f1c38ab47e4e14. Revert "Fix buildbot breakage after https://reviews.llvm.org/D130309." This reverts commit 0bbce7a4c2d2bff622bdadd4323f93f5d90e6d24. Revert "Cache the value for absolute path in FileSpec." This reverts commit dabe877248b85b34878e75d5510339325ee087d0.
2022-07-22Fix buildbot breakage after https://reviews.llvm.org/D130309.Greg Clayton
2022-07-22[NFC] Improve FileSpec internal APIs and usage in preparation for adding ↵Greg Clayton
caching of resolved/absolute. The FileSpect APIs allow users to modify instance variables directly by getting a non const reference to the directory and filename instance variables. This makes it impossibly to control all of the times the FileSpec object is modified so we can clear the cache. This patch modifies the APIs of FileSpec so no one can modify the directory or filename directly by adding set accessors and by removing the get accessors that are non const. Many clients were using FileSpec::GetCString(...) which returned a unique C string from a ConstString'ified version of the result of GetPath() which returned a std::string. This caused many locations to use this convenient function incorrectly and could cause many strings to be added to the constant string pool that didn't need to. Most clients were converted to using FileSpec::GetPath().c_str() when possible. Other clients were modified to use the newly renamed version of this function which returns an actualy ConstString: ConstString FileSpec::GetPathAsConstString(bool denormalize = true) const; This avoids the issue where people were getting an already uniqued "const char *" that came from a ConstString only to put the "const char *" back into a "ConstString" object. By returning the ConstString instead of a "const char *" clients can be more efficient with the result. The patch: - Removes the non const GetDirectory() and GetFilename() get accessors - Adds set accessors to replace the above functions: SetDirectory() and SetFilename(). - Adds ClearDirectory() and ClearFilename() to replace usage of the FileSpec::GetDirectory().Clear()/FileSpec::GetFilename().Clear() call sites - Fixed all incorrect usage of FileSpec::GetCString() to use FileSpec::GetPath().c_str() where appropriate, and updated other call sites that wanted a ConstString to use the newly returned ConstString appropriately and efficiently. Differential Revision: https://reviews.llvm.org/D130309
2022-07-18When the module path for `command script import` is invalid, echo the path.Jim Ingham
We were just emitting "invalid module" w/o saying which module. That's not particularly helpful. Differential Revision: https://reviews.llvm.org/D129338
2022-04-27Remove Python 2 support from the ScriptInterpreter pluginJonas Devlieghere
We dropped downstream support for Python 2 in the previous release. Now that we have branched for the next release the window where this kind of change could introduce conflicts is closing too. Start by getting rid of Python 2 support in the Script Interpreter plugin. Differential revision: https://reviews.llvm.org/D124429
2022-03-03[lldb] Remove FileSystem::Initialize from FileCollectorJonas Devlieghere
This patch removes the ability to instantiate the LLDB FileSystem class with a FileCollector. It keeps the ability to collect files, but uses the FileCollectorFileSystem to do that transparently. Because the two are intertwined, this patch also removes the finalization logic which copied the files over out of process.
2022-02-03[lldb] Rename Logging.h to LLDBLog.h and clean up includesPavel Labath
Most of our code was including Log.h even though that is not where the "lldb" log channel is defined (Log.h defines the generic logging infrastructure). This worked because Log.h included Logging.h, even though it should. After the recent refactor, it became impossible the two files include each other in this direction (the opposite inclusion is needed), so this patch removes the workaround that was put in place and cleans up all files to include the right thing. It also renames the file to LLDBLog to better reflect its purpose.
2022-02-02[lldb] Convert "LLDB" log channel to the new APIPavel Labath
2022-01-20[lldb] Decouple instrumentation from the reproducersJonas Devlieghere
Remove the last remaining references to the reproducers from the instrumentation. This patch renames the relevant files and macros. Differential revision: https://reviews.llvm.org/D117712
2022-01-19[lldb] Initialize Python exactly onceJonas Devlieghere
We got a few crash reports that showed LLDB initializing Python on two separate threads. Make sure Python is initialized exactly once. rdar://87287005 Differential revision: https://reviews.llvm.org/D117601
2022-01-18[lldb/python] Use PythonObject in LLDBSwigPython functionsPavel Labath
Return our PythonObject wrappers instead of raw PyObjects (obfuscated as void *). This ensures that ownership (reference counts) of python objects is automatically tracked. Differential Revision: https://reviews.llvm.org/D117462
2022-01-17[LLDB] Fix Python GIL-not-held issuesRalf Grosse-Kunstleve
The GIL must be held when calling any Python C API functions. In multithreaded applications that use callbacks this requirement can easily be violated by accident. A general tool to ensure GIL health is not available, but patching Python Py_INCREF to add an assert provides a basic health check: ``` +int PyGILState_Check(void); /* Include/internal/pystate.h */ + #define Py_INCREF(op) ( \ + assert(PyGILState_Check()), \ _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ ((PyObject *)(op))->ob_refcnt++) #define Py_DECREF(op) \ do { \ + assert(PyGILState_Check()); \ PyObject *_py_decref_tmp = (PyObject *)(op); \ if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ --(_py_decref_tmp)->ob_refcnt != 0) \ ``` Adding this assertion causes around 50 test failures in LLDB. Adjusting the scope of things guarded by `py_lock` fixes them. More background: https://docs.python.org/3/glossary.html#term-global-interpreter-lock Patch by Ralf Grosse-Kunstleve Differential Revision: https://reviews.llvm.org/D114722
2022-01-13[lldb] Fix that the embedded Python REPL crashes if it receives SIGINTJonas Devlieghere
When LLDB receives a SIGINT while running the embedded Python REPL it currently just crashes in ScriptInterpreterPythonImpl::Interrupt with an error such as the one below: Fatal Python error: PyThreadState_Get: the function must be called with the GIL held, but the GIL is released (the current Python thread state is NULL) The faulty code that causes this error is this part of ScriptInterpreterPythonImpl::Interrupt: PyThreadState *state = PyThreadState_GET(); if (!state) state = GetThreadState(); if (state) { long tid = state->thread_id; PyThreadState_Swap(state); int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); The obvious fix I tried is to just acquire the GIL before this code is running which fixes the crash but the KeyboardInterrupt we want to raise immediately is actually just queued and would only be raised once the next line of input has been parsed (which e.g. won't interrupt Python code that is currently waiting on a timer or IO from what I can see). Also none of the functions we call here is marked as safe to be called from a signal handler from what I can see, so we might still end up crashing here with some bad timing. Python 3.2 introduced PyErr_SetInterrupt to solve this and the function takes care of all the details and avoids doing anything that isn't safe to do inside a signal handler. The only thing we need to do is to manually setup our own fake SIGINT handler that behaves the same way as the standalone Python REPL signal handler (which raises a KeyboardInterrupt). From what I understand the old code used to work with Python 2 so I kept the old code around until we officially drop support for Python 2. There is a small gap here with Python 3.0->3.1 where we might still be crashing, but those versions have reached their EOL more than a decade ago so I think we don't need to bother about them. Differential revision: https://reviews.llvm.org/D104886
2022-01-09[lldb] Remove reproducer instrumentationJonas Devlieghere
This patch removes most of the reproducer instrumentation. It keeps around the LLDB_RECORD_* macros for logging. See [1] for more details. [1] https://lists.llvm.org/pipermail/lldb-dev/2021-September/017045.html Differential revision: https://reviews.llvm.org/D116847
2021-12-20[lldb/python] Fix (some) dangling pointers in our glue codePavel Labath
This starts to fix the other half of the lifetime problems in this code -- dangling references. SB objects created on the stack will go away when the function returns, which is a problem if the python code they were meant for stashes a reference to them somewhere. Most of the time this goes by unnoticed, as the code rarely has a reason to store these, but in case it does, we shouldn't respond by crashing. This patch fixes the management for a couple of SB objects (Debugger, Frame, Thread). The SB objects are now created on the heap, and their ownership is immediately passed on to SWIG, which will ensure they are destroyed when the last python reference goes away. I will handle the other objects in separate patches. I include one test which demonstrates the lifetime issue for SBDebugger. Strictly speaking, one should create a test case for each of these objects and each of the contexts they are being used. That would require figuring out how to persist (and later access) each of these objects. Some of those may involve a lot of hoop-jumping (we can run python code from within a frame-format string). I don't think that is necessary/worth it since the new wrapper functions make it very hard to get this wrong. Differential Revision: https://reviews.llvm.org/D115925
2021-12-13[lldb] Clarify StructuredDataImpl ownershipPavel Labath
StructuredDataImpl ownership semantics is unclear at best. Various structures were holding a non-owning pointer to it, with a comment that the object is owned somewhere else. From what I was able to gather that "somewhere else" was the SBStructuredData object, but I am not sure that all created object eventually made its way there. (It wouldn't matter even if they did, as we are leaking most of our SBStructuredData objects.) Since StructuredDataImpl is just a collection of two (shared) pointers, there's really no point in elaborate lifetime management, so this patch replaces all StructuredDataImpl pointers with actual objects or unique_ptrs to it. This makes it much easier to resolve SBStructuredData leaks in a follow-up patch. Differential Revision: https://reviews.llvm.org/D114791
2021-11-30[lldb] Remove 'extern "C"' from the lldb-swig-python interfacePavel Labath
The LLDBSWIGPython functions had (at least) two problems: - There wasn't a single source of truth (a header file) for the prototypes of these functions. This meant that subtle differences in copies of function declarations could go by undetected. And not-so-subtle differences would result in strange runtime failures. - All of the declarations had to have an extern "C" interface, because the function definitions were being placed inside and extert "C" block generated by swig. This patch fixes both problems by moving the function definitions to the %header block of the swig files. This block is not surrounded by extern "C", and seems more appropriate anyway, as swig docs say it is meant for "user-defined support code" (whereas the previous %wrapper code was for automatically-generated wrappers). It also puts the declarations into the SWIGPythonBridge header file (which seems to have been created for this purpose), and ensures it is included by all code wishing to define or use these functions. This means that any differences in the declaration become a compiler error instead of a runtime failure. Differential Revision: https://reviews.llvm.org/D114369
2021-11-22[lldb] Fix [some] leaks in python bindingsPavel Labath
Using an lldb_private object in the bindings involves three steps - wrapping the object in it's lldb::SB variant - using swig to convert/wrap that to a PyObject - wrapping *that* in a lldb_private::python::PythonObject Our SBTypeToSWIGWrapper was only handling the middle part. This doesn't just result in increased boilerplate in the callers, but is also a functionality problem, as it's very hard to get the lifetime of of all of these objects right. Most of the callers are creating the SB object (step 1) on the stack, which means that we end up with dangling python objects after the function terminates. Most of the time this isn't a problem, because the python code does not need to persist the objects. However, there are legitimate cases where they can do it (and even if the use case is not completely legitimate, crashing is not the best response to that). For this reason, some of our code creates the SB object on the heap, but it has another problem -- it never gets cleaned up. This patch begins to add a new function (ToSWIGWrapper), which does all of the three steps, while properly taking care of ownership. In the first step, I have converted most of the leaky code (except for SBStructuredData, which needs a bit more work). Differential Revision: https://reviews.llvm.org/D114259
2021-11-16[lldb] fix -print-script-interpreter-info on windowsLawrence D'Anna
Apparently "{sys.prefix}/bin/python3" isn't where you find the python interpreter on windows, so the test I wrote for -print-script-interpreter-info is failing. We can't rely on sys.executable at runtime, because that will point to lldb.exe not python.exe. We can't just record sys.executable from build time, because python could have been moved to a different location. But it should be OK to apply relative path from sys.prefix to sys.executable from build-time to the sys.prefix at runtime. Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D113650
2021-11-13Revert "[lldb] Fix that the embedded Python REPL crashes if it receives SIGINT"Raphael Isemann
This reverts commit cef1e07cc6d00b5b429d77133201e1f404a8023c. It broke the windows bot.
2021-11-12[lldb] Fix that the embedded Python REPL crashes if it receives SIGINTRaphael Isemann
When LLDB receives a SIGINT while running the embedded Python REPL it currently just crashes in `ScriptInterpreterPythonImpl::Interrupt` with an error such as the one below: ``` Fatal Python error: PyThreadState_Get: the function must be called with the GIL held, but the GIL is released (the current Python thread state is NULL) ``` The faulty code that causes this error is this part of `ScriptInterpreterPythonImpl::Interrupt`: ``` PyThreadState *state = PyThreadState_GET(); if (!state) state = GetThreadState(); if (state) { long tid = state->thread_id; PyThreadState_Swap(state); int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); ``` The obvious fix I tried is to just acquire the GIL before this code is running which fixes the crash but the `KeyboardInterrupt` we want to raise immediately is actually just queued and would only be raised once the next line of input has been parsed (which e.g. won't interrupt Python code that is currently waiting on a timer or IO from what I can see). Also none of the functions we call here is marked as safe to be called from a signal handler from what I can see, so we might still end up crashing here with some bad timing. Python 3.2 introduced `PyErr_SetInterrupt` to solve this and the function takes care of all the details and avoids doing anything that isn't safe to do inside a signal handler. The only thing we need to do is to manually setup our own fake SIGINT handler that behaves the same way as the standalone Python REPL signal handler (which raises a KeyboardInterrupt). From what I understand the old code used to work with Python 2 so I kept the old code around until we officially drop support for Python 2. There is a small gap here with Python 3.0->3.1 where we might still be crashing, but those versions have reached their EOL more than a decade ago so I think we don't need to bother about them. Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D104886
2021-11-10[lldb] make it easier to find LLDB's pythonLawrence D'Anna
It is surprisingly difficult to write a simple python script that can reliably `import lldb` without failing, or crashing. I'm currently resorting to convolutions like this: def find_lldb(may_reexec=False): if prefix := os.environ.get('LLDB_PYTHON_PREFIX'): if os.path.realpath(prefix) != os.path.realpath(sys.prefix): raise Exception("cannot import lldb.\n" f" sys.prefix should be: {prefix}\n" f" but it is: {sys.prefix}") else: line1, line2 = subprocess.run( ['lldb', '-x', '-b', '-o', 'script print(sys.prefix)'], encoding='utf8', stdout=subprocess.PIPE, check=True).stdout.strip().splitlines() assert line1.strip() == '(lldb) script print(sys.prefix)' prefix = line2.strip() os.environ['LLDB_PYTHON_PREFIX'] = prefix if sys.prefix != prefix: if not may_reexec: raise Exception( "cannot import lldb.\n" + f" This python, at {sys.prefix}\n" f" does not math LLDB's python at {prefix}") os.environ['LLDB_PYTHON_PREFIX'] = prefix python_exe = os.path.join(prefix, 'bin', 'python3') os.execl(python_exe, python_exe, *sys.argv) lldb_path = subprocess.run(['lldb', '-P'], check=True, stdout=subprocess.PIPE, encoding='utf8').stdout.strip() sys.path = [lldb_path] + sys.path This patch aims to replace all that with: #!/usr/bin/env lldb-python import lldb ... ... by adding the following features: * new command line option: --print-script-interpreter-info. This prints language-specific information about the script interpreter in JSON format. * new tool (unix only): lldb-python which finds python and exec's it. Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D112973
2021-10-28[lldb] Remove ConstString from Process, ScriptInterpreter and StructuredData ↵Pavel Labath
plugin names
2021-10-18[lldb] Return StringRef from PluginInterface::GetPluginNamePavel Labath
There is no reason why this function should be returning a ConstString. While modifying these files, I also fixed several instances where GetPluginName and GetPluginNameStatic were returning different strings. I am not changing the return type of GetPluginNameStatic in this patch, as that would necessitate additional changes, and this patch is big enough as it is. Differential Revision: https://reviews.llvm.org/D111877
2021-10-01[lldb] [Host] Refactor TerminalStateMichał Górny
Refactor TerminalState to make the code simpler. Move 'struct termios' to a PImpl-style subclass. Add an RAII interface to automatically store and restore the state. Differential revision: https://reviews.llvm.org/D110721
2021-09-13[lldb] Remove PluginInterface::GetPluginVersionPavel Labath
In all these years, we haven't found a use for this function (it has zero callers). Lets just remove the boilerplate. Differential Revision: https://reviews.llvm.org/D109600
2021-07-09[lldb] Add the ability to silently import scripted commandsJonas Devlieghere
Add the ability to silence command script import. The motivation for this change is being able to add command script import -s lldb.macosx.crashlog to your ~/.lldbinit without it printing the following message at the beginning of every debug session. "malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help. In addition to forwarding the silent option to LoadScriptingModule, this also changes ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn and ScriptInterpreterPythonImpl::ExecuteMultipleLines to honor the enable IO option in ExecuteScriptOptions, which until now was ignored. Note that IO is only enabled (or disabled) at the start of a session, and for this particular use case, that's done when taking the Python lock in LoadScriptingModule, which means that the changes to these two functions are not strictly necessary, but (IMO) desirable nonetheless. Differential revision: https://reviews.llvm.org/D105327
2021-07-02[lldb] Replace default bodies of special member functions with = default;Jonas Devlieghere
Replace default bodies of special member functions with = default; $ run-clang-tidy.py -header-filter='lldb' -checks='-*,modernize-use-equals-default' -fix , https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-equals-default.html Differential revision: https://reviews.llvm.org/D104041
2021-06-15Convert functions that were returning BreakpointOption * to BreakpointOption &.Jim Ingham
This is an NFC cleanup. Many of the API's that returned BreakpointOptions always returned valid ones. Internally the BreakpointLocations usually have null BreakpointOptions, since they use their owner's options until an option is set specifically on the location. So the original code used pointers & unique_ptr everywhere for consistency. But that made the code hard to reason about from the outside. This patch changes the code so that everywhere an API is guaranteed to return a non-null BreakpointOption, it returns it as a reference to make that clear. It also changes the Breakpoint to hold a BreakpointOption member where it previously had a UP. Since we were always filling the UP in the Breakpoint constructor, having the UP wasn't helping anything. Differential Revision: https://reviews.llvm.org/D104162
2021-06-09[lldb] Use C++11 default member initializersJonas Devlieghere
This converts a default constructor's member initializers into C++11 default member initializers. This patch was automatically generated with clang-tidy and the modernize-use-default-member-init check. $ run-clang-tidy.py -header-filter='lldb' -checks='-*,modernize-use-default-member-init' -fix This is a mass-refactoring patch and this commit will be added to .git-blame-ignore-revs. Differential revision: https://reviews.llvm.org/D103483