[{"cid":58188,"parent_cid":null,"body":"Breaking the LLDB/Python Revlock\r\n\r\nhttps://jonasdevlieghere.com/post/breaking-lldb-python-revlock/\r\n\r\nvia Jonas Devlieghere","created_at":"2026-06-05T23:20:00.120Z","tags":["blog","bot","jonas_devlieghere"],"orgs":[],"usrs":[],"created_by":"bot_blogs","thumb":"https://jonasdevlieghere.com/images/empty.png","c_comments":1,"c_reactions":"","c_flags":0,"links":[],"flaggers":[],"author_ups":16,"author_downs":7,"author_posts_count":970,"tag_ups":446,"tag_downs":77,"domain_ups":0,"domain_downs":0,"score":"2026-06-03T17:52:32.601Z","repost_ups":0,"mentions":[],"domains":["jonasdevlieghere.com"],"comments":"1","reaction_count":"0","reaction_counts":{},"user_reactions":[],"child_comments":[{"cid":58193,"body":"> # [Breaking the LLDB/Python Revlock](https://jonasdevlieghere.com/post/breaking-lldb-python-revlock/)\r\n>\r\n> Since its inception, scripting has been an integral part of LLDB. At the time, Python was chosen as the primary, and for a long time the only supported, scripting language. Python is used within LLDB to automate things, write custom data formatters, and extend core concepts like Processes and Threads with an implementation written in Python. Another powerful way to use LLDB is as a debugger library in Python, by importing the lldb module.\r\n>\r\n> We can distinguish two ways LLDB and Python are used together:\r\n>\r\n> - Python in LLDB: When using LLDB, either directly (e.g. from the command line or with lldb-dap), or as a library, it comes with an embedded Python interpreter. LLDB drops you into the embedded interpreter when you use the script command, and it’s what powers LLDB’s ability to execute Python code for things like data formatters and breakpoint callbacks. In this mode, LLDB loads Python.\r\n>\r\n> - LLDB in Python: When using LLDB from Python, via import lldb, Python loads LLDB. In this scenario, LLDB uses the existing interpreter so it can share state between the two.\r\n>\r\n> Both use cases are critical and apply equally to other scripting languages such as Lua. Each introduces its own trade-offs that have shaped LLDB’s design.\r\n>\r\n> LLDB’s dependency on Python came with a long-standing caveat: the Python that LLDB ran against had to be the exact one it was built against.\r\n>\r\n> ## Load-Time Dependency\r\n>\r\n> Both use cases mentioned earlier need the Python library mapped into the process, which is why LLDB has historically linked against it at build time.\r\n>\r\n> LLDB (specifically libLLDB) has a load-time dependency on its build-time Python at a specific install name. If the Python library doesn’t exist at runtime, the dynamic loader fails to load LLDB, often resulting in a crash. Since this happens before LLDB gets a chance to run, there’s no way to fail gracefully.\r\n>\r\n> When you import lldb in an existing Python interpreter, it has already loaded its own copy of the Python library. If that library doesn’t match the one LLDB linked against, the dynamic loader will pull in a second copy. Having two copies of the same library is generally dangerous, and not something Python supports.\r\n>\r\n> ## Unstable Python C API\r\n>\r\n> Besides the load-time issue, there’s a second problem. LLDB’s use of Python predates the Limited API, which was introduced by PEP 384 in Python 3.2. This is a subset of Python’s C API that can be compiled once and loaded on multiple versions of Python.\r\n>\r\n> LLDB relies on SWIG to generate the Python bindings for its public Scripting Bridge API. Until SWIG version 4.2, it couldn’t limit the generated code to the Limited API. Later versions generate Limited-API-compatible code by default.\r\n>\r\n> ## Adopting the Python Limited C API\r\n>\r\n> The first step towards breaking the revlock was adopting the Python Limited C API in LLDB. This work was tracked by issue #151617 and was relatively unglamorous. Most replacements were mechanical, but some APIs needed real surgery, and a few had to be guarded by a minimum Python version when their stable equivalent only landed in a later release.\r\n>\r\n> Adopting the Limited API also requires picking a floor: the Py_LIMITED_API macro sets the oldest Python version the resulting binary can load against. We kept the existing minimum: Python 3.8.\r\n>\r\n> …","orgs":[],"tags":["blog","bot","jonas_devlieghere"],"usrs":[],"c_flags":0,"comments":0,"created_at":"2026-06-05T23:20:19.561958+00:00","created_by":"bot_reader","parent_cid":58188,"child_comments":[],"user_reactions":[],"reaction_counts":{}}]}]