From 3a668dcf035041a7a372bbde7872f3b85ad02e19 Mon Sep 17 00:00:00 2001 From: Alexander Aprelev Date: Thu, 11 May 2023 03:14:27 +0000 Subject: [PATCH] [vm/win/aot] Provide unwinding information for Windows AOT snapshots. Fixes https://github.com/dart-lang/sdk/issues/52045 TEST=ffi_induce_a_crash_test Change-Id: Ic047df10732d6ff8cf695ce098d80ec3a098dbf9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/302380 Reviewed-by: Ryan Macnak Commit-Queue: Alexander Aprelev --- runtime/bin/elf_loader.cc | 26 +++++ runtime/platform/platform_sources.gni | 3 + runtime/platform/unwinding_records.cc | 25 +++++ runtime/platform/unwinding_records.h | 94 +++++++++++++++++ runtime/platform/unwinding_records_win.cc | 86 +++++++++++++++ runtime/vm/dart.cc | 6 +- runtime/vm/elf.cc | 30 ++++++ runtime/vm/heap/pages.cc | 3 +- runtime/vm/unwinding_records.cc | 5 - runtime/vm/unwinding_records.h | 5 +- runtime/vm/unwinding_records_win.cc | 122 ++++------------------ tests/ffi/ffi_induce_a_crash_test.dart | 2 - 12 files changed, 295 insertions(+), 112 deletions(-) create mode 100644 runtime/platform/unwinding_records.cc create mode 100644 runtime/platform/unwinding_records.h create mode 100644 runtime/platform/unwinding_records_win.cc diff --git a/runtime/bin/elf_loader.cc b/runtime/bin/elf_loader.cc index fb0e3a039a5..cd799e0f6d3 100644 --- a/runtime/bin/elf_loader.cc +++ b/runtime/bin/elf_loader.cc @@ -16,6 +16,8 @@ #include "bin/virtual_memory.h" #include "platform/elf.h" +#include "platform/unwinding_records.h" + namespace dart { namespace bin { @@ -239,6 +241,12 @@ class LoadedElf { const dart::elf::Symbol* dynamic_symbol_table_ = nullptr; uword dynamic_symbol_count_ = 0; +#if defined(DART_HOST_OS_WINDOWS) && defined(HOST_ARCH_X64) + // Dynamic table for looking up unwinding exceptions info. + // Initialized by LoadSegments as we load executable segment. + MallocGrowableArray dynamic_runtime_function_tables_; +#endif + DISALLOW_COPY_AND_ASSIGN(LoadedElf); }; @@ -261,6 +269,7 @@ class LoadedElf { } bool LoadedElf::Load() { + UnwindingRecordsPlatform::Init(); VirtualMemory::Init(); if (error_ != nullptr) { @@ -291,6 +300,13 @@ LoadedElf::~LoadedElf() { program_table_mapping_.reset(); section_table_mapping_.reset(); section_string_table_mapping_.reset(); +#if defined(DART_HOST_OS_WINDOWS) && defined(HOST_ARCH_X64) + for (intptr_t i = 0; i < dynamic_runtime_function_tables_.length(); i++) { + UnwindingRecordsPlatform::UnregisterDynamicTable( + dynamic_runtime_function_tables_[i]); + } + UnwindingRecordsPlatform::Cleanup(); +#endif } bool LoadedElf::ReadHeader() { @@ -446,6 +462,16 @@ bool LoadedElf::LoadSegments() { CHECK_ERROR(memory != nullptr, "Could not map segment."); CHECK_ERROR(memory->address() == memory_start, "Mapping not at requested address."); +#if defined(DART_HOST_OS_WINDOWS) && defined(HOST_ARCH_X64) + // For executable pages register unwinding information that should be + // present on the page. + if (map_type == File::kReadExecute) { + void* ptable = nullptr; + UnwindingRecordsPlatform::RegisterExecutableMemory( + memory->address(), memory->size(), &ptable); + dynamic_runtime_function_tables_.Add(ptable); + } +#endif } return true; diff --git a/runtime/platform/platform_sources.gni b/runtime/platform/platform_sources.gni index bef56feb093..e300478c7ea 100644 --- a/runtime/platform/platform_sources.gni +++ b/runtime/platform/platform_sources.gni @@ -32,6 +32,9 @@ platform_sources = [ "thread_sanitizer.h", "unicode.cc", "unicode.h", + "unwinding_records.cc", + "unwinding_records.h", + "unwinding_records_win.cc", "utils.cc", "utils.h", "utils_android.cc", diff --git a/runtime/platform/unwinding_records.cc b/runtime/platform/unwinding_records.cc new file mode 100644 index 00000000000..c9db5a6e9bf --- /dev/null +++ b/runtime/platform/unwinding_records.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2023, 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. + +#include "platform/unwinding_records.h" +#include "vm/globals.h" + +#if !defined(DART_HOST_OS_WINDOWS) || !defined(TARGET_ARCH_X64) + +namespace dart { + +void UnwindingRecordsPlatform::Init() {} +void UnwindingRecordsPlatform::Cleanup() {} +void UnwindingRecordsPlatform::RegisterExecutableMemory( + void* start, + intptr_t size, + void** pp_dynamic_table) {} +void UnwindingRecordsPlatform::UnregisterDynamicTable(void* p_dynamic_table) {} +intptr_t UnwindingRecordsPlatform::SizeInBytes() { + return 0; +} + +} // namespace dart + +#endif // !defined(DART_HOST_OS_WINDOWS) || !defined(TARGET_ARCH_X64) diff --git a/runtime/platform/unwinding_records.h b/runtime/platform/unwinding_records.h new file mode 100644 index 00000000000..b0da0c6804b --- /dev/null +++ b/runtime/platform/unwinding_records.h @@ -0,0 +1,94 @@ +// Copyright (c) 2023, 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. +// Class for patching compiled code. + +#ifndef RUNTIME_PLATFORM_UNWINDING_RECORDS_H_ +#define RUNTIME_PLATFORM_UNWINDING_RECORDS_H_ + +#include "platform/allocation.h" + +namespace dart { + +class UnwindingRecordsPlatform : public AllStatic { + public: + static void Init(); + static void Cleanup(); + + static intptr_t SizeInBytes(); + + static void RegisterExecutableMemory(void* start, + intptr_t size, + void** pp_dynamic_table); + static void UnregisterDynamicTable(void* p_dynamic_table); + + static void* GetAddGrowableFunctionTableFunc(); + static void* GetDeleteGrowableFunctionTableFunc(); +}; + +#if defined(DART_HOST_OS_WINDOWS) && defined(TARGET_ARCH_X64) + +#pragma pack(push, 1) +// +// Refer to https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64 +// +typedef unsigned char UBYTE; +typedef union _UNWIND_CODE { + struct { + UBYTE CodeOffset; + UBYTE UnwindOp : 4; + UBYTE OpInfo : 4; + }; + USHORT FrameOffset; +} UNWIND_CODE, *PUNWIND_CODE; + +typedef struct _UNWIND_INFO { + UBYTE Version : 3; + UBYTE Flags : 5; + UBYTE SizeOfProlog; + UBYTE CountOfCodes; + UBYTE FrameRegister : 4; + UBYTE FrameOffset : 4; + UNWIND_CODE UnwindCode[2]; +} UNWIND_INFO, *PUNWIND_INFO; + +static constexpr int kPushRbpInstructionLength = 1; +static const int kMovRbpRspInstructionLength = 3; +static constexpr int kRbpPrefixLength = + kPushRbpInstructionLength + kMovRbpRspInstructionLength; +static constexpr int kRBP = 5; + +struct GeneratedCodeUnwindInfo { + UNWIND_INFO unwind_info; + + GeneratedCodeUnwindInfo() { + unwind_info.Version = 1; + unwind_info.Flags = UNW_FLAG_NHANDLER; + unwind_info.SizeOfProlog = kRbpPrefixLength; + unwind_info.CountOfCodes = 2; + unwind_info.FrameRegister = kRBP; + unwind_info.FrameOffset = 0; + unwind_info.UnwindCode[0].CodeOffset = kRbpPrefixLength; + unwind_info.UnwindCode[0].UnwindOp = 3; // UWOP_SET_FPREG + unwind_info.UnwindCode[0].OpInfo = 0; + unwind_info.UnwindCode[1].CodeOffset = kPushRbpInstructionLength; + unwind_info.UnwindCode[1].UnwindOp = 0; // UWOP_PUSH_NONVOL + unwind_info.UnwindCode[1].OpInfo = kRBP; + } +}; + +struct CodeRangeUnwindingRecord { + void* dynamic_table; + uint32_t runtime_function_count; + GeneratedCodeUnwindInfo unwind_info; + intptr_t exception_handler; + RUNTIME_FUNCTION runtime_function[1]; +}; + +#pragma pack(pop) + +#endif // defined(DART_HOST_OS_WINDOWS) && defined(TARGET_ARCH_X64) + +} // namespace dart + +#endif // RUNTIME_PLATFORM_UNWINDING_RECORDS_H_ diff --git a/runtime/platform/unwinding_records_win.cc b/runtime/platform/unwinding_records_win.cc new file mode 100644 index 00000000000..342a8d24fa4 --- /dev/null +++ b/runtime/platform/unwinding_records_win.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2023, 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. + +#include "platform/unwinding_records.h" + +#include "platform/assert.h" +#include "platform/globals.h" + +#if defined(DART_HOST_OS_WINDOWS) && defined(TARGET_ARCH_X64) + +namespace dart { + +static HMODULE ntdll_module; +static decltype( + &::RtlAddGrowableFunctionTable) add_growable_function_table_func_ = nullptr; +static decltype( + &::RtlDeleteGrowableFunctionTable) delete_growable_function_table_func_ = + nullptr; + +const intptr_t kReservedUnwindingRecordsSizeBytes = 64; +intptr_t UnwindingRecordsPlatform::SizeInBytes() { + return kReservedUnwindingRecordsSizeBytes; +} + +void* UnwindingRecordsPlatform::GetAddGrowableFunctionTableFunc() { + return add_growable_function_table_func_; +} + +void* UnwindingRecordsPlatform::GetDeleteGrowableFunctionTableFunc() { + return delete_growable_function_table_func_; +} + +void UnwindingRecordsPlatform::Init() { + ntdll_module = + LoadLibraryEx(L"ntdll.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + ASSERT(ntdll_module != nullptr); + // This pair of functions is not available on Windows 7. + add_growable_function_table_func_ = + reinterpret_cast( + ::GetProcAddress(ntdll_module, "RtlAddGrowableFunctionTable")); + delete_growable_function_table_func_ = + reinterpret_cast( + ::GetProcAddress(ntdll_module, "RtlDeleteGrowableFunctionTable")); + // Either both available, or both not available. + ASSERT((add_growable_function_table_func_ == nullptr) == + (delete_growable_function_table_func_ == nullptr)); +} + +void UnwindingRecordsPlatform::Cleanup() { + FreeLibrary(ntdll_module); +} + +void UnwindingRecordsPlatform::RegisterExecutableMemory( + void* start, + intptr_t size, + void** pp_dynamic_table) { + auto func = add_growable_function_table_func_; + if (func == nullptr) { + return; + } + intptr_t unwinding_record_offset = size - kReservedUnwindingRecordsSizeBytes; + uint8_t* record_ptr = static_cast(start) + unwinding_record_offset; + CodeRangeUnwindingRecord* record = + reinterpret_cast(record_ptr); + uword start_num = reinterpret_cast(start); + uword end_num = start_num + size; + if (func(pp_dynamic_table, + /*FunctionTable=*/record->runtime_function, + /*EntryCount=*/record->runtime_function_count, + /*MaximumEntryCount=*/record->runtime_function_count, + /*RangeBase=*/start_num, + /*RangeEnd=*/end_num) != 0) { + FATAL("Failed to add growable function table: %d\n", GetLastError()); + } +} + +void UnwindingRecordsPlatform::UnregisterDynamicTable(void* p_dynamic_table) { + auto func = delete_growable_function_table_func_; + if (func == nullptr) return; + func(p_dynamic_table); +} + +} // namespace dart + +#endif // defined(DART_HOST_OS_WINDOWS) diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index 3701f855a13..547335cca09 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc @@ -7,6 +7,8 @@ #include "vm/dart.h" +#include "platform/unwinding_records.h" + #include "vm/app_snapshot.h" #include "vm/code_observers.h" #include "vm/compiler/runtime_offsets_extracted.h" @@ -334,7 +336,7 @@ char* Dart::DartInit(const Dart_InitializeParams* params) { Api::Init(); NativeSymbolResolver::Init(); NOT_IN_PRODUCT(Profiler::Init()); - UnwindingRecords::Init(); + UnwindingRecordsPlatform::Init(); Page::Init(); StoreBuffer::Init(); MarkingStack::Init(); @@ -767,7 +769,7 @@ char* Dart::Cleanup() { StoreBuffer::Cleanup(); Object::Cleanup(); Page::Cleanup(); - UnwindingRecords::Cleanup(); + UnwindingRecordsPlatform::Cleanup(); StubCode::Cleanup(); #if defined(SUPPORT_TIMELINE) if (FLAG_trace_shutdown) { diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc index fe803b78ac3..fbdecd4718b 100644 --- a/runtime/vm/elf.cc +++ b/runtime/vm/elf.cc @@ -5,12 +5,14 @@ #include "vm/elf.h" #include "platform/elf.h" +#include "platform/unwinding_records.h" #include "vm/cpu.h" #include "vm/dwarf.h" #include "vm/hash_map.h" #include "vm/image_snapshot.h" #include "vm/stack_frame.h" #include "vm/thread.h" +#include "vm/unwinding_records.h" #include "vm/zone_text_buffer.h" namespace dart { @@ -1409,6 +1411,28 @@ void Elf::FinalizeEhFrame() { // No text section added means no .eh_frame. if (text_section == nullptr) return; +#if defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_X64) + // Append Windows unwinding instructions to the end of .text section. + { + auto* const unwinding_instructions_frame = new (zone_) TextSection(type_); + ZoneWriteStream stream( + zone(), + /*initial_size=*/UnwindingRecordsPlatform::SizeInBytes()); + uint8_t* unwinding_instructions = + zone()->Alloc(UnwindingRecordsPlatform::SizeInBytes()); + + intptr_t start_offset = + Utils::RoundUp(text_section->FileSize(), text_section->alignment); + stream.WriteBytes(UnwindingRecords::GenerateRecordsInto( + start_offset, unwinding_instructions), + UnwindingRecordsPlatform::SizeInBytes()); + + unwinding_instructions_frame->AddPortion(stream.buffer(), + stream.bytes_written()); + section_table_->Add(unwinding_instructions_frame, kTextName); + } +#endif + // Multiplier which will be used to scale operands of DW_CFA_offset and // DW_CFA_val_offset. const intptr_t kDataAlignment = -compiler::target::kWordSize; @@ -1449,6 +1473,12 @@ void Elf::FinalizeEhFrame() { // Emit an FDE covering each .text section. for (const auto& portion : text_section->portions()) { +#if defined(DART_TARGET_OS_WINDOWS) && defined(TARGET_ARCH_X64) + if (portion.label == 0) { + // Unwinding instructions sections doesn't have label, doesn't dwarf + continue; + } +#endif ASSERT(portion.label != 0); // Needed for relocations. dwarf_stream.WritePrefixedLength([&]() { // Offset to CIE. Note that unlike pcrel this offset is encoded diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc index b46168f4659..6309b4cf460 100644 --- a/runtime/vm/heap/pages.cc +++ b/runtime/vm/heap/pages.cc @@ -6,6 +6,7 @@ #include "platform/assert.h" #include "platform/leak_sanitizer.h" +#include "platform/unwinding_records.h" #include "vm/dart.h" #include "vm/heap/become.h" #include "vm/heap/compactor.h" @@ -217,7 +218,7 @@ Page* PageSpace::AllocatePage(bool is_exec, bool link) { Page* PageSpace::AllocateLargePage(intptr_t size, bool is_exec) { const intptr_t page_size_in_words = LargePageSizeInWordsFor( - size + (is_exec ? UnwindingRecords::SizeInBytes() : 0)); + size + (is_exec ? UnwindingRecordsPlatform::SizeInBytes() : 0)); { MutexLocker ml(&pages_lock_); if (!CanIncreaseCapacityInWordsLocked(page_size_in_words)) { diff --git a/runtime/vm/unwinding_records.cc b/runtime/vm/unwinding_records.cc index b7158f63c2a..58836ca408e 100644 --- a/runtime/vm/unwinding_records.cc +++ b/runtime/vm/unwinding_records.cc @@ -9,11 +9,6 @@ namespace dart { -void UnwindingRecords::Init() {} -void UnwindingRecords::Cleanup() {} -intptr_t UnwindingRecords::SizeInBytes() { - return 0; -} void UnwindingRecords::RegisterExecutablePage(Page* page) {} void UnwindingRecords::UnregisterExecutablePage(Page* page) {} diff --git a/runtime/vm/unwinding_records.h b/runtime/vm/unwinding_records.h index b15c7127f75..0a23a545c2e 100644 --- a/runtime/vm/unwinding_records.h +++ b/runtime/vm/unwinding_records.h @@ -13,9 +13,8 @@ namespace dart { class UnwindingRecords : public AllStatic { public: - static void Init(); - static void Cleanup(); - static intptr_t SizeInBytes(); + static const void* GenerateRecordsInto(intptr_t offset, + uint8_t* target_buffer); static void RegisterExecutablePage(Page* page); static void UnregisterExecutablePage(Page* page); }; diff --git a/runtime/vm/unwinding_records_win.cc b/runtime/vm/unwinding_records_win.cc index 0b9477de831..f56fe6ec7d1 100644 --- a/runtime/vm/unwinding_records_win.cc +++ b/runtime/vm/unwinding_records_win.cc @@ -2,99 +2,16 @@ // 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. -#include "vm/globals.h" #include "vm/unwinding_records.h" +#include "vm/globals.h" + +#include "platform/unwinding_records.h" + #if defined(DART_HOST_OS_WINDOWS) && defined(TARGET_ARCH_X64) namespace dart { -static HMODULE ntdll_module; -static decltype( - &::RtlAddGrowableFunctionTable) add_growable_function_table_func = nullptr; -static decltype( - &::RtlDeleteGrowableFunctionTable) delete_growable_function_table_func = - nullptr; - -void UnwindingRecords::Init() { - ntdll_module = - LoadLibraryEx(L"ntdll.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); - ASSERT(ntdll_module != nullptr); - // This pair of functions is not available on Windows 7. - add_growable_function_table_func = - reinterpret_cast( - ::GetProcAddress(ntdll_module, "RtlAddGrowableFunctionTable")); - delete_growable_function_table_func = - reinterpret_cast( - ::GetProcAddress(ntdll_module, "RtlDeleteGrowableFunctionTable")); - // Either both available, or both not available. - ASSERT((add_growable_function_table_func == nullptr) == - (delete_growable_function_table_func == nullptr)); -} - -void UnwindingRecords::Cleanup() { - FreeLibrary(ntdll_module); -} - -#pragma pack(push, 1) -// -// Refer to https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64 -// -typedef unsigned char UBYTE; -typedef union _UNWIND_CODE { - struct { - UBYTE CodeOffset; - UBYTE UnwindOp : 4; - UBYTE OpInfo : 4; - }; - USHORT FrameOffset; -} UNWIND_CODE, *PUNWIND_CODE; - -typedef struct _UNWIND_INFO { - UBYTE Version : 3; - UBYTE Flags : 5; - UBYTE SizeOfProlog; - UBYTE CountOfCodes; - UBYTE FrameRegister : 4; - UBYTE FrameOffset : 4; - UNWIND_CODE UnwindCode[2]; -} UNWIND_INFO, *PUNWIND_INFO; - -static constexpr int kPushRbpInstructionLength = 1; -static const int kMovRbpRspInstructionLength = 3; -static constexpr int kRbpPrefixLength = - kPushRbpInstructionLength + kMovRbpRspInstructionLength; -static constexpr int kRBP = 5; - -struct GeneratedCodeUnwindInfo { - UNWIND_INFO unwind_info; - - GeneratedCodeUnwindInfo() { - unwind_info.Version = 1; - unwind_info.Flags = UNW_FLAG_NHANDLER; - unwind_info.SizeOfProlog = kRbpPrefixLength; - unwind_info.CountOfCodes = 2; - unwind_info.FrameRegister = kRBP; - unwind_info.FrameOffset = 0; - unwind_info.UnwindCode[0].CodeOffset = kRbpPrefixLength; - unwind_info.UnwindCode[0].UnwindOp = 3; // UWOP_SET_FPREG - unwind_info.UnwindCode[0].OpInfo = 0; - unwind_info.UnwindCode[1].CodeOffset = kPushRbpInstructionLength; - unwind_info.UnwindCode[1].UnwindOp = 0; // UWOP_PUSH_NONVOL - unwind_info.UnwindCode[1].OpInfo = kRBP; - } -}; - -struct CodeRangeUnwindingRecord { - void* dynamic_table; - uint32_t runtime_function_count; - GeneratedCodeUnwindInfo unwind_info; - intptr_t exception_handler; - RUNTIME_FUNCTION runtime_function[1]; -}; - -#pragma pack(pop) - static void InitUnwindingRecord(intptr_t offset, CodeRangeUnwindingRecord* record, size_t code_size_in_bytes) { @@ -106,11 +23,12 @@ static void InitUnwindingRecord(intptr_t offset, record->runtime_function_count = 1; } -const intptr_t kReservedUnwindingRecordsSizeBytes = 64; -COMPILE_ASSERT(kReservedUnwindingRecordsSizeBytes > - sizeof(CodeRangeUnwindingRecord)); -intptr_t UnwindingRecords::SizeInBytes() { - return kReservedUnwindingRecordsSizeBytes; +const void* UnwindingRecords::GenerateRecordsInto(intptr_t offset, + uint8_t* target_buffer) { + CodeRangeUnwindingRecord* record = + new (target_buffer) CodeRangeUnwindingRecord(); + InitUnwindingRecord(offset, record, offset); + return target_buffer; } // Special exception-unwinding records are put at the end of executable @@ -118,16 +36,20 @@ intptr_t UnwindingRecords::SizeInBytes() { void UnwindingRecords::RegisterExecutablePage(Page* page) { // Won't set up unwinding records on Windows 7, so users won't be able // to benefit from proper unhandled exceptions filtering. - if (add_growable_function_table_func == nullptr) return; + auto function = static_cast( + UnwindingRecordsPlatform::GetAddGrowableFunctionTableFunc()); + if (function == nullptr) return; ASSERT(page->is_executable()); - page->top_ -= kReservedUnwindingRecordsSizeBytes; + ASSERT(sizeof(CodeRangeUnwindingRecord) <= + UnwindingRecordsPlatform::SizeInBytes()); + page->top_ -= UnwindingRecordsPlatform::SizeInBytes(); intptr_t unwinding_record_offset = - page->memory_->size() - kReservedUnwindingRecordsSizeBytes; + page->memory_->size() - UnwindingRecordsPlatform::SizeInBytes(); CodeRangeUnwindingRecord* record = new (reinterpret_cast(page->memory_->start()) + unwinding_record_offset) CodeRangeUnwindingRecord(); InitUnwindingRecord(unwinding_record_offset, record, page->memory_->size()); - if (add_growable_function_table_func( + if (function( /*DynamicTable=*/&record->dynamic_table, /*FunctionTable=*/record->runtime_function, /*EntryCount=*/record->runtime_function_count, @@ -139,15 +61,17 @@ void UnwindingRecords::RegisterExecutablePage(Page* page) { } void UnwindingRecords::UnregisterExecutablePage(Page* page) { - if (delete_growable_function_table_func == nullptr) return; + auto function = static_cast( + UnwindingRecordsPlatform::GetDeleteGrowableFunctionTableFunc()); + if (function == nullptr) return; ASSERT(page->is_executable() && !page->is_image()); intptr_t unwinding_record_offset = - page->memory_->size() - kReservedUnwindingRecordsSizeBytes; + page->memory_->size() - UnwindingRecordsPlatform::SizeInBytes(); CodeRangeUnwindingRecord* record = reinterpret_cast( reinterpret_cast(page->memory_->start()) + unwinding_record_offset); - delete_growable_function_table_func(record->dynamic_table); + function(record->dynamic_table); } } // namespace dart diff --git a/tests/ffi/ffi_induce_a_crash_test.dart b/tests/ffi/ffi_induce_a_crash_test.dart index b8b7823b1f7..ae877062c8c 100644 --- a/tests/ffi/ffi_induce_a_crash_test.dart +++ b/tests/ffi/ffi_induce_a_crash_test.dart @@ -19,8 +19,6 @@ import 'dylib_utils.dart'; void main(List args) async { // Test exercises JIT, Windows-only functionality. if (!Platform.isWindows) return; - if (path.basenameWithoutExtension(Platform.executable) == - 'dart_precompiled_runtime') return; if (args.length == 0) { asyncStart(); final results = await Process.run(