LibWebView+UI: Allow profiling any helper process

This removes the --enable-callgrind-profiling flag, and replaces it with
a --profile-process=<process-name> flag. For example:

    ladybird --profile-process=WebContent
    ladybird --profile-process=RequestServer

This allows profiling any helper process with callgrind.
This commit is contained in:
Timothy Flynn 2024-08-01 07:13:09 -04:00 committed by Andreas Kling
parent 7106a7bd58
commit ce5f2861d8
Notes: github-actions[bot] 2024-08-01 13:41:38 +00:00
3 changed files with 16 additions and 18 deletions

View file

@ -15,13 +15,12 @@ static ErrorOr<NonnullRefPtr<ClientType>> launch_server_process(
StringView server_name,
ReadonlySpan<ByteString> candidate_server_paths,
Vector<ByteString> arguments,
WebView::EnableCallgrindProfiling enable_callgrind_profiling,
ClientArguments&&... client_arguments)
{
auto process_type = WebView::process_type_from_name(server_name);
auto const& chrome_options = WebView::Application::chrome_options();
if (enable_callgrind_profiling == WebView::EnableCallgrindProfiling::Yes) {
if (chrome_options.profile_helper_process == process_type) {
arguments.prepend({
"--tool=callgrind"sv,
"--instr-atstart=no"sv,
@ -35,7 +34,7 @@ static ErrorOr<NonnullRefPtr<ClientType>> launch_server_process(
for (auto [i, path] : enumerate(candidate_server_paths)) {
Core::ProcessSpawnOptions options { .name = server_name, .arguments = arguments };
if (enable_callgrind_profiling == WebView::EnableCallgrindProfiling::Yes) {
if (chrome_options.profile_helper_process == process_type) {
options.executable = "valgrind"sv;
options.search_for_executable_in_path = true;
arguments[2] = path;
@ -53,7 +52,7 @@ static ErrorOr<NonnullRefPtr<ClientType>> launch_server_process(
WebView::Application::the().add_child_process(WebView::Process { process_type, process.client, move(process.process) });
if (enable_callgrind_profiling == WebView::EnableCallgrindProfiling::Yes) {
if (chrome_options.profile_helper_process == process_type) {
dbgln();
dbgln("\033[1;45mLaunched {} process under callgrind!\033[0m", server_name);
dbgln("\033[100mRun `\033[4mcallgrind_control -i on\033[24m` to start instrumentation and `\033[4mcallgrind_control -i off\033[24m` stop it again.\033[0m");
@ -115,7 +114,7 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(
arguments.append("--image-decoder-socket"sv);
arguments.append(ByteString::number(image_decoder_socket.fd()));
return launch_server_process<WebView::WebContentClient>("WebContent"sv, candidate_web_content_paths, move(arguments), web_content_options.enable_callgrind_profiling, view);
return launch_server_process<WebView::WebContentClient>("WebContent"sv, candidate_web_content_paths, move(arguments), view);
}
ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_image_decoder_process(ReadonlySpan<ByteString> candidate_image_decoder_paths)
@ -126,7 +125,7 @@ ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_image_decoder_process(
arguments.append(server.value());
}
return launch_server_process<ImageDecoderClient::Client>("ImageDecoder"sv, candidate_image_decoder_paths, arguments, WebView::EnableCallgrindProfiling::No);
return launch_server_process<ImageDecoderClient::Client>("ImageDecoder"sv, candidate_image_decoder_paths, arguments);
}
ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(ReadonlySpan<ByteString> candidate_web_worker_paths, RefPtr<Protocol::RequestClient> request_client)
@ -137,10 +136,10 @@ ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(Rea
arguments.append("--request-server-socket"sv);
arguments.append(ByteString::number(socket.fd()));
arguments.append("--use-lagom-networking"sv);
return launch_server_process<Web::HTML::WebWorkerClient>("WebWorker"sv, candidate_web_worker_paths, move(arguments), WebView::EnableCallgrindProfiling::No);
return launch_server_process<Web::HTML::WebWorkerClient>("WebWorker"sv, candidate_web_worker_paths, move(arguments));
}
return launch_server_process<Web::HTML::WebWorkerClient>("WebWorker"sv, candidate_web_worker_paths, move(arguments), WebView::EnableCallgrindProfiling::No);
return launch_server_process<Web::HTML::WebWorkerClient>("WebWorker"sv, candidate_web_worker_paths, move(arguments));
}
ErrorOr<NonnullRefPtr<Protocol::RequestClient>> launch_request_server_process(ReadonlySpan<ByteString> candidate_request_server_paths, StringView serenity_resource_root)
@ -160,7 +159,7 @@ ErrorOr<NonnullRefPtr<Protocol::RequestClient>> launch_request_server_process(Re
arguments.append(server.value());
}
return launch_server_process<Protocol::RequestClient>("RequestServer"sv, candidate_request_server_paths, move(arguments), WebView::EnableCallgrindProfiling::No);
return launch_server_process<Protocol::RequestClient>("RequestServer"sv, candidate_request_server_paths, move(arguments));
}
ErrorOr<IPC::File> connect_new_request_server_client(Protocol::RequestClient& client)

View file

@ -39,8 +39,8 @@ void Application::initialize(Main::Arguments const& arguments, URL::URL new_tab_
bool allow_popups = false;
bool disable_sql_database = false;
Optional<StringView> debug_process;
Optional<StringView> profile_process;
Optional<StringView> webdriver_content_ipc_path;
bool enable_callgrind_profiling = false;
bool log_all_js_exceptions = false;
bool enable_idl_tracing = false;
bool enable_http_cache = false;
@ -55,8 +55,8 @@ void Application::initialize(Main::Arguments const& arguments, URL::URL new_tab_
args_parser.add_option(allow_popups, "Disable popup blocking by default", "allow-popups");
args_parser.add_option(disable_sql_database, "Disable SQL database", "disable-sql-database");
args_parser.add_option(debug_process, "Wait for a debugger to attach to the given process name (WebContent, RequestServer, etc.)", "debug-process", 0, "process-name");
args_parser.add_option(profile_process, "Enable callgrind profiling of the given process name (WebContent, RequestServer, etc.)", "profile-process", 0, "process-name");
args_parser.add_option(webdriver_content_ipc_path, "Path to WebDriver IPC for WebContent", "webdriver-content-path", 0, "path", Core::ArgsParser::OptionHideMode::CommandLineAndMarkdown);
args_parser.add_option(enable_callgrind_profiling, "Enable Callgrind profiling", "enable-callgrind-profiling", 'P');
args_parser.add_option(log_all_js_exceptions, "Log all JavaScript exceptions", "log-all-js-exceptions");
args_parser.add_option(enable_idl_tracing, "Enable IDL tracing", "enable-idl-tracing");
args_parser.add_option(enable_http_cache, "Enable HTTP cache", "enable-http-cache");
@ -66,8 +66,12 @@ void Application::initialize(Main::Arguments const& arguments, URL::URL new_tab_
args_parser.parse(arguments);
Optional<ProcessType> debug_process_type;
Optional<ProcessType> profile_process_type;
if (debug_process.has_value())
debug_process_type = process_type_from_name(*debug_process);
if (profile_process.has_value())
profile_process_type = process_type_from_name(*profile_process);
m_chrome_options = {
.urls = sanitize_urls(raw_urls, new_tab_page_url),
@ -79,6 +83,7 @@ void Application::initialize(Main::Arguments const& arguments, URL::URL new_tab_
.allow_popups = allow_popups ? AllowPopups::Yes : AllowPopups::No,
.disable_sql_database = disable_sql_database ? DisableSQLDatabase::Yes : DisableSQLDatabase::No,
.debug_helper_process = move(debug_process_type),
.profile_helper_process = move(profile_process_type),
};
if (webdriver_content_ipc_path.has_value())
@ -87,7 +92,6 @@ void Application::initialize(Main::Arguments const& arguments, URL::URL new_tab_
m_web_content_options = {
.command_line = MUST(String::join(' ', arguments.strings)),
.executable_path = MUST(String::from_byte_string(MUST(Core::System::current_executable_path()))),
.enable_callgrind_profiling = enable_callgrind_profiling ? EnableCallgrindProfiling::Yes : EnableCallgrindProfiling::No,
.log_all_js_exceptions = log_all_js_exceptions ? LogAllJSExceptions::Yes : LogAllJSExceptions::No,
.enable_idl_tracing = enable_idl_tracing ? EnableIDLTracing::Yes : EnableIDLTracing::No,
.enable_http_cache = enable_http_cache ? EnableHTTPCache::Yes : EnableHTTPCache::No,

View file

@ -45,14 +45,10 @@ struct ChromeOptions {
AllowPopups allow_popups { AllowPopups::No };
DisableSQLDatabase disable_sql_database { DisableSQLDatabase::No };
Optional<ProcessType> debug_helper_process {};
Optional<ProcessType> profile_helper_process {};
Optional<ByteString> webdriver_content_ipc_path {};
};
enum class EnableCallgrindProfiling {
No,
Yes,
};
enum class IsLayoutTestMode {
No,
Yes,
@ -87,7 +83,6 @@ struct WebContentOptions {
String command_line;
String executable_path;
Optional<ByteString> config_path {};
EnableCallgrindProfiling enable_callgrind_profiling { EnableCallgrindProfiling::No };
IsLayoutTestMode is_layout_test_mode { IsLayoutTestMode::No };
UseLagomNetworking use_lagom_networking { UseLagomNetworking::Yes };
LogAllJSExceptions log_all_js_exceptions { LogAllJSExceptions::No };