[ VM / Service ] Add --log_service_response_sizes=<log.csv> debug option

Providing `--log_service_response_sizes` will cause the VM to log VM service
response sizes to the provided file in CSV format.

Also added `--service_response_sizes_directory` to the service test
runner to allow for collecting response size data for the entire service
test suite.

TEST=Local

Change-Id: I7aaf4ba936e2593e67d46ff9052e2130374ef461
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/226805
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi
2022-01-07 21:22:56 +00:00
committed by Commit Bot
parent 1982520d1f
commit 4475267f70
8 changed files with 99 additions and 1 deletions
@@ -64,6 +64,7 @@ class TestConfiguration {
this.keepGeneratedFiles,
this.sharedOptions,
String packages,
this.serviceResponseSizesDirectory,
this.suiteDirectory,
this.outputDirectory,
this.reproducingArguments,
@@ -176,6 +177,7 @@ class TestConfiguration {
return _packages;
}
final String serviceResponseSizesDirectory;
final String outputDirectory;
final String suiteDirectory;
String get babel => configuration.babel;
+6 -1
View File
@@ -338,7 +338,10 @@ has been specified on the command line.''',
hide: true),
_Option.bool('print_passing_stdout',
'Print the stdout of passing, as well as failing, tests.',
hide: true)
hide: true),
_Option('service_response_sizes_directory',
'Log VM service response sizes in CSV files in the provided directory',
hide: true),
];
/// For printing out reproducing command lines, we don't want to add these
@@ -777,6 +780,8 @@ has been specified on the command line.''',
localIP: data["local_ip"] as String,
sharedOptions: sharedOptions,
packages: data["packages"] as String,
serviceResponseSizesDirectory:
data['service_response_sizes_directory'] as String,
suiteDirectory: data["suite_dir"] as String,
outputDirectory: data["output_directory"] as String,
reproducingArguments:
+2
View File
@@ -763,6 +763,8 @@ class StandardTestSuite extends TestSuite {
...vmOptionsList[vmOptionsVariant],
...extraVmOptions,
if (emitDdsTest) '-DUSE_DDS=true',
if (configuration.serviceResponseSizesDirectory != null)
'-DSERVICE_RESPONSE_SIZES_DIR=${configuration.serviceResponseSizesDirectory}',
];
var isCrashExpected = expectations.contains(Expectation.crash);
var commands = _makeCommands(
@@ -18,6 +18,10 @@ export 'service_test_common.dart' show DDSTest, IsolateTest, VMTest;
/// Determines whether DDS is enabled for this test run.
const bool useDds = const bool.fromEnvironment('USE_DDS');
/// The directory to output VM service response size data files to.
const String serviceResponseSizesDir =
const String.fromEnvironment('SERVICE_RESPONSE_SIZES_DIR');
/// The extra arguments to use
const List<String> extraDebuggingArgs = ['--lazy-async-stacks'];
@@ -178,6 +182,15 @@ class _ServiceTesteeLauncher {
if (!testeeControlsServer) {
fullArgs.add('--enable-vm-service:$port');
}
if (serviceResponseSizesDir != null) {
// Dump service response size details to a CSV. This feature is not used
// on the build bots and the generated output will persist after the test
// has completed.
final dir = path.prettyUri(serviceResponseSizesDir);
final testName = path.withoutExtension(path.basename(args.last));
final logName = '${testName}_${useDds ? "" : "no_"}dds_sizes.csv';
fullArgs.add('--log_service_response_sizes=$dir/$logName');
}
fullArgs.addAll(args);
return _spawnCommon(dartExecutable, fullArgs, <String, String>{});
@@ -20,6 +20,10 @@ export 'service_test_common.dart' show DDSTest, IsolateTest, VMTest;
/// Determines whether DDS is enabled for this test run.
const bool useDds = const bool.fromEnvironment('USE_DDS');
/// The directory to output VM service response size data files to.
const String serviceResponseSizesDir =
const String.fromEnvironment('SERVICE_RESPONSE_SIZES_DIR');
/// The extra arguments to use
const List<String> extraDebuggingArgs = ['--lazy-async-stacks'];
@@ -178,6 +182,15 @@ class _ServiceTesteeLauncher {
if (!testeeControlsServer) {
fullArgs.add('--enable-vm-service:$port');
}
if (serviceResponseSizesDir != null) {
// Dump service response size details to a CSV. This feature is not used
// on the build bots and the generated output will persist after the test
// has completed.
final dir = path.prettyUri(serviceResponseSizesDir);
final testName = path.withoutExtension(path.basename(args.last));
final logName = '${testName}_${useDds ? "" : "no_"}dds_sizes.csv';
fullArgs.add('--log_service_response_sizes=$dir/$logName');
}
fullArgs.addAll(args);
return _spawnCommon(dartExecutable, fullArgs, <String, String>{});
+2
View File
@@ -343,6 +343,7 @@ char* Dart::DartInit(const uint8_t* vm_isolate_snapshot,
Isolate::InitVM();
UserTags::Init();
PortMap::Init();
Service::Init();
FreeListElement::Init();
ForwardingCorpse::Init();
Api::Init();
@@ -802,6 +803,7 @@ char* Dart::Cleanup() {
ShutdownIsolate();
vm_isolate_ = NULL;
ASSERT(Isolate::IsolateListLength() == 0);
Service::Cleanup();
PortMap::Cleanup();
UserTags::Cleanup();
IsolateGroup::Cleanup();
+53
View File
@@ -72,6 +72,56 @@ DEFINE_FLAG(bool,
"Print a message when an isolate is paused but there is no "
"debugger attached.");
DEFINE_FLAG(
charp,
log_service_response_sizes,
nullptr,
"Log sizes of service responses and events to a file in CSV format.");
void* Service::service_response_size_log_file_ = nullptr;
void Service::LogResponseSize(const char* method, JSONStream* js) {
if (service_response_size_log_file_ == nullptr) {
return;
}
Dart_FileWriteCallback file_write = Dart::file_write_callback();
char* entry =
OS::SCreate(nullptr, "%s, %" Pd "\n", method, js->buffer()->length());
(*file_write)(entry, strlen(entry), service_response_size_log_file_);
free(entry);
}
void Service::Init() {
if (FLAG_log_service_response_sizes == nullptr) {
return;
}
Dart_FileOpenCallback file_open = Dart::file_open_callback();
Dart_FileWriteCallback file_write = Dart::file_write_callback();
Dart_FileCloseCallback file_close = Dart::file_close_callback();
if ((file_open == nullptr) || (file_write == nullptr) ||
(file_close == nullptr)) {
OS::PrintErr("Error: Could not access file callbacks.");
UNREACHABLE();
}
ASSERT(service_response_size_log_file_ == nullptr);
service_response_size_log_file_ =
(*file_open)(FLAG_log_service_response_sizes, true);
if (service_response_size_log_file_ == nullptr) {
OS::PrintErr("Warning: Failed to open service response size log file: %s\n",
FLAG_log_service_response_sizes);
return;
}
}
void Service::Cleanup() {
if (service_response_size_log_file_ == nullptr) {
return;
}
Dart_FileCloseCallback file_close = Dart::file_close_callback();
(*file_close)(service_response_size_log_file_);
service_response_size_log_file_ = nullptr;
}
static void PrintInvalidParamError(JSONStream* js, const char* param) {
#if !defined(PRODUCT)
js->PrintError(kInvalidParams, "%s: invalid '%s' parameter: %s", js->method(),
@@ -988,6 +1038,7 @@ ErrorPtr Service::InvokeMethod(Isolate* I,
return T->StealStickyError();
}
method->entry(T, &js);
Service::LogResponseSize(c_method_name, &js);
js.PostReply();
return T->StealStickyError();
}
@@ -1239,6 +1290,8 @@ void Service::PostEventImpl(Isolate* isolate,
}
}
Service::LogResponseSize(kind, event);
// Message is of the format [<stream id>, <json string>].
//
// Build the event message in the C heap to avoid dart heap
+8
View File
@@ -89,6 +89,9 @@ class StreamInfo {
class Service : public AllStatic {
public:
static void Init();
static void Cleanup();
// Handles a message which is not directed to an isolate.
static ErrorPtr HandleRootMessage(const Array& message);
@@ -159,6 +162,9 @@ class Service : public AllStatic {
const Instance& id,
const Error& error);
// Logs the size of the contents of `js` to FLAG_log_service_response_sizes.
static void LogResponseSize(const char* method, JSONStream* js);
// Enable/Disable timeline categories.
// Returns True if the categories were successfully enabled, False otherwise.
static bool EnableTimelineStreams(char* categories_list);
@@ -250,6 +256,8 @@ class Service : public AllStatic {
static Dart_GetVMServiceAssetsArchive get_service_assets_callback_;
static Dart_EmbedderInformationCallback embedder_information_callback_;
static void* service_response_size_log_file_;
static const uint8_t* dart_library_kernel_;
static intptr_t dart_library_kernel_len_;
};