Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,177 @@
// Copyright 2015 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_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_
#define CRASHPAD_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_
#include <memory>
#include <string>
#include "base/macros.h"
#include "client/crash_report_database.h"
#include "util/misc/uuid.h"
#include "util/stdlib/thread_safe_vector.h"
#include "util/thread/worker_thread.h"
namespace crashpad {
//! \brief A thread that processes pending crash reports in a
//! CrashReportDatabase by uploading them or marking them as completed
//! without upload, as desired.
//!
//! A producer of crash reports should notify an object of this class that a new
//! report has been added to the database by calling ReportPending().
//!
//! Independently of being triggered by ReportPending(), objects of this class
//! can periodically examine the database for pending reports. This allows
//! failed upload attempts for reports left in the pending state to be retried.
//! 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
//! other processes.
class CrashReportUploadThread : public WorkerThread::Delegate {
public:
//! \brief Options to be passed to the CrashReportUploadThread constructor.
struct Options {
//! Whether client identifying parameters like product name or version
//! should be added to the URL.
bool identify_client_via_url;
//! Whether uploads should be throttled to a (currently hardcoded) rate.
bool rate_limit;
//! Whether uploads should use `gzip` compression.
bool upload_gzip;
//! Whether to periodically check for new pending reports not already known
//! to exist. When `false`, only an initial upload attempt will be made for
//! reports known to exist by having been added by the ReportPending()
//! method. No scans for new pending reports will be conducted.
bool watch_pending_reports;
};
//! \brief Constructs a new object.
//!
//! \param[in] database The database to upload crash reports from.
//! \param[in] url The URL of the server to upload crash reports to.
//! \param[in] options Options for the report uploads.
CrashReportUploadThread(CrashReportDatabase* database,
const std::string& url,
const Options& options);
~CrashReportUploadThread();
//! \brief Starts a dedicated upload thread, which executes ThreadMain().
//!
//! This method may only be be called on a newly-constructed object or after
//! a call to Stop().
void Start();
//! \brief Stops the upload thread.
//!
//! The upload thread will terminate after completing whatever task it is
//! performing. If it is not performing any task, it will terminate
//! immediately. This method blocks while waiting for the upload thread to
//! terminate.
//!
//! This method must only be called after Start(). If Start() has been called,
//! this method must be called before destroying an object of this class.
//!
//! 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().
void Stop();
//! \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:
//! \brief The result code from UploadReport().
enum class UploadResult {
//! \brief The crash report was uploaded successfully.
kSuccess,
//! \brief The crash report upload failed in such a way that recovery is
//! impossible.
//!
//! No further upload attempts should be made for the report.
kPermanentFailure,
//! \brief The crash report upload failed, but it might succeed again if
//! retried in the future.
//!
//! If the report has not already been retried too many times, the caller
//! may arrange to call UploadReport() for the report again in the future,
//! after a suitable delay.
kRetry,
};
//! \brief Calls ProcessPendingReport() on pending reports.
//!
//! Assuming Stop() has not been called, this will process reports that the
//! object has been made aware of in ReportPending(). Additionally, if the
//! object was constructed with \a watch_pending_reports, it will also scan
//! the crash report database for other pending reports, and process those as
//! well.
void ProcessPendingReports();
//! \brief Processes a single pending report from the database.
//!
//! \param[in] report The crash report to process.
//!
//! If report upload is enabled, this method attempts to upload \a report by
//! calling UplaodReport(). If the upload is successful, the report will be
//! marked as “completed” in the database. If the upload fails and more
//! retries are desired, the reports upload-attempt count and
//! last-upload-attempt time will be updated in the database and it will
//! remain in the “pending” state. If the upload fails and no more retries are
//! desired, or report upload is disabled, it will be marked as “completed” in
//! the database without ever having been uploaded.
void ProcessPendingReport(const CrashReportDatabase::Report& report);
//! \brief Attempts to upload a crash report.
//!
//! \param[in] report The report to upload. The caller is responsible for
//! calling CrashReportDatabase::GetReportForUploading() before calling
//! this method, and for calling
//! CrashReportDatabase::RecordUploadAttempt() after calling this method.
//! \param[out] response_body If the upload attempt is successful, this will
//! be set to the response body sent by the server. Breakpad-type servers
//! provide the crash ID assigned by the server in the response body.
//!
//! \return A member of UploadResult indicating the result of the upload
//! attempt.
UploadResult UploadReport(const CrashReportDatabase::Report* report,
std::string* response_body);
// WorkerThread::Delegate:
//! \brief Calls ProcessPendingReports() in response to ReportPending() having
//! been called on any thread, as well as periodically on a timer.
void DoWork(const WorkerThread* thread) override;
const Options options_;
const std::string url_;
WorkerThread thread_;
ThreadSafeVector<UUID> known_pending_report_uuids_;
CrashReportDatabase* database_; // weak
DISALLOW_COPY_AND_ASSIGN(CrashReportUploadThread);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_
@@ -0,0 +1,65 @@
// Copyright 2017 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_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_
#define CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_
#include <map>
#include <string>
#include "base/macros.h"
#include "client/crash_report_database.h"
#include "handler/crash_report_upload_thread.h"
#include "handler/user_stream_data_source.h"
namespace crashpad {
//! \brief An exception handler that writes crash reports for exception messages
//! to a CrashReportDatabase. This class is not yet implemented.
class CrashReportExceptionHandler {
public:
//! \brief Creates a new object that will store crash reports in \a database.
//!
//! \param[in] database The database to store crash reports in. Weak.
//! \param[in] upload_thread The upload thread to notify when a new crash
//! report is written into \a database.
//! \param[in] process_annotations A map of annotations to insert as
//! process-level annotations into each crash report that is written. Do
//! not confuse this with module-level annotations, which are under the
//! control of the crashing process, and are used to implement Chrome's
//! "crash keys." Process-level annotations are those that are beyond the
//! control of the crashing process, which must reliably be set even if
//! the process crashes before its able to establish its own annotations.
//! To interoperate with Breakpad servers, the recommended practice is to
//! specify values for the `"prod"` and `"ver"` keys as process
//! annotations.
//! \param[in] user_stream_data_sources Data sources to be used to extend
//! crash reports. For each crash report that is written, the data sources
//! are called in turn. These data sources may contribute additional
//! minidump streams. `nullptr` if not required.
CrashReportExceptionHandler(
CrashReportDatabase* database,
CrashReportUploadThread* upload_thread,
const std::map<std::string, std::string>* process_annotations,
const UserStreamDataSources* user_stream_data_sources);
~CrashReportExceptionHandler();
private:
DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_
@@ -0,0 +1,44 @@
// Copyright 2017 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_HANDLER_FUCHSIA_EXCEPTION_HANDLER_SERVER_H_
#define CRASHPAD_HANDLER_FUCHSIA_EXCEPTION_HANDLER_SERVER_H_
#include "base/macros.h"
namespace crashpad {
class CrashReportExceptionHandler;
//! \brief Runs the main exception-handling server in Crashpad's handler
//! process. This class is not yet implemented.
class ExceptionHandlerServer {
public:
//! \brief Constructs an ExceptionHandlerServer object.
ExceptionHandlerServer();
~ExceptionHandlerServer();
//! \brief Runs the exception-handling server.
//!
//! \param[in] handler The handler to which the exceptions are delegated when
//! they are caught in Run(). Ownership is not transferred.
void Run(CrashReportExceptionHandler* handler);
private:
DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServer);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_FUCHSIA_EXCEPTION_HANDLER_SERVER_H_
@@ -0,0 +1,39 @@
// Copyright 2015 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_HANDLER_HANDLER_MAIN_H_
#define CRASHPAD_HANDLER_HANDLER_MAIN_H_
#include "handler/user_stream_data_source.h"
namespace crashpad {
//! \brief The `main()` of the `crashpad_handler` binary.
//!
//! This is exposed so that `crashpad_handler` can be embedded into another
//! binary, but called and used as if it were a standalone executable.
//!
//! \param[in] argc \a argc as passed to `main()`.
//! \param[in] argv \a argv as passed to `main()`.
//! \param[in] user_stream_sources An optional vector containing the
//! extensibility data sources to call on crash. Each time a minidump is
//! created, the sources are called in turn. Any streams returned are added
//! to the minidump.
int HandlerMain(int argc,
char* argv[],
const UserStreamDataSources* user_stream_sources);
} // namespace crashpad
#endif // CRASHPAD_HANDLER_HANDLER_MAIN_H_
@@ -0,0 +1,155 @@
// Copyright 2017 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_HANDLER_LINUX_EXCEPTION_HANDLER_SERVER_H_
#define CRASHPAD_HANDLER_LINUX_EXCEPTION_HANDLER_SERVER_H_
#include <stdint.h>
#include <sys/socket.h>
#include <memory>
#include <unordered_map>
#include "base/macros.h"
#include "util/file/file_io.h"
#include "util/linux/exception_handler_protocol.h"
#include "util/misc/address_types.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
//! \brief Abstract base class for deciding how the handler should `ptrace` a
//! client.
class PtraceStrategyDecider {
public:
virtual ~PtraceStrategyDecider() = default;
//! \brief The possible return values for ChooseStrategy().
enum class Strategy {
//! \brief An error occurred, with a message logged.
kError,
//! \brief Ptrace cannot be used.
kNoPtrace,
//! \brief The handler should `ptrace`-attach the client directly.
kDirectPtrace,
//! \brief The client should `fork` a PtraceBroker for the handler.
kForkBroker,
};
//! \brief Chooses an appropriate `ptrace` strategy.
//!
//! \param[in] sock A socket conncted to a ExceptionHandlerClient.
//! \param[in] client_credentials The credentials for the connected client.
//! \return the chosen #Strategy.
virtual Strategy ChooseStrategy(int sock,
const ucred& client_credentials) = 0;
protected:
PtraceStrategyDecider() = default;
};
//! \brief Runs the main exception-handling server in Crashpads handler
//! process.
class ExceptionHandlerServer {
public:
class Delegate {
public:
//! \brief Called on receipt of a crash dump request from a client.
//!
//! \param[in] client_process_id The process ID of the crashing client.
//! \param[in] exception_information_address The address in the client's
//! address space of an ExceptionInformation struct.
//! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleException(pid_t client_process_id,
VMAddress exception_information_address) = 0;
//! \brief Called on the receipt of a crash dump request from a client for a
//! crash that should be mediated by a PtraceBroker.
//!
//! \param[in] client_process_id The process ID of the crashing client.
//! \param[in] exception_information_address The address in the client's
//! address space of an ExceptionInformation struct.
//! \param[in] broker_sock A socket connected to the PtraceBroker.
//! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleExceptionWithBroker(
pid_t client_process_id,
VMAddress exception_information_address,
int broker_sock) = 0;
protected:
~Delegate() {}
};
ExceptionHandlerServer();
~ExceptionHandlerServer();
//! \brief Sets the handler's PtraceStrategyDecider.
//!
//! If this method is not called, a default PtraceStrategyDecider will be
//! used.
void SetPtraceStrategyDecider(std::unique_ptr<PtraceStrategyDecider> decider);
//! \brief Initializes this object.
//!
//! This method must be successfully called before Run().
//!
//! \param[in] sock A socket on which to receive client requests.
//! \return `true` on success. `false` on failure with a message logged.
bool InitializeWithClient(ScopedFileHandle sock);
//! \brief Runs the exception-handling server.
//!
//! This method must only be called once on an ExceptionHandlerServer object.
//! This method returns when there are no more client connections or Stop()
//! has been called.
//!
//! \param[in] delegate An object to send exceptions to.
void Run(Delegate* delegate);
//! \brief Stops a running exception-handling server.
//!
//! Stop() may be called at any time, and may be called from a signal handler.
//! If Stop() is called before Run() it will cause Run() to return as soon as
//! it is called. It is harmless to call Stop() after Run() has already
//! returned, or to call Stop() after it has already been called.
void Stop();
private:
struct Event;
void HandleEvent(Event* event, uint32_t event_type);
bool InstallClientSocket(ScopedFileHandle socket);
bool UninstallClientSocket(Event* event);
bool ReceiveClientMessage(Event* event);
bool HandleCrashDumpRequest(const msghdr& msg,
const ClientInformation& client_info,
int client_sock);
std::unordered_map<int, std::unique_ptr<Event>> clients_;
std::unique_ptr<Event> shutdown_event_;
std::unique_ptr<PtraceStrategyDecider> strategy_decider_;
Delegate* delegate_;
ScopedFileHandle pollfd_;
bool keep_running_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServer);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_LINUX_EXCEPTION_HANDLER_SERVER_H_
@@ -0,0 +1,93 @@
// Copyright 2015 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_HANDLER_MAC_CRASH_REPORT_EXCEPTION_HANDLER_H_
#define CRASHPAD_HANDLER_MAC_CRASH_REPORT_EXCEPTION_HANDLER_H_
#include <mach/mach.h>
#include <map>
#include <string>
#include "base/macros.h"
#include "client/crash_report_database.h"
#include "handler/crash_report_upload_thread.h"
#include "handler/user_stream_data_source.h"
#include "util/mach/exc_server_variants.h"
namespace crashpad {
//! \brief An exception handler that writes crash reports for exception messages
//! to a CrashReportDatabase.
class CrashReportExceptionHandler : public UniversalMachExcServer::Interface {
public:
//! \brief Creates a new object that will store crash reports in \a database.
//!
//! \param[in] database The database to store crash reports in. Weak.
//! \param[in] upload_thread The upload thread to notify when a new crash
//! report is written into \a database.
//! \param[in] process_annotations A map of annotations to insert as
//! process-level annotations into each crash report that is written. Do
//! not confuse this with module-level annotations, which are under the
//! control of the crashing process, and are used to implement Chromes
//! “crash keys.” Process-level annotations are those that are beyond the
//! control of the crashing process, which must reliably be set even if
//! the process crashes before its able to establish its own annotations.
//! To interoperate with Breakpad servers, the recommended practice is to
//! specify values for the `"prod"` and `"ver"` keys as process
//! annotations.
//! \param[in] user_stream_data_sources Data sources to be used to extend
//! crash reports. For each crash report that is written, the data sources
//! are called in turn. These data sources may contribute additional
//! minidump streams. `nullptr` if not required.
CrashReportExceptionHandler(
CrashReportDatabase* database,
CrashReportUploadThread* upload_thread,
const std::map<std::string, std::string>* process_annotations,
const UserStreamDataSources* user_stream_data_sources);
~CrashReportExceptionHandler();
// UniversalMachExcServer::Interface:
//! \brief Processes an exception message by writing a crash report to this
//! objects CrashReportDatabase.
kern_return_t CatchMachException(
exception_behavior_t behavior,
exception_handler_t exception_port,
thread_t thread,
task_t task,
exception_type_t exception,
const mach_exception_data_type_t* code,
mach_msg_type_number_t code_count,
thread_state_flavor_t* flavor,
ConstThreadState old_state,
mach_msg_type_number_t old_state_count,
thread_state_t new_state,
mach_msg_type_number_t* new_state_count,
const mach_msg_trailer_t* trailer,
bool* destroy_complex_request) override;
private:
CrashReportDatabase* database_; // weak
CrashReportUploadThread* upload_thread_; // weak
const std::map<std::string, std::string>* process_annotations_; // weak
const UserStreamDataSources* user_stream_data_sources_; // weak
DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_MAC_CRASH_REPORT_EXCEPTION_HANDLER_H_
@@ -0,0 +1,82 @@
// Copyright 2014 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_HANDLER_MAC_EXCEPTION_HANDLER_SERVER_H_
#define CRASHPAD_HANDLER_MAC_EXCEPTION_HANDLER_SERVER_H_
#include <mach/mach.h>
#include "base/mac/scoped_mach_port.h"
#include "base/macros.h"
#include "util/mach/exc_server_variants.h"
namespace crashpad {
//! \brief Runs the main exception-handling server in Crashpads handler
//! process.
class ExceptionHandlerServer {
public:
//! \brief Constructs an ExceptionHandlerServer object.
//!
//! \param[in] receive_port The port that exception messages and no-senders
//! notifications will be received on.
//! \param[in] launchd If `true`, the exception handler is being run from
//! launchd. \a receive_port is not monitored for no-senders
//! notifications, and instead, Stop() must be called to provide a “quit”
//! signal.
ExceptionHandlerServer(base::mac::ScopedMachReceiveRight receive_port,
bool launchd);
~ExceptionHandlerServer();
//! \brief Runs the exception-handling server.
//!
//! \param[in] exception_interface An object to send exception messages to.
//!
//! This method monitors the receive port for exception messages and, if
//! not being run by launchd, no-senders notifications. It continues running
//! until it has no more clients, indicated by the receipt of a no-senders
//! notification, or until Stop() is called. When not being run by launchd, it
//! is important to assure that a send right exists in a client (or has been
//! queued by `mach_msg()` to be sent to a client) prior to calling this
//! method, or it will detect that it is sender-less and return immediately.
//!
//! All exception messages will be passed to \a exception_interface.
//!
//! This method must only be called once on an ExceptionHandlerServer object.
//!
//! If an unexpected condition that prevents this method from functioning is
//! encountered, it will log a message and terminate execution. Receipt of an
//! invalid message on the receive port will cause a message to be logged, but
//! this method will continue running normally.
void Run(UniversalMachExcServer::Interface* exception_interface);
//! \brief Stops a running exception-handling server.
//!
//! Stop() may be called at any time, and may be called from a signal handler.
//! If Stop() is called before Run() it will cause Run() to return as soon as
//! it is called. It is harmless to call Stop() after Run() has already
//! returned, or to call Stop() after it has already been called.
void Stop();
private:
base::mac::ScopedMachReceiveRight receive_port_;
base::mac::ScopedMachReceiveRight notify_port_;
bool launchd_;
DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServer);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_MAC_EXCEPTION_HANDLER_SERVER_H_
@@ -0,0 +1,38 @@
// Copyright 2017 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_HANDLER_MAC_FILE_LIMIT_ANNOTATION_H_
#define CRASHPAD_HANDLER_MAC_FILE_LIMIT_ANNOTATION_H_
namespace crashpad {
//! \brief Records a `"file-limits"` simple annotation for the process.
//!
//! This annotation will be used to confirm the theory that certain crashes are
//! caused by systems at or near their file descriptor table size limits.
//!
//! The format of the annotation is four comma-separated values: the system-wide
//! `kern.num_files` and `kern.maxfiles` values from `sysctl()`, and the
//! process-specific current and maximum file descriptor limits from
//! `getrlimit(RLIMIT_NOFILE, …)`.
//!
//! See https://crashpad.chromium.org/bug/180.
//!
//! TODO(mark): Remove this annotation after sufficient data has been collected
//! for analysis.
void RecordFileLimitAnnotation();
} // namespace crashpad
#endif // CRASHPAD_HANDLER_MAC_FILE_LIMIT_ANNOTATION_H_
@@ -0,0 +1,61 @@
// Copyright 2017 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 HANDLER_MINIDUMP_TO_UPLOAD_PARAMETERS_H_
#define HANDLER_MINIDUMP_TO_UPLOAD_PARAMETERS_H_
#include <map>
#include <string>
#include "snapshot/process_snapshot.h"
namespace crashpad {
//! \brief Given a ProcessSnapshot, returns a map of key-value pairs to use as
//! HTTP form parameters for upload to a Breakpad crash report colleciton
//! server.
//!
//! The map is built by combining the process simple annotations map with
//! each modules simple annotations map and annotation objects.
//!
//! In the case of duplicate simple map keys or annotation names, the map will
//! retain the first value found for any key, and will log a warning about
//! discarded values. The precedence rules for annotation names are: the two
//! reserved keys discussed below, process simple annotations, module simple
//! annotations, and module annotation objects.
//!
//! For annotation objects, only ones of that are Annotation::Type::kString are
//! included.
//!
//! Each modules annotations vector is also examined and built into a single
//! string value, with distinct elements separated by newlines, and stored at
//! the key named “list_annotations”, which supersedes any other key found by
//! that name.
//!
//! The client ID stored in the minidump is converted to a string and stored at
//! the key named “guid”, which supersedes any other key found by that name.
//!
//! In the event of an error reading the minidump file, a message will be
//! logged.
//!
//! \param[in] process_snapshot The process snapshot from which annotations
//! will be extracted.
//!
//! \returns A string map of the annotations.
std::map<std::string, std::string> BreakpadHTTPFormParametersFromMinidump(
const ProcessSnapshot* process_snapshot);
} // namespace crashpad
#endif // HANDLER_MINIDUMP_TO_UPLOAD_PARAMETERS_H_
@@ -0,0 +1,76 @@
// Copyright 2016 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_HANDLER_PRUNE_CRASH_REPORTS_THREAD_H_
#define CRASHPAD_HANDLER_PRUNE_CRASH_REPORTS_THREAD_H_
#include <memory>
#include "base/macros.h"
#include "util/thread/worker_thread.h"
namespace crashpad {
class CrashReportDatabase;
class PruneCondition;
//! \brief A thread that periodically prunes crash reports from the database
//! using the specified 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
//! performing the initial prune operation.
class PruneCrashReportThread : public WorkerThread::Delegate {
public:
//! \brief Constructs a new object.
//!
//! \param[in] database The database to prune crash reports from.
//! \param[in] condition The condition used to evaluate crash reports for
//! pruning.
PruneCrashReportThread(CrashReportDatabase* database,
std::unique_ptr<PruneCondition> condition);
~PruneCrashReportThread();
//! \brief Starts a dedicated pruning thread.
//!
//! The thread waits before running the initial prune, so as to not interfere
//! with any startup-related IO performed by the client.
//!
//! This method may only be be called on a newly-constructed object or after
//! a call to Stop().
void Start();
//! \brief Stops the pruning thread.
//!
//! This method must only be called after Start(). If Start() has been called,
//! this method must be called before destroying an object of this class.
//!
//! 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().
void Stop();
private:
// WorkerThread::Delegate:
void DoWork(const WorkerThread* thread) override;
WorkerThread thread_;
std::unique_ptr<PruneCondition> condition_;
CrashReportDatabase* database_; // weak
DISALLOW_COPY_AND_ASSIGN(PruneCrashReportThread);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_PRUNE_CRASH_REPORTS_THREAD_H_
@@ -0,0 +1,68 @@
// Copyright 2017 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_HANDLER_USER_STREAM_DATA_SOURCE_H_
#define CRASHPAD_HANDLER_USER_STREAM_DATA_SOURCE_H_
#include <memory>
#include <vector>
namespace crashpad {
class MinidumpFileWriter;
class MinidumpUserExtensionStreamDataSource;
class ProcessSnapshot;
//! \brief Extensibility interface for embedders who wish to add custom streams
//! to minidumps.
class UserStreamDataSource {
public:
virtual ~UserStreamDataSource() {}
//! \brief Produce the contents for an extension stream for a crashed program.
//!
//! Called after \a process_snapshot has been initialized for the crashed
//! process to (optionally) produce the contents of a user extension stream
//! that will be attached to the minidump.
//!
//! \param[in] process_snapshot An initialized snapshot for the crashed
//! process.
//!
//! \return A new data source for the stream to add to the minidump or
//! `nullptr` on failure or to opt out of adding a stream.
virtual std::unique_ptr<MinidumpUserExtensionStreamDataSource>
ProduceStreamData(ProcessSnapshot* process_snapshot) = 0;
};
using UserStreamDataSources =
std::vector<std::unique_ptr<UserStreamDataSource>>;
//! \brief Adds user extension streams to a minidump.
//!
//! Dispatches to each source in \a user_stream_data_sources and adds returned
//! extension streams to \a minidump_file_writer.
//!
//! \param[in] user_stream_data_sources A pointer to the data sources, or
//! `nullptr`.
//! \param[in] process_snapshot An initialized snapshot to the crashing process.
//! \param[in] minidump_file_writer Any extension streams will be added to this
//! minidump.
void AddUserExtensionStreams(
const UserStreamDataSources* user_stream_data_sources,
ProcessSnapshot* process_snapshot,
MinidumpFileWriter* minidump_file_writer);
} // namespace crashpad
#endif // CRASHPAD_HANDLER_USER_STREAM_DATA_SOURCE_H_
@@ -0,0 +1,84 @@
// Copyright 2015 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_HANDLER_WIN_CRASH_REPORT_EXCEPTION_HANDLER_H_
#define CRASHPAD_HANDLER_WIN_CRASH_REPORT_EXCEPTION_HANDLER_H_
#include <windows.h>
#include <map>
#include <string>
#include "base/macros.h"
#include "handler/user_stream_data_source.h"
#include "util/win/exception_handler_server.h"
namespace crashpad {
class CrashReportDatabase;
class CrashReportUploadThread;
//! \brief An exception handler that writes crash reports for exception messages
//! to a CrashReportDatabase.
class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
public:
//! \brief Creates a new object that will store crash reports in \a database.
//!
//! \param[in] database The database to store crash reports in. Weak.
//! \param[in] upload_thread The upload thread to notify when a new crash
//! report is written into \a database.
//! \param[in] process_annotations A map of annotations to insert as
//! process-level annotations into each crash report that is written. Do
//! not confuse this with module-level annotations, which are under the
//! control of the crashing process, and are used to implement Chrome's
//! "crash keys." Process-level annotations are those that are beyond the
//! control of the crashing process, which must reliably be set even if
//! the process crashes before it's able to establish its own annotations.
//! To interoperate with Breakpad servers, the recommended practice is to
//! specify values for the `"prod"` and `"ver"` keys as process
//! annotations.
//! \param[in] user_stream_data_sources Data sources to be used to extend
//! crash reports. For each crash report that is written, the data sources
//! are called in turn. These data sources may contribute additional
//! minidump streams. `nullptr` if not required.
CrashReportExceptionHandler(
CrashReportDatabase* database,
CrashReportUploadThread* upload_thread,
const std::map<std::string, std::string>* process_annotations,
const UserStreamDataSources* user_stream_data_sources);
~CrashReportExceptionHandler();
// ExceptionHandlerServer::Delegate:
//! \brief Processes an exception message by writing a crash report to this
//! object's CrashReportDatabase.
void ExceptionHandlerServerStarted() override;
unsigned int ExceptionHandlerServerException(
HANDLE process,
WinVMAddress exception_information_address,
WinVMAddress debug_critical_section_address) override;
private:
CrashReportDatabase* database_; // weak
CrashReportUploadThread* upload_thread_; // weak
const std::map<std::string, std::string>* process_annotations_; // weak
const UserStreamDataSources* user_stream_data_sources_; // weak
DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
};
} // namespace crashpad
#endif // CRASHPAD_HANDLER_WIN_CRASH_REPORT_EXCEPTION_HANDLER_H_