-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from elegios/debug-section
Add a how-to section on debugging
- Loading branch information
Showing
3 changed files
with
102 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
label: 'Debugging' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# Examining large ASTs as JSON | ||
|
||
Sometimes the ASTs you wish to examine are too large for the various | ||
`--debug-*` flags to be viable, or you want the ability to | ||
programmatically explore it outside the compiler. | ||
|
||
This can be achieved using `mexpr/json-debug.mc`, which is a small | ||
library in the standard library. Usage centers around a few functions | ||
like `exprToJson`, `typeToJson`, etc., To use these functions you need | ||
include `mexpr/json-debug.mc` and `use` the `MExprToJson` language | ||
fragment: | ||
|
||
```mc | ||
-- Add this include to the file | ||
include "mexpr/json-debug.mc" | ||
-- Later: | ||
let ast = /- Some code producing an AST to examine -/ in | ||
printLn (json2string (use MExprToJson in exprToJson ast)); | ||
-- ... more code that keeps processing the AST ... | ||
``` | ||
|
||
:::note | ||
|
||
If you are working with an extended language, e.g., in `miking-dppl`, | ||
then you will need to create a new language fragment that implements | ||
the corresponding `sem`s (`exprToJson` for constructors in `Expr`, | ||
etc.). See `stdlib/mexpr/json-debug.mc` for examples. | ||
|
||
::: | ||
|
||
When run, this code will typically print a *very* large json object, | ||
thus it's typically useful to redirect the output to a file for later | ||
processing: | ||
|
||
```bash | ||
# Assuming the above code has been added somewhere in the main `mi` compiler: | ||
mi compile test.mc > debug.json | ||
``` | ||
|
||
Some useful tools to explore this data are [jless](https://jless.io/) | ||
and [jq](https://jqlang.github.io/jq/). | ||
|
||
:::tip | ||
|
||
When looking at data from a program that prints both json-encoded data | ||
and arbitrary strings (e.g., an edited `mi` compiler) it might be | ||
useful to pre-process the output first: | ||
|
||
```bash | ||
# Filter out non-json lines | ||
jq -R 'try fromjson' < debug.json | jless | ||
|
||
# Reformat all non-json lines as strings with `-> ` added at the start | ||
jq -R '. as $line | try fromjson catch ("-> " + $line)' < debug.json | jless | ||
``` | ||
|
||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Getting stack traces when using the OCaml backend | ||
|
||
There are two primary ways to get stack traces from a program compiled | ||
with the OCaml backend. Note that regardless of the method used most | ||
functions will have mangled names, i.e., they differ somewhat from the | ||
source code, but the connection is typically quite clear | ||
nonetheless. For example, a function `typeCheckExpr` in a language | ||
fragment `ExtMCore` might become something like | ||
`camlDune__exe__Program__v_vExtMCore_typeCheckExpr_142839`. | ||
|
||
First, the `OCAMLRUNPARAM` environment flag can be set to `b` to | ||
instruct the OCaml runtime to emit a backtrace when it encounters an | ||
exception: | ||
|
||
```bash | ||
OCAMLRUNPARAM=b ./program | ||
``` | ||
|
||
Second, the program can be run using a debugger such as `gdb`: | ||
|
||
```bash | ||
gdb ./program | ||
|
||
# Once inside gdb: | ||
run <program args> | ||
|
||
# Use `bt` to get a backtrace when the program has crashed or been interrupted: | ||
bt | ||
``` | ||
|
||
:::tip | ||
|
||
If the program prints an error and exits explicitly (e.g., via `exit | ||
1`) rather than throwing an exception and crashing `gdb` can still | ||
extract a backtrace by adding a breakpoint to `exit`: | ||
|
||
```bash | ||
# Inside gdb, before running the program: | ||
break exit | ||
# Then run as usual, the program will break just before exiting, at which point you can run `bt` | ||
``` | ||
|
||
::: |