Skip to content

[ffi] Async sample crashes on Windows precompiled #40564

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
dcharkes opened this issue Feb 10, 2020 · 2 comments
Closed

[ffi] Async sample crashes on Windows precompiled #40564

dcharkes opened this issue Feb 10, 2020 · 2 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi

Comments

@dcharkes
Copy link
Contributor

dcharkes commented Feb 10, 2020

Test crashes on Windows in precompiled mode, but runs fine in JIT mode.

https://dart-review.googlesource.com/c/sdk/+/134704

C:\src\dart-sdk\sdk>python tools/test.py -n dartk-win-debug-x64 samples/ffi/async/async_test -v -k
Test configuration:
    dartk-win-debug-x64(architecture: x64, compiler: dartk, mode: debug, runtime: vm, system: win)
Suites tested: samples
Running "vm" command: set DART_CONFIGURATION=DebugX64 & set DART_SUPPRESS_WER=1 & out\DebugX64\dart.exe --ignore-unrecognized-flags --packages=C:\src\dart-sdk\sdk\.packages C:\src\dart-sdk\sdk\samples\ffi\async\async_test.dart
Done dartk-vm debug_x64 samples/ffi/async/async_test: pass
C:\src\dart-sdk\sdk>python tools/test.py -n dartkp-win-debug-x64 samples/ffi/async/async_test -v -k
Test configuration:
    dartkp-win-debug-x64(architecture: x64, compiler: dartkp, mode: debug, runtime: dart_precompiled, system: win, vm-options: [--no-enable-malloc-hooks])
Suites tested: samples
Running "vm_compile_to_kernel []" command: set DART_CONFIGURATION=DebugX64 & set DART_SUPPRESS_WER=1 & C:\src\dart-sdk\sdk\pkg\vm\tool\gen_kernel.bat --aot --platform=out/DebugX64/vm_platform_strong.dill -o C:\src\dart-sdk\sdk\out\DebugX64\generated_compilations\dartkp\samples_ffi_async_async_test\out.dill C:\src\dart-sdk\sdk\samples\ffi\async\async_test.dart --packages=C:\src\dart-sdk\sdk\.packages -Ddart.developer.causal_async_stacks=true
Running "precompiler" command: set DART_CONFIGURATION=DebugX64 & set DART_SUPPRESS_WER=1 & out\DebugX64\gen_snapshot --snapshot-kind=app-aot-elf --elf=C:/src/dart-sdk/sdk/out/DebugX64/generated_compilations/dartkp/samples_ffi_async_async_test/out.aotsnapshot --no-enable-malloc-hooks --ignore-unrecognized-flags --packages=C:\src\dart-sdk\sdk\.packages C:\src\dart-sdk\sdk\out\DebugX64\generated_compilations\dartkp\samples_ffi_async_async_test\out.dill
Running "vm" command: set DART_CONFIGURATION=DebugX64 & set DART_SUPPRESS_WER=1 & out\DebugX64\dart_precompiled_runtime.exe --no-enable-malloc-hooks --ignore-unrecognized-flags --packages=C:\src\dart-sdk\sdk\.packages C:/src/dart-sdk/sdk/out/DebugX64/generated_compilations/dartkp/samples_ffi_async_async_test/out.aotsnapshot

FAILED: dartkp-dart_precompiled debug_x64 samples/ffi/async/async_test
Expected: Pass
Actual: Crash

--- Command "vm_compile_to_kernel []" (took 14.000224s):
set DART_CONFIGURATION=DebugX64 & set DART_SUPPRESS_WER=1 & C:\src\dart-sdk\sdk\pkg\vm\tool\gen_kernel.bat --aot --platform=out/DebugX64/vm_platform_strong.dill -o C:\src\dart-sdk\sdk\out\DebugX64\generated_compilations\dartkp\samples_ffi_async_async_test\out.dill C:\src\dart-sdk\sdk\samples\ffi\async\async_test.dart --packages=C:\src\dart-sdk\sdk\.packages -Ddart.developer.causal_async_stacks=true

exit code:
0

--- Command "precompiler" (took 11.000273s):
set DART_CONFIGURATION=DebugX64 & set DART_SUPPRESS_WER=1 & out\DebugX64\gen_snapshot --snapshot-kind=app-aot-elf --elf=C:/src/dart-sdk/sdk/out/DebugX64/generated_compilations/dartkp/samples_ffi_async_async_test/out.aotsnapshot --no-enable-malloc-hooks --ignore-unrecognized-flags --packages=C:\src\dart-sdk\sdk\.packages C:\src\dart-sdk\sdk\out\DebugX64\generated_compilations\dartkp\samples_ffi_async_async_test\out.dill

exit code:
0

--- Command "vm" (took 307ms):
set DART_CONFIGURATION=DebugX64 & set DART_SUPPRESS_WER=1 & out\DebugX64\dart_precompiled_runtime.exe --no-enable-malloc-hooks --ignore-unrecognized-flags --packages=C:\src\dart-sdk\sdk\.packages C:/src/dart-sdk/sdk/out/DebugX64/generated_compilations/dartkp/samples_ffi_async_async_test/out.aotsnapshot

exit code:
3

stdout:
a
b
yielding
Starting SimulateWork.
Starting worker threads.
Work1 Start.
Work2 Start.
Posting message (send_port: e9adb7343b907, work_address: 30efa60).
Started SimulateWork.

stderr:
===== CRASH =====
ExceptionCode=-1073741819, ExceptionFlags=0, ExceptionAddress=00000000015510F6
version=2.8.0-edge.76e7065ad5aaa2fe3010e9d767b964c0e86793d5 (Mon Feb 10 16:04:55 2020 +0100) on "windows_x64"
thread=14320, isolate=(null)(0000000000000000)
isolate_instructions=0, vm_instructions=21f2000
Stack dump aborted because InitialRegisterCheck failed.

From VS debugger:

Exception thrown at 0x00000000015510F6 in dart_precompiled_runtime.exe: 0xC0000005: Access violation executing location 0x00000000015510F6.

0000000004C86C41 call qword ptr [__imp_EnterCriticalSection (0538F4F0h)]

 	00000000015510f6()	Unknown
>	dart.exe!__acrt_lock(__acrt_lock_id _Lock) Line 55	C++
 	dart.exe!_realloc_dbg(void * block, unsigned __int64 requested_size, int block_use, const char * file_name, int line_number) Line 754	C++
 	dart.exe!realloc(void * block, unsigned __int64 size) Line 41	C++
 	[Inline Frame] dart.exe!dart::WriteStream::{ctor}(unsigned char * *) Line 324	C++
 	[Inline Frame] dart.exe!dart::BaseWriter::{ctor}(unsigned char *(*)(unsigned char *, __int64, __int64)) Line 542	C++
 	dart.exe!dart::ApiMessageWriter::ApiMessageWriter() Line 777	C++
 	dart.exe!dart::PostCObjectHelper(__int64 port_id, _Dart_CObject * message) Line 47	C++
 	ffi_test_functions.dll!dart::NotifyDart(__int64 send_port, const std::function<void __cdecl(void)> * work) Line 306	C++
 	ffi_test_functions.dll!dart::doCallback2(__int64 a) Line 339	C++
 	ffi_test_functions.dll!dart::Work2() Line 363	C++
 	[Inline Frame] ffi_test_functions.dll!std::_Invoker_functor::_Call(void(*)() &&) Line 230	C++
 	[Inline Frame] ffi_test_functions.dll!std::invoke(void(*)() &&) Line 230	C++
 	[Inline Frame] ffi_test_functions.dll!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Execute(std::tuple<void (__cdecl*)(void)> &) Line 238	C++
 	[Inline Frame] ffi_test_functions.dll!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Run(std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > > *) Line 245	C++
 	ffi_test_functions.dll!std::_LaunchPad<std::unique_ptr<std::tuple<void (__cdecl*)(void)>,std::default_delete<std::tuple<void (__cdecl*)(void)> > > >::_Go() Line 230	C++
 	ffi_test_functions.dll!std::_Pad::_Call_func(void * _Data) Line 209	C++
 	ffi_test_functions.dll!thread_start<unsigned int (__cdecl*)(void *),1>(void * const parameter) Line 97	C++
 	kernel32.dll!BaseThreadInitThunk�()	Unknown
 	ntdll.dll!RtlUserThreadStart�()	Unknown

cc @mkustermann

The alloc that is used:

