Skip to content

[dart:ffi] Default initial struct values are uninitialised on allocation #43596

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

Closed
provokateurin opened this issue Sep 29, 2020 · 5 comments
Closed
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi

Comments

@provokateurin
Copy link

When allocating a struct the default value for all pointer fields is null, but that is really counter intuitive, because in they should be nullptr like in C/C++.
This code demonstrates it:

import 'dart:ffi';

class Test extends Struct {
    ffi.Pointer<ffi.Int8> test;
}

void main() {
    final test = allocate<Test>().ref;
    assert(test.test == null); // This should fail
    assert(test.test == nullptr); // This shouldn't fail
}
@mit-mit
Copy link
Member

mit-mit commented Sep 30, 2020

cc @dcharkes

@mit-mit mit-mit added library-ffi area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. labels Sep 30, 2020
@dcharkes
Copy link
Contributor

dcharkes commented Sep 30, 2020

Actually, the memory is uninitialized. So, I would expect a Pointer<Int8> with an address with whatever was in the memory.

  final test = allocate<Test>().ref;
  print(test.test);
  print(test.test == null);
Pointer<Int8>: address=0x7fb6138b5e80
false

Which is exactly what I see locally (MacOS).

Can you give more details on how to reproduce this? Is this the full Dart program? How are you running it (asserts are disabled by default)? What platform?

@provokateurin
Copy link
Author

So I'm writing a flutter embedder in dart and I created the bindings using ffigen. It works quite well, but when I allocate FlutterProjectArgs (https://github.com/flutter/engine/blob/master/shell/platform/embedder/embedder.h#L1165) I don't specify fields like custom_dart_entrypoint, but the flutter engine checks if it's not a nullptr and then uses it (and crashes due to wrong pointers). If I would do the same in C/C++ it would work by just not specifying these fields, because the would be nullptr's.

@dcharkes
Copy link
Contributor

If I would do the same in C/C++ it would work by just not specifying these fields, because the would be nullptr's.

The equivalent of what you're doing in Dart (allocate + ref) in C would be:

MyStruct* ptr = malloc(sizeof(MyStruct)); // Allocates memory, does not initialise.
MyStruct test = *ptr; // Uses uninitialised memory.

Which is not the same as what you'd be normally doing in C:

MyStruct test;

When adding support for passing struct by value(#36730), we're adding support for structs backed by TypedData instead of Pointer. TypedData is initialised to 0 and automatically garbage collected.

For now, you should manually initialise the backing memory. (You could open an issue on the ffigen repository to provide a static method on all generated Structs that initialises the backing memory, and use those instead of allocate+ref.)

@dcharkes dcharkes changed the title [dart:ffi] Default initial struct pointer values are null on allocation [dart:ffi] Default initial struct values are uninitialised on allocation Sep 30, 2020
@mkustermann
Copy link
Member

@jld3103 As explained above, allocating memory using package:ffis allocate<>() leaves the memory uninitialized. This works just as if one calls malloc() in C code and is intentional. It makes memory allocation faster. If a user wants to 0-initialize the memory he can always use <ptr>.asTypedList(...).setRange(0, <ptr>.length, 0) (or something along those lines).

Closing this issue since this is working as intended.

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. library-ffi
Projects
None yet
Development

No branches or pull requests

4 participants