Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

co19/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/Finalizer_A01_t04 failed on vm-aot-win-release-x64 #59858

Open
derekxu16 opened this issue Jan 7, 2025 · 2 comments
Assignees
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. gardening library-ffi triaged Issue has been triaged by sub team

Comments

@derekxu16
Copy link
Member

stderr:
Unhandled exception:
Expect.equals(expected: <0>, actual: <1>) fails.
#0      _fail (file:///C:/b/s/w/ir/tests/co19/src/Utils/expect.dart:18)
#1      Expect.equals (file:///C:/b/s/w/ir/tests/co19/src/Utils/expect_common.dart:15)
#2      attachToFinalizer.<anonymous closure> (file:///C:/b/s/w/ir/tests/co19/src/LanguageFeatures/FinalizationRegistry/ffi/Finalizer/Finalizer_A01_t04.dart:40)
<asynchronous suspension>

https://ci.chromium.org/ui/p/dart/builders/ci.sandbox/vm-aot-win-release-x64/4440/overview

@dcharkes
@blaugold

@derekxu16 derekxu16 added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. gardening labels Jan 7, 2025
@a-siva a-siva added the triaged Issue has been triaged by sub team label Jan 8, 2025
@dcharkes
Copy link
Contributor

dcharkes commented Jan 9, 2025

@dcharkes
Copy link
Contributor

dcharkes commented Jan 9, 2025

My hunch is that the optimizer in AOT is being smart here:

accessibleLink is not read in the async callback, nor in main. So, my guess is that the object is no longer alive after object = null.

Because Finalizer does not have require Finalizables in the same way that NativeFinalizer does, there are no guarantees that objects stay alive until a certain point. The optimizer is free to optimize as much as doesn't change the language semantics, and since the object is never accessed again, it may even already forget about object immediately after finalizer.attach(object, 123).

/// @description Checks that finalizer object can be created and its callback
/// will never run if attached object is accessible.

So this comment is wrong. Finalizables if they are accessible the callback will not be run. But for non-Finalizables the callback may run as soon as the object will never be accessed anymore. So for non-Finalizables a more precise description would be:

/// @description Checks that finalizer object can be created and its callback
/// will never run if attached object is accessed.

Possible fix, but this might it redundant with respect to other tests:

// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// @assertion Finalizer<T> constructor (Null safety)
/// Finalizer<T>(void callback(T))
/// Creates a finalizer with the given finalization callback.
///
/// The callback is bound to the current zone when the [Finalizer] is created,
/// and will run in that zone when called.
///
/// @description Checks that finalizer object can be created and its callback
/// will never run if attached object is accessed.
/// @author iarkh@unipro.ru

import 'dart:async';
import '../../gc_utils_lib.dart';
import '../../../../Utils/expect.dart';

int called = 0;
Object? accessedLink;

final Finalizer finalizer = Finalizer((token) {
  Expect.equals(123, token);
  called++;
});

Completer<void> completer = Completer<void>();

@pragma('vm:never-inline')
attachToFinalizer() async {
  Object? object = Object();
  finalizer.attach(object, 123);
  await triggerGcWithDelay();
  accessedLink = object;
  object = null;
  Expect.equals(0, called);
  () async {
    await triggerGcWithDelay();
    Expect.equals(0, called);
    print(accessedLink)
    completer.complete();
  }();
}

main() async {
  await attachToFinalizer();
  await completer.future;
  accessedLink = null;
  // Previous triggerGc move some objects to old space. Do multiple GCs to
  // force all objects to old space.
  await triggerGcWithDelay(repeat: 3);
  Expect.equals(1, called);
  await triggerGcWithDelay();
  Expect.equals(1, called);
}

cc @sgrekhov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. gardening library-ffi triaged Issue has been triaged by sub team
Projects
None yet
Development

No branches or pull requests

3 participants