Amber Framework
WebsiteBlogGithubDiscord
  • Introduction
  • Getting Started
  • Guides
    • Overview
    • Installation
    • Create New App
    • Directory Structure
    • Configuration
    • Docker
    • Controllers
      • Sessions
      • Request & Response Objects
      • Halt!
      • Respond With
      • Params
      • Cookies
      • Filters
      • Flash
      • Redirection
      • CSRF
    • Views
      • Basic View Helpers
      • Form Builder
    • Models
      • Granite
        • Granite's README
        • Migrations
        • Validations
        • Callbacks
        • Associations
        • Querying
        • Bulk Insertions
      • Jennifer
        • Jennifer Docs
        • Migrations
        • Models
    • Routing
      • Pipelines
      • Routes
    • Websockets
      • Channels
      • Sockets
      • JavaScript Client
    • Mailers
    • Testing
      • System Tests
  • Deployment
    • Manual Deploy
    • Digital Ocean
    • Heroku
    • Dokku
  • CLI
    • New
    • Recipes
    • Plugins
    • Generate
    • Database
    • Watch
    • Routes
    • Exec
    • Encrypt
  • Examples
    • Amber Auth
    • Crystal Debug
    • Minimal Configuration
  • Cookbook
    • From Scratch
    • Hello World
    • CORS
    • File Download
    • File Upload
    • Cookies
    • Authenticate
    • JSON API
    • JSON Mapping
    • WebSocket Chat
  • Troubleshooting
  • In Production
  • Contributing
  • Code of Conduct
  • HAVE A QUESTION?
    • Join the Discord
    • Follow on Twitter
    • Submit an issue
Powered by GitBook
On this page
  • Prerequisites
  • Debug on VSCode
  • 1. tasks.json configuration to compile a crystal project
  • 2. launch.json configuration to debug a binary
  • 3. Then hit the DEBUG green play button
  • Tips and Tricks for debugging Crystal applications
  • 1. Use debugger keyword
  • 2. Avoid breakpoints inside blocks
  • 3. Try @[NoInline] to debug arguments data
  • 4. Printing strings objects (GDB)
  • 5. Printing array variables
  • 6. Printing instance variables
  • 7. Print hidden objects
  1. Examples

Crystal Debug

PreviousAmber AuthNextMinimal Configuration

Last updated 2 years ago

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 for VSCode.

Prerequisites

  • Crystal - See installation guide

  • Crystal project - See installation guide or

  • VSCode with and or extensions

  • GNU debugger (GDB) or LLVM debugger (LLDB) - See installation guide below

Install gdb or lldb accordingly to your OS.

Confirm that the above prerequisites are installed before setting up the debugger. These settings have been verified for mac OS and Linux environments.

Debug on VSCode

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

1. tasks.json configuration to compile a crystal project

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

2. launch.json configuration to debug a binary

Using GDB

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

Using LLDB

{
  "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

Tips and Tricks for debugging Crystal applications

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.

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.

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.

@[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:

foo = "Hello World!"
debugger

Then use print in the debugging console.

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

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

5. Printing array variables

To print array items in the debugger:

First, setup the debugger with the debugger statement:

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

Then use print in the debugging console:

(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:

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:

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.

debugging

lldb does not show data for variables in crystal yet, see issue

Using VSCode GUI
Native Debug
here
here
here (Amber)
Crystal Lang
Native Debug
CodeLLDB
#4457