【发布时间】:2023-03-05 00:01:01
【问题描述】:
我的问题是:是否可以(以任何方式)在运行时分析和修改调用堆栈(帧内容和堆栈内容)?
我正在寻找任何可能性 - 低级、不安全或内部 API、编写 C 扩展的可能性等。唯一的限制:它应该可以在标准运行时使用,无需调试或分析模式。这就是我正在研究“这可能吗?”,而不是“这是个好主意吗?”。
我想从一个框架中收集所有本地数据,将其存储在某处,然后从堆栈中删除该框架,并有可能在以后恢复它。这有效地为我们提供了 JVM 中的延续,它们将允许快速异步框架(如来自 python 的 gevent)和生成器构造(如来自 python 的那些)出现。
这看起来像是重复的问题,但我只找到了用“使用Thread.currentThread().getStackTrace()”或“应该使用调试工具来完成”回答的问题。有similiar question to mine,但它只在询问人想要做什么的情况下得到回答(从事异步计算),而我需要更一般的(面向java堆栈的)答案。 This question 也是类似的,但和以前一样,它侧重于并行化,答案也侧重于此。
我再说一遍:这是提出新语言功能提案过程中的研究步骤。我不想冒险破坏 JVM 中的任何东西 - 我正在寻找可能性,然后我将分析可能的风险并寻找它们。我知道手动操作堆栈是丑陋的,但是使用省略构造函数创建实例也是如此 - 它是对象的基础。肮脏的 hack 可能很脏,但它们可能有助于引入一些很酷的东西。
PS。我知道Quasar 和Lightwolf 存在,但是如上所述,它们是以并发为中心的框架。
编辑
一点澄清:我正在寻找与未来 JVM 和库版本兼容的东西。最好我们谈论的是被认为是稳定的公共 API 的东西,但如果解决方案存在于内部,但几乎是标准的或在成为内部的标准之后(如 sun.misc.Unsafe) - 那也可以。如果它可以通过仅使用 C JVM API 的 C 扩展来实现 - 没关系。如果通过字节码操作可以做到这一点 - 那也可以(我认为 ASM 可以做到)。
【问题讨论】:
-
我没用过,但也许你可以用JVM Tool Interface做点什么。它有一些functions to work with stack frames。
-
谢谢!这看起来很有希望,但不幸的是,它只允许弹出帧(甚至在弹出后不提供)并获取一些原始帧信息。这不足以存储和恢复完整的执行上下文。
-
恐怕你不能使用超过 JVMTI 允许的堆栈。需要 JVM 支持才能执行您想要的操作。即使您碰巧使用直接内存访问成功地操作了堆栈,下一次 JVM 更新也可能很容易破坏这一点。
-
我将稍微澄清一下未来的兼容性,以避免 cmets 和答案警告我有关 JVM 更新的信息;)不过,也许有人知道一些事情......
-
“为什么决定禁止它” - 不是。也没有决定允许它。直接操作堆栈的动机尚不清楚。如果你想在 Java 中继续,有other ways 来实现这一点。
标签: java jvm stack-trace