Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lldb/docs] Add scripting extensions documentation to the website #97262

Conversation

medismailben
Copy link
Member

This patch adds the documentation for a subset of scripting extensions such as scripted process, scripted thread, operating system threads & scritped thread plans to the lldb website.

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 1, 2024

@llvm/pr-subscribers-lldb

Author: Med Ismail Bennani (medismailben)

Changes

This patch adds the documentation for a subset of scripting extensions such as scripted process, scripted thread, operating system threads & scritped thread plans to the lldb website.


Full diff: https://github.com/llvm/llvm-project/pull/97262.diff

6 Files Affected:

  • (modified) lldb/docs/CMakeLists.txt (+8-1)
  • (modified) lldb/docs/use/python.rst (+59)
  • (modified) lldb/examples/python/templates/operating_system.py (+9-10)
  • (modified) lldb/examples/python/templates/scripted_platform.py (+11-13)
  • (modified) lldb/examples/python/templates/scripted_process.py (+16-23)
  • (added) lldb/examples/python/templates/scripted_thread_plan.py (+70)
diff --git a/lldb/docs/CMakeLists.txt b/lldb/docs/CMakeLists.txt
index f482e91d1b10c..f327596f3ef31 100644
--- a/lldb/docs/CMakeLists.txt
+++ b/lldb/docs/CMakeLists.txt
@@ -25,10 +25,17 @@ if (LLDB_ENABLE_PYTHON AND SPHINX_FOUND)
     # Pretend that the SWIG generated API is a Python package.
     file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lldb)
     get_target_property(lldb_bindings_dir swig_wrapper_python BINARY_DIR)
+
     add_custom_target(lldb-python-doc-package
       COMMAND "${CMAKE_COMMAND}" -E copy "${lldb_bindings_dir}/lldb.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/__init__.py"
+      COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins"
+      COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
+      COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
+      COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/operating_system.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
+      COMMAND "${CMAKE_COMMAND}" -E copy "${LLDB_SOURCE_DIR}/examples/python/templates/scripted_thread_plan.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/plugins/"
       COMMENT "Copying lldb.py to pretend its a Python package.")
-    add_dependencies(lldb-python-doc-package swig_wrapper_python)
+
+    add_dependencies(lldb-python-doc-package swig_wrapper_python lldb-python)
 
     # FIXME: Don't treat Sphinx warnings as errors. The files generated by
     # automodapi are full of warnings (partly caused by SWIG, our documentation
diff --git a/lldb/docs/use/python.rst b/lldb/docs/use/python.rst
index d9c29d95708c1..39a488c2d84f5 100644
--- a/lldb/docs/use/python.rst
+++ b/lldb/docs/use/python.rst
@@ -11,6 +11,65 @@ some of these things by going through an example, explaining how to use
 Python scripting to find a bug in a program that searches for text in a
 large binary tree.
 
+Operating System Thread Plugins
+-------------------------------
+
+.. automodapi:: lldb.plugins.operating_system
+    :no-heading:
+    :members:
+    :undoc-members:
+    :skip: command
+    :skip: declaration
+    :skip: in_range
+    :skip: is_numeric_type
+    :skip: lldb_iter
+    :no-inheritance-diagram:
+
+Scripted Process Plugins
+-------------------------------
+
+.. automodapi:: lldb.plugins.scripted_process
+    :no-heading:
+    :members:
+    :undoc-members:
+    :skip: ABCMeta
+    :skip: command
+    :skip: declaration
+    :skip: in_range
+    :skip: is_numeric_type
+    :skip: lldb_iter
+    :no-inheritance-diagram:
+
+Scripted Platform Plugins
+-------------------------------
+
+.. automodapi:: lldb.plugins.scripted_platform
+    :no-heading:
+    :members:
+    :undoc-members:
+    :skip: ABCMeta
+    :skip: command
+    :skip: declaration
+    :skip: in_range
+    :skip: is_numeric_type
+    :skip: lldb_iter
+    :no-inheritance-diagram:
+
+Scripted Thread Plan Plugins
+-------------------------------
+
+.. automodapi:: lldb.plugins.scripted_thread_plan
+    :no-heading:
+    :members:
+    :undoc-members:
+    :skip: ABCMeta
+    :skip: command
+    :skip: declaration
+    :skip: in_range
+    :skip: is_numeric_type
+    :skip: lldb_iter
+    :no-inheritance-diagram:
+
 The Test Program and Input
 --------------------------
 
diff --git a/lldb/examples/python/templates/operating_system.py b/lldb/examples/python/templates/operating_system.py
index a8053bcaa21af..e5c106de473bf 100644
--- a/lldb/examples/python/templates/operating_system.py
+++ b/lldb/examples/python/templates/operating_system.py
@@ -10,16 +10,15 @@ class OperatingSystem(ScriptedThread):
     """
     Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class.
 
-    ```
-    thread_info = {
-        "tid": tid,
-        "name": "four",
-        "queue": "queue4",
-        "state": "stopped",
-        "stop_reason": "none",
-        "core" : 2
-    }
-    ```
+    .. code-block:: python
+        thread_info = {
+            "tid": tid,
+            "name": "four",
+            "queue": "queue4",
+            "state": "stopped",
+            "stop_reason": "none",
+            "core" : 2
+        }
 
     - tid : thread ID (mandatory)
     - name : thread name (optional key/value pair)
diff --git a/lldb/examples/python/templates/scripted_platform.py b/lldb/examples/python/templates/scripted_platform.py
index fb1bde8fd4cb7..b9ead9e80741f 100644
--- a/lldb/examples/python/templates/scripted_platform.py
+++ b/lldb/examples/python/templates/scripted_platform.py
@@ -10,9 +10,6 @@ class ScriptedPlatform(metaclass=ABCMeta):
 
     Most of the base class methods are `@abstractmethod` that need to be
     overwritten by the inheriting class.
-
-    DISCLAIMER: THIS INTERFACE IS STILL UNDER DEVELOPMENT AND NOT STABLE.
-                THE METHODS EXPOSED MIGHT CHANGE IN THE FUTURE.
     """
 
     processes = None
@@ -32,16 +29,17 @@ def __init__(self, exe_ctx, args):
     def list_processes(self):
         """Get a list of processes that are running or that can be attached to on the platform.
 
-        processes = {
-            420: {
-                    name: a.out,
-                    arch: aarch64,
-                    pid: 420,
-                    parent_pid: 42 (optional),
-                    uid: 0 (optional),
-                    gid: 0 (optional),
-            },
-        }
+        .. code-block:: python
+            processes = {
+                420: {
+                        name: a.out,
+                        arch: aarch64,
+                        pid: 420,
+                        parent_pid: 42 (optional),
+                        uid: 0 (optional),
+                        gid: 0 (optional),
+                },
+            }
 
         Returns:
             Dict: The processes represented as a dictionary, with at least the
diff --git a/lldb/examples/python/templates/scripted_process.py b/lldb/examples/python/templates/scripted_process.py
index 3ddcebd128eaa..ea5d073715319 100644
--- a/lldb/examples/python/templates/scripted_process.py
+++ b/lldb/examples/python/templates/scripted_process.py
@@ -11,9 +11,6 @@ class ScriptedProcess(metaclass=ABCMeta):
 
     Most of the base class methods are `@abstractmethod` that need to be
     overwritten by the inheriting class.
-
-    DISCLAIMER: THIS INTERFACE IS STILL UNDER DEVELOPMENT AND NOT STABLE.
-                THE METHODS EXPOSED MIGHT CHANGE IN THE FUTURE.
     """
 
     capabilities = None
@@ -106,8 +103,8 @@ def write_memory_at_address(self, addr, data, error):
 
         Args:
             addr (int): Address from which we should start reading.
-            data (lldb.SBData): An `lldb.SBData` buffer to write to the
-                process memory.
+            data (lldb.SBData): An `lldb.SBData` buffer to write to the process
+            memory.
             error (lldb.SBError): Error object.
 
         Returns:
@@ -121,13 +118,12 @@ def write_memory_at_address(self, addr, data, error):
     def get_loaded_images(self):
         """Get the list of loaded images for the scripted process.
 
-        ```
-        scripted_image = {
-            uuid = "c6ea2b64-f77c-3d27-9528-74f507b9078b",
-            path = "/usr/lib/dyld"
-            load_addr = 0xbadc0ffee
-        }
-        ```
+        .. code-block:: python
+            scripted_image = {
+                uuid = "c6ea2b64-f77c-3d27-9528-74f507b9078b",
+                path = "/usr/lib/dyld"
+                load_addr = 0xbadc0ffee
+            }
 
         Returns:
             List[scripted_image]: A list of `scripted_image` dictionaries
@@ -238,9 +234,6 @@ class ScriptedThread(metaclass=ABCMeta):
 
     Most of the base class methods are `@abstractmethod` that need to be
     overwritten by the inheriting class.
-
-    DISCLAIMER: THIS INTERFACE IS STILL UNDER DEVELOPMENT AND NOT STABLE.
-                THE METHODS EXPOSED MIGHT CHANGE IN THE FUTURE.
     """
 
     @abstractmethod
@@ -305,10 +298,11 @@ def get_name(self):
     def get_state(self):
         """Get the scripted thread state type.
 
+        .. code-block:: python
             eStateStopped,   ///< Process or thread is stopped and can be examined.
             eStateRunning,   ///< Process or thread is running and can't be examined.
-            eStateStepping,  ///< Process or thread is in the process of stepping and can
-                             /// not be examined.
+            eStateStepping,  ///< Process or thread is in the process of stepping and
+                             /// can not be examined.
             eStateCrashed,   ///< Process or thread has crashed and can be examined.
 
         Returns:
@@ -340,12 +334,11 @@ def get_stop_reason(self):
     def get_stackframes(self):
         """Get the list of stack frames for the scripted thread.
 
-        ```
-        scripted_frame = {
-            idx = 0,
-            pc = 0xbadc0ffee
-        }
-        ```
+        .. code-block:: python
+            scripted_frame = {
+                idx = 0,
+                pc = 0xbadc0ffee
+            }
 
         Returns:
             List[scripted_frame]: A list of `scripted_frame` dictionaries
diff --git a/lldb/examples/python/templates/scripted_thread_plan.py b/lldb/examples/python/templates/scripted_thread_plan.py
new file mode 100644
index 0000000000000..71ac236956e0b
--- /dev/null
+++ b/lldb/examples/python/templates/scripted_thread_plan.py
@@ -0,0 +1,70 @@
+from abc import abstractmethod
+
+import lldb
+
+
+class ScriptedThreadPlan:
+    """
+    Class that provides data for an instance of a LLDB 'ScriptedThreadPlan' plug-in class used to construct custom stepping logic.
+
+    """
+
+    def __init__(self, thread_plan: lldb.SBThreadPlan):
+        """Initialization needs a valid lldb.SBThreadPlan object. This plug-in will get created after a live process is valid and has stopped.
+
+        Args:
+            thread_plan (lldb.SBThreadPlan): The underlying `ThreadPlan` that is pushed onto the plan stack.
+        """
+        self.thread_plan = thread_plan
+
+    def explains_stop(self, event: lldb.SBEvent) -> bool:
+        """Each plan is asked if it "explains" the stop.  The first plan to claim the stop wins.
+
+        Args:
+            event (lldb.SBEvent): The process stop event.
+
+        Returns:
+            bool: `True` if this stop could be claimed by this thread plan, `False` otherwise.
+            Defaults to `True`.
+        """
+        return True
+
+    def is_stale(self) -> bool:
+        """If your plan is no longer relevant (for instance, you were stepping in a particular stack frame, but some other operation pushed that frame off the stack) return True and your plan will get popped.
+
+        Returns:
+            bool: `True` if this thread plan is stale, `False` otherwise.
+            Defaults to `True`.
+        """
+        return True
+
+    def should_stop(self, event: lldb.SBEvent) -> bool:
+        """Whether this thread plan should stop and return control to the user.
+        If your plan is done at this point, call SetPlanComplete on your thread plan instance. Also, do any work you need here to set up the next stage of stepping.
+
+        Args:
+            event (lldb.SBEvent): The process stop event.
+
+        Returns:
+            bool: `True` if this plan wants to stop and return control to the user at this point, `False` otherwise.
+            Defaults to `False`.
+        """
+        self.thread_plan.SetPlanComplete(True)
+        return True
+
+    def should_step(self) -> bool:
+        """Whether this thread plan should instruction step one instruction, or continue till the next breakpoint is hit.
+
+        Returns:
+            bool: `True` if this plan will instruction step one instruction, `False` otherwise.
+            Defaults to `True`.
+        """
+        return True
+
+    def stop_description(self, stream: lldb.SBStream) -> None:
+        """Customize the thread plan stop reason when the thread plan is complete.
+
+        Args:
+            stream (lldb.SBStream): The stream containing the stop description.
+        """
+        return True

@medismailben medismailben force-pushed the website-scripted-extensions-documentation branch from b6594ad to b11dd59 Compare July 1, 2024 07:39
Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm excited to see these extension points getting documented! What would make this even more valuable is having a page that documents all of LLDB's extension points (and explains the duality between scripting LLDB interactions vs scripting LLDB's behavior) and explain what you can use them for and how to do that. Basically the points you made in your EuroLLVM talk, but in website form. The Python Reference page already covers a bit of that so that could serve as a starting point.

lldb/docs/use/python.rst Outdated Show resolved Hide resolved
@medismailben medismailben force-pushed the website-scripted-extensions-documentation branch from b11dd59 to e08689b Compare July 2, 2024 07:27
Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know you've been thinking about and working on this for a while, so glad to see it come together like this! 😃

@@ -25,10 +25,17 @@ if (LLDB_ENABLE_PYTHON AND SPHINX_FOUND)
# Pretend that the SWIG generated API is a Python package.
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lldb)
get_target_property(lldb_bindings_dir swig_wrapper_python BINARY_DIR)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: stray space?

lldb/docs/python_extensions.rst Outdated Show resolved Hide resolved
lldb/docs/python_extensions.rst Outdated Show resolved Hide resolved

Operating System Thread Plugins
-------------------------------

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A short blurb explaining what each of these are for would be useful. It may not be obvious what "Operating System Thread Plugins" are for, as an example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

We get the blurb from the docstrings.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this looks great! Thanks for showing me what it will look like :)

@@ -0,0 +1,70 @@
from abc import abstractmethod
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an entire scripting interface. Maybe a separate PR would be more appropriate? Seems like you're doing multiple things here.

This patch adds the documentation for a subset of scripting extensions
such as scripted process, scripted thread, operating system threads &
scritped thread plans to the lldb website.

Signed-off-by: Med Ismail Bennani <[email protected]>
@medismailben medismailben force-pushed the website-scripted-extensions-documentation branch from e08689b to 06a79c1 Compare July 2, 2024 19:48
Copy link
Member

@bulbazord bulbazord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@medismailben medismailben merged commit 59f4267 into llvm:main Jul 2, 2024
5 of 6 checks passed
medismailben added a commit to medismailben/llvm-project that referenced this pull request Jul 2, 2024
Following a feedback request in llvm#97262, I took out the scripted thread
plan python base class from it and make a separate PR for it.

This patch adds the scripted thread plan base python class to the lldb
python module as well as the lldb documentation website.

Signed-off-by: Med Ismail Bennani <[email protected]>
medismailben added a commit that referenced this pull request Jul 2, 2024
…97481)

Following a feedback request in #97262, I took out the scripted thread
plan python base class from it and make a separate PR for it.

This patch adds the scripted thread plan base python class to the lldb
python module as well as the lldb documentation website.

Signed-off-by: Med Ismail Bennani <[email protected]>
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
…vm#97262)

This patch adds the documentation for a subset of scripting extensions
such as scripted process, scripted thread, operating system threads &
scritped thread plans to the lldb website.

Signed-off-by: Med Ismail Bennani <[email protected]>
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
…lvm#97481)

Following a feedback request in llvm#97262, I took out the scripted thread
plan python base class from it and make a separate PR for it.

This patch adds the scripted thread plan base python class to the lldb
python module as well as the lldb documentation website.

Signed-off-by: Med Ismail Bennani <[email protected]>
kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
…vm#97262)

This patch adds the documentation for a subset of scripting extensions
such as scripted process, scripted thread, operating system threads &
scritped thread plans to the lldb website.

Signed-off-by: Med Ismail Bennani <[email protected]>
kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
…lvm#97481)

Following a feedback request in llvm#97262, I took out the scripted thread
plan python base class from it and make a separate PR for it.

This patch adds the scripted thread plan base python class to the lldb
python module as well as the lldb documentation website.

Signed-off-by: Med Ismail Bennani <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants