How to debug my Crystal app?

I read the topic Debugger support but could not find a small example or a link to doc’s on how to debug
a Crystal app.

No nice way to do it right now

I wrote this guide for the support within vscode Debug Crystal in VSCode via CodeLLDB - DEV Community

If you know gdb lldb you can use them, yet there is a limitation regarding what values can be inspected.

3 Likes

Perhaps time for me to switch from Geany to VSCode.
Thanks.

You can kind of use gdb the “normal way” as it were…

@bcardiff Do you know if the LLDB helpers are up-to-date at all? I still see Strings formatted as an initial character and a length and I’m on LLDB version 15. Thanks

That is normal unfortunately, and something I’m currently looking into

Possibly related: LLVM 16 supports Crystal's DWARF5 language code · Issue #13174 · crystal-lang/crystal · GitHub

Ah, yes, good point. I have had problems with DWARF 4/5 with gdb when compiling with clang, but in those situations I have had some output telling me gdb can’t make sense of them. I tried lldb-17 with the same result though.

Does this solution still available? i test on my emacs with dap-codelldb 1.8.1, get following error:

plugins/dap-mode/.extension/vscode/codelldb/extension/adapter/codelldb --port 12489

[ERROR codelldb::dap_session] Deserialization error: data did not match any variant 
of untagged enum ResponseResult at line 1 column 84

[ERROR codelldb::terminal] [61] channel closed

I just run the things as described in Debug Crystal in VSCode via CodeLLDB - DEV Community and things works as expected using CodeLLDB vscode extension.

I also just try using lldb from mac directly and it seems to work.

The script is mimicking what ./spec/debug/driver.cr do under the hood.

% crystal build --debug ./spec/debug/strings.cr -o string-debug

% lldb string-debug 
(lldb) target create "string-debug"
Current executable set to '/Users/bcardiff/Projects/crystal/master/string-debug' (arm64).
(lldb) version
lldb-1500.0.200.58
Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.5)
(lldb) command script import etc/lldb/crystal_formatters.py
(lldb) breakpoint set -n main -G true -o true -C 'process handle -s false -n false SIGSEGV SIGBUS'
Breakpoint 1: 2 locations.
(lldb) breakpoint set -n __crystal_main -G true -o true -C 'process handle -s true -n true SIGSEGV SIGBUS'
Breakpoint 2: where = string-debug`__crystal_main + 208 at strings.cr:1:1, address = 0x000000010000394c
(lldb) run
Process 36134 launched: '/Users/bcardiff/Projects/crystal/master/string-debug' (arm64)
(lldb)  process handle -s false -n false SIGSEGV SIGBUS
NAME         PASS   STOP   NOTIFY
===========  =====  =====  ======
SIGSEGV      true   false  false
SIGBUS       true   false  false
(lldb)  process handle -s true -n true SIGSEGV SIGBUS
NAME         PASS   STOP   NOTIFY
===========  =====  =====  ======
SIGSEGV      true   true   true 
SIGBUS       true   true   true
Process 36134 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100003c8c)
    frame #0: 0x0000000100003c90 string-debug`__crystal_main at strings.cr:9:1
   6    # print: b
   7    # lldb-check: (String *) $1 = {{0x[0-9a-f]+}} "abcσdeσf"
   8    # gdb-check: $2 = "abcσdeσf"
-> 9    debugger
Target 0: (string-debug) stopped.
(lldb) print a
(String *) 0x00000001000c5970 "hello world"
(lldb) print b
(String *) 0x00000001000c5990 "abcσdeσf"

Hi, I get following error on my my arch linux when try to reproduce your’s process.

 ╰─ $ lldb string-debug
(lldb) target create "string-debug"
Current executable set to '/home/zw963/Crystal/crystal-lang/crystal/string-debug' (x86_64).
(lldb) command script import etc/lldb/crystal_formatters.py
/home/zw963/Crystal/crystal-lang/crystal/etc/lldb/crystal_formatters.py:60: SyntaxWarning: invalid escape sequence '\('
  debugger.HandleCommand('type synthetic add -l crystal_formatters.CrystalArraySyntheticProvider -x "^Array\(.+\)(\s*\**)?" -w Crystal')
/home/zw963/Crystal/crystal-lang/crystal/etc/lldb/crystal_formatters.py:61: SyntaxWarning: invalid escape sequence '\('
  debugger.HandleCommand('type summary add -F crystal_formatters.CrystalString_SummaryProvider -x "^(String|\(String \| Nil\))(\s*\**)?$" -w Crystal')
(lldb)

I’m not sure, maybe is a python issue. If you copy/edit crystal_formatters.py, can you check if
adding r to the following strings fix the issue? I didn’t try but a couple of search points into that direction. Disclaimer: I’m not familiar with python.

def __lldb_init_module(debugger, dict):
    debugger.HandleCommand(r'type synthetic add -l crystal_formatters.CrystalArraySyntheticProvider -x "^Array\(.+\)(\s*\**)?" -w Crystal')
    debugger.HandleCommand(r'type summary add -F crystal_formatters.CrystalString_SummaryProvider -x "^(String|\(String \| Nil\))(\s*\**)?$" -w Crystal')
    debugger.HandleCommand(r'type category enable Crystal')
1 Like

It is working! thank you very much.