Copy link to clipboard
Copied
I have an application that works just fine in Flash player 29 in all browsers and does not work in Flash player 30 in any browsers. My app doesn't use any of the restricted methods that were in scope for the version 30 release. I've put trace statements in my code and can attach the debugger to it, however, when it freezes the debugger doesn't give any output or errors and the trace statements don't output text any more. It's very bizarre and frustrating. We have other Flash apps that work just fine with version 30 but this single app no longer works in version 30.
I've experienced instances where stepping through the code in the debugger will result in the app working on occasion, it's not clear whether that's due to a timing issue introduced by stepping through the code or if there's some other factor at play.
What's the best way to get to the bottom of this problem and determine a fix? The guidance we've giving our users is to downgrade to version 29, which isn't a path that many people are able to do due to corporate restrictions or other factors.
My guess is that this is related to the timer or event jitter mitigations that were deployed in Flash Player 30; however, those changes typically introduce something on the order of 100 microseconds of delay per call. If you're only calling them once every couple milliseconds, you shouldn't really feel it.
It would be interesting to know if one of these two mms.cfg directives make the problem go away:
EventJitterMicroseconds = 0
TimerJitterMicroseconds = 0
If they do, my suspicion would be that som
...Copy link to clipboard
Copied
It's probably easiest for us to look at it under a C++ debugger. Can you give us a reproducible example?
Copy link to clipboard
Copied
Through a significant amount of troubleshooting and debugging it appears that the problem lies within a section of code that uses setTimeout with a 2 millisecond wait period. The function passed to setTimeout would check for the population of a variable and if the variable isn't populated it would again call setTimeout with a 2 millisecond wait time. Essentially a recursive function with a wait period, whereby the variable being checked could be populated by another part of the app executing in its own thread.
Removing the call for setTimeout makes the app work again. It's very odd because the code works just fine in version 29 but essentially gets caught in an infinite recursive/setTimeout loop in version 30. Our plan is to remove this piece of code and redeploy.
The application in question is not generally available to the public. If you'd like to debug it under a C++ debugger that's something we can certainly facilitate, but it will require more than just providing a url to the app. Let me know if you'd like to discuss further.
Copy link to clipboard
Copied
My guess is that this is related to the timer or event jitter mitigations that were deployed in Flash Player 30; however, those changes typically introduce something on the order of 100 microseconds of delay per call. If you're only calling them once every couple milliseconds, you shouldn't really feel it.
It would be interesting to know if one of these two mms.cfg directives make the problem go away:
EventJitterMicroseconds = 0
TimerJitterMicroseconds = 0
If they do, my suspicion would be that something is throwing events or polling a timer quite a bit faster than expected. That may be happening under the hood, but I haven't heard anyone complaining about setTimeout up until now. If you could share a snippet that gets to the heart of it (I don't want to guess about the specifics of what you might have implemented if I can avoid it), I'd definitely be interested in looking into it further.
Copy link to clipboard
Copied
Well, adding those directives to the mms.cfg file for Chome definitely fixed it. Chrome's mms.cfg file is located here:
C:\Users\{UserName}\AppData\Local\Google\Chrome\User Data\Default\Pepper Data\Shockwave Flash\System\mms.cfg
where {UserName} is replaced with the current user's username. You'll need to create the file and folder if it doesn't already exist.
Unfortunately that's not a scalable, nor secure solution for our users as it disables some critical patches made to the Flash run-time. We're going to stick with the changes to the code we made and redeploy the .swf.
The offending code looked similar to this, and sat in an initialization path for a UI component:
public function someFunction():void {
// myArrayCollection is updated by another component
// in another executing context
if( myArrayCollection.length == 0 ) {
setTimeout(someFunction, 2);
}
// rest of the function below doing mundane stuff
......
}
My guess is that when this component was originally developed there was some race condition that was "fixed" by adding this timeout. Removing the length check and call to setTimeout fixes the application with no observed detrimental side effects to the app.
Copy link to clipboard
Copied
Thanks for the update.
The intent is definitely not to get end-users to set these flags. They're a nice troubleshooting measure for determining what to look at, and possibly as a workaround for enterprise organizations with large deployment that might need to mitigate the impact to an internal tool or something.
Unfortunately, these mitigations are necessary and aren't going away, and I'm not optimistic that we'd be able to optimize for this use-case while still maintaining the integrity of the original mitigation.
If you're a content provider, the best solution is going to be to update your code to avoid calling timers in tight loops. In this instance, setting the timer recursively probably unrolls into a long sequence of timer calls that proves similarly problematic.