Status Update
Comments
st...@visokio.com <st...@visokio.com> #2
class FixDrawerLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
) : DrawerLayout(context, attrs) {
fun registerToFragmentLifecycle(fragment: Fragment) {
fragment.viewLifecycleOwner.launchOnLifecycleDestroy {
super.onDetachedFromWindow()
}
}
}
js...@google.com <js...@google.com> #3
With markdown the same:
I have a project on SingleActivity. And in manifest android:enableOnBackInvokedCallback="true". I have a Root Fragment with a toolbar to which I attach a DrawerLayout.
<!-- XML Root Fragment -->
<androidx.drawerlayout.widget.DrawerLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.appbar.MaterialToolbar />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<androidx.core.widget.NestedScrollView
android:layout_gravity="start">
</androidx.drawerlayout.widget.DrawerLayout>
On button click in DrawerLayout I change RootFragment and lose all View in this Xml after onDestroyView. I don't call close() or closeDrawer() because I need the old state when I return to this fragment. But!
The DrawerLayout calls onDetachedFromWindow() which calls updateBackInvokedCallbackState() where ViewCompat.isAttachedToWindow(this) returns true and all the following condition is also true.
boolean shouldBeRegistered = visibleDrawer != null
&& currentDispatcher != null
&& getDrawerLockMode(visibleDrawer) == LOCK_MODE_UNLOCKED
&& ViewCompat.isAttachedToWindow(this);
As a consequence, the following code cannot be executed:
} else if (!shouldBeRegistered && mBackInvokedDispatcher != null) {
Api33Impl.tryUnregisterOnBackInvokedCallback(
mBackInvokedDispatcher, mBackInvokedCallback);
mBackInvokedDispatcher = null;
}
Where mBackInvokedDispatcher != null is true, and shouldBeRegistered is true (but !shouldBeRegistered is false).
Consequently, my mechanical back button or slide (back gesture) is blocked and not called on a new Root fragment when the DrawerLayout is Destroyed.
<!-- new Root fragment -->
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.appbar.MaterialToolbar />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
There may be a workaround, but that's not all. The fact is that LeakCanary reacts to this error, which claims that after registerOnBackInvokedCallback and not called tryUnregisterOnBackInvokedCallback, a memory leak occurs.
fast fix: android:enableOnBackInvokedCallback="false" or downgrade DrawerLayout to 1.1.1 or
st...@visokio.com <st...@visokio.com> #4
What I've seen is that when I show a new fragment as a result of a drawer layout navigation view being selected, back gestures break with `enableOnBackInvokedCallback` on stop working - and I saw the same else if block you mentioned above _not_ get called and result in stale/stuck back handlers consuming the gestures in this scenario.
I was able to delay showing the fragment until after the drawer layout closed, and the issue did not exist there.
The odd thing is - when I try out older drawer layout versions, the bug still exists. So maybe it's something deeper? I'm working to get a sample app setup to demo this, will circle back soon but wanted to add my current observations.
pe...@google.com <pe...@google.com> #5
after the drawer layout closed
According to my requirements, it should not close, since there is a screen animation where you can see that it is open. So the hot fix only helps through custom view.
fun registerToFragmentLifecycle(fragment: Fragment) {
fragment.viewLifecycleOwner.launchOnLifecycleDestroy {
super.onDetachedFromWindow()
}
}
ko...@chromium.org <ko...@chromium.org> #6
related to `launchOnLifecycleDestroy` - what is that method? I don't see it anywhere in my repo/online. Is that a custom API? Would be curious what that does!
ko...@chromium.org <ko...@chromium.org> #7
Here's my sample app btw -
Again, I'm not sure if our issues are exactly the same, but I get "stuck" not being able to swipe back between fragments after navigating to a fragment starting from a menu item being selected in a Drawer Layout - so it sounds similar...
cb...@chromium.org <cb...@chromium.org> #8
launchOnLifecycleDestroy ->
fun(block: suspend CoroutineScope.(Lifecycle.Event) -> Unit) {
coroutineScope.launch {
val observer = LifecycleEventObserver { _, event -> launch { if (Event.ON_DESTROY == event) block(event) } }
addObserver(observer)
try {
awaitCancellation()
} catch (_: CancellationException) {
removeObserver(observer)
}
}
}
st...@visokio.com <st...@visokio.com> #9
I found that if the drawer layout is part of a fragment, which is in turn replaced with another fragment as part of a navigation action, the bug occurs (back actions are consumed and not forwarded to the app as expected).
However, if you place the drawer layout as part of the parent activity, no bug occurs when you navigate from the drawer layout to another fragment/back/etc.
I assume that's because the drawer layout, when part of the activity, never goes destroyed/removed from the view, so it does not encounter the bug in question.
This is beginning to look like a separate issue related to navigation logic with drawer layouts in fragments/non-activity lifecycles.
st...@visokio.com <st...@visokio.com> #10
I agree with you completely.
st...@visokio.com <st...@visokio.com> #11
And now I've reverted to the same code as previously and cannot reproduce it. Same browser version, same app version. When I looked into it back in 3 months ago, it also suddenly stopped happening while testing. It's intermittent.
Note that when I investigated this back then, I remember that I could not pause the Chrome debugger. This was my first point of call, to see what my code was doing. (I can't recall exactly what the experience was. Maybe devtools was frozen, or maybe clicking pause didn't interrupt anything.) Doesn't this mean it's not a user code issue such as a library problem or infinite loop, and some hang in native code?
I'll come back here when I next see it, and answer Q1-3.
st...@visokio.com <st...@visokio.com> #12
Today I was able to reproduce it immediately.
Q1: Does it happen in incognito more as well? (extensions are sometimes bad for memory)
I could not reproduce it in Incognito. Nor can I reproduce it in my other Chrome user profile. However, since it is intermittent, this is not conclusive.
However, in normal browser mode, I disabled all my extensions (I had just docs and react enabled previously), restarted Chrome, and could still reproduce it. Here's the result:
Crash from Wednesday 5 March 2025 at 05:48:22
Status: Uploaded
Uploaded crash report ID: b5abd6ae63274d6f
Upload time: Wednesday 5 March 2025 at 05:48:23
Local crash context: d31b3885-94db-4d10-ab0e-ee755c454802
Q2: Does it happen with Chrome Dev (https://www.google.com/chrome/dev/ ) version too? (if yes, this means it's likely already fixed)
I could not reproduce it in Chrome Dev, including after I had copied my Chrome data dir in entirety and used the same user profile. However, since it is intermittent, this is not conclusive.
Q3: Do you repro the same issue in Firefox or Safari? (if yes, we have another clue pointing in at the JS library code being the issue)
I could not reproduce it in Safari. Again, inconclusive.
Other observations
I reproduced it with Dev Tools showing. When the browser tab hung (aside from CSS animations), I could interact with the dev console. There was nothing in the Console, and in Sources, I clicked Pause to debug it, the button appeared to accept my click, but the pause did not take effect; I could not see any script position; the debugger did not interrupt any code.
We have a workaround (don't use fetch, use a polyfill, it's crazy but it works), and I will update this report over time as new Chrome versions land if I still see it.
ss...@google.com <ss...@google.com> #13
As per the steps to reproduce provided in
Requesting inputs from the dev team to help move this issue forward. Please feel free to add the Unconfirmed hotlist back if this issue requires TE's attention.
Thanks
cb...@chromium.org <cb...@chromium.org> #14
Thanks for all the details!
Re Q1: Looks like we got indeed the same crasher, where we run OOM when allocating a new stack trace from v8::internal::Isolate::CaptureAndSetErrorStack
If you can consistently reproduce this, it might be an experiment we run.
Q4: Would you mind trying running chrome with the --disable-field-trial-config
flag?
You can launch it from the terminal:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-field-trial-config
Q5: DevTools can increase the memory consumption depending on what tool is active. So that could match here.
st...@visokio.com <st...@visokio.com> #15
Today I'm now on 134.0.6998.45.
- I reproduced the issue as normal (and running an unoptimised dev build of our app): uploaded crash ID
38f52217cc47db46
. - Then Q4 with field trials disabled:
03d5b32905b5ba9d
. - Then back to normal Chrome, and changed to Closure Compiler advanced optimisation build of our app (obfuscated, vastly smaller, maybe it's useful to see another variant), reproduced again,
c392464279c23311
.
In all 3 cases Q5 I did not have dev tools open.
In some cases today, I saw the unresponsive dialog, hit exit, saw RESULT_CODE_HUNG
. Not saw this before, normally I had to wait around a minute for the page to "Aw, Snap" by itself.
Again, it's native fetch
that causes it. Changing that single line of code to use the polyfill stops it happening.
I hope this helps.
cb...@chromium.org <cb...@chromium.org> #16
Handing over to the current stability gardener since I'm on vacation for the next 2 weeks.
cb...@chromium.org <cb...@chromium.org> #17
Ok this looks more promising for debugging. Would it be possible to provide a public version of the broken app somewhere?
st...@visokio.com <st...@visokio.com> #18
I can set one up, but I need a way to share access details with you privately. Is this possible?
Also I have not seen it happen except locally in development via loopback. So I can give you the same app, with the fetch
call (before the polyfill was added), but you may not be able to reproduce it. Do you still want this?
aw...@chromium.org <aw...@chromium.org> #19
drive-by: if this is a regression (the description mentions that the problem was first noticed in December 2024), Steve you could try using the bisect script to pinpoint a commit range where the regression was introduced (assuming the issue reproduces with Chromium as well):
In December 2024 it looks like Chrome Stable would have been at M131, so maybe a good starting revision for the bisection is something like 130.0.6703.0 (the release schedule is at
st...@visokio.com <st...@visokio.com> #20
Unfortunately I don't think bisect will yield fruit. Last December was when we noticed the problem, but this was new code in our app. I have nothing that suggests it is a regression. Also, since it is intermittent, not 100% immediately reprodu inle, it would be very difficult to bisect.
Description
Steps to reproduce the problem
I cannot provide a reproduction case because it only happens specifically in development locally on my MacBook Pro (where it is 100% reproducible). When accessed on a public server by colleagues, it has not been reproduced. I have a crash report.
Problem Description
I have a web app which launches a nested webapp in an IFRAME. The nested webapp uses native browser fetch with promises to request data. In this case the HTTP request takes 5 seconds or more to complete.
I use an action in the app to close the IFRAME. In fact I'm pressing Escape, which is configured to use messaging to tell the parent app to close and dispose of the IFRAME.
When this happens, the tab freezes. Rendering of CSS animations continues, but the tab is completely unresponsive. In OS X Activity Manager, I see CPU at around 400 to 600%, for about a minute, before "Aw, Snap" appears. Before this, I can only recover by closing the tab and reopening it.
If I wait for the fetch to complete, everything is fine thereafter.
If I change the fetch to use XHR, in fact by using the whatwg-fetch official polyfill, the problem does not occur.
I have not been able to get this to happen with a dedicated test case. It is possible that the complexity of our large webapps is a factor.
Additional Comments
I've attached the command-line variations and also the local crash report which Chrome saved, gzipped. If needed to correlate with online reports, client_id is 17299083937919186226. Note this problem was first noticed early December 2024.
Summary
Chrome tab hangs, CPU spikes, then Aw Snap, when you close IFRAME which has an active fetch request
Additional Data
Category: JavaScript
Chrome Channel: Stable
Regression: N/A