Java(Android 8.0.0)中的局部浮点变量是如何损坏的?

Java(Android 8.0.0)中的局部浮点变量是如何损坏的?,java,local-variables,corruption,Java,Local Variables,Corruption,更新了重要的新信息(见底部) 使用更好的日志代码进行编辑 我正在追踪我们的应用程序中的一些图形损坏,并将其追踪到这个函数(我随意添加了日志): 大多数情况下,这都能按预期工作,但在游戏中的某个特定点,这会被记录: 09-30 14:40:59.086 10545-11101/? I/[Monkey]: Dissolve encountered. 09-30 14:40:59.086 10545-11101/? I/[Monkey]: Cached dissolve value locally:

更新了重要的新信息(见底部)

使用更好的日志代码进行编辑

我正在追踪我们的应用程序中的一些图形损坏,并将其追踪到这个函数(我随意添加了日志):

大多数情况下,这都能按预期工作,但在游戏中的某个特定点,这会被记录:

09-30 14:40:59.086 10545-11101/? I/[Monkey]: Dissolve encountered.
09-30 14:40:59.086 10545-11101/? I/[Monkey]: Cached dissolve value locally: 1.0 1.0
09-30 14:40:59.086 10545-11101/? I/[Monkey]: Updated dissolve value: 0.1
09-30 14:40:59.086 10545-11101/? I/[Monkey]: Monitoring t_d=1.0
09-30 14:40:59.087 10545-11101/? I/[Monkey]: Monitoring t_d=-1.6314132E-19
09-30 14:40:59.087 10545-11101/? I/[Monkey]: Dissolve post restore -1.6314132E-19
要对其进行分解:将静态值m_dissole复制到局部变量t_d,其值为1.0f。然后将静态值修改为0.1f,并用于子对象的渲染。完成后,局部变量t_d在用于恢复静态值之前再次被记录,但同时神秘地变为-1.6314132E-19(该值每次似乎都不可预测地不同)

我不知道本地Java变量会以这种方式损坏

更新:

作为测试,我将t_d作为包含上述代码列表的类的成员变量(而不是局部变量),其值不再损坏

作为进一步的测试,我随后添加了一些局部浮点变量(m_e到m_j),这些变量除了在super.p_PostDraw()之前和之后打印外,什么都不用。事情是这样的:

09-30 15:20:51.219 28384-28877/? I/[Monkey]: M_E ETC BEFORE: 1.0 1.0 1.0 1.0 1.0 1.0
09-30 15:20:51.220 28384-28877/? I/[Monkey]: M_E ETC AFTER: 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44
09-30 15:56:37.686 1815-2373/? I/[Monkey]: M_E BEFORE: 2.0 1.0 3.0 4.0 5.0 1.0
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_IffLT.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_Delay.p_Pump2(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_SetUniform_4F.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_EX_VarString.p_Set7(app.hidden.name.c_Expression) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing java.lang.String app.hidden.name.c_EX_Format.p_AsString() due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_IffNotEqual.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_PinVP.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/[Monkey]: M_E AFTER: 2.0 -5.6063644E-30 3.0 4.0 5.0 -5.6063644E-30
然后,我从logcat中删除了所有过滤器,并发现这两行之间隐藏着:

09-30 15:20:51.219 28384-28877/? I/[Monkey]: M_E ETC BEFORE: 1.0 1.0 1.0 1.0 1.0 1.0
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_IffLT.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_Delay.p_Pump2(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_SetUniform_4F.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_EX_VarString.p_Set7(app.hidden.name.c_Expression) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing java.lang.String app.hidden.name.c_EX_Format.p_AsString() due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_IffNotEqual.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/zygote64: Deoptimizing int app.hidden.name.c_PinVP.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:20:51.220 28384-28877/? I/[Monkey]: M_E ETC AFTER: 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44
更新:

我调整了上面的代码,将局部变量设置为不同的值,而不是全部设置为1.0f,结果是:

09-30 15:20:51.219 28384-28877/? I/[Monkey]: M_E ETC BEFORE: 1.0 1.0 1.0 1.0 1.0 1.0
09-30 15:20:51.220 28384-28877/? I/[Monkey]: M_E ETC AFTER: 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44 6.7E-44
09-30 15:56:37.686 1815-2373/? I/[Monkey]: M_E BEFORE: 2.0 1.0 3.0 4.0 5.0 1.0
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_IffLT.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_Delay.p_Pump2(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_SetUniform_4F.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.687 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_EX_VarString.p_Set7(app.hidden.name.c_Expression) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing java.lang.String app.hidden.name.c_EX_Format.p_AsString() due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_IffNotEqual.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/zygote64: Deoptimizing int app.hidden.name.c_PinVP.p_Update4(app.hidden.name.c_Gel) due to JIT inline cache
09-30 15:56:37.688 1815-2373/? I/[Monkey]: M_E AFTER: 2.0 -5.6063644E-30 3.0 4.0 5.0 -5.6063644E-30
换句话说,只有设置为1.0f的局部变量已损坏。不是第一个声明的或任何东西,只是设置为1.0f的。然后,我尝试将所有局部变量设置为除1.0f以外的不同数字,未发生损坏

肯定会有某种奖品给史上最晦涩难懂的虫子吗?如果ART对函数进行优化,但仅当局部变量的值为1.0时,局部变量才会损坏

我不知道本地Java变量会以这种方式损坏

如果某个地方的本机代码践踏了包含
t\d
变量的堆栈帧,则可能会发生这种情况

如果本节中存在竞争条件或内存危险,也可能发生这种情况:

   float t_d=c_GColour.m_dissolve;
   bb_std_lang.print("Dissolve pre stack: " + c_GColour.m_dissolve);
如果仔细观察,您实际上并不是在打印
t\u d
。您所做的是打印
c\u GColour.m\u dissole
的(明显)值。。。分配给
t\u d
后。它可能已经改变了

(请注意,您正在访问一个裸变量
m_dissolve
,显然没有任何同步。即使
m_dissolve
声明为
volatile
,这里也存在潜在的争用条件)

我不知道本地Java变量会以这种方式损坏

如果某个地方的本机代码践踏了包含
t\d
变量的堆栈帧,则可能会发生这种情况

如果本节中存在竞争条件或内存危险,也可能发生这种情况:

   float t_d=c_GColour.m_dissolve;
   bb_std_lang.print("Dissolve pre stack: " + c_GColour.m_dissolve);
如果仔细观察,您实际上并不是在打印
t\u d
。您所做的是打印
c\u GColour.m\u dissole
的(明显)值。。。分配给
t\u d
后。它可能已经改变了


(请注意,您正在访问一个裸变量
m_dissolve
,显然没有任何同步。即使
m_dissolve
被声明为
volatile
),这里也存在潜在的争用条件)

这是一个非常奇怪的问题,似乎是ART/JIT中的bug。 我可以看到至少3个不同的开发人员故事有相同的问题。我认为可能会有更多的错误,但这种错误真的很难复制

我在使用LibGDX框架开发游戏的过程中遇到了这个问题。这个框架中的UI是通过大量复杂的计算创建的,在那里大量使用浮点数。在我的例子中,UI组件接收到错误的坐标,所以布局被完全破坏

奇怪的是,你不能用DEBUG-apk重现这个问题,只能用RELEASE-apk。更改manifest
android:debuggable=true
的值也将不起作用。所以调试是非常痛苦的,您需要监视logcat并验证浮点变量的值

有一个问题是@Peeling造成的,因此如果您有相关问题,请要求android开发人员解决:

变通办法 在我真正需要UI之前,我强迫编译器执行和UI相关的方法的“去优化”。我创建了模拟“表”组件,用其他模拟组件填充它(创建类似于真实组件的布局),并调用了我在日志中看到的方法(当发生去优化时)。我每次在应用程序启动时都会执行此操作,对我来说,这个问题似乎是“固定的”——“去优化”在这一点之后永远不会发生,在这之后布局总是正确的


我希望它能帮助那些在这个问题上花了很多时间的人。

这是一个非常奇怪的问题,似乎是ART/JIT中的错误。 我可以看到至少3个不同的开发人员故事有相同的问题。我认为可能会有更多的错误,但这种错误真的很难复制

我在使用LibGDX框架开发游戏的过程中遇到了这个问题。这个框架中的UI是通过大量复杂的计算创建的,在那里大量使用浮点数。在我的例子中,UI组件接收到错误的坐标,所以布局被完全破坏

奇怪的是,你不能用DEBUG-apk重现这个问题,只能用RELEASE-apk。更改manifest
android:debuggable=true
的值也将不起作用。所以调试是非常痛苦的,您需要监视logcat并验证浮点变量的值

有一个问题是@Peeling造成的,因此如果您有相关的