【问题标题】:How is the stacktrace printed when the program is compiled?程序编译时stacktrace是如何打印的?
【发布时间】:2015-08-18 01:26:53
【问题描述】:

这是一个非常简单的问题:

当你编译一个java程序时,它被转换为字节码,因此,.java或.class文件的每一行号都被遗漏了(我想是的,可能我错了..)。那么,当您打印堆栈跟踪时,它如何设法获取调用堆栈中的所有类名和行号?我认为我可能在这里遗漏了一些东西,但我找不到与此相关的任何东西。

【问题讨论】:

  • 类名(以及变量名、方法名...)不会被删除。它们在字节码中。您甚至可以在 .class 文件上使用文本编辑器看到这一点。
  • 许多其他语言也是如此。人们很快发现在原始可执行代码中添加“调试符号”是一件很有用的事情。
  • 即使没有文件名和行号(可以去掉),你仍然会得到类名和方法名(这些是实际运行程序所需要的,Java 是非常晚绑定的)。

标签: java compiler-construction stack-trace bytecode


【解决方案1】:

当你编译一个java程序时,它被转换成字节码

正确。

因此,.java 或 .class 文件的每一行号都被遗漏了(我想是的,可能我错了..)。

你错了。行号信息嵌入到 .class 文件中,除非您以某些方式使用 -g 编译器选项。

【讨论】:

  • 字节码什么时候变成汇编代码?我在这里有点困惑,我想..
  • @PabloMatíasGomez:定义“汇编代码”。字节码是 JVM 运行的编译输出。它可能会也可能不会将其进一步编译为实际的机器代码。 “汇编”是一种人类可读的编程语言,非常接近二进制代码(字节码或机器码)。
  • @Thilo 现在我明白了!当我说“汇编代码”时,我指的是汇编程序,但当然,我错过了 JVM 直接运行字节码的部分。
【解决方案2】:

如果存在行号,则 java 编译器创建的字节码将 debug 标志设置为 true。这可以使用java -g来实现

来自 Oracle 的 javac 文档:

  • -g
    • 生成所有调试信息,包括局部变量。默认只生成行号和源文件信息。
  • -g:none
    • 不生成任何调试信息。
  • -g:{keyword list} - 仅生成某些类型的调试信息,由逗号分隔的关键字列表指定。有效的关键字是:
    • source
      • 源文件调试信息
    • lines
      • 行号调试信息
    • vars
      • 局部变量调试信息

【讨论】:

    猜你喜欢
    • 2011-01-03
    • 2017-03-04
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 2014-01-25
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多