static uint8_t* malloc_allocator(uint8_t* ptr,
                                 intptr_t old_size,
                                 intptr_t new_size) {
  void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
  return reinterpret_cast<uint8_t*>(new_ptr);
}

N.b. it also fails in Release mode.

If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes.

	block	0x0000000000000000	void * const
	size	0x0000000000000200	const unsigned __int64

runtime\vm\datastream.h:324

   *buffer_ = reinterpret_cast<uint8_t*>(alloc_(NULL, 0, initial_size_));

Debugger is at some locking step.

--- minkernel\crts\ucrt\src\appcrt\internal\locks.cpp --------------------------
void __cdecl __vcrt_lock(_In_ __vcrt_lock_id _Lock)
{
    EnterCriticalSection(&__vcrt_lock_table[_Lock]);
0000000004C86C20  mov         dword ptr [rsp+8],ecx  
0000000004C86C24  sub         rsp,28h  
}
0000000004C86C28  movsxd      rax,dword ptr [_Lock]  
0000000004C86C2D  imul        rax,rax,28h  
0000000004C86C31  lea         rcx,[__acrt_lock_table (052BCEA0h)]  
0000000004C86C38  add         rcx,rax  
0000000004C86C3B  mov         rax,rcx  
0000000004C86C3E  mov         rcx,rax  
0000000004C86C41  call        qword ptr [__imp_EnterCriticalSection (0538F4F0h)]  
^^^^^^^^^^^
0000000004C86C47  add         rsp,28h  
0000000004C86C4B  ret  
@dcharkes dcharkes added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi labels Feb 10, 2020
@dcharkes
Copy link
Contributor Author

dcharkes commented Feb 11, 2020

Update, it's trying to use dart.exe symbols, instead of dart_precompiled_runtime.exe symbols in AOT. That's why it works in JIT but not in AOT.

Changing the way we build the dll makes it work in AOT, but not in JIT:

shared_library("ffi_test_functions") {
  deps = [
    ":dart",
  ]

  # The two files here do not depend on each other.
  # flutter/flutter integration tests will only use `ffi_test_functions.cc` -
  # any test functionality using `dart_api.h` has to go into
  # `ffi_test_functions_vmspecific.cc`.
  sources = [
    "ffi_test/ffi_test_functions.cc",
    "ffi_test/ffi_test_functions_vmspecific.cc",
  ]
  if (is_win && current_cpu == "x64") {
    sources += [ "ffi_test/clobber_x64_win.S" ]
  } else if (!is_win) {
    sources += [ "ffi_test/clobber_$current_cpu.S" ]
  }
  include_dirs = [ ".." ]
  defines = [
    # The only effect of DART_SHARED_LIB is to export the Dart API.
    "DART_SHARED_LIB",
  ]
  if (is_linux || is_android) {
    cflags = [ "-fPIC" ]
  }
  if (is_win) {
    libs = [ "dart_precompiled_runtime.lib" ] # changed this one
    abs_root_out_dir = rebase_path(root_out_dir)
    ldflags = [ "/LIBPATH:$abs_root_out_dir" ]
  }
}

@dcharkes
Copy link
Contributor Author

I filed an issue for the root cause: #40579.

copybara-service bot pushed a commit that referenced this issue Oct 14, 2021
Splits up tests/ffi/function_structs_by_value_generated_test.dart in
- compounds
- non-leaf calls
- leaf calls

We could also consider splitting on chunks from the `functions` from
tests/ffi/generator/structs_by_value_tests_configuration.dart as a
follow up.

TEST=This only splits up the tests, please reapprove failures.
Expected failures:
https://dart-ci.firebaseapp.com/current_results/#/filter=ffi
- windows precompiled #40564
- mac arm64 #46349

Bug: #45007

Change-Id: Id3d9987cbc1e09f579b8cc68ce72fe5d36348b80
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-nnbd-win-release-x64-try,vm-kernel-precomp-win-release-x64-try,vm-kernel-precomp-win-debug-x64c-try,pkg-mac-release-arm64-try,vm-kernel-mac-release-arm64-try,vm-kernel-nnbd-mac-debug-arm64-try,vm-kernel-nnbd-mac-release-arm64-try,vm-kernel-precomp-nnbd-mac-release-arm64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216666
Reviewed-by: Clement Skau <[email protected]>
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

1 participant