debugging - 使用 GDB 进行 Crystal 调试

标签 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")

我用 --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"
    
  • 优化:可能是因为 LLVM 优化了一些方法调用。如果你看到 <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/

    相关文章:

    python - 如何在 tensorflow 中查找类型或打印变量详细信息\内容

    android - 如何调试android框架服务?

    eclipse - 无法通过 Eclipse 在 Genymotion 中调试 native Android 应用程序

    c++ - 如何在 C++ 程序中查看 gdb 中的 vtable?

    crystal-lang - 在 Crystal 库中引用 C 枚举

    crystal-lang - Crystal : Class+ is not a class, 这是一个 Class+

    c++ - Visual Studio(或任何其他工具)能否将地址解释为调用堆栈的开始( boost 上下文)?

    windows-xp - 要让 DDD 在 XP 上正常运行,最低限度的 Cygwin 安装是什么?

    database - Crystal Lang 和数据库连接池

    c - Eclipse CDT 中的 GDB 崩溃 : Error in `gdb' : free(): invalid next size (fast):