mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
Don't spawn an upload thread if url is empty
Also automatically stop upload and prune threads on destruction. Bug: crashpad:30 Change-Id: I45a30944eb3052182da296e00a6d6041691ab772 Reviewed-on: https://chromium-review.googlesource.com/924456 Commit-Queue: Joshua Peraza <jperaza@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
d8d03172c2
commit
ebad8bd925
@ -58,11 +58,18 @@ CrashReportUploadThread::CrashReportUploadThread(CrashReportDatabase* database,
|
|||||||
: WorkerThread::kIndefiniteWait,
|
: WorkerThread::kIndefiniteWait,
|
||||||
this),
|
this),
|
||||||
known_pending_report_uuids_(),
|
known_pending_report_uuids_(),
|
||||||
database_(database) {}
|
database_(database) {
|
||||||
|
DCHECK(!url_.empty());
|
||||||
|
}
|
||||||
|
|
||||||
CrashReportUploadThread::~CrashReportUploadThread() {
|
CrashReportUploadThread::~CrashReportUploadThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CrashReportUploadThread::ReportPending(const UUID& report_uuid) {
|
||||||
|
known_pending_report_uuids_.PushBack(report_uuid);
|
||||||
|
thread_.DoWorkNow();
|
||||||
|
}
|
||||||
|
|
||||||
void CrashReportUploadThread::Start() {
|
void CrashReportUploadThread::Start() {
|
||||||
thread_.Start(
|
thread_.Start(
|
||||||
options_.watch_pending_reports ? 0.0 : WorkerThread::kIndefiniteWait);
|
options_.watch_pending_reports ? 0.0 : WorkerThread::kIndefiniteWait);
|
||||||
@ -72,11 +79,6 @@ void CrashReportUploadThread::Stop() {
|
|||||||
thread_.Stop();
|
thread_.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrashReportUploadThread::ReportPending(const UUID& report_uuid) {
|
|
||||||
known_pending_report_uuids_.PushBack(report_uuid);
|
|
||||||
thread_.DoWorkNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CrashReportUploadThread::ProcessPendingReports() {
|
void CrashReportUploadThread::ProcessPendingReports() {
|
||||||
std::vector<UUID> known_report_uuids = known_pending_report_uuids_.Drain();
|
std::vector<UUID> known_report_uuids = known_pending_report_uuids_.Drain();
|
||||||
for (const UUID& report_uuid : known_report_uuids) {
|
for (const UUID& report_uuid : known_report_uuids) {
|
||||||
@ -140,9 +142,8 @@ void CrashReportUploadThread::ProcessPendingReport(
|
|||||||
Settings* const settings = database_->GetSettings();
|
Settings* const settings = database_->GetSettings();
|
||||||
|
|
||||||
bool uploads_enabled;
|
bool uploads_enabled;
|
||||||
if (url_.empty() ||
|
if (!report.upload_explicitly_requested &&
|
||||||
(!report.upload_explicitly_requested &&
|
(!settings->GetUploadsEnabled(&uploads_enabled) || !uploads_enabled)) {
|
||||||
(!settings->GetUploadsEnabled(&uploads_enabled) || !uploads_enabled))) {
|
|
||||||
// Don’t attempt an upload if there’s no URL to upload to. Allow upload if
|
// Don’t attempt an upload if there’s no URL to upload to. Allow upload if
|
||||||
// it has been explicitly requested by the user, otherwise, respect the
|
// it has been explicitly requested by the user, otherwise, respect the
|
||||||
// upload-enabled state stored in the database’s settings.
|
// upload-enabled state stored in the database’s settings.
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "client/crash_report_database.h"
|
#include "client/crash_report_database.h"
|
||||||
#include "util/misc/uuid.h"
|
#include "util/misc/uuid.h"
|
||||||
#include "util/stdlib/thread_safe_vector.h"
|
#include "util/stdlib/thread_safe_vector.h"
|
||||||
|
#include "util/thread/stoppable.h"
|
||||||
#include "util/thread/worker_thread.h"
|
#include "util/thread/worker_thread.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
@ -39,7 +40,8 @@ namespace crashpad {
|
|||||||
//! It also catches reports that are added without a ReportPending() signal
|
//! It also catches reports that are added without a ReportPending() signal
|
||||||
//! being caught. This may happen if crash reports are added to the database by
|
//! being caught. This may happen if crash reports are added to the database by
|
||||||
//! other processes.
|
//! other processes.
|
||||||
class CrashReportUploadThread : public WorkerThread::Delegate {
|
class CrashReportUploadThread : public WorkerThread::Delegate,
|
||||||
|
public Stoppable {
|
||||||
public:
|
public:
|
||||||
//! \brief Options to be passed to the CrashReportUploadThread constructor.
|
//! \brief Options to be passed to the CrashReportUploadThread constructor.
|
||||||
struct Options {
|
struct Options {
|
||||||
@ -70,11 +72,22 @@ class CrashReportUploadThread : public WorkerThread::Delegate {
|
|||||||
const Options& options);
|
const Options& options);
|
||||||
~CrashReportUploadThread();
|
~CrashReportUploadThread();
|
||||||
|
|
||||||
|
//! \brief Informs the upload thread that a new pending report has been added
|
||||||
|
//! to the database.
|
||||||
|
//!
|
||||||
|
//! \param[in] report_uuid The unique identifier of the newly added pending
|
||||||
|
//! report.
|
||||||
|
//!
|
||||||
|
//! This method may be called from any thread.
|
||||||
|
void ReportPending(const UUID& report_uuid);
|
||||||
|
|
||||||
|
// Stoppable:
|
||||||
|
|
||||||
//! \brief Starts a dedicated upload thread, which executes ThreadMain().
|
//! \brief Starts a dedicated upload thread, which executes ThreadMain().
|
||||||
//!
|
//!
|
||||||
//! This method may only be be called on a newly-constructed object or after
|
//! This method may only be be called on a newly-constructed object or after
|
||||||
//! a call to Stop().
|
//! a call to Stop().
|
||||||
void Start();
|
void Start() override;
|
||||||
|
|
||||||
//! \brief Stops the upload thread.
|
//! \brief Stops the upload thread.
|
||||||
//!
|
//!
|
||||||
@ -88,16 +101,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate {
|
|||||||
//!
|
//!
|
||||||
//! This method may be called from any thread other than the upload thread.
|
//! This method may be called from any thread other than the upload thread.
|
||||||
//! It is expected to only be called from the same thread that called Start().
|
//! It is expected to only be called from the same thread that called Start().
|
||||||
void Stop();
|
void Stop() override;
|
||||||
|
|
||||||
//! \brief Informs the upload thread that a new pending report has been added
|
|
||||||
//! to the database.
|
|
||||||
//!
|
|
||||||
//! \param[in] report_uuid The unique identifier of the newly added pending
|
|
||||||
//! report.
|
|
||||||
//!
|
|
||||||
//! This method may be called from any thread.
|
|
||||||
void ReportPending(const UUID& report_uuid);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! \brief The result code from UploadReport().
|
//! \brief The result code from UploadReport().
|
||||||
|
@ -417,6 +417,26 @@ void MonitorSelf(const Options& options) {
|
|||||||
ReinstallCrashHandler();
|
ReinstallCrashHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ScopedStoppable {
|
||||||
|
public:
|
||||||
|
ScopedStoppable() = default;
|
||||||
|
|
||||||
|
~ScopedStoppable() {
|
||||||
|
if (stoppable_) {
|
||||||
|
stoppable_->Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset(Stoppable* stoppable) { stoppable_.reset(stoppable); }
|
||||||
|
|
||||||
|
Stoppable* Get() { return stoppable_.get(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Stoppable> stoppable_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ScopedStoppable);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int HandlerMain(int argc,
|
int HandlerMain(int argc,
|
||||||
@ -770,31 +790,35 @@ int HandlerMain(int argc,
|
|||||||
return ExitFailure();
|
return ExitFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(scottmg): options.rate_limit should be removed when we have a
|
ScopedStoppable upload_thread;
|
||||||
// configurable database setting to control upload limiting.
|
if (!options.url.empty()) {
|
||||||
// See https://crashpad.chromium.org/bug/23.
|
// TODO(scottmg): options.rate_limit should be removed when we have a
|
||||||
CrashReportUploadThread::Options upload_thread_options;
|
// configurable database setting to control upload limiting.
|
||||||
upload_thread_options.identify_client_via_url =
|
// See https://crashpad.chromium.org/bug/23.
|
||||||
options.identify_client_via_url;
|
CrashReportUploadThread::Options upload_thread_options;
|
||||||
upload_thread_options.rate_limit = options.rate_limit;
|
upload_thread_options.identify_client_via_url =
|
||||||
upload_thread_options.upload_gzip = options.upload_gzip;
|
options.identify_client_via_url;
|
||||||
upload_thread_options.watch_pending_reports = options.periodic_tasks;
|
upload_thread_options.rate_limit = options.rate_limit;
|
||||||
CrashReportUploadThread upload_thread(database.get(),
|
upload_thread_options.upload_gzip = options.upload_gzip;
|
||||||
options.url,
|
upload_thread_options.watch_pending_reports = options.periodic_tasks;
|
||||||
upload_thread_options);
|
|
||||||
upload_thread.Start();
|
|
||||||
|
|
||||||
std::unique_ptr<PruneCrashReportThread> prune_thread;
|
upload_thread.Reset(new CrashReportUploadThread(
|
||||||
if (options.periodic_tasks) {
|
database.get(), options.url, upload_thread_options));
|
||||||
prune_thread.reset(new PruneCrashReportThread(
|
upload_thread.Get()->Start();
|
||||||
database.get(), PruneCondition::GetDefault()));
|
|
||||||
prune_thread->Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CrashReportExceptionHandler exception_handler(database.get(),
|
ScopedStoppable prune_thread;
|
||||||
&upload_thread,
|
if (options.periodic_tasks) {
|
||||||
&options.annotations,
|
prune_thread.Reset(new PruneCrashReportThread(
|
||||||
user_stream_sources);
|
database.get(), PruneCondition::GetDefault()));
|
||||||
|
prune_thread.Get()->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
CrashReportExceptionHandler exception_handler(
|
||||||
|
database.get(),
|
||||||
|
static_cast<CrashReportUploadThread*>(upload_thread.Get()),
|
||||||
|
&options.annotations,
|
||||||
|
user_stream_sources);
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
if (options.initial_client_data.IsValid()) {
|
if (options.initial_client_data.IsValid()) {
|
||||||
@ -805,11 +829,6 @@ int HandlerMain(int argc,
|
|||||||
|
|
||||||
exception_handler_server.Run(&exception_handler);
|
exception_handler_server.Run(&exception_handler);
|
||||||
|
|
||||||
upload_thread.Stop();
|
|
||||||
if (prune_thread) {
|
|
||||||
prune_thread->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,12 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
|
|||||||
return KERN_FAILURE;
|
return KERN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
upload_thread_->ReportPending(uuid);
|
if (upload_thread_) {
|
||||||
|
upload_thread_->ReportPending(uuid);
|
||||||
|
} else {
|
||||||
|
database_->SkipReportUpload(
|
||||||
|
uuid, Metrics::CrashSkippedReason::kUploadsDisabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_options.system_crash_reporter_forwarding != TriState::kDisabled &&
|
if (client_options.system_crash_reporter_forwarding != TriState::kDisabled &&
|
||||||
|
@ -36,7 +36,8 @@ class CrashReportExceptionHandler : public UniversalMachExcServer::Interface {
|
|||||||
//!
|
//!
|
||||||
//! \param[in] database The database to store crash reports in. Weak.
|
//! \param[in] database The database to store crash reports in. Weak.
|
||||||
//! \param[in] upload_thread The upload thread to notify when a new crash
|
//! \param[in] upload_thread The upload thread to notify when a new crash
|
||||||
//! report is written into \a database.
|
//! report is written into \a database. Report upload is skipped if this
|
||||||
|
//! value is `nullptr`.
|
||||||
//! \param[in] process_annotations A map of annotations to insert as
|
//! \param[in] process_annotations A map of annotations to insert as
|
||||||
//! process-level annotations into each crash report that is written. Do
|
//! process-level annotations into each crash report that is written. Do
|
||||||
//! not confuse this with module-level annotations, which are under the
|
//! not confuse this with module-level annotations, which are under the
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
|
#include "util/thread/stoppable.h"
|
||||||
#include "util/thread/worker_thread.h"
|
#include "util/thread/worker_thread.h"
|
||||||
|
|
||||||
namespace crashpad {
|
namespace crashpad {
|
||||||
@ -31,7 +32,7 @@ class PruneCondition;
|
|||||||
//! After the thread is started, the database is pruned using the condition
|
//! After the thread is started, the database is pruned using the condition
|
||||||
//! every 24 hours. Upon calling Start(), the thread waits 10 minutes before
|
//! every 24 hours. Upon calling Start(), the thread waits 10 minutes before
|
||||||
//! performing the initial prune operation.
|
//! performing the initial prune operation.
|
||||||
class PruneCrashReportThread : public WorkerThread::Delegate {
|
class PruneCrashReportThread : public WorkerThread::Delegate, public Stoppable {
|
||||||
public:
|
public:
|
||||||
//! \brief Constructs a new object.
|
//! \brief Constructs a new object.
|
||||||
//!
|
//!
|
||||||
@ -42,6 +43,8 @@ class PruneCrashReportThread : public WorkerThread::Delegate {
|
|||||||
std::unique_ptr<PruneCondition> condition);
|
std::unique_ptr<PruneCondition> condition);
|
||||||
~PruneCrashReportThread();
|
~PruneCrashReportThread();
|
||||||
|
|
||||||
|
// Stoppable:
|
||||||
|
|
||||||
//! \brief Starts a dedicated pruning thread.
|
//! \brief Starts a dedicated pruning thread.
|
||||||
//!
|
//!
|
||||||
//! The thread waits before running the initial prune, so as to not interfere
|
//! The thread waits before running the initial prune, so as to not interfere
|
||||||
@ -49,7 +52,7 @@ class PruneCrashReportThread : public WorkerThread::Delegate {
|
|||||||
//!
|
//!
|
||||||
//! This method may only be be called on a newly-constructed object or after
|
//! This method may only be be called on a newly-constructed object or after
|
||||||
//! a call to Stop().
|
//! a call to Stop().
|
||||||
void Start();
|
void Start() override;
|
||||||
|
|
||||||
//! \brief Stops the pruning thread.
|
//! \brief Stops the pruning thread.
|
||||||
//!
|
//!
|
||||||
@ -58,7 +61,7 @@ class PruneCrashReportThread : public WorkerThread::Delegate {
|
|||||||
//!
|
//!
|
||||||
//! This method may be called from any thread other than the pruning thread.
|
//! This method may be called from any thread other than the pruning thread.
|
||||||
//! It is expected to only be called from the same thread that called Start().
|
//! It is expected to only be called from the same thread that called Start().
|
||||||
void Stop();
|
void Stop() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// WorkerThread::Delegate:
|
// WorkerThread::Delegate:
|
||||||
|
@ -124,7 +124,12 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
|
|||||||
return termination_code;
|
return termination_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
upload_thread_->ReportPending(uuid);
|
if (upload_thread_) {
|
||||||
|
upload_thread_->ReportPending(uuid);
|
||||||
|
} else {
|
||||||
|
database_->SkipReportUpload(
|
||||||
|
uuid, Metrics::CrashSkippedReason::kUploadsDisabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSuccess);
|
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSuccess);
|
||||||
|
@ -37,7 +37,8 @@ class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
|
|||||||
//!
|
//!
|
||||||
//! \param[in] database The database to store crash reports in. Weak.
|
//! \param[in] database The database to store crash reports in. Weak.
|
||||||
//! \param[in] upload_thread The upload thread to notify when a new crash
|
//! \param[in] upload_thread The upload thread to notify when a new crash
|
||||||
//! report is written into \a database.
|
//! report is written into \a database. Report upload is skipped if this
|
||||||
|
//! value is `nullptr`.
|
||||||
//! \param[in] process_annotations A map of annotations to insert as
|
//! \param[in] process_annotations A map of annotations to insert as
|
||||||
//! process-level annotations into each crash report that is written. Do
|
//! process-level annotations into each crash report that is written. Do
|
||||||
//! not confuse this with module-level annotations, which are under the
|
//! not confuse this with module-level annotations, which are under the
|
||||||
|
@ -144,6 +144,7 @@ static_library("util") {
|
|||||||
"string/split_string.cc",
|
"string/split_string.cc",
|
||||||
"string/split_string.h",
|
"string/split_string.h",
|
||||||
"synchronization/semaphore.h",
|
"synchronization/semaphore.h",
|
||||||
|
"thread/stoppable.h",
|
||||||
"thread/thread.cc",
|
"thread/thread.cc",
|
||||||
"thread/thread.h",
|
"thread/thread.h",
|
||||||
"thread/thread_log_messages.cc",
|
"thread/thread_log_messages.cc",
|
||||||
|
39
util/thread/stoppable.h
Normal file
39
util/thread/stoppable.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2018 The Crashpad Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef CRASHPAD_UTIL_THREAD_STOPPABLE_H_
|
||||||
|
#define CRASHPAD_UTIL_THREAD_STOPPABLE_H_
|
||||||
|
|
||||||
|
#include "base/macros.h"
|
||||||
|
|
||||||
|
namespace crashpad {
|
||||||
|
|
||||||
|
//! \brief An interface for operations that may be Started and Stopped.
|
||||||
|
class Stoppable {
|
||||||
|
public:
|
||||||
|
virtual ~Stoppable() = default;
|
||||||
|
|
||||||
|
//! \brief Starts the operation.
|
||||||
|
virtual void Start() = 0;
|
||||||
|
|
||||||
|
//! \brief Stops the operation.
|
||||||
|
virtual void Stop() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Stoppable() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace crashpad
|
||||||
|
|
||||||
|
#endif // CRASHPAD_UTIL_THREAD_STOPPABLE_H_
|
@ -228,6 +228,7 @@
|
|||||||
'synchronization/semaphore_posix.cc',
|
'synchronization/semaphore_posix.cc',
|
||||||
'synchronization/semaphore_win.cc',
|
'synchronization/semaphore_win.cc',
|
||||||
'synchronization/semaphore.h',
|
'synchronization/semaphore.h',
|
||||||
|
'thread/stoppable.h',
|
||||||
'thread/thread.cc',
|
'thread/thread.cc',
|
||||||
'thread/thread.h',
|
'thread/thread.h',
|
||||||
'thread/thread_log_messages.cc',
|
'thread/thread_log_messages.cc',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user