fix: utilityProcess exit codes (#42297)

This commit is contained in:
Shelley Vohr 2024-06-07 10:06:00 +02:00 committed by GitHub
parent 1c6d7d7ece
commit 7f3dc7d4ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 226 additions and 34 deletions

View file

@ -808,12 +808,6 @@ void App::BrowserChildProcessCrashedOrKilled(
if (!data.name.empty()) {
details.Set("name", data.name);
}
if (data.process_type == content::PROCESS_TYPE_UTILITY) {
base::ProcessId pid = data.GetProcess().Pid();
auto utility_process_wrapper = UtilityProcessWrapper::FromProcessId(pid);
if (utility_process_wrapper)
utility_process_wrapper->Shutdown(info.exit_code);
}
Emit("child-process-gone", details);
}

View file

@ -145,6 +145,9 @@ UtilityProcessWrapper::UtilityProcessWrapper(
}
}
if (!content::ServiceProcessHost::HasObserver(this))
content::ServiceProcessHost::AddObserver(this);
mojo::PendingReceiver<node::mojom::NodeService> receiver =
node_service_remote_.BindNewPipeAndPassReceiver();
@ -172,9 +175,10 @@ UtilityProcessWrapper::UtilityProcessWrapper(
: content::ChildProcessHost::CHILD_NORMAL)
#endif
.WithProcessCallback(
base::BindOnce(&UtilityProcessWrapper::OnServiceProcessLaunched,
base::BindOnce(&UtilityProcessWrapper::OnServiceProcessLaunch,
weak_factory_.GetWeakPtr()))
.Pass());
node_service_remote_.set_disconnect_with_reason_handler(
base::BindOnce(&UtilityProcessWrapper::OnServiceProcessDisconnected,
weak_factory_.GetWeakPtr()));
@ -210,37 +214,61 @@ UtilityProcessWrapper::UtilityProcessWrapper(
network_context->CreateHostResolver(
{}, host_resolver.InitWithNewPipeAndPassReceiver());
params->host_resolver = std::move(host_resolver);
node_service_remote_->Initialize(std::move(params));
}
UtilityProcessWrapper::~UtilityProcessWrapper() = default;
UtilityProcessWrapper::~UtilityProcessWrapper() {
content::ServiceProcessHost::RemoveObserver(this);
}
void UtilityProcessWrapper::OnServiceProcessLaunched(
void UtilityProcessWrapper::OnServiceProcessLaunch(
const base::Process& process) {
DCHECK(node_service_remote_.is_connected());
pid_ = process.Pid();
GetAllUtilityProcessWrappers().AddWithID(this, pid_);
if (stdout_read_fd_ != -1) {
if (stdout_read_fd_ != -1)
EmitWithoutEvent("stdout", stdout_read_fd_);
}
if (stderr_read_fd_ != -1) {
if (stderr_read_fd_ != -1)
EmitWithoutEvent("stderr", stderr_read_fd_);
}
// Emit 'spawn' event
EmitWithoutEvent("spawn");
}
void UtilityProcessWrapper::OnServiceProcessDisconnected(
uint32_t error_code,
const std::string& description) {
void UtilityProcessWrapper::HandleTermination(uint64_t exit_code) {
if (pid_ != base::kNullProcessId)
GetAllUtilityProcessWrappers().Remove(pid_);
CloseConnectorPort();
// Emit 'exit' event
EmitWithoutEvent("exit", error_code);
EmitWithoutEvent("exit", exit_code);
Unpin();
}
void UtilityProcessWrapper::OnServiceProcessDisconnected(
uint32_t exit_code,
const std::string& description) {
if (description == "process_exit_termination")
HandleTermination(exit_code);
}
void UtilityProcessWrapper::OnServiceProcessTerminatedNormally(
const content::ServiceProcessInfo& info) {
if (!info.IsService<node::mojom::NodeService>() ||
info.GetProcess().Pid() != pid_)
return;
HandleTermination(info.exit_code());
}
void UtilityProcessWrapper::OnServiceProcessCrashed(
const content::ServiceProcessInfo& info) {
if (!info.IsService<node::mojom::NodeService>() ||
info.GetProcess().Pid() != pid_)
return;
HandleTermination(info.exit_code());
}
void UtilityProcessWrapper::CloseConnectorPort() {
if (!connector_closed_ && connector_->is_valid()) {
host_port_.GiveDisentangledHandle(connector_->PassMessagePipe());
@ -250,7 +278,7 @@ void UtilityProcessWrapper::CloseConnectorPort() {
}
}
void UtilityProcessWrapper::Shutdown(int exit_code) {
void UtilityProcessWrapper::Shutdown(uint64_t exit_code) {
if (pid_ != base::kNullProcessId)
GetAllUtilityProcessWrappers().Remove(pid_);
node_service_remote_.reset();

View file

@ -13,9 +13,11 @@
#include "base/environment.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process_handle.h"
#include "content/public/browser/service_process_host.h"
#include "gin/wrappable.h"
#include "mojo/public/cpp/bindings/connector.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "shell/browser/event_emitter_mixin.h"
#include "shell/common/gin_helper/pinnable.h"
@ -38,7 +40,8 @@ class UtilityProcessWrapper
: public gin::Wrappable<UtilityProcessWrapper>,
public gin_helper::Pinnable<UtilityProcessWrapper>,
public gin_helper::EventEmitterMixin<UtilityProcessWrapper>,
public mojo::MessageReceiver {
public mojo::MessageReceiver,
public content::ServiceProcessHost::Observer {
public:
enum class IOHandle : size_t { STDIN = 0, STDOUT = 1, STDERR = 2 };
enum class IOType { IO_PIPE, IO_INHERIT, IO_IGNORE };
@ -47,7 +50,7 @@ class UtilityProcessWrapper
static gin::Handle<UtilityProcessWrapper> Create(gin::Arguments* args);
static raw_ptr<UtilityProcessWrapper> FromProcessId(base::ProcessId pid);
void Shutdown(int exit_code);
void Shutdown(uint64_t exit_code);
// gin::Wrappable
static gin::WrapperInfo kWrapperInfo;
@ -62,11 +65,11 @@ class UtilityProcessWrapper
base::EnvironmentMap env_map,
base::FilePath current_working_directory,
bool use_plugin_helper);
void OnServiceProcessDisconnected(uint32_t error_code,
const std::string& description);
void OnServiceProcessLaunched(const base::Process& process);
void OnServiceProcessLaunch(const base::Process& process);
void CloseConnectorPort();
void HandleTermination(uint64_t exit_code);
void PostMessage(gin::Arguments* args);
bool Kill() const;
v8::Local<v8::Value> GetOSProcessId(v8::Isolate* isolate) const;
@ -74,6 +77,15 @@ class UtilityProcessWrapper
// mojo::MessageReceiver
bool Accept(mojo::Message* mojo_message) override;
// content::ServiceProcessHost::Observer
void OnServiceProcessTerminatedNormally(
const content::ServiceProcessInfo& info) override;
void OnServiceProcessCrashed(
const content::ServiceProcessInfo& info) override;
void OnServiceProcessDisconnected(uint32_t exit_code,
const std::string& description);
base::ProcessId pid_ = base::kNullProcessId;
#if BUILDFLAG(IS_WIN)
// Non-owning handles, these will be closed when the