Skip to content

Commit

Permalink
Update Crashpad to c0a0d70a2b7a5d973828e6079386cb2a852e5b1c
Browse files Browse the repository at this point in the history
edc8084c3bdc Roll mini_chromium to d5523a7 [fuchsia] Update to
             zx_cprng_draw_new
fa47143c8c62 [fuchsia] Move to zx_take_startup_handle
85565c545cb1 Doc update for GN build
0a665e3c81a1 Suppress output when generating test server key
2771ebf805ae fuchsia: Package test cert and key when running in Fuchsia
             tree
639cba075c8d Use new Fuchsia kernel API to suspend threads
c0a0d70a2b7a Increase max annotations size

Change-Id: Id16830d847a07880c6b2750d0b5245da985b8996
Reviewed-on: https://chromium-review.googlesource.com/1109210
Reviewed-by: Scott Graham <scottmg@chromium.org>
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569142}
  • Loading branch information
Joshua Peraza authored and Commit Bot committed Jun 21, 2018
1 parent e61250b commit 9b33df2
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 89 deletions.
2 changes: 1 addition & 1 deletion third_party/crashpad/README.chromium
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad
URL: https://crashpad.chromium.org/
Version: unknown
Revision: 7c6d2334a93ce5ae9d376db9f8f577a51682338f
Revision: c0a0d70a2b7a5d973828e6079386cb2a852e5b1c
License: Apache 2.0
License File: crashpad/LICENSE
Security Critical: yes
Expand Down
12 changes: 12 additions & 0 deletions third_party/crashpad/crashpad/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
"snapshot:crashpad_snapshot_test_module_large",
"snapshot:crashpad_snapshot_test_module_small",
"test:crashpad_test_test_multiprocess_exec_test_child",
"util:generate_test_server_key",
"util:http_transport_test_server",
]

Expand All @@ -60,6 +61,17 @@ if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
name = "http_transport_test_server"
dest = "crashpad_test_data/http_transport_test_server"
},

# These aren't actually tests, but that seems to be the only way to
# convince package() to get them from the output directory.
{
name = "crashpad_util_test_cert.pem"
dest = "crashpad_test_data/crashpad_util_test_cert.pem"
},
{
name = "crashpad_util_test_key.pem"
dest = "crashpad_test_data/crashpad_util_test_key.pem"
},
]

loadable_modules = [
Expand Down
2 changes: 1 addition & 1 deletion third_party/crashpad/crashpad/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ deps = {
'5e2b3ddde7cda5eb6bc09a5546a76b00e49d888f',
'crashpad/third_party/mini_chromium/mini_chromium':
Var('chromium_git') + '/chromium/mini_chromium@' +
'd5a36d3c51a7a270afc2c888baaaec2a6e496219',
'd5523a7033c013dd2ae73fa29428f7b70dc0b3a0',
'crashpad/third_party/libfuzzer/src':
Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
'fda403cf93ecb8792cb1d061564d89a6553ca020',
Expand Down
2 changes: 1 addition & 1 deletion third_party/crashpad/crashpad/client/annotation.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class Annotation {
static constexpr size_t kNameMaxLength = 64;

//! \brief The maximum size of an annotation’s value, in bytes.
static constexpr size_t kValueMaxSize = 2048;
static constexpr size_t kValueMaxSize = 5 * 4096;

//! \brief The type used for \a SetSize().
using ValueSizeType = uint32_t;
Expand Down
29 changes: 13 additions & 16 deletions third_party/crashpad/crashpad/doc/developing.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,25 @@ $ gclient sync

## Building

Crashpad uses [GYP](https://gyp.gsrc.io/) to generate
[Ninja](https://ninja-build.org/) build files. The build is described by `.gyp`
files throughout the Crashpad source code tree. The
[`build/gyp_crashpad.py`](https://chromium.googlesource.com/crashpad/crashpad/+/master/build/gyp_crashpad.py)
script runs GYP properly for Crashpad, and is also called when you run `fetch
crashpad`, `gclient sync`, or `gclient runhooks`.

The Ninja build files and build output are in the `out` directory. Both debug-
and release-mode configurations are available. The examples below show the debug
configuration. To build and test the release configuration, substitute `Release`
for `Debug`. On Windows, four configurations are available: `Debug` and
`Release` produce 32-bit x86 executables, and `Debug_x64` and `Release_x64`
produce x86_64 executables.
### Windows, Mac, Linux, Fuchsia

On Windows, Mac, Linux, and Fuchsia Crashpad uses
[GN](https://gn.googlesource.com/gn) to generate
[Ninja](https://ninja-build.org/) build files. For example,

```
$ cd ~/crashpad/crashpad
$ ninja -C out/Debug
$ gn gen out/Default
$ ninja -C out/Default
```

Ninja is part of the
You can then use `gn args out/Default` or edit `out/Default/args.gn` to
configure the build, for example things like `is_debug=true` or
`target_cpu="x86"`.

GN and Ninja are part of the
[depot_tools](https://www.chromium.org/developers/how-tos/depottools). There’s
no need to install it separately.
no need to install them separately.

### Android

Expand Down
8 changes: 8 additions & 0 deletions third_party/crashpad/crashpad/test/test_paths.cc
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ base::FilePath TestPaths::BuildArtifact(
break;

case FileType::kCertificate:
#if defined(CRASHPAD_IS_IN_FUCHSIA)
// When running in the Fuchsia tree, the .pem files are packaged as assets
// into the test data folder. This will need to be rationalized when
// things are actually run from a package.
// https://crashpad.chromium.org/bug/196.
directory =
base::FilePath(FILE_PATH_LITERAL("/system/test/crashpad_test_data"));
#endif
extension = FILE_PATH_LITERAL(".pem");
break;
}
Expand Down
84 changes: 23 additions & 61 deletions third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,80 +40,42 @@ zx_obj_type_t GetHandleType(zx_handle_t handle) {
return basic.type;
}

enum class SuspensionResult {
FailedSuspendCall,
FailedToSuspendInTimelyFashion,
Succeeded,
};

SuspensionResult SuspendThread(zx_handle_t thread) {
zx_status_t status = zx_task_suspend(thread);
ZX_LOG_IF(ERROR, status != ZX_OK, status) << "zx_task_suspend";
if (status != ZX_OK)
return SuspensionResult::FailedSuspendCall;
// zx_task_suspend() suspends the thread "sometime soon", but it's hard to
// use when it's not guaranteed to be suspended after return. Try reading the
// thread state until the registers are retrievable, which means that the
// thread is actually suspended. Don't wait forever in case the suspend
// failed for whatever reason, but try a few times.
for (int i = 0; i < 5; ++i) {
zx_thread_state_general_regs_t regs;
status = zx_thread_read_state(
thread, ZX_THREAD_STATE_GENERAL_REGS, &regs, sizeof(regs));
if (status == ZX_OK) {
return SuspensionResult::Succeeded;
}
zx_nanosleep(zx_deadline_after(ZX_MSEC(10)));
// Returns the suspend token of the suspended thread. This function attempts
// to wait a short time for the thread to actually suspend before returning
// but this is not guaranteed.
base::ScopedZxHandle SuspendThread(zx_handle_t thread) {
zx_handle_t token = ZX_HANDLE_INVALID;
zx_status_t status = zx_task_suspend_token(thread, &token);
if (status != ZX_OK) {
ZX_LOG(ERROR, status) << "zx_task_suspend";
base::ScopedZxHandle();
}
LOG(ERROR) << "thread failed to suspend";
return SuspensionResult::FailedToSuspendInTimelyFashion;
}

bool ResumeThread(zx_handle_t thread) {
zx_status_t status = zx_task_resume(thread, 0);
ZX_LOG_IF(ERROR, status != ZX_OK, status) << "zx_task_resume";
return status == ZX_OK;
zx_signals_t observed = 0u;
if (zx_object_wait_one(thread, ZX_THREAD_SUSPENDED,
zx_deadline_after(ZX_MSEC(50)), &observed) != ZX_OK) {
LOG(ERROR) << "thread failed to suspend";
}
return base::ScopedZxHandle(token);
}

} // namespace

ScopedTaskSuspend::ScopedTaskSuspend(zx_handle_t task) : task_(task) {
DCHECK_NE(task_, zx_process_self());
DCHECK_NE(task_, zx_thread_self());
ScopedTaskSuspend::ScopedTaskSuspend(zx_handle_t task) {
DCHECK_NE(task, zx_process_self());
DCHECK_NE(task, zx_thread_self());

zx_obj_type_t type = GetHandleType(task_);
zx_obj_type_t type = GetHandleType(task);
if (type == ZX_OBJ_TYPE_THREAD) {
// Note that task_ is only marked invalid if the zx_task_suspend() call
// completely fails, otherwise the suspension might just not have taken
// effect yet, so avoid leaving it suspended forever by still resuming on
// destruction.
if (SuspendThread(task_) == SuspensionResult::FailedSuspendCall) {
task_ = ZX_HANDLE_INVALID;
}
suspend_tokens_.push_back(SuspendThread(task));
} else if (type == ZX_OBJ_TYPE_PROCESS) {
for (const auto& thread : GetChildHandles(task_, ZX_INFO_PROCESS_THREADS)) {
SuspendThread(thread.get());
}
for (const auto& thread : GetChildHandles(task, ZX_INFO_PROCESS_THREADS))
suspend_tokens_.push_back(SuspendThread(thread.get()));
} else {
LOG(ERROR) << "unexpected handle type";
task_ = ZX_HANDLE_INVALID;
}
}

ScopedTaskSuspend::~ScopedTaskSuspend() {
if (task_ != ZX_HANDLE_INVALID) {
zx_obj_type_t type = GetHandleType(task_);
if (type == ZX_OBJ_TYPE_THREAD) {
ResumeThread(task_);
} else if (type == ZX_OBJ_TYPE_PROCESS) {
for (const auto& thread :
GetChildHandles(task_, ZX_INFO_PROCESS_THREADS)) {
ResumeThread(thread.get());
}
} else {
LOG(ERROR) << "unexpected handle type";
}
}
}
ScopedTaskSuspend::~ScopedTaskSuspend() = default;

} // namespace crashpad
18 changes: 10 additions & 8 deletions third_party/crashpad/crashpad/util/fuchsia/scoped_task_suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,21 @@

#include <zircon/types.h>

#include <vector>

#include "base/fuchsia/scoped_zx_handle.h"
#include "base/macros.h"

namespace crashpad {

//! \brief Manages the suspension of another task.
//!
//! Currently, suspends and resumes are not counted on Fuchsia, so while this
//! class attempts to manage suspension of a task, if another caller or process
//! is simultaneously suspending or resuming this task, the results may not be
//! as expected.
//! The underlying API only supports suspending threads (despite its name) not
//! entire tasks. As a result, it's possible some threads may not be correctly
//! suspended/resumed as their creation might race enumeration.
//!
//! Additionally, the underlying API only supports suspending threads (despite
//! its name) not entire tasks. As a result, it's possible some threads may not
//! be correctly suspended/resumed as their creation might race enumeration.
//! Additionally, suspending a thread is asynchronous and may take an
//! arbitrary amount of time.
//!
//! Because of these limitations, this class is limited to being a best-effort,
//! and correct suspension/resumption cannot be relied upon.
Expand All @@ -43,7 +44,8 @@ class ScopedTaskSuspend {
~ScopedTaskSuspend();

private:
zx_handle_t task_; // weak
// Could be one (for a thread) or many (for every process in a thread).
std::vector<base::ScopedZxHandle> suspend_tokens_;

DISALLOW_COPY_AND_ASSIGN(ScopedTaskSuspend);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import subprocess

# GN requires a Python script for actions, so this just wraps the openssl
Expand All @@ -23,4 +24,5 @@
cert = 'crashpad_util_test_cert.pem'
subprocess.check_call(
['openssl', 'req', '-x509', '-nodes', '-subj', '/CN=localhost',
'-days', '365', '-newkey', 'rsa:2048', '-keyout', key, '-out', cert])
'-days', '365', '-newkey', 'rsa:2048', '-keyout', key, '-out', cert],
stderr=open(os.devnull, 'w'))

0 comments on commit 9b33df2

Please sign in to comment.