如何在java程序中禁用堆栈跟踪生成?

AD.*_*AD. 7 java debugging stack-trace

我想禁用在抛出异常时生成的堆栈跟踪.我用过,

Runtime.getRuntime().traceInstructions(false);
Runtime.getRuntime().traceMethodCalls(false);
Run Code Online (Sandbox Code Playgroud)

但我仍然可以看到跟踪生成.你怎么能这样做?此外,我需要检测是否有人正在调试我的课程.

我想禁用所有异常跟踪.我不能使用混淆,因为我的产品是一个将用于开发的SDK.我还提供了Runtime,当人们想要部署使用我的SDK构建的应用程序时,会使用它.我的要求是任何使用我的运行时jar的人都不应该能够调试编写的代码...或者至少我会通过避免从我的运行时jar生成堆栈跟踪来使调试变得困难.

我发现的一种方法是所有来自我的运行时jar的异常,我只是捕获它们并在异常对象上设置一个空的StackTraceElement数组并重新抛出它...

为何如此要求?假设您使用我的SDK开发应用程序.(SDK jar无法与您的应用程序捆绑在一起..我已经限制了它,那就是最终:) !!)现在要在客户端的机器上运行您的应用程序,您(或客户端)需要安装客户端计算机上的运行时并运行您的应用程序.现在如果你的客户使用我的Runtime jar开始开发他自己的应用程序怎么办 这对我的生意构成威胁....这就是为什么这个可怕的要求.

为什么禁用堆栈跟踪?
通过禁用堆栈跟踪生成或方法调用跟踪生成我想用我的Runtime jar开发代码很困难,这就是为什么我以这种方式开始我的问题...建议一些其他解决方案来实现这样的要求......

jar*_*bjo 11

我也很想知道你为什么要这样做,但如果你真的有理由,你至少有两个选择:

如果要为自己的Exception实现禁用堆栈跟踪生成,可以简单地覆盖fillInStackTrace方法:

public static class MyException extends Exception {
    @Override
    public Throwable fillInStackTrace() {
        return this;
    }       
}
Run Code Online (Sandbox Code Playgroud)

如果要为所有异常禁用它,可以使用字节代码检测代理来替换Throwable类中的fillInStackTrace方法.但这只适用于Java 6,因为不允许在Java 5中使用检测使用Java方法替换本机方法(fillInStackTrace).

  • 你想要'return this',而不是'return null',否则你违反了fillInStackTrace()的javadoc (3认同)
  • 替换所有异常的`fillInStackTrace`可能会破坏事物; 例如Java安全性. (2认同)

Ste*_*n C 5

  1. 我认为代码不可能知道它正在被调试,除非通过间接(和不可靠)方式测量,例如测量执行代码序列所需的时间.

  2. 无法禁用所有堆栈跟踪.您可以通过覆盖Throwable.fillInStackTrace()不执行任何操作禁用您自己定义的异常类的stracktraces .但这对于你无法改变的课程不起作用.

但是如果你正在考虑做这些事情以防止逆向工程,即使你能做到这一点,你也会浪费你的时间.对于黑客来说,识别应用程序的反向反向工程代码并编辑相关的字节码文件以禁用它是很简单的.

编辑 - 我已经修改了我对你要做的事情的看法.鉴于您正在做的是分发一个SDK,您期望您的客户将其嵌入到他们自己的应用程序中,禁用整个Java应用程序的堆栈跟踪将被视为 客户敌对行为 IMO.作为保护"宝贵"IP的副作用,您使客户/开发人员难以调试自己的代码.即使代码在调用堆栈上没有您宝贵的方法!

如果我是客户,我可能更愿意发送混淆代码而不是这样.但最有可能的是,我会非常努力地找到另一家软件供应商,该供应商并未将其付费客户视为小偷.


Tho*_*nin 3

如果禁用堆栈跟踪生成,JVM 的一些复杂部分(至少是 Sun 的 JVM 实现)将无法工作(我在一些反射支持方法的实现中看到了这一点)。所以我认为根本无法禁用堆栈跟踪生成。这些Runtime.trace*()方法是关于其他东西的(一种比堆栈跟踪更彻底的调试工具)。

总的来说,任何 Java 代码都可以被透明地分析,只要通过字节码检测(字节码在加载时使用额外的指令进行修改)即可。针对此类分析的唯一已知防御措施(我假设您试图对代码内部保密)是混淆。例如,参见ProGuard。混淆将使堆栈跟踪对于任何过度好奇的用户来说毫无用处(而且,遗憾的是,出于同样的原因,它也使调试变得非常困难)。

  • 我发现的一种方法是,所有源自运行时 jar 的异常,我都会捕获它们并在异常对象上设置一个空的 StackTraceElement 数组,然后重新抛出它... (2认同)