DP.*_*DP. 5 debugging gdb crystal-lang
我正在尝试学习使用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")
Run Code Online (Sandbox Code Playgroud)
我用--debug标志编译了上面的示例并将其加载到GDB中.然后我让它运行并停在标记线(GDB breakpoint here).现在我有三个问题:
foo):
当我检查字符串变量时,我经常会看到类似的东西$1 = (struct String *) 0x4b9f18.当我说printf "%s", foo,我什么都没有回来.如何显示字符串变量的当前值?$1 = <optimized out>在检查变量时看到.这意味着什么?如何在这种情况下看到价值?@array在给定的情况下查看值?p array在当前上下文中没有符号,并p @array返回未知的地址空间修饰符.
编辑:我找到了一种方法:使用p self.arrayputs "HI")我根本看不到变量html:p html在当前上下文中不返回符号.为什么这样,我该如何解决?Crystal 调试功能仍在开发中,因此您看不到某些符号或符号数据已由 LLVM 优化。关于优化输出,有时晶体算法优化得太多,甚至在--debug构建时也是如此。举例:
目前 yield 方法是内联和优化的,所以这不是很容易调试。
3.times do |i|
pp i
end
Run Code Online (Sandbox Code Playgroud)
但是,您可以使用pp关键字来打印name => value。
pp i
i => 1
i => 2
i => 3
Run Code Online (Sandbox Code Playgroud)
您也可以使用debugger关键字设置断点并使用{% debug() %}或$ crystal tool expand命令检查宏输出。
另一方面,使用 GDB 等工具可以轻松调试复合语句。
i = 0
while i < 3
debugger
i += 1 # i variable is listed by GDB
end
Run Code Online (Sandbox Code Playgroud)
最后,您可以尝试我在调试日常任务中发现的一些技巧。
@[NoInline]与p &foo.c这将使ARGS数据,您将能够打印所有结构字符串值使用@[NoInline]属性:
@[NoInline]
def do(foo)
debugger
end
Run Code Online (Sandbox Code Playgroud)
在 GDB 上:
(gdb) p &foo.c
$1 = (UInt8 *) 0x10008e6c4 "HI"
Run Code Online (Sandbox Code Playgroud)
优化出来:可能是因为 LLVM 优化了一些方法调用。如果您看到<optimized out>使用@[NoInline]并尝试将实例变量分配给本地变量array = @array
访问对象变量:使用self.var实例变量。
也用于p array.buffer[0]@size打印数组值。
(gdb) p &array.buffer[0].c
$19 = (UInt8 *) 0x10008e7f4 "HI"
Run Code Online (Sandbox Code Playgroud)
尝试手动添加调试信息转换或转换值:
@[NoInline]
def do(foo)
html = bar(foo).as(String)
html = bar(foo).to_s
debugger
end
Run Code Online (Sandbox Code Playgroud)
由于.asor.to_s方法,现在 html var 在 GDB 上可见
(gdb) p &html.c
$1 = (UInt8 *) 0x1002fcfec "hihi"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
711 次 |
| 最近记录: |