fix: utilityProcess exit codes (#42297)
This commit is contained in:
parent
1c6d7d7ece
commit
7f3dc7d4ce
8 changed files with 226 additions and 34 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue