> For the complete documentation index, see [llms.txt](https://mazeframework.gitbook.io/maze/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mazeframework.gitbook.io/maze/examples/crystal-debug.md).

# Crystal Debug

This tutorial has tips and tricks on how to debug Crystal projects. It shows how to leverage tools like GDB or LLDB using debugger clients like [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) for VSCode.

## Prerequisites

* Crystal - See instalation guide [here](https://crystal-lang.org/docs/installation/)
* Crystal project - See installation guide [here](https://crystal-lang.org/docs/using_the_compiler/#creating-a-project-or-library) or [here (Maze)](/maze/guides/installation.md)
* VSCode with [Crystal Lang](https://marketplace.visualstudio.com/items?itemName=faustinoaq.crystal-lang) and [Native Debug](https://marketplace.visualstudio.com/items?itemName=webfreak.debug) extensions
* GNU debugger (GDB) or LLVM debugger (LLDB) - See installation guide below

Install `gdb` or `lldb` accordingly to your OS.

{% hint style="info" %}
Confirm that the above prerequisites are installed before setting up the debugger. These settings have been verified for a MacOS and Linux's environments.
{% endhint %}

## Debug on VSCode

{% hint style="warning" %}
By convention the project directory name is the same as your application name, if you have changed it, please update `${workspaceFolderBasename}` with the name configured inside `shards.yml`
{% endhint %}

### 1. `task.json` configuration to compile a crystal project

```javascript
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Compile",
      "command": "shards build --debug ${workspaceFolderBasename}",
      "type": "shell"
    }
  ]
}
```

### 2. `launch.json` configuration to debug a binary

#### Using GDB

```javascript
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug",
      "type": "gdb",
      "request": "launch",
      "target": "./bin/${workspaceFolderBasename}",
      "cwd": "${workspaceRoot}",
      "preLaunchTask": "Compile"
    }
  ]
}
```

#### Using LLDB

```javascript
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug",
      "type": "lldb-mi",
      "request": "launch",
      "target": "./bin/${workspaceFolderBasename}",
      "cwd": "${workspaceRoot}",
      "preLaunchTask": "Compile"
    }
  ]
}
```

### 3. Then hit the DEBUG green play button

![debugging](https://i.imgur.com/GsGT1h0.png)

## Tips and Tricks for debugging Crystal applications

{% hint style="danger" %}
`lldb` does not show data for variables in crystal yet, see issue [#4457](https://github.com/crystal-lang/crystal/issues/4457)
{% endhint %}

Fully debugging Crystal applications is not supported yet. You can use some of the techniques below to improve the debugging experience.

### 1. Use debugger keyword

Instead of putting breakpoints using commands inside GDB or LLDB you can try to set a breakpoint using `debugger` keyword.

```ruby
i = 0
while i < 3
  i += 1
  debugger # => breakpoint
end
```

### 2. Avoid breakpoints inside blocks

Currently, Crystal lacks support for debugging inside of blocks. If you put a breakpoint inside a block, it will be ignored.

As a workaround, use `pp` to pretty print objects inside of blocks.

```ruby
3.times do |i|
  pp i
end
# i => 1
# i => 2
# i => 3
```

### 3. Try `@[NoInline]` to debug arguments data

Sometimes crystal will optimize argument data, so the debugger will show `<optimized output>` instead of the arguments. To avoid this behavior use the `@[NoInline]` attribute before your function implementation.

```ruby
@[NoInline]
def foo(bar)
  debugger
end
```

### 4. Printing strings objects (GDB)

To print string objects in the debugger:

First, setup the debugger with the `debugger` statement:

```ruby
foo = "Hello World!"
debugger
```

Then use `print` in the debugging console.

```bash
(gdb) print &foo.c
$1 = (UInt8 *) 0x10008e6c4 "Hello World!"
```

Or add `&foo.c` using a new variable entry on watch section in VSCode debugger

![Using VSCode GUI](https://i.imgur.com/EpQinL7.png)

### 5. Printing array variables

To print array items in the debugger:

First, setup the debugger with the `debugger` statement:

```ruby
foo = ["item 0", "item 1", "item 2"]
debugger
```

Then use `print` in the debugging console:

```bash
(gdb) print &foo.buffer[0].c
$19 = (UInt8 *) 0x10008e7f4 "item 0"
```

Change the buffer index for each item you want to print.

### 6. Printing instance variables

For printing `@foo` var in this code:

```ruby
class Bar
  @foo = 0
  def baz
    debugger
  end
end

Bar.new
```

You can use `self.foo` in the debugger terminal or VSCode GUI.

### 7. Print hidden objects

Some objects do not show at all. You can unhide them using the `.to_s` method and a temporary debugging variable, like this:

```ruby
def bar(hello)
  "#{hello} World!"
end

def foo(hello)
  bar_hello_to_s = bar(hello).to_s
  debugger
end

foo("Hello")
```

This trick allows showing the `bar_hello_to_s` variable inside the debugger tool.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mazeframework.gitbook.io/maze/examples/crystal-debug.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
