我正在尝试学习使用 GDB 调试用 Crystal 编写的程序。这是一个示例:
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")
我用
--debug
编译了上面的示例标志并将其加载到 GDB 中。然后我让它运行并停在标记的线( GDB breakpoint here
)处。现在我有三个四个问题:foo
):当我检查一个字符串变量时,我经常看到类似
$1 = (struct String *) 0x4b9f18
的内容。 .当我说 printf "%s", foo
,我什么也得不到。如何显示字符串变量的当前值? 其他时候我只是看到
$1 = <optimized out>
检查变量时。这是什么意思,在这种情况下我如何才能看到值(value)? 如何查看
@array
的值在给定的情况下? p array
表示当前上下文中没有符号和 p @array
返回未知的地址空间修饰符。编辑:我找到了一个方法:使用
p self.array
在给定的情况下(在
puts "HI"
行中断)我根本看不到变量 html:p html
在当前上下文中不返回任何符号。为什么会这样,我该如何解决? 最佳答案
Crystal 调试能力还在on development所以你看不到一些符号或符号数据是由 LLVM 优化的。关于优化输出,有时晶体算法优化太多,甚至在--debug
建立。举例:
目前产量方法是inlined并进行了优化,因此这不是很可调试。
3.times do |i|
pp i
end
但是,您可以使用
pp
要打印的关键字 name => value
.pp i
i => 1
i => 2
i => 3
您也可以使用
debugger
设置断点关键字并使用 {% debug() %}
检查宏输出或 $ crystal tool expand
命令。另一方面,使用 GDB 等工具可以轻松调试复合语句。
i = 0
while i < 3
debugger
i += 1 # i variable is listed by GDB
end
最后,您可以尝试我在调试日常任务中发现的一些技巧。
@[NoInline]
和 p &foo.c
这将启用 args 数据,您将能够打印所有结构字符串值 使用
@[NoInline]
属性:@[NoInline]
def do(foo)
debugger
end
在 GDB 上:
(gdb) p &foo.c
$1 = (UInt8 *) 0x10008e6c4 "HI"
<optimized out>
使用 @[NoInline]
并尝试将实例变量分配给本地变量 array = @array
self.var
例如变量。 也可以使用
p array.buffer[0]@size
打印数组值。(gdb) p &array.buffer[0].c
$19 = (UInt8 *) 0x10008e7f4 "HI"
尝试手动添加调试信息转换或转换值:
@[NoInline]
def do(foo)
html = bar(foo).as(String)
html = bar(foo).to_s
debugger
end
由于
.as
,现在 html var 在 GDB 上可见或 .to_s
方法(gdb) p &html.c
$1 = (UInt8 *) 0x1002fcfec "hihi"
关于debugging - 使用 GDB 进行 Crystal 调试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46369703/