【问题标题】:Proguard ate my Object.wait()Proguard 吃了我的 Object.wait()
【发布时间】:2013-05-30 22:13:28
【问题描述】:

我刚刚发现 ProGuard 删除了一个我用来同步线程的 .wait() 调用,这导致了一个竞争条件,这导致了一天愉快的调试:) 无论如何...

我追踪到以下 proguard 配置:

-assumenosideeffects public class android.util.Log {
    <methods>;
}

我想了解为什么会发生这种情况。我不确定为什么假设删除 Log 类没有副作用会导致在不同的类/对象上删除 .wait()。

我看到ProGuard optimization also remove #wait() calls Eric 解释说可能会发生这样的事情。但是,他没有解释原因。

另外,我在这里找到了如何删除日志的示例 (http://proguard.sourceforge.net/index.html#manual/examples.html)。所以,我可以替换这个配置的proguard(但这不是这个问题的重点)。

【问题讨论】:

  • 请问您一个问题...您为什么使用 ProGuard?为了什么?
  • @AdamStelmaszczyk:主要是代码混淆。但是,日志删除是对整体应用程序混淆的一个很好的补充。为什么要问?
  • 因为我认为这不值得你花时间。检查 ProGuard 生成的代码(反编译 apk)。您将看到您可以轻松阅读“混淆”版本。您可以使用简单的 boolean DEBUG = false 标志删除日志。我扔掉了 ProGuard,因为它带来的问题多于好处。
  • 如果您将if (DEBUG) Log.d("")DEBUG 设为falsejavac 将删除它,因为它是无法访问的代码。
  • ProGuard 会删除执行应用程序不需要的所有信息(调试信息和未使用的代码)。它减少了代码大小,提高了性能,通常是保护应用程序的良好第一步。如果您需要更多:DexGuard 积极打击逆向工程,使用不适合开源程序的技术。 (我是 ProGuard 和 DexGuard 的开发者)

标签: android obfuscation proguard


【解决方案1】:

您的原始配置与 Log 的所有方法(显式或继承)匹配,包括 Object#wait()。它告诉 ProGuard wait() 方法没有副作用,并且可以在不损害程序的情况下将其删除。正如您所注意到的,这显然不是真的。使用 -assumenosideeffects,您应该始终明确列出可以安全删除的方法。

【讨论】:

  • 这是否意味着配置“;”如果在任何类上定义,保证会中断同步?
  • 是的,它会移除应用程序代码中对wait()、notify()和notifyAll()的所有调用,这很可能会破坏同步。
  • 如果在类中定义了 ,您是否考虑过返回错误(正是我的情况)?看起来它不是一个接口——它只是在自找麻烦。
猜你喜欢
  • 1970-01-01
  • 2014-05-03
  • 2012-12-20
  • 2017-02-03
  • 1970-01-01
  • 2011-04-12
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多