# Implementing Standalone Scripts

## Configuring `PYTHONPATH`

LLDB has all of its core code built into a shared library which gets used by
the `lldb` command line application.
- On macOS this shared library is a framework: `LLDB.framework`.
- On other unix variants the program is a shared library: lldb.so.

LLDB also provides an `lldb.py` module that contains the bindings from LLDB
into Python. To use the `LLDB.framework` to create your own stand-alone python
programs, you will need to tell python where to look in order to find this
module. This is done by setting the `PYTHONPATH` environment variable,
adding a path to the directory that contains the `lldb.py` python
module. The lldb driver program has an option to report the path to the lldb
module. You can use that to point to correct lldb.py:

For csh and tcsh:

```csh
% setenv PYTHONPATH `lldb -P`
```

For sh and bash:

```bash
$ export PYTHONPATH=`lldb -P`
```

Alternatively, you can append the LLDB Python directory to the sys.path list
directly in your Python code before importing the lldb module.

## Initialization

The standard test for `__main__`, like many python modules do, is useful for
creating scripts that can be run from the command line. However, for command
line scripts, the debugger instance must be created manually. Sample code would
look like:

```python3
if __name__ == '__main__':
    # Initialize the debugger before making any API calls.
    lldb.SBDebugger.Initialize()
    # Create a new debugger instance in your module if your module
    # can be run from the command line. When we run a script from
    # the command line, we won't have any debugger object in
    # lldb.debugger, so we can just create it if it will be needed
    debugger = lldb.SBDebugger.Create()

    # Next, do whatever work this module should do when run as a command.
    # ...

    # Finally, dispose of the debugger you just made.
    lldb.SBDebugger.Destroy(debugger)
    # Terminate the debug session
    lldb.SBDebugger.Terminate()
```

## Example

Now your python scripts are ready to import the lldb module. Below is a python
script that will launch a program from the current working directory called
`a.out`, set a breakpoint at `main`, and then run and hit the breakpoint, and
print the process, thread and frame objects if the process stopped:

```python3
#!/usr/bin/env python3

import lldb
import os

def disassemble_instructions(insts):
    for i in insts:
        print(i)

# Set the path to the executable to debug
exe = "./a.out"

# Create a new debugger instance
debugger = lldb.SBDebugger.Create()

# When we step or continue, don't return from the function until the process
# stops. Otherwise we would have to handle the process events ourselves which, while doable is
# a little tricky.  We do this by setting the async mode to false.
debugger.SetAsync(False)

# Create a target from a file and arch
print("Creating a target for '%s'" % exe)

target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)

if target:
    # If the target is valid set a breakpoint at main
    main_bp = target.BreakpointCreateByName(
        "main", target.GetExecutable().GetFilename()
    )

    print(main_bp)

    # Launch the process. Since we specified synchronous mode, we won't return
    # from this function until we hit the breakpoint at main
    process = target.LaunchSimple(None, None, os.getcwd())

    # Make sure the launch went ok
    if process:
        # Print some simple process info
        state = process.GetState()
        print(process)
        if state == lldb.eStateStopped:
            # Get the first thread
            thread = process.GetThreadAtIndex(0)
            if thread:
                # Print some simple thread info
                print(thread)
                # Get the first frame
                frame = thread.GetFrameAtIndex(0)
                if frame:
                    # Print some simple frame info
                    print(frame)
                    function = frame.GetFunction()
                    # See if we have debug info (a function)
                    if function:
                        # We do have a function, print some info for the function
                        print(function)
                        # Now get all instructions for this function and print them
                        insts = function.GetInstructions(target)
                        disassemble_instructions(insts)
                    else:
                        # See if we have a symbol in the symbol table for where we stopped
                        symbol = frame.GetSymbol()
                        if symbol:
                            # We do have a symbol, print some info for the symbol
                            print(symbol)
```

## Expected Output

Exact output varies by system, but you should see something like this:

```
Creating a target for './a.out'
SBBreakpoint: id = 1, name = 'main', module = a.out, locations = 1
SBProcess: pid = 2593449, state = stopped, threads = 1, executable = a.out
thread #1: tid = 2593449, 0x0000aaaaaaaa0714 a.out`main at test.c:3:9, name = 'test.o', stop reason = breakpoint 1.1
frame #0: 0x0000aaaaaaaa0714 a.out`main at test.c:3:9
SBFunction: id = 0x0000002e, name = main, type = main
a.out[0x714]: mov    w0, #0x0                  ; =0
a.out[0x718]: ret
```

## Troubleshooting

You can use all the usual Python tools to debug scripts, and on top of that
you can enable LLDB's log channels. To do this in the script shown above, add
this line right after `debugger` has been assigned:

```python
debugger.EnableLog("lldb", ["all"])
```

`lldb` `all` enables a lot of different channels, so you will probably want
to enable only a few channels once you know what you are interested in.

This API call is the equivalent of `log enable lldb all` when using LLDB
interactively. All channels available to `log enable` can be enabled using
`EnableLog` too.