[gardening] Fix memory leak of Dart::FeaturesString() buffer
The CL in [0] introduced a new usage of Dart::FeaturesString() but
missed to free the resulting buffer (it's not a compile-time constant
but rather built via TextBuffer).
Closes https://github.com/dart-lang/sdk/issues/47460
[0] https://dart-review.googlesource.com/c/sdk/+/215945
TEST=Fixes asan failures, e.g. vm/cc/DartAPI_InvokeVMServiceMethod
Change-Id: I954bd4a0af5959f1c38d4b70978bef6c6baed407
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216802
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/app_snapshot.cc b/runtime/vm/app_snapshot.cc
index 3cc94ca..a27d27c 100644
--- a/runtime/vm/app_snapshot.cc
+++ b/runtime/vm/app_snapshot.cc
@@ -6842,13 +6842,13 @@
const intptr_t version_len = strlen(expected_version);
WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
- const char* expected_features =
+ char* expected_features =
Dart::FeaturesString(IsolateGroup::Current(), is_vm_snapshot, kind_);
ASSERT(expected_features != NULL);
const intptr_t features_len = strlen(expected_features);
WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
features_len + 1);
- free(const_cast<char*>(expected_features));
+ free(expected_features);
}
#if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index b041eb8..ced30ca 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -1064,9 +1064,9 @@
return Error::null();
}
-const char* Dart::FeaturesString(IsolateGroup* isolate_group,
- bool is_vm_isolate,
- Snapshot::Kind kind) {
+char* Dart::FeaturesString(IsolateGroup* isolate_group,
+ bool is_vm_isolate,
+ Snapshot::Kind kind) {
TextBuffer buffer(64);
// Different fields are included for DEBUG/RELEASE/PRODUCT.
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index c22f1f0..9d0cdf1 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -111,9 +111,10 @@
static uword AllocateReadOnlyHandle();
static bool IsReadOnlyHandle(uword address);
- static const char* FeaturesString(IsolateGroup* isolate_group,
- bool is_vm_snapshot,
- Snapshot::Kind kind);
+ // The returned string has to be free()ed.
+ static char* FeaturesString(IsolateGroup* isolate_group,
+ bool is_vm_snapshot,
+ Snapshot::Kind kind);
static Snapshot::Kind vm_snapshot_kind() { return vm_snapshot_kind_; }
static Dart_ThreadExitCallback thread_exit_callback() {
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index fd3b9ee..a0a5b9c 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -4889,7 +4889,9 @@
#else
Snapshot::Kind kind = Snapshot::kFullJIT;
#endif
- jsobj.AddProperty("_features", Dart::FeaturesString(nullptr, true, kind));
+ char* features_string = Dart::FeaturesString(nullptr, true, kind);
+ jsobj.AddProperty("_features", features_string);
+ free(features_string);
jsobj.AddProperty("_profilerMode", FLAG_profile_vm ? "VM" : "Dart");
jsobj.AddProperty64("pid", OS::ProcessId());
jsobj.AddPropertyTimeMillis(