-
Notifications
You must be signed in to change notification settings - Fork 868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix MonitorChild thread violation in utility process #8620
Conversation
1499f09
to
9895a95
Compare
DISALLOW_COPY_AND_ASSIGN(IpfsServiceImpl); | ||
base::WeakPtrFactory<IpfsServiceImpl> weak_ptr_factory_{this}; | ||
|
||
IpfsServiceImpl(const IpfsServiceImpl&) = delete; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
methods/constructors should go before members.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 7757acb
} else if (WIFEXITED(status)) { | ||
VLOG(0) << "ipfs exit (" << WEXITSTATUS(status) << ")"; | ||
} | ||
if (callback) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just DCHECK(callback);
at start and remove if
s? it's unlikely someone would use it without a callback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 7757acb
@@ -108,22 +109,62 @@ bool LaunchProcessAndExit(const base::FilePath& path, | |||
return true; | |||
} | |||
|
|||
void MonitorChild(base::ProcessHandle p_handle, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we put this machinery in a dedicated .h/.cc
and fix code duplication? ipfs/tor impls clearly cannot be used simultaneously because of global sigaction
calls.
it would be nice to have a single entry point for the Setup/TearDownPipeHack, MonitorChild
and DCHECK if it's used in the same process for something else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will fix the duplication by wrapping a ChildMonitor
class and also global sigaction
calls don't matter because IpfsServiceImpl
and TorLauncherImpl
are in different utility processes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 7757acb
7757acb
to
d74ac50
Compare
memset(&action, 0, sizeof(action)); | ||
action.sa_handler = SIG_DFL; | ||
sigaction(SIGCHLD, &action, NULL); | ||
for (size_t i = 0; i < 2; ++i) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since there will only ever be two pipe elements a loop doesn't add much.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in fcf4957f689f39e8f09a0c9aa56494935fcbfd7d
d74ac50
to
fcf4957
Compare
@@ -0,0 +1,13 @@ | |||
source_set("child_monitor") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
components/child_process_monitor/BUILD.gn
source_set("child_process_monitor") { ... }
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
@@ -0,0 +1,13 @@ | |||
source_set("child_monitor") { | |||
visibility = [ | |||
"//brave/components/services/ipfs", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add a comment why we restrict visibility?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
NOTREACHED(); | ||
} | ||
} | ||
ChildMonitor::~ChildMonitor() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an empty line is missing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
<< ")"; | ||
} | ||
std::move(callback).Run(pid); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
break;
/ return;
to be safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
} // namespace | ||
|
||
ChildMonitor::ChildMonitor() | ||
: child_monitor_thread_(new base::Thread("child_monitor_thread")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::make_unique
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
child_process_ = std::move(child); | ||
|
||
DCHECK(child_monitor_thread_.get()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just DCHECK(child_monitor_thread_);
#include "base/process/kill.h" | ||
#include "base/single_thread_task_runner.h" | ||
#include "base/task/post_task.h" | ||
#include "base/threading/thread_task_runner_handle.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sequenced_task_runner_handle.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
} | ||
|
||
#if defined(OS_MAC) | ||
static void SetupFD(int fd) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static void SIGCHLDHandler
static void SetupFD
static void SetupPipeHack
static void TearDownPipeHack
static
is not necessary. we're already in anonymous namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
// processes created above. | ||
SetupPipeHack(); | ||
#endif | ||
child_monitor_.reset(new brave::ChildMonitor()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::make_unique
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
#if defined(OS_MAC) | ||
// TODO(https://crbug.com/806451): The Mac implementation currently blocks | ||
// the calling thread for up to two seconds. | ||
base::PostTask( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base::ThreadPool::PostTask
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 76857501ecbfb2f31ff1023ec197de6d90d62618
cff041b
to
1db72ee
Compare
1db72ee
to
4a9daf2
Compare
if (fcntl(pipehack[1], F_SETFL, flags) == -1) | ||
VLOG(0) << "set flags errno:" << errno; | ||
|
||
struct sigaction action; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generally it's a good idea to set SA_RESTART
in your sigaction flags, especially since your code is doing a lot of syscalls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in 2ce89fab2bc58cb8ab04ef80cb0f2efaaa56cbbe
4a9daf2
to
1efc1c6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
1efc1c6
to
6f3389b
Compare
not related to this PR |
Resolves brave/brave-browser#15235
MonitorChild
is no longer a member function but still running on child monitor thread, and it will run callback in the original thread usingBindPostTask
.We cannot bind
crash_handler_callback_
directly inBindPostTask
because we need to access some members inOnChildCrash
and the callback must be called before it is destructed otherwise we will hit this DCHECKAlso introduce
ChildProcessMonitor
to deduplicate the external child lifetime monitoring logicSubmitter Checklist:
QA/Yes
orQA/No
;release-notes/include
orrelease-notes/exclude
;OS/...
) to the associated issuenpm run test -- brave_browser_tests
,npm run test -- brave_unit_tests
,npm run lint
,npm run gn_check
,npm run tslint
git rebase master
(if needed)Reviewer Checklist:
gn
After-merge Checklist:
changes has landed on
Test Plan: