I am trying to learn to debug programs written in Crystal with GDB. Here is a sample:
class Demo
@array = [] of String
def bar(url)
ret = url.downcase * 2
if ret == "alsj"
return false
else
return ret
end
end
def do(foo)
@array.push(foo)
html = bar(foo)
puts "HI" # GDB breakpoint here
return html
end
end
a = Demo.new
puts a.do("HI")
I compiled the sample above with the --debug
flag and loaded it into GDB. Then I let it run and stopped at the marked line ( GDB breakpoint here
). Now I have three four questions:
foo
): When I inspect a string variable, I often see something like $1 = (struct String *) 0x4b9f18
. When I say printf "%s", foo
, I get nothing back. How can I display the current value of a string variable? $1 = <optimized out>
when inspecting a variable. What does that mean and how can I see the value in that case? @array
in the given situation? p array
says no symbol in current context and p @array
returns unknown address space modifier. Edit: I found a way: use p self.array
puts "HI"
) I can't see the variable html at all: p html
returns no symbol in current context. Why is that and how do I solve it? Crystal debugging capabilities are still on development so you can't see some symbols or symbols data is optimized by LLVM. About optimized output , sometimes crystal algorithms are optimized too much, even on --debug
builds. By example:
Currently yield methods are inlined and optimized, so this isn't very debuggable.
3.times do |i|
pp i
end
However, you can use pp
keyword to print name => value
.
pp i
i => 1
i => 2
i => 3
Also you can set breakpoints using debugger
keyword and inspect macro output using {% debug() %}
or $ crystal tool expand
command.
On the other hand compound statement are easy to debug using tools like GDB.
i = 0
while i < 3
debugger
i += 1 # i variable is listed by GDB
end
Finally you can try some tricks I found in my debugging daily tasks.
@[NoInline]
and p &foo.c
this will enable args data and you will be able to print all struct string value Using @[NoInline]
attribute:
@[NoInline]
def do(foo)
debugger
end
On GDB:
(gdb) p &foo.c
$1 = (UInt8 *) 0x10008e6c4 "HI"
optimized out: maybe because LLVM optimizes some method calls. if you see <optimized out>
use @[NoInline]
and try assigning instance vars to local vars array = @array
Accessing object variables: use self.var
for instance vars.
Also use p array.buffer[0]@size
to print array values.
(gdb) p &array.buffer[0].c
$19 = (UInt8 *) 0x10008e7f4 "HI"
Try adding debug info manually converting or casting values:
@[NoInline]
def do(foo)
html = bar(foo).as(String)
html = bar(foo).to_s
debugger
end
Now html var is visible on GDB thanks to .as
or .to_s
methods
(gdb) p &html.c
$1 = (UInt8 *) 0x1002fcfec "hihi"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.