mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:16:51 +00:00
[standalone] Fix memory leak in the tag handler.
TEST=asan Bug: https://github.com/dart-lang/sdk/issues/37030 Bug: https://github.com/dart-lang/sdk/issues/51210 Change-Id: Ia62a4d7d1805c6ac4a311ef9952fff248e7b4693 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280284 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
99a9f3d516
commit
c81b00938d
|
@ -372,12 +372,19 @@ static void ReadFile(const char* filename, uint8_t** buffer, intptr_t* size) {
|
|||
}
|
||||
}
|
||||
|
||||
static void MallocFinalizer(void* isolate_callback_data, void* peer) {
|
||||
free(peer);
|
||||
}
|
||||
|
||||
static void MaybeLoadExtraInputs(const CommandLineOptions& inputs) {
|
||||
for (intptr_t i = 1; i < inputs.count(); i++) {
|
||||
uint8_t* buffer = NULL;
|
||||
intptr_t size = 0;
|
||||
ReadFile(inputs.GetArgument(i), &buffer, &size);
|
||||
Dart_Handle result = Dart_LoadLibraryFromKernel(buffer, size);
|
||||
Dart_Handle td = Dart_NewExternalTypedDataWithFinalizer(
|
||||
Dart_TypedData_kUint8, buffer, size, buffer, size, MallocFinalizer);
|
||||
CHECK_RESULT(td);
|
||||
Dart_Handle result = Dart_LoadLibrary(td);
|
||||
CHECK_RESULT(result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,16 @@ Dart_Handle Loader::Init(const char* packages_file,
|
|||
static void MallocFinalizer(void* isolate_callback_data, void* peer) {
|
||||
free(peer);
|
||||
}
|
||||
static Dart_Handle WrapMallocedKernelBuffer(uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size) {
|
||||
Dart_Handle result = Dart_NewExternalTypedDataWithFinalizer(
|
||||
Dart_TypedData_kUint8, kernel_buffer, kernel_buffer_size, kernel_buffer,
|
||||
kernel_buffer_size, MallocFinalizer);
|
||||
if (Dart_IsError(result)) {
|
||||
free(kernel_buffer);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
|
||||
|
@ -87,11 +97,7 @@ Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
|
|||
&kernel_buffer_size)) {
|
||||
return DartUtils::NewError("'%s' is not a kernel file", url_string);
|
||||
}
|
||||
result = Dart_NewExternalTypedData(Dart_TypedData_kUint8, kernel_buffer,
|
||||
kernel_buffer_size);
|
||||
Dart_NewFinalizableHandle(result, kernel_buffer, kernel_buffer_size,
|
||||
MallocFinalizer);
|
||||
return result;
|
||||
return WrapMallocedKernelBuffer(kernel_buffer, kernel_buffer_size);
|
||||
}
|
||||
if (dfe.CanUseDartFrontend() && dfe.UseDartFrontend() &&
|
||||
(tag == Dart_kImportTag)) {
|
||||
|
@ -103,7 +109,8 @@ Dart_Handle Loader::LibraryTagHandler(Dart_LibraryTag tag,
|
|||
dfe.CompileAndReadScript(url_string, &kernel_buffer, &kernel_buffer_size,
|
||||
&error, &exit_code, NULL, false);
|
||||
if (exit_code == 0) {
|
||||
return Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
|
||||
return Dart_LoadLibrary(
|
||||
WrapMallocedKernelBuffer(kernel_buffer, kernel_buffer_size));
|
||||
} else if (exit_code == kCompilationErrorExitCode) {
|
||||
Dart_Handle result = Dart_NewCompilationError(error);
|
||||
free(error);
|
||||
|
|
|
@ -3646,6 +3646,8 @@ DART_EXPORT Dart_Handle Dart_LibraryHandleError(Dart_Handle library,
|
|||
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
|
||||
Dart_LoadLibraryFromKernel(const uint8_t* kernel_buffer,
|
||||
intptr_t kernel_buffer_size);
|
||||
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle
|
||||
Dart_LoadLibrary(Dart_Handle kernel_buffer);
|
||||
|
||||
/**
|
||||
* Indicates that all outstanding load requests have been satisfied.
|
||||
|
|
|
@ -5841,24 +5841,8 @@ DART_EXPORT Dart_Handle Dart_LibraryHandleError(Dart_Handle library_in,
|
|||
return error_in;
|
||||
}
|
||||
|
||||
DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t* buffer,
|
||||
intptr_t buffer_size) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
|
||||
#else
|
||||
DARTSCOPE(Thread::Current());
|
||||
API_TIMELINE_DURATION(T);
|
||||
StackZone zone(T);
|
||||
|
||||
CHECK_CALLBACK_STATE(T);
|
||||
|
||||
// NOTE: We do not attach a finalizer for this object, because the embedder
|
||||
// will/should free it once the isolate group has shutdown.
|
||||
// See also http://dartbug.com/37030.
|
||||
const auto& td = ExternalTypedData::Handle(ExternalTypedData::New(
|
||||
kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
|
||||
buffer_size, Heap::kOld));
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
static Dart_Handle LoadLibrary(Thread* T, const ExternalTypedData& td) {
|
||||
const char* error = nullptr;
|
||||
std::unique_ptr<kernel::Program> program =
|
||||
kernel::Program::ReadFromTypedData(td, &error);
|
||||
|
@ -5873,6 +5857,40 @@ DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t* buffer,
|
|||
source->add_loaded_blob(Z, td);
|
||||
|
||||
return Api::NewHandle(T, result.ptr());
|
||||
}
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
DART_EXPORT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t* buffer,
|
||||
intptr_t buffer_size) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
|
||||
#else
|
||||
DARTSCOPE(Thread::Current());
|
||||
API_TIMELINE_DURATION(T);
|
||||
StackZone zone(T);
|
||||
|
||||
CHECK_CALLBACK_STATE(T);
|
||||
|
||||
// NOTE: We do not attach a finalizer for this object, because the embedder
|
||||
// will/should free it once the isolate group has shutdown.
|
||||
const auto& td = ExternalTypedData::Handle(ExternalTypedData::New(
|
||||
kExternalTypedDataUint8ArrayCid, const_cast<uint8_t*>(buffer),
|
||||
buffer_size, Heap::kOld));
|
||||
return LoadLibrary(T, td);
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
DART_EXPORT Dart_Handle Dart_LoadLibrary(Dart_Handle kernel_buffer) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
return Api::NewError("%s: Cannot compile on an AOT runtime.", CURRENT_FUNC);
|
||||
#else
|
||||
DARTSCOPE(Thread::Current());
|
||||
const ExternalTypedData& td =
|
||||
Api::UnwrapExternalTypedDataHandle(Z, kernel_buffer);
|
||||
if (td.IsNull()) {
|
||||
RETURN_TYPE_ERROR(Z, kernel_buffer, ExternalTypedData);
|
||||
}
|
||||
return LoadLibrary(T, td);
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
|
|
|
@ -433,6 +433,10 @@ Dart_Handle TestCase::LoadTestScript(const char* script,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void MallocFinalizer(void* isolate_callback_data, void* peer) {
|
||||
free(peer);
|
||||
}
|
||||
|
||||
Dart_Handle TestCase::LoadTestLibrary(const char* lib_uri,
|
||||
const char* script,
|
||||
Dart_NativeEntryResolver resolver) {
|
||||
|
@ -448,12 +452,14 @@ Dart_Handle TestCase::LoadTestLibrary(const char* lib_uri,
|
|||
if ((kernel_buffer == NULL) && (error != NULL)) {
|
||||
return Dart_NewApiError(error);
|
||||
}
|
||||
Dart_Handle lib =
|
||||
Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
|
||||
EXPECT_VALID(lib);
|
||||
|
||||
// Ensure kernel buffer isn't leaked after test is run.
|
||||
AddToKernelBuffers(kernel_buffer);
|
||||
Dart_Handle td = Dart_NewExternalTypedDataWithFinalizer(
|
||||
Dart_TypedData_kUint8, const_cast<uint8_t*>(kernel_buffer),
|
||||
kernel_buffer_size, const_cast<uint8_t*>(kernel_buffer),
|
||||
kernel_buffer_size, MallocFinalizer);
|
||||
EXPECT_VALID(td);
|
||||
Dart_Handle lib = Dart_LoadLibrary(td);
|
||||
EXPECT_VALID(lib);
|
||||
|
||||
// TODO(32618): Kernel doesn't correctly represent the root library.
|
||||
lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri));
|
||||
|
@ -488,13 +494,14 @@ Dart_Handle TestCase::LoadTestScriptWithDFE(int sourcefiles_count,
|
|||
return Dart_NewApiError(error);
|
||||
}
|
||||
|
||||
Dart_Handle lib =
|
||||
Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
|
||||
Dart_Handle td = Dart_NewExternalTypedDataWithFinalizer(
|
||||
Dart_TypedData_kUint8, const_cast<uint8_t*>(kernel_buffer),
|
||||
kernel_buffer_size, const_cast<uint8_t*>(kernel_buffer),
|
||||
kernel_buffer_size, MallocFinalizer);
|
||||
EXPECT_VALID(td);
|
||||
Dart_Handle lib = Dart_LoadLibrary(td);
|
||||
EXPECT_VALID(lib);
|
||||
|
||||
// Ensure kernel buffer isn't leaked after test is run.
|
||||
AddToKernelBuffers(kernel_buffer);
|
||||
|
||||
// BOGUS: Kernel doesn't correctly represent the root library.
|
||||
lib = Dart_LookupLibrary(Dart_NewStringFromCString(
|
||||
entry_script_uri != NULL ? entry_script_uri : sourcefiles[0].uri));
|
||||
|
|
Loading…
Reference in a new issue