Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions client/crashpad_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,14 @@ class CrashpadClient {
void RemoveAttachment(const base::FilePath& attachment);
#endif

//! \brief Requests that the handler retry pending report uploads.
//!
//! Wakes the handler's upload thread to immediately process pending reports
//! rather than waiting for its next periodic scan. Useful after state
//! changes (such as clearing UploadsPaused) that should take effect without
//! delay.
void RequestRetry();

private:
#if BUILDFLAG(IS_WIN) || DOXYGEN
//! \brief Registers process handlers for the client.
Expand Down
10 changes: 10 additions & 0 deletions client/crashpad_client_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,11 @@ class RequestCrashDumpHandler : public SignalHandler {
client.RemoveAttachment(attachment);
}

void RequestRetry() {
ExceptionHandlerClient client(sock_to_handler_.get(), true);
client.RequestRetry();
}

private:
RequestCrashDumpHandler() = default;

Expand Down Expand Up @@ -832,4 +837,9 @@ void CrashpadClient::RemoveAttachment(const base::FilePath& attachment) {
signal_handler->RemoveAttachment(attachment);
}

void CrashpadClient::RequestRetry() {
auto signal_handler = RequestCrashDumpHandler::Get();
signal_handler->RequestRetry();
}
Comment thread
sentry[bot] marked this conversation as resolved.
Resolved

} // namespace crashpad
6 changes: 6 additions & 0 deletions client/crashpad_client_mac.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "util/mac/mac_util.h"
#include "util/mach/bootstrap.h"
#include "util/mach/child_port_handshake.h"
#include "util/mach/exception_handler_protocol.h"
#include "util/mach/exception_ports.h"
#include "util/mach/mach_extensions.h"
#include "util/mach/mach_message.h"
Expand Down Expand Up @@ -612,6 +613,11 @@ base::apple::ScopedMachSendRight CrashpadClient::GetHandlerMachPort() const {
return base::apple::ScopedMachSendRight(exception_port_.get());
}

void CrashpadClient::RequestRetry() {
SendClientToServerMessage(exception_port_.get(),
ClientToServerMessage::kRequestRetry);
}

// static
void CrashpadClient::UseSystemDefaultHandler() {
base::apple::ScopedMachSendRight system_crash_reporter_handler(
Expand Down
7 changes: 7 additions & 0 deletions client/crashpad_client_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1231,4 +1231,11 @@ void CrashpadClient::RemoveAttachment(const base::FilePath& attachment) {
&response);
}

void CrashpadClient::RequestRetry() {
ClientToServerMessage message = {};
message.type = ClientToServerMessage::kRequestRetry;
ServerToClientMessage response = {};
SendToCrashHandlerServer(ipc_pipe_, message, &response);
}

} // namespace crashpad
28 changes: 28 additions & 0 deletions client/settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ struct SettingsReader::Data {

enum Options : uint32_t {
kUploadsEnabled = 1 << 0,
kUploadsPaused = 1 << 1,
};

Data() : magic(kSettingsMagic),
Expand Down Expand Up @@ -174,6 +175,17 @@ bool SettingsReader::GetUploadsEnabled(bool* enabled) {
return true;
}

bool SettingsReader::GetUploadsPaused(bool* paused) {
DCHECK(initialized().is_valid());

Data settings;
if (!OpenAndReadSettings(&settings))
return false;

*paused = (settings.options & Data::Options::kUploadsPaused) != 0;
return true;
}

bool SettingsReader::GetLastUploadAttemptTime(time_t* time) {
DCHECK(initialized().is_valid());

Expand Down Expand Up @@ -268,6 +280,22 @@ bool Settings::SetUploadsEnabled(bool enabled) {
return WriteSettings(handle.get(), settings);
}

bool Settings::SetUploadsPaused(bool paused) {
DCHECK(initialized().is_valid());

Data settings;
ScopedLockedFileHandle handle = OpenForWritingAndReadSettings(&settings);
if (!handle.is_valid())
return false;

if (paused)
settings.options |= Data::Options::kUploadsPaused;
else
settings.options &= ~Data::Options::kUploadsPaused;

return WriteSettings(handle.get(), settings);
}

bool Settings::SetLastUploadAttemptTime(time_t time) {
DCHECK(initialized().is_valid());

Expand Down
24 changes: 24 additions & 0 deletions client/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ class SettingsReader {
//! error logged.
bool GetUploadsEnabled(bool* enabled);

//! \brief Retrieves whether uploads are paused.
//!
//! When paused, pending reports are retained in the `pending` state rather
//! than being uploaded or skipped. Reports accumulate in `pending` until the
//! flag is cleared, at which point normal processing resumes.
//!
//! The default value is `false`.
//!
//! \param[out] paused Whether uploads are paused.
//!
//! \return On success, returns `true`, otherwise returns `false` with an
//! error logged.
bool GetUploadsPaused(bool* paused);

//! \brief Retrieves the last time at which a report was attempted to be
//! uploaded.
//!
Expand Down Expand Up @@ -172,6 +186,16 @@ class Settings final : public SettingsReader {
//! error logged.
bool SetUploadsEnabled(bool enabled);

//! \brief Sets whether uploads are paused.
//!
//! See GetUploadsPaused() for the semantics of this flag.
//!
//! \param[in] paused Whether uploads should be paused.
//!
//! \return On success, returns `true`, otherwise returns `false` with an
//! error logged.
bool SetUploadsPaused(bool paused);

//! \brief Sets the last time at which a report was attempted to be uploaded.
//!
//! This is only meant to be used internally by the CrashReportDatabase.
Expand Down
13 changes: 13 additions & 0 deletions handler/crash_report_upload_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ void CrashReportUploadThread::ReportPendingSync(const UUID& report_uuid) {
DoWork(nullptr);
}

void CrashReportUploadThread::RetryPending() {
if (thread_.is_running())
thread_.DoWorkNow();
}

void CrashReportUploadThread::Start() {
thread_.Start(
options_.watch_pending_reports ? 0.0 : WorkerThread::kIndefiniteWait);
Expand All @@ -140,6 +145,14 @@ void CrashReportUploadThread::ProcessPendingReports() {
// uploads complete (regardless of whether or not that succeeded).
ScopedFunctionInvoker scoped_function_invoker(callback_);

bool uploads_paused;
if (database_->GetSettings()->GetUploadsPaused(&uploads_paused) &&
uploads_paused) {
// Leave known pending report UUIDs in the queue so they are retried once
// the pause is lifted, and skip scanning for new pending reports.
return;
Comment thread
sentry[bot] marked this conversation as resolved.
Resolved
}
Comment thread
cursor[bot] marked this conversation as resolved.
Resolved

std::vector<UUID> known_report_uuids = known_pending_report_uuids_.Drain();
for (const UUID& report_uuid : known_report_uuids) {
CrashReportDatabase::Report report;
Expand Down
9 changes: 9 additions & 0 deletions handler/crash_report_upload_thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,15 @@ class CrashReportUploadThread : public WorkerThread::Delegate,
//! This method will run on the pool thread executing the OnCrashDumpEvent
void ReportPendingSync(const UUID& report_uuid);

//! \brief Wakes the upload thread to immediately process pending reports.
//!
//! Unlike ReportPending(), no specific report UUID is enqueued; the next
//! pass relies on the thread's pending-report scan (requires
//! \a watch_pending_reports).
//!
//! This method may be called from any thread.
void RetryPending();

// Stoppable:

//! \brief Starts a dedicated upload thread, which executes ThreadMain().
Expand Down
6 changes: 6 additions & 0 deletions handler/linux/crash_report_exception_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ void CrashReportExceptionHandler::RemoveAttachment(
attachments_.erase(it);
}

void CrashReportExceptionHandler::RequestRetry() {
if (upload_thread_) {
upload_thread_->RetryPending();
}
}

bool CrashReportExceptionHandler::WriteMinidumpToDatabase(
ProcessSnapshotLinux* process_snapshot,
ProcessSnapshotSanitized* sanitized_snapshot,
Expand Down
1 change: 1 addition & 0 deletions handler/linux/crash_report_exception_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {

void AddAttachment(const base::FilePath& attachment) override;
void RemoveAttachment(const base::FilePath& attachment) override;
void RequestRetry() override;

private:
bool HandleExceptionWithConnection(
Expand Down
4 changes: 4 additions & 0 deletions handler/linux/exception_handler_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,10 @@ bool ExceptionHandlerServer::ReceiveClientMessage(Event* event) {
case ExceptionHandlerProtocol::ClientToServerMessage::kTypeRemoveAttachment:
delegate_->RemoveAttachment(base::FilePath(message.attachment_info.path));
return true;

case ExceptionHandlerProtocol::ClientToServerMessage::kTypeRequestRetry:
delegate_->RequestRetry();
return true;
}

DCHECK(false);
Expand Down
4 changes: 4 additions & 0 deletions handler/linux/exception_handler_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ class ExceptionHandlerServer {
//! \brief Called to remove an attachment from the crash report.
virtual void RemoveAttachment(const base::FilePath& attachment) = 0;

//! \brief Called when the server has received a request to retry pending
//! report uploads.
virtual void RequestRetry() = 0;

virtual ~Delegate() {}
};

Expand Down
6 changes: 6 additions & 0 deletions handler/mac/crash_report_exception_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -308,4 +308,10 @@ kern_return_t CrashReportExceptionHandler::CatchMachException(
return KERN_SUCCESS;
}

void CrashReportExceptionHandler::RequestRetry() {
if (upload_thread_) {
upload_thread_->RetryPending();
}
}

} // namespace crashpad
7 changes: 6 additions & 1 deletion handler/mac/crash_report_exception_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "client/crash_report_database.h"
#include "handler/crash_report_upload_thread.h"
#include "handler/mac/exception_handler_server.h"
#include "handler/user_stream_data_source.h"
#include "util/misc/uuid.h"
#include "util/mach/exc_server_variants.h"
Expand All @@ -31,7 +32,7 @@ namespace crashpad {
//! \brief An exception handler that writes crash reports for exception messages
//! to a CrashReportDatabase.
class CrashReportExceptionHandler final
: public UniversalMachExcServer::Interface {
: public ExceptionHandlerServer::Delegate {
public:
//! \brief Creates a new object that will store crash reports in \a database.
//!
Expand Down Expand Up @@ -91,7 +92,11 @@ class CrashReportExceptionHandler final
const mach_msg_trailer_t* trailer,
bool* destroy_complex_request) override;

// ExceptionHandlerServer::Delegate:
void RequestRetry() override;

private:

CrashReportDatabase* database_; // weak
CrashReportUploadThread* upload_thread_; // weak
const std::map<std::string, std::string>* process_annotations_; // weak
Expand Down
Loading
Loading