Commit 5aa6275b authored by Sadrul Habib Chowdhury's avatar Sadrul Habib Chowdhury Committed by Commit Bot

code coverage: Fix writing profiles from child processes.

Notable changes:
. Introduce CLANG_COVERAGE define if use_clang_coverage gn arg is set.
. For child processes to be able to correctly write the coverage profile
  during teardown, it is necessary to allow them to shut-down cleanly.
  So avoid terminating the processes from ~ChildProcessLauncher() when
  CLANG_COVERAGE is set.
. Child processes can do fast-shutdown by calling _exit(0). So force the
  profile file to be written from the child process before calling that.

With both changes, it is still necessary to run with --no-sandbox, since
otherwise the child processes are not able to write to the profile file.

BUG=838582, 834781

Change-Id: I742521e756a7dead983f40462798f7c4dac2ac02
Reviewed-on: https://chromium-review.googlesource.com/1041271Reviewed-by: default avatarMax Moroz <mmoroz@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Reviewed-by: default avatarDirk Pranke <dpranke@chromium.org>
Commit-Queue: Sadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556236}
parent dfd6a351
...@@ -6,6 +6,7 @@ import("//build/config/allocator.gni") ...@@ -6,6 +6,7 @@ import("//build/config/allocator.gni")
import("//build/config/c++/c++.gni") import("//build/config/c++/c++.gni")
import("//build/config/chrome_build.gni") import("//build/config/chrome_build.gni")
import("//build/config/chromecast_build.gni") import("//build/config/chromecast_build.gni")
import("//build/config/coverage/coverage.gni")
import("//build/config/crypto.gni") import("//build/config/crypto.gni")
import("//build/config/dcheck_always_on.gni") import("//build/config/dcheck_always_on.gni")
import("//build/config/features.gni") import("//build/config/features.gni")
...@@ -118,6 +119,9 @@ config("feature_flags") { ...@@ -118,6 +119,9 @@ config("feature_flags") {
if (is_ubsan || is_ubsan_null || is_ubsan_vptr || is_ubsan_security) { if (is_ubsan || is_ubsan_null || is_ubsan_vptr || is_ubsan_security) {
defines += [ "UNDEFINED_SANITIZER" ] defines += [ "UNDEFINED_SANITIZER" ]
} }
if (use_clang_coverage) {
defines += [ "CLANG_COVERAGE" ]
}
if (safe_browsing_mode == 1) { if (safe_browsing_mode == 1) {
defines += [ "FULL_SAFE_BROWSING" ] defines += [ "FULL_SAFE_BROWSING" ]
defines += [ "SAFE_BROWSING_CSD" ] defines += [ "SAFE_BROWSING_CSD" ]
......
...@@ -35,7 +35,7 @@ ChildProcessLauncher::ChildProcessLauncher( ...@@ -35,7 +35,7 @@ ChildProcessLauncher::ChildProcessLauncher(
start_time_(base::TimeTicks::Now()), start_time_(base::TimeTicks::Now()),
#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ #if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \
defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
defined(UNDEFINED_SANITIZER) defined(UNDEFINED_SANITIZER) || defined(CLANG_COVERAGE)
terminate_child_on_shutdown_(false), terminate_child_on_shutdown_(false),
#else #else
terminate_child_on_shutdown_(terminate_on_shutdown), terminate_child_on_shutdown_(terminate_on_shutdown),
......
...@@ -74,9 +74,19 @@ ...@@ -74,9 +74,19 @@
#include "content/public/common/content_descriptors.h" #include "content/public/common/content_descriptors.h"
#endif #endif
#if defined(CLANG_COVERAGE)
extern "C" int __llvm_profile_write_file(void);
#endif
namespace content { namespace content {
namespace { namespace {
void WriteClangCoverageProfile() {
#if defined(CLANG_COVERAGE)
__llvm_profile_write_file();
#endif
}
// How long to wait for a connection to the browser process before giving up. // How long to wait for a connection to the browser process before giving up.
const int kConnectionTimeoutS = 15; const int kConnectionTimeoutS = 15;
...@@ -100,6 +110,7 @@ class WaitAndExitDelegate : public base::PlatformThread::Delegate { ...@@ -100,6 +110,7 @@ class WaitAndExitDelegate : public base::PlatformThread::Delegate {
void ThreadMain() override { void ThreadMain() override {
base::PlatformThread::Sleep(duration_); base::PlatformThread::Sleep(duration_);
WriteClangCoverageProfile();
_exit(0); _exit(0);
} }
...@@ -160,6 +171,7 @@ class SuicideOnChannelErrorFilter : public IPC::MessageFilter { ...@@ -160,6 +171,7 @@ class SuicideOnChannelErrorFilter : public IPC::MessageFilter {
__lsan_do_leak_check(); __lsan_do_leak_check();
#endif #endif
#else #else
WriteClangCoverageProfile();
_exit(0); _exit(0);
#endif #endif
} }
...@@ -620,8 +632,10 @@ ChildThreadImpl::~ChildThreadImpl() { ...@@ -620,8 +632,10 @@ ChildThreadImpl::~ChildThreadImpl() {
} }
void ChildThreadImpl::Shutdown() { void ChildThreadImpl::Shutdown() {
// Delete objects that hold references to blink so derived classes can // The renderer process (and others) can to fast shutdown by calling _exit(0),
// safely shutdown blink in their Shutdown implementation. // in which case the clang-coverage profile does not get written to the file.
// So force write the profile here before shutting down.
WriteClangCoverageProfile();
} }
bool ChildThreadImpl::ShouldBeDestroyed() { bool ChildThreadImpl::ShouldBeDestroyed() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment