Files
TheRock/compiler/amd-llvm/lldb/docs/use/tutorials/breakpoint-triggered-scripts.md
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

4.4 KiB

Breakpoint-Triggered Scripts

One very powerful use of the lldb Python API is to have a python script run when a breakpoint gets hit. Adding python scripts to breakpoints provides a way to create complex breakpoint conditions and also allows for smart logging and data gathering.

When your process hits a breakpoint to which you have attached some python code, the code is executed as the body of a function which takes three arguments:

def breakpoint_function_wrapper(frame, bp_loc, internal_dict):
   # Your code goes here

or:

def breakpoint_function_wrapper(frame, bp_loc, extra_args, internal_dict):
   # Your code goes here
Argument Type Description
frame lldb.SBFrame The current stack frame where the breakpoint got hit. The object will always be valid. This frame argument might not match the currently selected stack frame found in the lldb module global variable lldb.frame.
bp_loc lldb.SBBreakpointLocation The breakpoint location that just got hit. Breakpoints are represented by lldb.SBBreakpoint objects. These breakpoint objects can have one or more locations. These locations are represented by lldb.SBBreakpointLocation objects.
extra_args lldb.SBStructuredData Optional If your breakpoint callback function takes this extra parameter, then when the callback gets added to a breakpoint, its contents can parametrize this use of the callback. For instance, instead of writing a callback that stops when the caller is "Foo", you could take the function name from a field in the extra_args, making the callback more general. The -k and -v options to breakpoint command add will be passed as a Dictionary in the extra_args parameter, or you can provide it with the SB API's.
internal_dict dict The python session dictionary as a standard python dictionary object.

Optionally, a Python breakpoint command can return a value. Returning False tells LLDB that you do not want to stop at the breakpoint. Any other return value (including None or leaving out the return statement altogether) is akin to telling LLDB to actually stop at the breakpoint. This can be useful in situations where a breakpoint only needs to stop the process when certain conditions are met, and you do not want to inspect the program state manually at every stop and then continue.

An example will show how simple it is to write some python code and attach it to a breakpoint. The following example will allow you to track the order in which the functions in a given shared library are first executed during one run of your program. This is a simple method to gather an order file which can be used to optimize function placement within a binary for execution locality.

We do this by setting a regular expression breakpoint that will match every function in the shared library. The regular expression '.' will match any string that has at least one character in it, so we will use that. This will result in one lldb.SBBreakpoint object that contains an lldb.SBBreakpointLocation object for each function. As the breakpoint gets hit, we use a counter to track the order in which the function at this particular breakpoint location got hit. Since our code is passed the location that was hit, we can get the name of the function from the location, disable the location so we won't count this function again; then log some info and continue the process.

Note we also have to initialize our counter, which we do with the simple one-line version of the script command.

Here is the code:

(lldb) breakpoint set --func-regex=. --shlib=libfoo.dylib
Breakpoint created: 1: regex = '.', module = libfoo.dylib, locations = 223
(lldb) script counter = 0
(lldb) breakpoint command add --script-type python 1
Enter your Python command(s). Type 'DONE' to end.
> # Increment our counter.  Since we are in a function, this must be a global python variable
> global counter
> counter += 1
> # Get the name of the function
> name = frame.GetFunctionName()
> # Print the order and the function name
> print('[%i] %s' % (counter, name))
> # Disable the current breakpoint location so it doesn't get hit again
> bp_loc.SetEnabled(False)
> # No need to stop here
> return False
> DONE

The breakpoint command add command above attaches a python script to breakpoint 1. To remove the breakpoint command:

(lldb) breakpoint command delete 1