【问题标题】:Can you detect in Java if the code is being debugged? [duplicate]如果代码正在被调试,你能在 Java 中检测到吗? [复制]
【发布时间】:2012-07-16 11:54:54
【问题描述】:

可能重复:
How to find out if “debug mode” is enabled

来自 C#,我无法相信 Java 只有在调试程序时才能执行代码。不知何故,Log4J 似乎能够做到这一点。有谁知道这种可能性?我正在考虑这样的事情:

#if DEBUG
    executedCode();
#endif

或者是这样的:

if (Java.isDebugging())
    executeCode();

想法?

编辑:感谢 Matt Ball,this 中的代码可能重复工作:

public static boolean debugging = java.lang.management.ManagementFactory.getRuntimeMXBean().
        getInputArguments().toString().indexOf("-agentlib:jdwp") > 0;

【问题讨论】:

  • 是什么让你觉得 Log4J 可以做到?我知道它确实有一个 DEBUG 日志级别,但是 Log4J 的日志级别是在配置文件中设置的。
  • Log4j 的Logger#isDebugEnabled() 与代码是否被调试无关。它仅基于该记录器的配置。
  • 如果设置了调试标志,您可能只需添加一个命令行标志并检查 argv。非常简单,满足您的需求

标签: java debugging


【解决方案1】:

也许您正在考虑与使用调试器不同的调试日志记录。

您会发现的问题是,Java 有六个以上广泛用于日志记录的库。

有内置的记录器。

http://docs.oracle.com/javase/1.4.2/docs/guide/util/logging/overview.html

Log4j 应用广泛,slf4j 和 Logback 也很流行。

甚至还有一些库可以抽象出您实际使用的记录器,例如公共日志记录。

【讨论】:

  • 我正在考虑我只想在调试时做的 System.out.println()。诸如反射之类的东西,可以确定是否附加了调试器。
  • @Akku,Eclipse 允许您指定不同的调试配置。因此,您可以将调试配置设置为使用与部署应用程序时不同的 Log4J 配置文件。
  • 您可以检查 JVM 是否在启用调试的情况下启动,(参见 Matt Ball 的评论)但您无法检查是否实际附加了调试器。
  • 你能解释一下你为什么要这样做吗?有什么东西你不能从你的调试器中运行吗?调试器应该允许您运行临时代码。
  • @JackEdmonds:我不使用 Eclipse。 PeterLawrey:我正在为其他一些开发人员制作一个小 .jar,并希望在调试时在命令行上输出调试信息。大家:是的,我知道我应该明确地设置它,但这正是我不想要它的原因。我讨厌做的比我必须做的多。 :-)
【解决方案2】:

C 仅在调试时才执行代码,您显示的是条件编译指令,代码仅在标志值为 true 时才被编译。正在运行的代码不知道它何时被调试。与 Log4j 类似,它从其配置中读取要使用的级别,它不知道何时调试。

条件编译标志被故意排除在 Java 之外,他们想避免复杂性。 C# 有不同的哲学。

【讨论】:

    【解决方案3】:

    您可以按照说明进行操作,使用全局标志。虽然它应该注意它不会自动检测,但您必须在开始调试之前自己更改标志。

    public class Globals
    {
        public static final boolean debugFlag = false;
    }
    

    稍后...

    if (Globals.debugFlag){...}
    

    仅当您想在调试时执行功能代码时才真正需要这样做。这也是一种蛮力解决方案,因为您必须在任何地方打开它才能在任何地方打开它。如果您需要更多粒度,您可以在要使用成员标志调试的特定类中执行类似的操作。如果您只想在调试块内进行日志记录,请参阅 Peter 关于日志库的回答。

    【讨论】:

    • 不适用。这家伙想知道攻击者是否正在调试他的应用程序。
    【解决方案4】:

    我认为您将程序的调试构建与在调试器下运行(除非 C# 相当奇怪)混为一谈。

    许多系统 - 包括许多 C/C++ 构建环境,我希望 C# 考虑到 Microsoft 历来设计 Visual Studio 构建过程的方式 - 有两种不同类型的构建可供您执行:

    • 发布版本,只有信息/错误/警告日志,没有调试符号,额外的优化等。
    • 调试版本,启用额外的日志记录,调试符号,可能已调低优化。

    您在开发和调试程序时使用调试版本,并为最终的 QA 和发布发布版本。然而,调试版本独立于在调试器下运行——它们是普通程序,如果你运行它们,运行仍然会输出它们额外的日志信息。这可能非常有用。

    在调试器下运行它们是完全正交的。您可以在调试器下运行发布版本(尽管缺少调试符号,它可能不是很有用)。事实上,我会提出您不希望代码根据您是否在调试器下运行而更改 - 这使得调试在应用程序中实际运行的代码变得相当困难。

    与 C、C++ 和 C# 不同,Java 没有编译时条件的功能,因此程序中的所有内容都已启用。您通常通过一种非常快速的方法来检查是否要发出调试消息,并在没有发出的情况下做尽可能少的工作来处理这个问题。

    【讨论】:

      猜你喜欢
      • 2012-05-17
      • 1970-01-01
      • 2021-02-14
      • 2011-05-06
      • 1970-01-01
      • 2012-09-23
      • 2020-10-31
      • 2018-10-06
      • 2011-05-30
      相关资源
      最近更新 更多