The pony language reference has a debugging section that got me pointed in the right direction for getting VSCode set up and integrated with lldb
.
There were a few steps that were glossed over in the instructions, but I eventually got everything working, including:
- breakpoints (including conditional breakpoints)
- current variable values (including evaluated Strings not pointers)
- watch expressions
- step debugging
- lldb console interaction
There's a good lldb
cheatsheet on the pony website.
Setup VSCode instructions
Using brew
:
brew install llvm
sudo /usr/sbin/DevToolsSecurity --enable
These type summary extensions configure lldb
to print out formatted results for your expressions and variables. Instead of having to manually evaluate data types like String *
in lldb
like this (assuming pony code let my_var = "world"
):
p (char *)(my_var->_ptr)
(char *) $1 = 0x0000000100018940 "world"
They'll automatically show up in the IDE as the resolved value of "b'world'"
.
As of 2021-08-13, there's a bug in the main repo of pony-lldb
where it doesn't work with python3.
Till that is merged, I've got a fork with the fix that can be cloned locally.
Later config assumes this is cloned into a sibling directory of your project repo.
git clone git@github.com:tednaleid/pony-lldb.git
In the VSCode settings, under Features->Debug, check "Allow breakpoints in any file."
This will be in your global settings.json as:
"debug.allowBreakpointsEverywhere": true,
In the "Extensions" view, you should be able to search for CodeLLDB
and install it.
Under Settings->Extensions->LLDB make the following changes:
- uncheck "Lldb: Derefernece Pointers" (settings.json will show:
"lldb.dereferencePointers": false,
)- this gets the UI to show the nicer versions of values from
pony-lldb
above
- this gets the UI to show the nicer versions of values from
- Under "Lldb > Launch: Init Commands" click "Edit in settings.json" and to add the command to add
lldb
extensions:
"lldb.launch.initCommands": [
"command script import ${workspaceRoot}/../pony-lldb/pony_lldb.py"
],
This instructs lldb to load the pony-lldb
type summary extensions before running your app with lldb
.
Here's a sample file you can use, scratch.pony
:
actor Main
new create(env: Env) =>
let target = "world"
let buf = recover String end
let one: U64 = 1
buf.append("hello ")
buf.append(target)
env.out.print(consume buf)
create a ponyc_debug
task in the menu: Terminal->Configure Tasks...
{
"version": "2.0.0",
"tasks": [
{
"label": "ponyc_debug",
"type": "shell",
"command": "ponyc --debug"
}
]
}
This will call the ponyc_debug
task above to create a debug version of your app, then will launch lldb
.
If your app has arguments to pass in, you can also add those.
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "launch debug",
"program": "${workspaceRoot}/scratch",
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": "ponyc_debug",
},
]
}
This is the equivalent to doing this on the command line:
ponyc --debug && lldb ./scratch
You should now be able to set breakpoints, watch statements, etc, in your app.
Then you can run the "launch debug" configuration under View->Run and it should stop at your breakpoints.
You can also run any native lldb
commands you want in the Debug Console
pane at the bottom of your screen.
The Pony LLDB Cheatsheet has a bunch of good instructions for that.