Commit 3b0ce9fb authored by Oystein Eftevaag's avatar Oystein Eftevaag Committed by Commit Bot

Make sure the main-thread TracingSamplerProfiler is explicitly destroyed

Otherwise, if it's destroyed through TLS, it can hang forever waiting
for a signal from the StackSamplingThread which never occurs.

This is going back to the behavior prior to
https://chromium-review.googlesource.com/c/chromium/src/+/1638578

R=ssid@chromium.org

Bug: 995323
Change-Id: I08863f5ee8ccd01c70b95bbce5fc28922dc06d1f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1761291Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarssid <ssid@chromium.org>
Commit-Queue: oysteine <oysteine@chromium.org>
Cr-Commit-Position: refs/heads/master@{#688622}
parent d12ff379
......@@ -634,7 +634,8 @@ bool ChromeMainDelegate::BasicStartupComplete(int* exit_code) {
content::Profiling::ProcessStarted();
// Setup tracing sampler profiler as early as possible at startup if needed.
tracing::TracingSamplerProfiler::CreateForCurrentThread();
tracing_sampler_profiler_ =
tracing::TracingSamplerProfiler::CreateOnMainThread();
#if defined(OS_WIN) && !defined(CHROME_MULTIPLE_DLL_BROWSER)
v8_crashpad_support::SetUp();
......
......@@ -22,6 +22,10 @@ namespace base {
class CommandLine;
}
namespace tracing {
class TracingSamplerProfiler;
}
class ChromeContentBrowserClient;
// Chrome implementation of ContentMainDelegate.
......@@ -84,6 +88,8 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
std::unique_ptr<StartupData> startup_data_;
#endif
std::unique_ptr<tracing::TracingSamplerProfiler> tracing_sampler_profiler_;
DISALLOW_COPY_AND_ASSIGN(ChromeMainDelegate);
};
......
......@@ -1171,7 +1171,7 @@ void ChromeBrowserMainParts::PostCreateThreads() {
#if !defined(OS_ANDROID)
base::PostTask(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&tracing::TracingSamplerProfiler::CreateForCurrentThread));
base::BindOnce(&tracing::TracingSamplerProfiler::CreateOnChildThread));
#endif
tracing::SetupBackgroundTracingFieldTrial();
......
......@@ -362,7 +362,8 @@ int GpuMain(const MainFunctionParams& parameters) {
gpu_process.set_main_thread(child_thread);
// Setup tracing sampler profiler as early as possible.
tracing::TracingSamplerProfiler::CreateForCurrentThread();
std::unique_ptr<tracing::TracingSamplerProfiler> tracing_sampler_profiler =
tracing::TracingSamplerProfiler::CreateOnMainThread();
#if defined(OS_ANDROID)
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
......
......@@ -192,7 +192,8 @@ int RendererMain(const MainFunctionParams& parameters) {
std::move(main_thread_scheduler));
// Setup tracing sampler profiler as early as possible.
tracing::TracingSamplerProfiler::CreateForCurrentThread();
auto tracing_sampler_profiler =
tracing::TracingSamplerProfiler::CreateOnMainThread();
if (need_sandbox)
should_run_loop = platform.EnableSandbox();
......
......@@ -457,7 +457,14 @@ TracingSamplerProfiler::TracingProfileBuilder::GetCallstackIDAndMaybeEmit(
}
// static
void TracingSamplerProfiler::CreateForCurrentThread() {
std::unique_ptr<TracingSamplerProfiler>
TracingSamplerProfiler::CreateOnMainThread() {
return std::make_unique<TracingSamplerProfiler>(
(base::PlatformThread::CurrentId()));
}
// static
void TracingSamplerProfiler::CreateOnChildThread() {
auto* slot = GetThreadLocalStorageProfilerSlot();
if (slot->Get())
return;
......@@ -468,7 +475,7 @@ void TracingSamplerProfiler::CreateForCurrentThread() {
}
// static
void TracingSamplerProfiler::DeleteForCurrentThreadForTesting() {
void TracingSamplerProfiler::DeleteOnChildThreadForTesting() {
auto* profiler = GetThreadLocalStorageProfilerSlot()->Get();
if (profiler) {
delete static_cast<TracingSamplerProfiler*>(profiler);
......
......@@ -93,19 +93,26 @@ class COMPONENT_EXPORT(TRACING_CPP) TracingSamplerProfiler {
const bool should_enable_filtering_;
};
// Sets up tracing sampling profiler on the current thread. The profiler will
// be stored in SequencedLocalStorageSlot and will be destroyed with the
// thread task runner.
static void CreateForCurrentThread();
// Creates sampling profiler on main thread. The profiler *must* be
// destroyed prior to process shutdown.
static std::unique_ptr<TracingSamplerProfiler> CreateOnMainThread();
// Sets up tracing sampling profiler on a child thread. The profiler will be
// stored in SequencedLocalStorageSlot and will be destroyed with the thread
// task runner.
static void CreateOnChildThread();
// Registers the TracingSamplerProfiler as a Perfetto data source
static void RegisterDataSource();
static void SetupStartupTracing();
// For tests.
static void DeleteForCurrentThreadForTesting();
static void DeleteOnChildThreadForTesting();
static void StartTracingForTesting(tracing::PerfettoProducer* producer);
static void StopTracingForTesting();
explicit TracingSamplerProfiler(base::PlatformThreadId sampled_thread_id);
virtual ~TracingSamplerProfiler();
void StartTracing(std::unique_ptr<perfetto::TraceWriter> trace_writer,
......@@ -113,8 +120,6 @@ class COMPONENT_EXPORT(TRACING_CPP) TracingSamplerProfiler {
void StopTracing();
private:
explicit TracingSamplerProfiler(base::PlatformThreadId sampled_thread_id);
const base::PlatformThreadId sampled_thread_id_;
base::Lock lock_;
......
......@@ -249,29 +249,27 @@ class TestModule : public base::ModuleCache::Module {
} // namespace
TEST_F(TracingSampleProfilerTest, OnSampleCompleted) {
TracingSamplerProfiler::CreateForCurrentThread();
auto profiler = TracingSamplerProfiler::CreateOnMainThread();
BeginTrace();
base::RunLoop().RunUntilIdle();
WaitForEvents();
EndTracing();
base::RunLoop().RunUntilIdle();
ValidateReceivedEvents();
TracingSamplerProfiler::DeleteForCurrentThreadForTesting();
}
TEST_F(TracingSampleProfilerTest, JoinRunningTracing) {
BeginTrace();
TracingSamplerProfiler::CreateForCurrentThread();
auto profiler = TracingSamplerProfiler::CreateOnMainThread();
base::RunLoop().RunUntilIdle();
WaitForEvents();
EndTracing();
base::RunLoop().RunUntilIdle();
ValidateReceivedEvents();
TracingSamplerProfiler::DeleteForCurrentThreadForTesting();
}
TEST_F(TracingSampleProfilerTest, TestStartupTracing) {
TracingSamplerProfiler::CreateForCurrentThread();
auto profiler = TracingSamplerProfiler::CreateOnMainThread();
TracingSamplerProfiler::SetupStartupTracing();
base::RunLoop().RunUntilIdle();
WaitForEvents();
......@@ -302,13 +300,12 @@ TEST_F(TracingSampleProfilerTest, TestStartupTracing) {
EXPECT_LT(first_profile_ts,
start_tracing_ts.since_origin().InMicroseconds());
}
TracingSamplerProfiler::DeleteForCurrentThreadForTesting();
}
TEST_F(TracingSampleProfilerTest, JoinStartupTracing) {
TracingSamplerProfiler::SetupStartupTracing();
base::RunLoop().RunUntilIdle();
TracingSamplerProfiler::CreateForCurrentThread();
auto profiler = TracingSamplerProfiler::CreateOnMainThread();
WaitForEvents();
auto start_tracing_ts = TRACE_TIME_TICKS_NOW();
BeginTrace();
......@@ -337,15 +334,13 @@ TEST_F(TracingSampleProfilerTest, JoinStartupTracing) {
EXPECT_LT(first_profile_ts,
start_tracing_ts.since_origin().InMicroseconds());
}
TracingSamplerProfiler::DeleteForCurrentThreadForTesting();
}
TEST_F(TracingSampleProfilerTest, SamplingChildThread) {
base::Thread sampled_thread("sampling_profiler_test");
sampled_thread.Start();
sampled_thread.task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&TracingSamplerProfiler::CreateForCurrentThread));
FROM_HERE, base::BindOnce(&TracingSamplerProfiler::CreateOnChildThread));
BeginTrace();
base::RunLoop().RunUntilIdle();
WaitForEvents();
......@@ -353,8 +348,7 @@ TEST_F(TracingSampleProfilerTest, SamplingChildThread) {
ValidateReceivedEvents();
sampled_thread.task_runner()->PostTask(
FROM_HERE,
base::BindOnce(
&TracingSamplerProfiler::DeleteForCurrentThreadForTesting));
base::BindOnce(&TracingSamplerProfiler::DeleteOnChildThreadForTesting));
base::RunLoop().RunUntilIdle();
}
......
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