Commit 43ec5ab6 authored by Scott Graham's avatar Scott Graham Committed by Commit Bot

Update Crashpad to fa96a04fc64dd1d1cb34a1c38c32dc21c9f26c5e

21edfd3c3a20 [fuchsia] Move non-tests out of tests in the crashpad_tests
             package
ce122b644ce2 [util/net] add error message to scheme check
83e37a9ac145 [fuchsia] add commands for testing on Fuchsia
78d081ee4e91 linux: save and restore old signal actions
1b4fdd0fd079 fuchsia: Re-enable HTTPS transport, but disable tests
9554a89ab60a fuchsia: Use zx_task_resume_from_exception() instead of
             zx_task_resume()
9b2a119dc6d8 elf: don't warn on trailing unread bytes in the elf dynamic
             array
0fb654142873 [fuchsia][linux] optionally return local report ID on
             exception handling
1c09361c2cde fuchsia: Let util build in Mac-host builds
237c5ebdf3a9 fuchsia: Fix include_dirs for host Mac build
7682f0f6ebbd Add ThreadSnapshotMinidump
46b329b3690d list headers' includes as public dependencies
b6103e157c5e Add SystemSnapshotMinidump
8d17d5b4cf33 Decode Thread Context in minidump
3b68e1278952 Update bot link for new LUCI console
c7f1543dd388 Don't auto-generate gyp build files any more
289be79a33f2 Roll mini_chromium to 3577ffd
196897eb0804 Remove win buildbot bots from cq config
2951fbde523f Remove cq_name from cq.cfg, no longer required/allowed
fa96a04fc64d Add .vpython spec to add pywintypes to luci runs

TBR: mark@chromium.org
Change-Id: I8ecc5aa3925467c2e79a2c1eee7e1bf232aa7331
Reviewed-on: https://chromium-review.googlesource.com/c/1292150Reviewed-by: default avatarScott Graham <scottmg@chromium.org>
Commit-Queue: Scott Graham <scottmg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601300}
parent 647b30d7
......@@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad
URL: https://crashpad.chromium.org/
Version: unknown
Revision: 91781418bc4eb79e357687094811bab6430b10b2
Revision: fa96a04fc64dd1d1cb34a1c38c32dc21c9f26c5e
License: Apache 2.0
License File: crashpad/LICENSE
Security Critical: yes
......
# 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.
# This is a vpython "spec" file.
#
# It describes patterns for python wheel dependencies of the python scripts.
#
# Read more about `vpython` and how to modify this file here:
# https://chromium.googlesource.com/infra/infra/+/master/doc/users/vpython.md
# This is needed for snapshot/win/end_to_end_test.py.
wheel: <
name: "infra/python/wheels/pypiwin32/${vpython_platform}"
version: "version:219"
match_tag: <
platform: "win32"
>
match_tag: <
platform: "win_amd64"
>
>
......@@ -53,13 +53,21 @@ if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
{
name = "crashpad_tests"
},
]
# Note that the infix of "crashpad_tests" below in
# binary/resource entries should be removed once
# crashpad_tests is moved out of the system image;
# until then, it is used to disambiguate the crashpad
# binaries and data from others within /system/(bin|data).
binaries = [
{
name = "crashpad_test_test_multiprocess_exec_test_child"
dest = "crashpad_test_data/crashpad_test_test_multiprocess_exec_test_child"
dest = "crashpad_tests/crashpad_test_test_multiprocess_exec_test_child"
},
{
name = "http_transport_test_server"
dest = "crashpad_test_data/http_transport_test_server"
dest = "crashpad_tests/http_transport_test_server"
},
]
......@@ -81,15 +89,15 @@ if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
resources = [
{
path = "util/net/testdata/ascii_http_body.txt"
dest = "crashpad_test_data/util/net/testdata/ascii_http_body.txt"
dest = "crashpad_tests/util/net/testdata/ascii_http_body.txt"
},
{
path = "util/net/testdata/binary_http_body.dat"
dest = "crashpad_test_data/util/net/testdata/binary_http_body.dat"
dest = "crashpad_tests/util/net/testdata/binary_http_body.dat"
},
{
path = "test/test_paths_test_data_root.txt"
dest = "crashpad_test_data/test/test_paths_test_data_root.txt"
dest = "crashpad_tests/test/test_paths_test_data_root.txt"
},
]
......@@ -97,16 +105,14 @@ if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
deps += [
"util:generate_test_server_key",
]
tests += [
# These aren't actually tests, but that seems to be the only way to
# convince package() to get them from the output directory.
resources += [
{
name = "crashpad_util_test_cert.pem"
dest = "crashpad_test_data/crashpad_util_test_cert.pem"
path = "$root_out_dir/crashpad_util_test_cert.pem"
dest = "crashpad_tests/crashpad_util_test_cert.pem"
},
{
name = "crashpad_util_test_key.pem"
dest = "crashpad_test_data/crashpad_util_test_key.pem"
path = "$root_out_dir/crashpad_util_test_key.pem"
dest = "crashpad_tests/crashpad_util_test_key.pem"
},
]
}
......
......@@ -30,7 +30,7 @@ deps = {
'5e2b3ddde7cda5eb6bc09a5546a76b00e49d888f',
'crashpad/third_party/mini_chromium/mini_chromium':
Var('chromium_git') + '/chromium/mini_chromium@' +
'8d641e30a8b12088649606b912c2bc4947419ccc',
'3577ffda752e26e506bb4971a8fb8bc67189ad1e',
'crashpad/third_party/libfuzzer/src':
Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
'fda403cf93ecb8792cb1d061564d89a6553ca020',
......@@ -212,11 +212,6 @@ hooks = [
'crashpad/build/install_linux_sysroot.py',
],
},
{
'name': 'gyp',
'pattern': '\.gypi?$',
'action': ['python', 'crashpad/build/gyp_crashpad.py'],
},
]
recursedeps = [
......
......@@ -36,7 +36,7 @@ https://chromium.googlesource.com/crashpad/crashpad.
* Bugs can be reported at the [Crashpad issue
tracker](https://crashpad.chromium.org/bug/).
* The [Crashpad Buildbots](https://build.chromium.org/p/client.crashpad)
* The [Crashpad bots](https://ci.chromium.org/p/crashpad/g/main/console)
perform automated builds and tests.
* [crashpad-dev](https://groups.google.com/a/chromium.org/group/crashpad-dev)
is the Crashpad developers’ mailing list.
......@@ -77,8 +77,7 @@ static_library("client") {
public_configs = [ "..:crashpad_config" ]
deps = [
"../compat",
public_deps = [
"../third_party/mini_chromium:base",
"../util",
]
......@@ -89,7 +88,7 @@ static_library("client") {
}
if (crashpad_is_fuchsia) {
deps += [ "../third_party/fuchsia:zx" ]
deps = [ "../third_party/fuchsia:zx" ]
if (crashpad_is_in_fuchsia) {
deps += [ "//zircon/public/lib/fdio" ]
}
......
......@@ -100,7 +100,7 @@ class LaunchAtCrashHandler {
&exception_information_));
StringVectorToCStringVector(argv_strings_, &argv_);
return Signals::InstallCrashHandlers(HandleCrash, 0, nullptr);
return Signals::InstallCrashHandlers(HandleCrash, 0, &old_actions_);
}
bool HandleCrashNonFatal(int signo, siginfo_t* siginfo, void* context) {
......@@ -144,7 +144,8 @@ class LaunchAtCrashHandler {
if (enabled_ && HandleCrashNonFatal(signo, siginfo, context)) {
return;
}
Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
Signals::RestoreHandlerAndReraiseSignalOnReturn(
siginfo, old_actions_.ActionForSignal(signo));
}
void SetFirstChanceHandler(CrashpadClient::FirstChanceHandler handler) {
......@@ -163,6 +164,7 @@ class LaunchAtCrashHandler {
state->HandleCrashFatal(signo, siginfo, context);
}
Signals::OldActions old_actions_ = {};
std::vector<std::string> argv_strings_;
std::vector<const char*> argv_;
std::vector<std::string> envp_strings_;
......
......@@ -193,6 +193,13 @@ $ cd ~/crashpad/crashpad
$ python build/run_tests.py out/Debug
```
To run a subset of the tests, use the --gtest\_filter flag, e.g., to run all the
tests for MinidumpStringWriter:
```sh
$ python build/run_tests.py out/Debug --gtest_filter MinidumpStringWriter*
```
### Windows
On Windows, `end_to_end_test.py` requires the CDB debugger, installed with
......@@ -220,6 +227,25 @@ variable. `run_tests.py` will upload test executables and data to a temporary
location on the detected or selected device, run them, and clean up after itself
when done.
### Fuchsia
To test on Fuchsia, you need a connected device running Fuchsia and then run:
```sh
$ gn gen out/fuchsia --args='target_os="fuchsia" target_cpu="x64" is_debug=true'
$ ninja -C out/fuchsia
$ python build/run_tests.py out/fuchsia
```
If you have multiple devices running, you will need to specify which device you
want using their hostname, for instance:
```sh
$ export ZIRCON_NODENAME=scare-brook-skip-dried; \
python build/run_tests.py out/fuchsia; \
unset ZIRCON_NODENAME
```
## Contributing
Crashpad’s contribution process is very similar to [Chromium’s contribution
......
......@@ -67,14 +67,16 @@ static_library("handler") {
public_configs = [ "..:crashpad_config" ]
deps = [
public_deps = [
"../client",
"../compat",
"../third_party/mini_chromium:base",
"../util",
]
deps = [
"../minidump",
"../snapshot",
"../third_party/mini_chromium:base",
"../tools:tool_support",
"../util",
]
if (crashpad_is_win) {
......
......@@ -30,20 +30,24 @@ namespace {
class ScopedThreadResumeAfterException {
public:
ScopedThreadResumeAfterException(const zx::thread& thread)
: thread_(thread) {}
ScopedThreadResumeAfterException(const zx::thread& thread,
const zx::unowned_port& exception_port)
: thread_(thread), exception_port_(exception_port) {}
~ScopedThreadResumeAfterException() {
DCHECK(thread_->is_valid());
// Resuming with ZX_RESUME_TRY_NEXT chains to the next handler. In normal
// operation, there won't be another beyond this one, which will result in
// the kernel terminating the process.
zx_status_t status =
thread_->resume(ZX_RESUME_EXCEPTION | ZX_RESUME_TRY_NEXT);
ZX_LOG_IF(ERROR, status != ZX_OK, status) << "zx_task_resume";
thread_->resume_from_exception(*exception_port_, ZX_RESUME_TRY_NEXT);
ZX_LOG_IF(ERROR, status != ZX_OK, status)
<< "zx_task_resume_from_exception";
}
private:
zx::unowned_thread thread_;
const zx::unowned_port& exception_port_;
DISALLOW_COPY_AND_ASSIGN(ScopedThreadResumeAfterException);
};
......@@ -63,15 +67,18 @@ CrashReportExceptionHandler::CrashReportExceptionHandler(
CrashReportExceptionHandler::~CrashReportExceptionHandler() {}
bool CrashReportExceptionHandler::HandleException(uint64_t process_id,
uint64_t thread_id) {
bool CrashReportExceptionHandler::HandleException(
uint64_t process_id,
uint64_t thread_id,
const zx::unowned_port& exception_port,
UUID* local_report_id) {
// TODO(scottmg): This function needs to be instrumented with metrics calls,
// https://crashpad.chromium.org/bug/230.
zx::process process(GetProcessFromKoid(process_id));
if (!process.is_valid()) {
// There's no way to zx_task_resume() the thread if the process retrieval
// fails. Assume that the process has been already killed, and bail.
// There's no way to resume the thread if the process retrieval fails.
// Assume that the process has been already killed, and bail.
return false;
}
......@@ -80,16 +87,19 @@ bool CrashReportExceptionHandler::HandleException(uint64_t process_id,
return false;
}
return HandleExceptionHandles(process, thread);
return HandleExceptionHandles(
process, thread, exception_port, local_report_id);
}
bool CrashReportExceptionHandler::HandleExceptionHandles(
const zx::process& process,
const zx::thread& thread) {
const zx::thread& thread,
const zx::unowned_port& exception_port,
UUID* local_report_id) {
// Now that the thread has been successfully retrieved, it is possible to
// correctly call zx_task_resume() to continue exception processing, even if
// something else during this function fails.
ScopedThreadResumeAfterException resume(thread);
// correctly call zx_task_resume_from_exception() to continue exception
// processing, even if something else during this function fails.
ScopedThreadResumeAfterException resume(thread, exception_port);
ProcessSnapshotFuchsia process_snapshot;
if (!process_snapshot.Initialize(process)) {
......@@ -171,6 +181,9 @@ bool CrashReportExceptionHandler::HandleExceptionHandles(
if (database_status != CrashReportDatabase::kNoError) {
return false;
}
if (local_report_id != nullptr) {
*local_report_id = uuid;
}
if (upload_thread_) {
upload_thread_->ReportPending(uuid);
......
......@@ -15,6 +15,7 @@
#ifndef CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_
#define CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_
#include <lib/zx/port.h>
#include <lib/zx/process.h>
#include <lib/zx/thread.h>
#include <stdint.h>
......@@ -28,6 +29,7 @@
#include "client/crash_report_database.h"
#include "handler/crash_report_upload_thread.h"
#include "handler/user_stream_data_source.h"
#include "util/misc/uuid.h"
namespace crashpad {
......@@ -70,28 +72,41 @@ class CrashReportExceptionHandler {
//! \brief Called when the exception handler server has caught an exception
//! and wants a crash dump to be taken.
//!
//! This function is expected to call `zx_task_resume()` in order to complete
//! handling of the exception.
//! This function is expected to call `zx_task_resume_from_exception()` in
//! order to complete handling of the exception.
//!
//! \param[in] process_id The koid of the process which sustained the
//! exception.
//! \param[in] thread_id The koid of the thread which sustained the exception.
//! \param[in] exception_port The exception port on which the exception was
//! serviced. This can be used to resume the excepting thread.
//! \param[out] local_report_id The unique identifier for the report created
//! in the local report database. Optional.
//! \return `true` on success, or `false` with an error logged.
bool HandleException(uint64_t process_id, uint64_t thread_id);
bool HandleException(uint64_t process_id,
uint64_t thread_id,
const zx::unowned_port& exception_port,
UUID* local_report_id = nullptr);
//! \brief Called when the exception handler server has caught an exception
//! and wants a crash dump to be taken.
//!
//! This function is expected to call `zx_task_resume()` in order to complete
//! handling of the exception.
//! This function is expected to call `zx_task_resume_from_exception()` in
//! order to complete handling of the exception.
//!
//! \param[in] process The handle to the process which sustained the
//! exception.
//! \param[in] thread The handle to the thread of \a process which sustained
//! the exception.
//! \param[in] exception_port The exception port on which the exception was
//! serviced. This can be used to resume the excepting thread.
//! \param[out] local_report_id The unique identifier for the report created
//! in the local report database. Optional.
//! \return `true` on success, or `false` with an error logged.
bool HandleExceptionHandles(const zx::process& process,
const zx::thread& thread);
const zx::thread& thread,
const zx::unowned_port& exception_port,
UUID* local_report_id = nullptr);
private:
CrashReportDatabase* database_; // weak
......
......@@ -47,8 +47,9 @@ void ExceptionHandlerServer::Run(CrashReportExceptionHandler* handler) {
continue;
}
bool result =
handler->HandleException(packet.exception.pid, packet.exception.tid);
bool result = handler->HandleException(packet.exception.pid,
packet.exception.tid,
zx::unowned_port(exception_port_));
if (!result) {
LOG(ERROR) << "HandleException failed";
}
......
......@@ -43,9 +43,9 @@ CrashReportExceptionHandler::CrashReportExceptionHandler(
CrashReportExceptionHandler::~CrashReportExceptionHandler() = default;
bool CrashReportExceptionHandler::HandleException(
pid_t client_process_id,
const ClientInformation& info) {
bool CrashReportExceptionHandler::HandleException(pid_t client_process_id,
const ClientInformation& info,
UUID* local_report_id) {
Metrics::ExceptionEncountered();
DirectPtraceConnection connection;
......@@ -55,13 +55,14 @@ bool CrashReportExceptionHandler::HandleException(
return false;
}
return HandleExceptionWithConnection(&connection, info);
return HandleExceptionWithConnection(&connection, info, local_report_id);
}
bool CrashReportExceptionHandler::HandleExceptionWithBroker(
pid_t client_process_id,
const ClientInformation& info,
int broker_sock) {
int broker_sock,
UUID* local_report_id) {
Metrics::ExceptionEncountered();
PtraceClient client;
......@@ -71,12 +72,13 @@ bool CrashReportExceptionHandler::HandleExceptionWithBroker(
return false;
}
return HandleExceptionWithConnection(&client, info);
return HandleExceptionWithConnection(&client, info, local_report_id);
}
bool CrashReportExceptionHandler::HandleExceptionWithConnection(
PtraceConnection* connection,
const ClientInformation& info) {
const ClientInformation& info,
UUID* local_report_id) {
ProcessSnapshotLinux process_snapshot;
if (!process_snapshot.Initialize(connection)) {
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
......@@ -180,6 +182,9 @@ bool CrashReportExceptionHandler::HandleExceptionWithConnection(
Metrics::CaptureResult::kFinishedWritingCrashReportFailed);
return false;
}
if (local_report_id != nullptr) {
*local_report_id = uuid;
}
if (upload_thread_) {
upload_thread_->ReportPending(uuid);
......
......@@ -26,6 +26,7 @@
#include "util/linux/exception_handler_protocol.h"
#include "util/linux/ptrace_connection.h"
#include "util/misc/address_types.h"
#include "util/misc/uuid.h"
namespace crashpad {
......@@ -64,15 +65,18 @@ class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
// ExceptionHandlerServer::Delegate:
bool HandleException(pid_t client_process_id,
const ClientInformation& info) override;
const ClientInformation& info,
UUID* local_report_id = nullptr) override;
bool HandleExceptionWithBroker(pid_t client_process_id,
const ClientInformation& info,
int broker_sock) override;
int broker_sock,
UUID* local_report_id = nullptr) override;
private:
bool HandleExceptionWithConnection(PtraceConnection* connection,
const ClientInformation& info);
const ClientInformation& info,
UUID* local_report_id = nullptr);
CrashReportDatabase* database_; // weak
CrashReportUploadThread* upload_thread_; // weak
......
......@@ -26,6 +26,7 @@
#include "util/linux/exception_handler_protocol.h"
#include "util/misc/address_types.h"
#include "util/misc/initialization_state_dcheck.h"
#include "util/misc/uuid.h"
namespace crashpad {
......@@ -72,9 +73,12 @@ class ExceptionHandlerServer {
//!
//! \param[in] client_process_id The process ID of the crashing client.
//! \param[in] info Information on the client.
//! \param[out] local_report_id The unique identifier for the report created
//! in the local report database. Optional.
//! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleException(pid_t client_process_id,
const ClientInformation& info) = 0;
const ClientInformation& info,
UUID* local_report_id = nullptr) = 0;
//! \brief Called on the receipt of a crash dump request from a client for a
//! crash that should be mediated by a PtraceBroker.
......@@ -82,10 +86,13 @@ class ExceptionHandlerServer {
//! \param[in] client_process_id The process ID of the crashing client.
//! \param[in] info Information on the client.
//! \param[in] broker_sock A socket connected to the PtraceBroker.
//! \param[out] local_report_id The unique identifier for the report created
//! in the local report database. Optional.
//! \return `true` on success. `false` on failure with a message logged.
virtual bool HandleExceptionWithBroker(pid_t client_process_id,
const ClientInformation& info,
int broker_sock) = 0;
int broker_sock,
UUID* local_report_id = nullptr) = 0;
protected:
~Delegate() {}
......
......@@ -25,6 +25,7 @@
#include "util/linux/exception_handler_client.h"
#include "util/linux/ptrace_client.h"
#include "util/linux/scoped_pr_set_ptracer.h"
#include "util/misc/uuid.h"
#include "util/synchronization/semaphore.h"
#include "util/thread/thread.h"
......@@ -101,7 +102,8 @@ class TestDelegate : public ExceptionHandlerServer::Delegate {
}
bool HandleException(pid_t client_process_id,
const ClientInformation& info) override {
const ClientInformation& info,
UUID* local_report_id = nullptr) override {
DirectPtraceConnection connection;
bool connected = connection.Initialize(client_process_id);
EXPECT_TRUE(connected);
......@@ -114,7 +116,8 @@ class TestDelegate : public ExceptionHandlerServer::Delegate {
bool HandleExceptionWithBroker(pid_t client_process_id,
const ClientInformation& info,
int broker_sock) override {
int broker_sock,
UUID* local_report_id = nullptr) override {
PtraceClient client;
bool connected = client.Initialize(broker_sock, client_process_id);
EXPECT_TRUE(connected);
......
......@@ -17,6 +17,7 @@
#include "base/logging.h"
#include "client/annotation.h"
#include "snapshot/module_snapshot.h"
#include "snapshot/process_snapshot.h"
#include "util/stdlib/map_insert.h"
namespace crashpad {
......
......@@ -18,10 +18,10 @@
#include <map>
#include <string>
#include "snapshot/process_snapshot.h"
namespace crashpad {
class ProcessSnapshot;
//! \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.
......
# 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.
def CheckChangeOnUpload(input_api, output_api):
return input_api.canned_checks.CheckChangedLUCIConfigs(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return input_api.canned_checks.CheckChangedLUCIConfigs(input_api, output_api)
......@@ -16,7 +16,6 @@
# documentation of this file format.
version: 1
cq_name: "crashpad"
cq_status_url: "https://chromium-cq-status.appspot.com"
# This is required for gerrit projects.
......@@ -31,15 +30,6 @@ verifiers {
dry_run_access_list: "project-crashpad-tryjob-access"
}
try_job {
buckets {
name: "master.client.crashpad"
builders { name: "crashpad_try_win_dbg" }
builders { name: "crashpad_try_win_rel" }
# https://crbug.com/743139 - disabled until we can move these to swarming,
# at which point we can just remove them.
#builders { name: "crashpad_try_win_x86_dbg" }
#builders { name: "crashpad_try_win_x86_rel" }
}
buckets {
name: "luci.crashpad.try"
builders { name: "crashpad_try_mac_dbg" }
......
......@@ -48,6 +48,10 @@ static_library("snapshot") {
"minidump/module_snapshot_minidump.h",
"minidump/process_snapshot_minidump.cc",
"minidump/process_snapshot_minidump.h",
"minidump/system_snapshot_minidump.cc",
"minidump/system_snapshot_minidump.h",
"minidump/thread_snapshot_minidump.cc",
"minidump/thread_snapshot_minidump.h",
"module_snapshot.h",
"process_snapshot.h",
"snapshot_constants.h",
......
......@@ -42,9 +42,6 @@ bool Read(const ProcessMemoryRange& memory,
switch (entry.d_tag) {
case DT_NULL:
values->swap(local_values);
if (size != 0) {
LOG(WARNING) << size << " trailing bytes not read";
}
return true;
case DT_NEEDED:
// Skip these entries for now.
......
......@@ -29,6 +29,8 @@ ProcessSnapshotMinidump::ProcessSnapshotMinidump()
modules_(),
unloaded_modules_(),
crashpad_info_(),
system_snapshot_(),
arch_(CPUArchitecture::kCPUArchitectureUnknown),
annotations_simple_map_(),
file_reader_(nullptr),
process_id_(static_cast<pid_t>(-1)),
......@@ -86,7 +88,9 @@ bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) {
if (!InitializeCrashpadInfo() ||
!InitializeMiscInfo() ||
!InitializeModules()) {
!InitializeModules() ||
!InitializeSystemSnapshot() ||
!InitializeThreads()) {
return false;
}
......@@ -153,14 +157,16 @@ ProcessSnapshotMinidump::AnnotationsSimpleMap() const {
const SystemSnapshot* ProcessSnapshotMinidump::System() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return nullptr;
return &system_snapshot_;
}
std::vector<const ThreadSnapshot*> ProcessSnapshotMinidump::Threads() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return std::vector<const ThreadSnapshot*>();
std::vector<const ThreadSnapshot*> threads;
for (const auto& thread : threads_) {
threads.push_back(thread.get());
}
return threads;
}
std::vector<const ModuleSnapshot*> ProcessSnapshotMinidump::Modules() const {
......@@ -390,4 +396,64 @@ bool ProcessSnapshotMinidump::InitializeModulesCrashpadInfo(
return true;
}
bool ProcessSnapshotMinidump::InitializeThreads() {
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeThreadList);
if (stream_it == stream_map_.end()) {
return true;
}
if (stream_it->second->DataSize < sizeof(MINIDUMP_THREAD_LIST)) {
LOG(ERROR) << "thread_list size mismatch";
return false;
}
if (!file_reader_->SeekSet(stream_it->second->Rva)) {
return false;
}
uint32_t thread_count;
if (!file_reader_->ReadExactly(&thread_count, sizeof(thread_count))) {
return false;
}
if (sizeof(MINIDUMP_THREAD_LIST) + thread_count * sizeof(MINIDUMP_THREAD) !=
stream_it->second->DataSize) {
LOG(ERROR) << "thread_list size mismatch";
return false;
}
for (uint32_t thread_index = 0; thread_index < thread_count; ++thread_index) {
const RVA thread_rva = stream_it->second->Rva + sizeof(thread_count) +
thread_index * sizeof(MINIDUMP_THREAD);
auto thread = std::make_unique<internal::ThreadSnapshotMinidump>();
if (!thread->Initialize(file_reader_, thread_rva, arch_)) {
return false;
}
threads_.push_back(std::move(thread));
}
return true;
}
bool ProcessSnapshotMinidump::InitializeSystemSnapshot() {
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeSystemInfo);
if (stream_it == stream_map_.end()) {
return true;
}
if (stream_it->second->DataSize < sizeof(MINIDUMP_SYSTEM_INFO)) {
LOG(ERROR) << "system info size mismatch";
return false;
}
if (!system_snapshot_.Initialize(file_reader_, stream_it->second->Rva)) {
return false;
}
arch_ = system_snapshot_.GetCPUArchitecture();
return true;
}
} // namespace crashpad
......@@ -30,6 +30,8 @@
#include "snapshot/exception_snapshot.h"
#include "snapshot/memory_snapshot.h"
#include "snapshot/minidump/module_snapshot_minidump.h"
#include "snapshot/minidump/system_snapshot_minidump.h"
#include "snapshot/minidump/thread_snapshot_minidump.h"
#include "snapshot/module_snapshot.h"
#include "snapshot/process_snapshot.h"
#include "snapshot/system_snapshot.h"
......@@ -85,6 +87,14 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
// Initialize().
bool InitializeModules();
// Initializes data carried in a MINIDUMP_THREAD_LIST stream on behalf of
// Initialize().
bool InitializeThreads();
// Initializes data carried in a MINIDUMP_SYSTEM_INFO stream on behalf of
// Initialize().
bool InitializeSystemSnapshot();
// Initializes data carried in a MinidumpModuleCrashpadInfoList structure on
// behalf of InitializeModules(). This makes use of MinidumpCrashpadInfo as
// well, so it must be called after InitializeCrashpadInfo().
......@@ -100,8 +110,11 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
std::vector<MINIDUMP_DIRECTORY> stream_directory_;
std::map<MinidumpStreamType, const MINIDUMP_LOCATION_DESCRIPTOR*> stream_map_;
std::vector<std::unique_ptr<internal::ModuleSnapshotMinidump>> modules_;
std::vector<std::unique_ptr<internal::ThreadSnapshotMinidump>> threads_;
std::vector<UnloadedModuleSnapshot> unloaded_modules_;
MinidumpCrashpadInfo crashpad_info_;
internal::SystemSnapshotMinidump system_snapshot_;
CPUArchitecture arch_;
std::map<std::string, std::string> annotations_simple_map_;
FileReaderInterface* file_reader_; // weak
pid_t process_id_;
......
// 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.
#include "snapshot/minidump/system_snapshot_minidump.h"
#include "snapshot/minidump/minidump_string_reader.h"
namespace crashpad {
namespace internal {
SystemSnapshotMinidump::SystemSnapshotMinidump()
: SystemSnapshot(),
minidump_system_info_(),
initialized_() {
}
SystemSnapshotMinidump::~SystemSnapshotMinidump() {
}
bool SystemSnapshotMinidump::Initialize(FileReaderInterface* file_reader,
RVA minidump_system_info_rva) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
if (!file_reader->SeekSet(minidump_system_info_rva)) {
return false;
}
if (!file_reader->ReadExactly(&minidump_system_info_,
sizeof(minidump_system_info_))) {
return false;
}
if (!ReadMinidumpUTF8String(file_reader, minidump_system_info_.CSDVersionRva,
&minidump_build_name_)) {
return false;
}
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
CPUArchitecture SystemSnapshotMinidump::GetCPUArchitecture() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
switch (minidump_system_info_.ProcessorArchitecture) {
case kMinidumpCPUArchitectureAMD64:
return kCPUArchitectureX86_64;
case kMinidumpCPUArchitectureX86:
case kMinidumpCPUArchitectureX86Win64:
return kCPUArchitectureX86;
case kMinidumpCPUArchitectureARM:
case kMinidumpCPUArchitectureARM32Win64:
return kCPUArchitectureARM;
case kMinidumpCPUArchitectureARM64:
case kMinidumpCPUArchitectureARM64Breakpad:
return kCPUArchitectureARM64;
case kMinidumpCPUArchitectureMIPS:
return kCPUArchitectureMIPSEL;
// No word on how MIPS64 is signalled
default:
return CPUArchitecture::kCPUArchitectureUnknown;
}
}
uint32_t SystemSnapshotMinidump::CPURevision() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return minidump_system_info_.ProcessorRevision;
}
uint8_t SystemSnapshotMinidump::CPUCount() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return minidump_system_info_.NumberOfProcessors;
}
std::string SystemSnapshotMinidump::CPUVendor() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (GetCPUArchitecture() == kCPUArchitectureX86) {
const char* ptr =
reinterpret_cast<const char*>(minidump_system_info_.Cpu.X86CpuInfo.
VendorId);
return std::string(ptr, ptr + (3 * sizeof(uint32_t)));
} else {
return std::string();
}
}
void SystemSnapshotMinidump::CPUFrequency(uint64_t* current_hz,
uint64_t* max_hz) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
}
uint32_t SystemSnapshotMinidump::CPUX86Signature() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return 0;
}
uint64_t SystemSnapshotMinidump::CPUX86Features() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return 0;
}
uint64_t SystemSnapshotMinidump::CPUX86ExtendedFeatures() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return 0;
}
uint32_t SystemSnapshotMinidump::CPUX86Leaf7Features() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return 0;
}
bool SystemSnapshotMinidump::CPUX86SupportsDAZ() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return false;
}
SystemSnapshot::OperatingSystem
SystemSnapshotMinidump::GetOperatingSystem() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
switch (minidump_system_info_.PlatformId) {
case kMinidumpOSMacOSX:
return OperatingSystem::kOperatingSystemMacOSX;
case kMinidumpOSWin32s:
case kMinidumpOSWin32Windows:
case kMinidumpOSWin32NT:
return OperatingSystem::kOperatingSystemWindows;
case kMinidumpOSLinux:
return OperatingSystem::kOperatingSystemLinux;
case kMinidumpOSAndroid:
return OperatingSystem::kOperatingSystemAndroid;
case kMinidumpOSFuchsia:
return OperatingSystem::kOperatingSystemFuchsia;
default:
return OperatingSystem::kOperatingSystemUnknown;
}
}
bool SystemSnapshotMinidump::OSServer() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return minidump_system_info_.ProductType == kMinidumpOSTypeServer;
}
void SystemSnapshotMinidump::OSVersion(int* major,
int* minor,
int* bugfix,
std::string* build) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
*major = minidump_system_info_.MajorVersion;
*minor = minidump_system_info_.MinorVersion;
*bugfix = minidump_system_info_.BuildNumber;
*build = minidump_build_name_;
}
std::string SystemSnapshotMinidump::OSVersionFull() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return std::string();
}
std::string SystemSnapshotMinidump::MachineDescription() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return std::string();
}
bool SystemSnapshotMinidump::NXEnabled() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
return false;
}
void SystemSnapshotMinidump::TimeZone(DaylightSavingTimeStatus* dst_status,
int* standard_offset_seconds,
int* daylight_offset_seconds,
std::string* standard_name,
std::string* daylight_name) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/10
}
} // namespace internal
} // namespace crashpad
// 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_SNAPSHOT_MINIDUMP_SYSTEM_SNAPSHOT_MINIDUMP_H_
#define CRASHPAD_SNAPSHOT_MINIDUMP_SYSTEM_SNAPSHOT_MINIDUMP_H_
#include <windows.h>
#include "base/macros.h"
#include "minidump/minidump_extensions.h"
#include "snapshot/system_snapshot.h"
#include "util/file/file_reader.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
namespace internal {
//! \brief A SystemSnapshot based on a minidump file.
class SystemSnapshotMinidump : public SystemSnapshot {
public:
SystemSnapshotMinidump();
~SystemSnapshotMinidump() override;
//! \brief Initializes the object.
//!
//! \param[in] file_reader A file reader corresponding to a minidump file.
//! The file reader must support seeking.
//! \param[in] minidump_system_info_rva The file offset in \a file_reader at
//! which the thread’s MINIDUMP_SYSTEM_INFO structure is located.
//!
//! \return `true` if the snapshot could be created, `false` otherwise with
//! an appropriate message logged.
bool Initialize(FileReaderInterface* file_reader,
RVA minidump_system_info_rva);
CPUArchitecture GetCPUArchitecture() const override;
uint32_t CPURevision() const override;
uint8_t CPUCount() const override;
std::string CPUVendor() const override;
void CPUFrequency(uint64_t* current_hz, uint64_t* max_hz) const override;
uint32_t CPUX86Signature() const override;
uint64_t CPUX86Features() const override;
uint64_t CPUX86ExtendedFeatures() const override;
uint32_t CPUX86Leaf7Features() const override;
bool CPUX86SupportsDAZ() const override;
OperatingSystem GetOperatingSystem() const override;
bool OSServer() const override;
void OSVersion(int* major,
int* minor,
int* bugfix,
std::string* build) const override;
std::string OSVersionFull() const override;
std::string MachineDescription() const override;
bool NXEnabled() const override;
void TimeZone(DaylightSavingTimeStatus* dst_status,
int* standard_offset_seconds,
int* daylight_offset_seconds,
std::string* standard_name,
std::string* daylight_name) const override;
private:
MINIDUMP_SYSTEM_INFO minidump_system_info_;
std::string minidump_build_name_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(SystemSnapshotMinidump);
};
} // namespace internal
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_MINIDUMP_SYSTEM_SNAPSHOT_MINIDUMP_H_
// 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_SNAPSHOT_MINIDUMP_THREAD_SNAPSHOT_MINIDUMP_H_
#define CRASHPAD_SNAPSHOT_MINIDUMP_THREAD_SNAPSHOT_MINIDUMP_H_
#include <windows.h>
#include "minidump/minidump_extensions.h"
#include "snapshot/thread_snapshot.h"
#include "snapshot/cpu_context.h"
#include "util/file/file_reader.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
namespace internal {
//! \brief A ThreadSnapshot based on a thread in a minidump file.
class ThreadSnapshotMinidump : public ThreadSnapshot {
public:
ThreadSnapshotMinidump();
~ThreadSnapshotMinidump() override;
//! \brief Initializes the object.
//!
//! \param[in] file_reader A file reader corresponding to a minidump file.
//! The file reader must support seeking.
//! \param[in] minidump_thread_rva The file offset in \a file_reader at which
//! the thread’s MINIDUMP_THREAD structure is located.
//! \param[in] arch The architecture of the system this thread is running on.
//! Used to decode CPU Context.
//!
//! \return `true` if the snapshot could be created, `false` otherwise with
//! an appropriate message logged.
bool Initialize(FileReaderInterface* file_reader, RVA minidump_thread_rva,
CPUArchitecture arch);
const CPUContext* Context() const override;
const MemorySnapshot* Stack() const override;
uint64_t ThreadID() const override;
int SuspendCount() const override;
int Priority() const override;
uint64_t ThreadSpecificDataAddress() const override;
std::vector<const MemorySnapshot*> ExtraMemory() const override;
private:
//! \brief Initializes the CPU Context
//!
//! \param[in] minidump_context the raw bytes of the context data from the
//! minidump file.
//!
//! \return `true` if the context could be decoded without error.
bool InitializeContext(const std::vector<unsigned char>& minidump_context);
MINIDUMP_THREAD minidump_thread_;
CPUContext context_;
std::vector<unsigned char> context_memory_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(ThreadSnapshotMinidump);
};
} // namespace internal
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_MINIDUMP_THREAD_SNAPSHOT_MINIDUMP_H_
......@@ -119,6 +119,10 @@
'minidump/module_snapshot_minidump.h',
'minidump/process_snapshot_minidump.cc',
'minidump/process_snapshot_minidump.h',
'minidump/system_snapshot_minidump.cc',
'minidump/system_snapshot_minidump.h',
'minidump/thread_snapshot_minidump.cc',
'minidump/thread_snapshot_minidump.h',
'module_snapshot.h',
'posix/timezone.cc',
'posix/timezone.h',
......
......@@ -50,7 +50,7 @@ base::FilePath TestDataRootInternal() {
// not appear as expected at /pkg/assets. Override the default so that tests
// can find their data for now.
// https://crashpad.chromium.org/bug/196.
asset_path = base::FilePath("/system/data/crashpad_test_data");
asset_path = base::FilePath("/system/data/crashpad_tests");
#endif
if (!IsTestDataRoot(asset_path)) {
LOG(WARNING) << "Test data root seems invalid, continuing anyway";
......@@ -133,7 +133,7 @@ base::FilePath TestPaths::Executable() {
// not appear as expected at /pkg/bin. Override the default of /pkg/bin/app
// so that tests can find the correct location for now.
// https://crashpad.chromium.org/bug/196.
executable_path = base::FilePath("/system/test/crashpad_test_data/app");
executable_path = base::FilePath("/system/bin/crashpad_tests/app");
#endif
return executable_path;
}
......@@ -208,7 +208,7 @@ base::FilePath TestPaths::BuildArtifact(
// /pkg/bin/app so that tests can find the correct location for now.
// https://crashpad.chromium.org/bug/196.
directory =
base::FilePath(FILE_PATH_LITERAL("/system/test/crashpad_test_data"));
base::FilePath(FILE_PATH_LITERAL("/system/bin/crashpad_tests"));
#else
directory = base::FilePath(FILE_PATH_LITERAL("/pkg/bin"));
#endif
......@@ -238,7 +238,7 @@ base::FilePath TestPaths::BuildArtifact(
// things are actually run from a package.
// https://crashpad.chromium.org/bug/196.
directory =
base::FilePath(FILE_PATH_LITERAL("/system/test/crashpad_test_data"));
base::FilePath(FILE_PATH_LITERAL("/system/data/crashpad_tests"));
#endif
extension = FILE_PATH_LITERAL(".pem");
break;
......
......@@ -20,7 +20,7 @@ if (crashpad_is_in_chromium) {
}
if (crashpad_is_mac) {
if (crashpad_is_in_chromium) {
if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
import("//build/config/sysroot.gni")
} else {
import("//third_party/mini_chromium/mini_chromium/build/sysroot.gni")
......@@ -416,7 +416,11 @@ static_library("util") {
public_configs = [ "..:crashpad_config" ]
# Include generated files starting with "util".
include_dirs = [ "$root_gen_dir/third_party/crashpad/crashpad" ]
if (crashpad_is_in_fuchsia) {
include_dirs = [ "$root_gen_dir/third_party/crashpad" ]
} else {
include_dirs = [ "$root_gen_dir/third_party/crashpad/crashpad" ]
}
public_deps = [
"../compat",
......
......@@ -57,8 +57,7 @@ struct ScopedAddrinfoTraits {
static addrinfo* InvalidValue() { return nullptr; }
static void Free(addrinfo* ai) { freeaddrinfo(ai); }
};
using ScopedAddrinfo =
base::ScopedGeneric<addrinfo*, ScopedAddrinfoTraits>;
using ScopedAddrinfo = base::ScopedGeneric<addrinfo*, ScopedAddrinfoTraits>;
class Stream {
public:
......@@ -81,7 +80,7 @@ class FdStream : public Stream {
return LoggingReadFileExactly(fd_, data, size);
}
bool LoggingReadToEOF(std::string* result) override{
bool LoggingReadToEOF(std::string* result) override {
return crashpad::LoggingReadToEOF(fd_, result);
}
......@@ -545,7 +544,8 @@ bool HTTPTransportSocket::ExecuteSynchronously(std::string* response_body) {
}
#if !defined(CRASHPAD_USE_BORINGSSL)
CHECK(scheme == "http");
CHECK(scheme == "http") << "Got " << scheme << " for scheme in '" << url()
<< "'";
#endif
base::ScopedFD sock(CreateSocket(hostname, port));
......
......@@ -364,7 +364,8 @@ TEST_P(HTTPTransport, Upload33k_LengthUnknown) {
RunUpload33k(GetParam(), false);
}
#if defined(CRASHPAD_USE_BORINGSSL)
// This should be on for Fuchsia, but DX-382. Debug and re-enabled.
#if defined(CRASHPAD_USE_BORINGSSL) && !defined(OS_FUCHSIA)
// The test server requires BoringSSL or OpenSSL, so https in tests can only be
// enabled where that's readily available. Additionally on Linux, the bots fail
// lacking libcrypto.so.1.1, so disabled there for now. On Mac, they could also
......
......@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../build/crashpad_buildconfig.gni")
declare_args() {
# This should at least be on for Fuchsia, but DX-382 happened.
# TODO(mark): Figure out what went wrong and re-enable.
crashpad_use_boringssl_for_http_transport_socket = false
crashpad_use_boringssl_for_http_transport_socket = crashpad_is_fuchsia
}
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