tauri-apps / tauri

Build smaller, faster, and more secure desktop applications with a web frontend.
https://tauri.app
Apache License 2.0
79.56k stars 2.36k forks source link

[bug] change window size quickly will cause memory bump so quickly, and finally crash the whole application #6754

Open CGQAQ opened 1 year ago

CGQAQ commented 1 year ago

Describe the bug

change window size quickly will cause memory bump so quickly, and finally crash the whole application

 ELIFECYCLE  Command failed with exit code 4294967295.  ELIFECYCLE  Command failed with exit code 3221225477.  ELIFECYCLE  Command failed with exit code 1.

Reproduction

run the app, drag window edge back and forth quickly, see memory useage go up very quickly

I'll found the code cusing this:

import * as win from "@tauri-apps/api/window";
export async function onMaximizeChange(
  callback: (isMaximized: boolean) => void
): Promise<() => void> {
  return win.appWindow.onResized(() => {
    win.appWindow.isMaximized().then((isMaximized) => {
      callback(isMaximized);
    });
  });
}

// later in component

 useEffect(() => {
    let handle: any = null;
    (async () => {
      try {
        const isMaximized_ = await isMaximized();

        console.log("isMaximized_", isMaximized_)
      } catch {
        /** NOOP */ 
      }

      try {
        // ref: https://github.com/tauri-apps/tao/issues/633
        handle = await onMaximizeChange(async (x) => {
          // console.log("onMaximizeChange", x)
          if (await isMaximized()) {  // <--  my colleague didn't notice that I already give the state in the first argument, 
            console.log("onMaximizeChange maximized");
          } else {
            console.log("onMaximizeChange minimized");
          }
        });
      } catch {
        /** NOOP */
      }
    })();

    return () => {
      // ref: https://tauri.app/v1/api/js/window#onresized
      handle?.();
    };
  }, []);

So basically is like calling win.appWindow.isMaximized() in a loop

Expected behavior

nothing should happen

Platform and versions

› Webview2: 112.0.1722.48
  › MSVC:
      - Visual Studio Community 2022
  › Node.js: 18.12.1
  › npm: 8.19.2
  › pnpm: 8.3.0
  › yarn: 1.22.19
  › rustup: 1.25.2
  › rustc: 1.70.0-nightly
  › cargo: 1.70.0-nightly
  › Rust toolchain: nightly-x86_64-pc-windows-msvc

Packages
  › @tauri-apps/cli [NPM]: 1.2.3

Stack trace

don't have

Additional context

No response

Borber commented 5 months ago

I'm starting to have this problem now, and I haven't found out what happened yet.

arialpew commented 1 month ago

Still happen in Tauri v2 (alpha.11 for me) on Windows 11.

I was abusing resize / minimizing to test my application behavior, and found random crash without stack trace.

At some point, I got a strack trace related to Rc / DispatchMessage / EventLoop / Rc::inc_strong assertion failed. But most of the time, you get nothing outside of a window disappear and npm run tauri dev exit.

Reproduction : Listen to appWindow.onResize event and spam the window resize by holding your left-mouse button and swiping left right very fast untill Tauri crash. This should happen at some point.

If you log message in the resize handler with console.log every time the event is trigger, you'll see it's called almost way to much, especially if you listen to this event in multiple components on your application.

It's well-known that abusing resize event can cause stuttering in web dev, and getting a smooth resize is one of the hardest thing in GUI. A good practice is to debounce resize event - so only the final one will be trigger.

On my Windows 11 laptop with integrated GPU : spamming the resize event by holding the left-mouse and swiping left/right while Chrome Dev Tools is open with Task manager = the Webview2 GPU process memory usage increase exponentially and suddently, boom, everything die.

If you add a debounce, this should help to mitigate but this will NOT solve the fundamental issue.

In release build, without Chrome Dev Tools open, debounce will probably solve this and this should almost never happen in production (almost, because like I said there's some degenerate scenario where to much events could cause this issue surface again). Using debounce also reduce pressure on Webview when resizing = you get a smoother layout resize.

TLDR : Do not spam IPC events and debounce events that could be fired to much (resize, scroll, ...).

Related issue : https://github.com/tauri-apps/tauri/issues/8177

Related keywords for search : event emit crash panicking inc_strong rc dispatchmessage oom allocation failure wry tao high-rate debounce gpu process resize

Edit : I upgraded my application to Tauri v2 beta 19, and it seem this problem is gone.

BUT I didn't extensively tested so take it with a grain of salt. Between v2 alpha.11 and v2 beta.19, there's a tons of update so it's hard to pinpoint which commit solved this - with bisection this should be doable to port this patch to v1 (if this isn't already done). If I found a new crash within this beta build I'll report it again.