From 8d34fd10ccd98989e4ebc6408fec353345d09b56 Mon Sep 17 00:00:00 2001 From: Mischan Toosarani-Hausberger Date: Mon, 24 Jun 2024 10:54:50 +0200 Subject: [PATCH] chore: update 2024-06-11 (#105) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use googletest flag macros to access googletest flags. The implementation details of flags can change; fixing this proactively makes it easier to roll googletest in chromium. Bug: chromium:1409870 Change-Id: Ib27a922a5b3147386a36f98b42e60950e2215190 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5081703 Commit-Queue: Daniel Cheng Reviewed-by: Robert Sesek * Fix improper use of bit_cast bit_cast should never be used on pointers, as it doesn't avoid UB and can lose qualifiers. Fortunately, the only use of bit_cast on a pointer was to cast nullptr into a function pointer, and because nullptr will implicitly behave as any kind of pointer, that cast isn't needed. Bug: none Change-Id: I3ad79b36b7fb5ab53d4b4b6dfc82dea883ec8b53 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5106728 Reviewed-by: Mark Mentovai Commit-Queue: Avi Drissman * [mac] mach_absolute_time() -> clock_gettime_nsec_np(CLOCK_UPTIME_RAW) https://developer.apple.com/documentation/kernel/1462446-mach_absolute_time > Prefer to use the equivalent clock_gettime_nsec_np(CLOCK_UPTIME_RAW) in nanoseconds. The two are equivalent: https://github.com/apple-oss-distributions/Libc/blob/c5a3293354e22262702a3add5b2dfc9bb0b93b85/gen/clock_gettime.c#L118 Change-Id: I1c7a08d821d1840b74fc5eaa0e9ceca2ade5bbfc Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5085307 Commit-Queue: Ben Hamilton Reviewed-by: Justin Cohen Reviewed-by: Mark Mentovai * Qualify bit_cast with base:: The real Chromium base/bit_cast.h is in the base namespace. mini_chromium's version was just changed to be in the base namespace as well. Roll to the latest mini_chromium and scope all calls to bit_cast. Bug: chromium:1506769 Change-Id: I7b25ee512f67694ef6ed3d0250e4f6a6db151eb3 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5116880 Reviewed-by: Mark Mentovai Commit-Queue: Avi Drissman * [ios] Add arm64e support to in_process_intermediate_dump_handler Change-Id: Ifc373d313db71872cc0fd7706da2bdc07cf4ba1b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5126940 Reviewed-by: Justin Cohen Commit-Queue: Ben Hamilton * [build] Re-enable action tracing Avoid unconditionally running mig in incremental builds, and causing un-necessary re-build of downstream targets. Bug: b/42147841 Bug: b/42084680 Change-Id: I961189870aec8f0b1a1ced22105730218664e109 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5171755 Reviewed-by: Mark Mentovai Commit-Queue: David Fang * Roll crashpad/third_party/mini_chromium/mini_chromium/ ac3e73239..cc2ae8eb0 (1 commit) https://chromium.googlesource.com/chromium/mini_chromium/+log/ac3e73239534..cc2ae8eb01d0 $ git log ac3e73239..cc2ae8eb0 --date=short --no-merges --format='%ad %ae %s' 2024-01-10 pbos Add Flush() method to LogMessage Created with: roll-dep crashpad/third_party/mini_chromium/mini_chromium Bug: chromium:1409729 Change-Id: I59b4c9fc9701f3a504b89f396de9da49b333712f Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5185844 Commit-Queue: Peter Boström Reviewed-by: Mark Mentovai * Roll crashpad/third_party/mini_chromium/mini_chromium/ cc2ae8eb0..1e64ecb51 (1 commit) https://chromium.googlesource.com/chromium/mini_chromium/+log/cc2ae8eb01d0..1e64ecb51edf $ git log cc2ae8eb0..1e64ecb51 --date=short --no-merges --format='%ad %ae %s' 2024-01-10 pbos Make ~LogMessage virtual Created with: roll-dep crashpad/third_party/mini_chromium/mini_chromium Bug: chromium:1409729 Change-Id: Ib0011b85c35c781ea35e0d399cccb81b54916ca4 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5186000 Commit-Queue: Peter Boström Reviewed-by: Mark Mentovai * Roll crashpad/third_party/mini_chromium/mini_chromium/ 1e64ecb51..c7fccaa8e (1 commit) https://chromium.googlesource.com/chromium/mini_chromium/+log/1e64ecb51edf..c7fccaa8ec14 $ git log 1e64ecb51..c7fccaa8e --date=short --no-merges --format='%ad %ae %s' 2024-01-10 pbos Implement base::ImmediateCrash() Created with: roll-dep crashpad/third_party/mini_chromium/mini_chromium Bug: chromium:1409729 Change-Id: Iaa4f4d81027cb0ddafe85bab8d186949eb7f852e Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5186004 Reviewed-by: Mark Mentovai Commit-Queue: Peter Boström * Roll crashpad/third_party/mini_chromium/mini_chromium/ c7fccaa8e..203a01130 (1 commit) https://chromium.googlesource.com/chromium/mini_chromium/+log/c7fccaa8ec14..203a01130fac $ git log c7fccaa8e..203a01130 --date=short --no-merges --format='%ad %ae %s' 2024-01-10 pbos Fix base::ImmediateCrash() IWYU Created with: roll-dep crashpad/third_party/mini_chromium/mini_chromium Bug: chromium:1409729 Change-Id: Ic9fee112a48b66c92b8446270280d5f2a3d0ef59 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5187485 Reviewed-by: Mark Mentovai Commit-Queue: Peter Boström * Add [[noreturn]] version of NtstatusLogMessage This will be used by base/logging.h in chromium to make sure that LOG(FATAL) variants never return and are properly understood as [[noreturn]] by the compiler. Once that's landed in chromium it'll be up/downstreamed into mini_chromium as well. Bug: chromium:1409729 Change-Id: I75340643fe075475f997bbc45250fa10df63c9fa Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5185996 Reviewed-by: Mark Mentovai Commit-Queue: Peter Boström * ios: Add crashpad_uptime_ns crash key to iOS reports. This CL introduces a new crash key 'crashpad_uptime_ns' that records the number of nanoseconds between when Crashpad was initialized and when a snapshot is generated. Crashpad minidumps record the MDRawMiscInfo process_create_time using a sysctl(KERN_PROC).kp_proc.p_starttime. This time is used to display the 'uptime' of a process. However, iOS 15 and later has a feature that 'prewarms' the app to reduce the amount of time the user waits before the app is usable. This mean crashes that may happen immediately on startup would appear to happen minutes or hours after process creation time. While initial implementations of prewarming would include some parts of main, since iOS16 prewarming is complete before main, and therefore before Crashpad is typically initialized. Bug: crashpad:472 Change-Id: Iff960e37ae40121bd5927d319a2767d1cafce846 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5171091 Reviewed-by: Ben Hamilton Reviewed-by: Mark Mentovai Commit-Queue: Justin Cohen * Remove should-be-dead code after PLOG(FATAL) This will trigger dead-code warnings in chromium once LOG(FATAL) is understood as [[noreturn]], which needs to be fixed in crashpad first. Bug: 1409729 Change-Id: I75cb4d93e648ca9804f1299345e52bb3e2834cd9 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5193351 Reviewed-by: Mark Mentovai Commit-Queue: Peter Boström * doc: Upgrade the crashpad-home App Engine app to the go121 flex runtime Change-Id: I0a30b816e2550e7df6d7777c6d27e6104fc2f9fa Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5206711 Reviewed-by: Robert Sesek Commit-Queue: Mark Mentovai * ios: Allow missing exception thread id from thread list. It's expected that iOS intermediate dumps can be written with missing information, but it's better to try and report as much as possible rather than drop the incomplete minidump. Bug: b/284959148 Change-Id: I04110b576a4ee552814234d559c9ba85db0382f0 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/4582167 Commit-Queue: Justin Cohen Reviewed-by: Mark Mentovai * Avoid assuming string_view iterators are char* This assumption is non-portable and prevents Chromium from using bounded iterators in libc++. Bug: chromium: 1519908 Change-Id: Iafe6639ef3bc896d6fa4fb3ceb7ac0b546363017 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5237292 Reviewed-by: Mark Mentovai Commit-Queue: danakj * [fxbug.dev] Migrate bug numbers This changes fxbug.dev/ URLs from Monorail bug numbers to the new Fuchsia Issue Tracker numbers. The migration to the new issue tracker was announced here: https://groups.google.com/a/fuchsia.dev/g/announce/c/GOYfJozEqmk/m/qsGsaJ7UAAAJ Bug: 298074672 Change-Id: I5f4b7a26a3f41bf539fa79d15e1a108ea35a5b29 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5246697 Commit-Queue: Mark Mentovai Reviewed-by: Mark Mentovai * ios: Read dyld modules in reverse order. The change in macOS 14's dyld to insert new modules in the front of `dyld_all_image_infos` means that if the any images are loaded during an exception while iterating the modules list, the primary executable will be missed. Instead, read the modules in reverse order. Change-Id: I49f6468173f18ef4bd0f326c84e4b48cfc696cd3 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5249275 Commit-Queue: Justin Cohen Reviewed-by: Mark Mentovai * Add Update method to CrashpadInfo This change adds a method to update a CrashpadInfo stream. As part of this change, AddUserDataMinidumpStream() now returns a handle to the added stream. This handle can be passed to UpdateUserDataMinidumpStream() if a new version of the stream needs to be attached to the crash report. This method is needed for e.g., allowing Chrome's System Profile to update, as it contains some data that takes a while to collect. Bug: crashpad:474 Change-Id: I19e935a6904d8843215582e5606b189479ee338b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5260024 Reviewed-by: Mark Mentovai Commit-Queue: Jesse McKenna * Honor ios_is_app_extension chromium build flag If building for chromium, honor the ios_is_app_extension gn variable that is set per toolchain. When it is defined, the code is built for an application extension (i.e. -fapplication-extension is passed to the compiler). Use CRASHPAD_IS_IOS_APP_EXTENSION build guard to not compile code that use unavailable extension when ios_is_app_extension is set. If the variable is not set, then check at runtime whether the API can be used or not (if the crashpad client uses the same toolchain for the main application and its application extensions). This is required to pass -fapplication-extension to the compiler when building application extensions (which allow catching API that is not available to application extensions). Bug: 40120082 Change-Id: I28d545fcfd0f8662430c40ff202b79b0c2b2ff8b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5286216 Reviewed-by: Justin Cohen Commit-Queue: Sylvain Defresne * Fix leaky CrashpadInfo test CrashpadInfo::AddUserDataMinidumpStream() and UpdateUserDataMinidumpStream() allocate memory for the newly added streams. This change makes the CrashpadInfo test free that allocated memory to prevent memory leaks from these tests. This is intended to fix the ASAN failures seen on crrev.com/c/5285881: https://ci.chromium.org/ui/p/chromium/builders/try/linux_chromium_asan_rel_ng/1839072/overview Bug: crashpad:474 Change-Id: I6e030291594d22e316942a58805a177ce448053b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5292137 Reviewed-by: Mark Mentovai Commit-Queue: Jesse McKenna * [Fuchsia] remove use of fuchsia mac sdk Bug: b/325495632 Change-Id: I19df5b44b76efcdb050344e79bcc2dfd18d8e289 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5299466 Reviewed-by: Mark Mentovai Commit-Queue: Mark Mentovai * Properly update iterator Bug: 325296797 Change-Id: I39f76519c46804ad663172abf91ef582bde135e7 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5310754 Commit-Queue: Joshua Peraza Reviewed-by: Justin Cohen * Log argv[0] for failing spawns This adds argv[0] for PLOG(FATAL) calls following a failed posix_spawn or execve call to make logs more useful. Bug: chromium:324982367 Change-Id: I179928ec9f791ce5b365b3444aa3bb667f4ec4b3 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5315332 Reviewed-by: Mark Mentovai Commit-Queue: Peter Boström * Increase kMaxNumberOfAnnotations Chrome on ChromeOS is starting to run into problems where there are more than 200 annotations, primarily because we use a lot of command-line switches (40 or more) and commandline-enabled-features as well, each of which takes up an annotation. It's still rare (100s a day) but will probably become worse over time as more CrashKey uses are added. Increase kMaxNumberOfAnnotations to 400. BUG=296821415 Change-Id: Iba7049014ee3c5ae9c45c4022600eaba50acd403 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5354336 Reviewed-by: Mark Mentovai Commit-Queue: Ian Barkley-Yeung Reviewed-by: Joshua Peraza * ios: Disable annotations tests on older simulators on macOS 14.3 There appears to be a change in dyld in macOS 14.3 that iOS 17 accounts for, but older simulators do not. This causes the main binary to be listed twice when iterating modules, breaking some tests. Bug: crbug.com/328282286 Change-Id: I71909fbc13bee6de23b10ffd92a791067f8ea909 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5353754 Reviewed-by: Mark Mentovai Commit-Queue: Justin Cohen * Make AnnotationList's iterator compliant to input iterator This CL make the iterators implemented by AnnotationList compliant to the requirements imposed by the C++ standard on input iterators. Change-Id: I263c94a97f5bcd7edd5ef4d8b65fa28b11876974 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5093147 Reviewed-by: Mark Mentovai Commit-Queue: Mark Mentovai * Fix invalid check for valid key of Pointer Authentication Arm's Pointer Authentication uses two keys for signing pointers, A-key and B-key. Although by default Clang uses the A-key if PAC support is enabled at compile time, this behaviour might be overridden via compiler command line. This CL fixes the check for the B-key being enabled. The key that shall be used for Pointer Authentication is denoted by bits 0 (A-key) or 1 (B-key) of __ARM_FEATURE_PAC_DEFAULT. Hence, the previous way of checking by using bits 0 and 2 does not correctly identify the B-key. Bug: 40608466 Change-Id: Ib2f226baa12a7145fa0b6e486e49d36e6b0a3cd7 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5341090 Reviewed-by: Mark Mentovai Commit-Queue: Mark Mentovai * ios: Update exception test for Chromium release builds. After https://crrev.com/c/5375084, Chromium __libcpp_verbose_abort is handled differently for official non-dcheck builds. This change fixes the test expectation for release non-official builds. Bug: 330168249 Change-Id: Iceb6d327f9e93fd366cc07abe27eefd1adf06472 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5378380 Reviewed-by: Mark Mentovai Commit-Queue: Justin Cohen * ios: Capture signal exception context memory regions correctly. Previously, Crashpad would only capture iOS thread context memory regions by iterating the task_threads->thread_get_state's. For Mach exception this worked as intended. However, for signal exceptions this missed the registers from the actual signal context. This change correctly captures these regions and stores them in the exception snapshot. Change-Id: I494e753a25c2687e61b5183ed0135f520ca8bf52 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5380505 Reviewed-by: Mark Mentovai Commit-Queue: Justin Cohen * Move crashpad to using Mac-13|Mac-14 (like chromium) and latest win sdk This should give crashpad a newer xcode and msvc that support C++20. These changes need to land separately from the C++20 usage, as they do not get applied until after landing, so can't affect the CQ from inside the CQ. Bug: 40284755 Change-Id: I3ae72befa008bfb37bac882de0986c5bcf9de079 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5425460 Commit-Queue: danakj Reviewed-by: Mark Mentovai * Roll mini_chromium to pick up the latest version of base::span. Also enables C++20 as span now depends on it. Roll buildtools to grab a newer libc++ that supports C++20. Explicitly capture `this` in lambdas in cpp-httplib as the implicit capture through `=` is deprecated and causes an error in C++20. Update the MacOS version to "Mac-13|Mac-14" which is the current value of `os.MAC_DEFAULT` in Chromium infra in order to have C++20 support in the std library on iOS. Moves iOS tests to run on iPhone 13 and includes a mini_chromium roll to fix Xcode 14.3 egtests. Bug: 40284755 Change-Id: Ic078f07d12473f2aaed5e84df0f0a7fb7b8c35c3 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5443384 Commit-Queue: Justin Cohen Reviewed-by: danakj * [ios] Fix TSAN issue and Mach port leak in CrashpadClient There were two issues with the iOS implementation of CrashpadClient which I reported in https://crbug.com/crashpad/481: 1) TSAN found a data race in ResetForTesting() when it modified the ScopedMachReceiveRight while the Mach exception port thread was reading it 2) The Mach port connected to the exception server was never deallocated This CL fixes both issues. Change-Id: I5bd4f79ae6d0eccca954d663be7a36f8ceb0a0e8 Bug: https://crbug.com/crashpad/481 Bug: b:332305593 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5410301 Reviewed-by: Mark Mentovai Commit-Queue: Justin Cohen * Use byte conversions over the byte swap functions base/sys_byteorder.h is going away. Instead, use the byte conversions in base::numerics to convert from a byte array in big endian to an integer. This avoids putting big endian data into integer types at all. mini_chromium was rolled and crashpad updated to work with newer mac/windows toolchains in order to support C++20 in f9cee5c147db30dc8fa1a048aabd165965b5cb60. Bug: 40284755 Change-Id: If690847b7aa54b0216e73ec297eae3d0bca2fa57 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5402184 Commit-Queue: danakj Reviewed-by: Mark Mentovai * Replace std::unique_ptr with HeapArray in process_info.cc and process_info_test.cc Bug: crashpad: 326459035,326458915,326459055 Change-Id: Ifb91297b6097aa81a9d5c883b2c284e9fdd512a8 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5463361 Reviewed-by: Mark Mentovai Commit-Queue: Arthur Wang * Fix incorrect DCHECK in CET contexts This DCHECK() was not correct. When dumping a process with CET enabled the cetumsr and cetussp registers are not available in the context obtained for the exception record. All contexts to be written to a minidump must have the same context format so those registers will be present for captured threads. It is therefore ok for the context to expect extended xsave registers but for them to be zero in some cases. Bug: 337665168 Change-Id: If7e5f40fe8eda6799b034991cb87e89437cb4821 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5507588 Reviewed-by: Mark Mentovai Commit-Queue: Alex Gough * Replace std::is_pod usage Replacing std::is_pod usage as per the following compilation error: ``` ../../util/misc/uuid.cc:44:20: error: 'is_pod' is deprecated: use 'is_standard_layout && is_trivial' instead [-Werror,-Wdeprecated-declarations] static_assert(std::is_pod::value, "UUID must be POD"); ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/type_traits:818:5: note: 'is_pod' has been explicitly marked deprecated here _GLIBCXX20_DEPRECATED_SUGGEST("is_standard_layout && is_trivial") ``` Bug: None Change-Id: I1d61ee12261877f7f1f84f0ea15d262d22959766 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5472885 Commit-Queue: Andrew Williams Reviewed-by: Mark Mentovai * Make NTSTATUS_LOG less likely to change ::GetLastError() value This better ensures that using code like `NTSTATUS_LOG(ERROR, status) << ::GetLastError()` would print the intended value. This isn't done today by the code AFAICT, but making this change primarily for consistency with the change to Chromium logging in https://chromium-review.googlesource.com/c/chromium/src/+/5443628 Bug: chromium:333445539 Change-Id: I49f16b9ed78d98a0b2f178f58465002aad757ae5 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5474027 Reviewed-by: Mark Mentovai Commit-Queue: Andrew Williams * Use the span version of RandBytes Some unique_ptr are also changed to HeapArray in order to facilitate the change. Bug: chromuim: 40284755 Change-Id: I30b9d55ff81f23c63ad4958786740f67ee612024 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5512569 Reviewed-by: Mark Mentovai Commit-Queue: danakj * Include build_config.h before checking COMPILER_MSVC This is caught by chromium presubmit when rolling crashpad. R=mark@chromium.org Change-Id: Ida9ff07e7b2bd27808c092afbc5a1345fa29a4f3 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5515300 Reviewed-by: Mark Mentovai Commit-Queue: danakj * Roll mini_chromium to remove the pointer-based overload of RandBytes() R=mark@chromium.org Bug: 40284755 Change-Id: I2f491cc3f630767e607ea1df7d21791be522b4de Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5518909 Reviewed-by: Mark Mentovai Commit-Queue: danakj * ios: Use correct address when storing register memory. The memory region data saved in the intermediate dump is an address offset by 128 bytes. However, the MemorySnapshot generated was using the original address and not the offset address. The same data is being captured in the minidump. Change-Id: Ia34912c035319e79cf446a130e662084f4ab51ea Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5529059 Commit-Queue: Justin Cohen Reviewed-by: Joshua Peraza Reviewed-by: Rohit Rao * Replace std::unique_ptr with HeapArray Bug: crashpad: 326459659,326458942,326459376,326459390,326459417,326458979,326459333,326459016,326458338,326458738,326459156,326459512,326458694 Change-Id: I04724530cbef50a8d3c18f306d16c0bbf3b0815b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5512394 Reviewed-by: Mark Mentovai Commit-Queue: Arthur Wang * Pull latest Fuchsia toolchain Change-Id: Ia328c6defc59fc06fcf69a2875a0eed335c8dd78 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5532142 Commit-Queue: Arthur Wang Reviewed-by: Mark Mentovai * Add build/build_config.h in capture_memory.cc Change-Id: I486e7bcdb205de5b24846a8e782a6163c2ce8829 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5531439 Commit-Queue: Arthur Wang Reviewed-by: Mark Mentovai * Replace std::unique_ptr with base::HeapArray in process_memory.cc Bug: crashpad:326459219 Change-Id: Ic5e252285ed1fb1769eef67ddaea00a830d0ee6a Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5535006 Reviewed-by: Mark Mentovai Commit-Queue: Arthur Wang * Fix format issue Change-Id: I9756fa76f94cfcb9edc9f8df8ecfa5ff33918c22 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5542412 Reviewed-by: Mark Mentovai Commit-Queue: Arthur Wang * Add guard pages to test stacks Bug: b:340659332 Change-Id: I4c2c82a1868d7a4f4a062a4e7a64258deedfb794 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5542248 Reviewed-by: Mark Mentovai Commit-Queue: Joshua Peraza * [ScopedSpinGuard] Use std::atomic::compare_exchange_strong() for spinlock Previously, ScopedSpinGuard used std::atomic::compare_exchange_weak() in a loop to implement a spinlock. After looping for the specified number of nanoseconds, it would give up and return an error. A few bugs have come in on ARM platforms (https://crbug.com/340980960, http://b/296082201) which indicate that this can fail even in single-threaded cases where nothing else has the spinlock. From https://cbloomrants.blogspot.com/2011/07/07-14-11-compareexchangestrong-vs.html : > compare_exchange_weak exists for LL-SC (load linked/store > conditional) type architectures (Power, ARM, basically everything > except x86), because on them compare_exchange_strong must be > implemented as a loop, while compare_exchange_weak can be > non-looping. and: https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange#Notes > compare_exchange_weak is allowed to fail spuriously, that is, acts > as if *this != expected even if they are equal. When a > compare-and-exchange is in a loop, compare_exchange_weak will yield > better performance on some platforms. > > When compare_exchange_weak would require a loop and > compare_exchange_strong would not, compare_exchange_strong is > preferable [...] My conclusion is that this logic needs to use `compare_exchange_strong` to avoid spurious failures on ARM in the common case when there's no other thread holding the spinlock. Change-Id: I2a08031db6b219d7d14a5cd02b3634985f81ab06 Bug: b:340980960 Change-Id: I2a08031db6b219d7d14a5cd02b3634985f81ab06 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5545257 Reviewed-by: Mark Mentovai Commit-Queue: Ben Hamilton * Roll crashpad/third_party/mini_chromium/mini_chromium/ a6607b1fd..5856e1ea6 (2 commits) https://chromium.googlesource.com/chromium/mini_chromium/+log/a6607b1fd76b..5856e1ea610f $ git log a6607b1fd..5856e1ea6 --date=short --no-merges --format='%ad %ae %s' 2024-05-16 pbos Add NOTREACHED_IN_MIGRATION() 2024-05-11 pwjworks Remove workaround for missing std::atomic_thread_fence Created with: roll-dep crashpad/third_party/mini_chromium/mini_chromium Bug: chromium:40580068 Change-Id: I6d1385739042fa5b826bfa91c50b914eebaaf8fd Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5544927 Commit-Queue: Peter Boström Reviewed-by: Mark Mentovai * Use NOTREACHED_IN_MIGRATION() This was generated by replacing " NOTREACHED()" with " NOTREACHED_IN_MIGRATION()" and running git cl format. This prepares for making NOTREACHED() [[noreturn]] alongside NotReachedIsFatal migration of existing inventory. Bug: chromium:40580068 Change-Id: Idb68e2fc8adba180350b0595fd494cf0f206bded Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5548246 Reviewed-by: Mark Mentovai Commit-Queue: Peter Boström * infra: Move crashpad ci/try builds from Ubuntu-18.04 to Ubuntu-22.04 These are the last remaining jobs on the last remaining bionic pools. Moving these over should let the bionic flex pool finally be decommed. All of chrome/chromium has been on Ubuntu-22.04 for months now. So hopefully this is transparent for crashpad. Bug: chromium:40255350 Change-Id: I82828c0ae0c6efc8868b33779d7ebf5fb9b16116 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5550958 Commit-Queue: Ben Pastene Reviewed-by: Mark Mentovai * ios: Remove duplicate implementations of ReadStringSysctlByName Bug: crashpad: 480 Change-Id: Ie37c557d2170f6d96968ec4922ec52bfc6ad8136 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5580854 Reviewed-by: Mark Mentovai * [Fuchsia] Run fuchsia-gn-sdk from chromium The latest build rules have the ffuchsia-api-level. Need https://crrev.com/c/5586319. Bug: fuchsia:42085580, fuchsia:327691011 Change-Id: I21383e02f9fff3db9405c0dbe42051122a325003 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5585353 Commit-Queue: Zijie He Reviewed-by: Mark Mentovai * DEPS: fix version of fuchsia/sdk/core to avoid build error This is a temporary workaround to avoid error like https://ci.chromium.org/ui/p/crashpad/builders/try/crashpad_fuchsia_arm64_dbg/1299/overview Bug: 41489832 Change-Id: Ia5404b5d7a2f01f53211fba7b8d602b9236ccbd3 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5599904 Commit-Queue: Takuto Ikuta Reviewed-by: Mark Mentovai * remove references to goma goma is not maintained anymore. Bug: 41489832 Change-Id: Ic82524205c7593ddba041c253e7d6283f9c89f33 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5599864 Reviewed-by: Mark Mentovai Commit-Queue: Takuto Ikuta * Revert "DEPS: fix version of fuchsia/sdk/core to avoid build error" This reverts commit a63adda6278e9caa75361051cb23fd914e533151. Reason for revert: This is not necessary after https://crrev.com/c/5585353. Original change's description: > DEPS: fix version of fuchsia/sdk/core to avoid build error > > This is a temporary workaround to avoid error like > https://ci.chromium.org/ui/p/crashpad/builders/try/crashpad_fuchsia_arm64_dbg/1299/overview > > Bug: 41489832 > Change-Id: Ia5404b5d7a2f01f53211fba7b8d602b9236ccbd3 > Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5599904 > Commit-Queue: Takuto Ikuta > Reviewed-by: Mark Mentovai Bug: 41489832 Change-Id: I2c6d3c3008047a6f79fb3bfddd8240a758ee645a Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5599914 Reviewed-by: Mark Mentovai Bot-Commit: Rubber Stamper Commit-Queue: Takuto Ikuta * Update minichromium * Update crashpad C++ standard to 20 via minichromium * Update minichromium build-script --------- Co-authored-by: Daniel Cheng Co-authored-by: Avi Drissman Co-authored-by: Ben Hamilton Co-authored-by: David Fang Co-authored-by: Peter Boström Co-authored-by: Justin Cohen Co-authored-by: Mark Mentovai Co-authored-by: danakj Co-authored-by: Mitchell Kember Co-authored-by: Jesse McKenna Co-authored-by: Sylvain Defresne Co-authored-by: Hzj_jie Co-authored-by: Joshua Peraza Co-authored-by: Ian Barkley-Yeung Co-authored-by: André Kempe Co-authored-by: Arthur Wang Co-authored-by: Alex Gough Co-authored-by: Andrew Williams Co-authored-by: Ben Pastene Co-authored-by: Takuto Ikuta --- .gitignore | 7 +- BUILD.gn | 3 +- CMakeLists.txt | 2 +- DEPS | 40 +- build/BUILD.gn | 13 + build/BUILDCONFIG.gn | 8 + build/config/fuchsia/gn_configs.gni | 62 ++++ build/crashpad_buildconfig.gni | 9 +- build/fuchsia/gen_build_defs.py | 350 ------------------ build/fuchsia_envs.py | 45 +++ build/ios/setup_ios_gn.config | 7 - build/run_tests.py | 6 +- client/BUILD.gn | 1 + client/annotation_list.cc | 83 ++--- client/annotation_list.h | 55 +-- client/annotation_list_test.cc | 66 ++++ client/crashpad_client_ios.cc | 46 ++- client/crashpad_client_linux_test.cc | 2 +- client/crashpad_info.cc | 70 +++- client/crashpad_info.h | 40 +- client/crashpad_info_test.cc | 142 +++++++ client/ios_handler/exception_processor.mm | 3 +- client/ios_handler/in_process_handler.cc | 5 +- .../in_process_intermediate_dump_handler.cc | 34 +- .../in_process_intermediate_dump_handler.h | 6 +- ..._process_intermediate_dump_handler_test.cc | 28 +- client/prune_crash_reports.cc | 2 +- client/settings.cc | 2 +- doc/appengine/README | 35 +- doc/appengine/go.mod | 10 + doc/appengine/go.sum | 37 ++ doc/appengine/src/crashpad-home/app.yaml | 3 +- doc/appengine/src/crashpad-home/main.go | 6 +- handler/crash_report_upload_thread.cc | 2 +- .../cros_crash_report_exception_handler.cc | 9 +- .../cros_crash_report_exception_handler.h | 2 + handler/win/hanging_program.cc | 6 +- infra/config/generated/commit-queue.cfg | 2 +- infra/config/generated/cr-buildbucket.cfg | 58 +-- infra/config/generated/luci-logdog.cfg | 2 +- infra/config/generated/luci-milo.cfg | 2 +- infra/config/generated/luci-scheduler.cfg | 2 +- infra/config/generated/project.cfg | 4 +- infra/config/generated/realms.cfg | 2 +- infra/config/main.star | 10 +- minidump/minidump_context_writer.cc | 35 +- minidump/minidump_context_writer_test.cc | 2 +- minidump/minidump_exception_writer.cc | 12 +- minidump/minidump_exception_writer.h | 7 +- minidump/minidump_exception_writer_test.cc | 5 +- minidump/minidump_file_writer.cc | 12 +- minidump/minidump_string_writer_test.cc | 2 +- minidump/minidump_system_info_writer.cc | 4 +- snapshot/BUILD.gn | 12 +- snapshot/capture_memory.cc | 11 +- snapshot/cpu_context.cc | 12 +- .../fuchsia/exception_snapshot_fuchsia.cc | 2 +- snapshot/fuchsia/process_reader_fuchsia.cc | 16 +- snapshot/fuchsia/process_snapshot_fuchsia.cc | 3 +- snapshot/fuchsia/system_snapshot_fuchsia.cc | 16 +- snapshot/fuchsia/thread_snapshot_fuchsia.cc | 2 +- ...xception_snapshot_ios_intermediate_dump.cc | 34 +- ...exception_snapshot_ios_intermediate_dump.h | 3 + .../process_snapshot_ios_intermediate_dump.cc | 3 + ...ess_snapshot_ios_intermediate_dump_test.cc | 41 ++ .../system_snapshot_ios_intermediate_dump.cc | 7 + .../system_snapshot_ios_intermediate_dump.h | 5 + .../linux/exception_snapshot_linux_test.cc | 7 +- snapshot/linux/process_reader_linux_test.cc | 26 +- snapshot/linux/system_snapshot_linux.cc | 10 +- snapshot/mac/cpu_context_mac.cc | 6 +- snapshot/mac/process_types.cc | 7 +- snapshot/mac/system_snapshot_mac.cc | 10 +- snapshot/memory_snapshot_generic.h | 7 +- snapshot/minidump/module_snapshot_minidump.cc | 4 +- .../minidump/process_snapshot_minidump.cc | 6 +- snapshot/minidump/system_snapshot_minidump.cc | 20 +- .../sanitized/module_snapshot_sanitized.cc | 8 +- .../process_snapshot_sanitized_test.cc | 2 +- snapshot/snapshot_constants.h | 2 +- snapshot/win/pe_image_reader.cc | 12 +- snapshot/win/system_snapshot_win.cc | 10 +- test/ios/crash_type_xctest.mm | 35 +- test/linux/fake_ptrace_connection.cc | 4 +- test/multiprocess_posix_test.cc | 2 +- test/scoped_guarded_page_test.cc | 2 +- test/win/win_child_process.cc | 1 - third_party/cpp-httplib/README.crashpad | 1 + third_party/cpp-httplib/cpp-httplib/httplib.h | 4 +- third_party/mini_chromium/CMakeLists.txt | 8 + third_party/mini_chromium/mini_chromium | 2 +- tools/tool_support.cc | 6 +- util/BUILD.gn | 14 +- util/file/file_io_posix.cc | 2 +- util/file/file_io_win.cc | 4 +- util/file/output_stream_file_writer.cc | 2 +- util/ios/ios_intermediate_dump_format.h | 1 + util/ios/ios_system_data_collector.h | 7 + util/ios/ios_system_data_collector.mm | 43 +-- util/linux/auxiliary_vector_test.cc | 8 +- util/linux/memory_map.cc | 1 - util/mac/mac_util.cc | 2 +- util/mach/child_port_handshake.cc | 2 +- util/mach/exc_client_variants.cc | 2 +- util/mach/exception_ports.cc | 2 +- util/mach/exception_ports_test.cc | 8 +- util/mach/symbolic_constants_mach.cc | 11 +- util/misc/arm64_pac_bti.S | 2 +- util/misc/clock_mac.cc | 24 +- util/misc/reinterpret_bytes_test.cc | 12 +- util/misc/uuid.cc | 24 +- util/net/http_body_gzip_test.cc | 26 +- util/net/http_body_test_util.cc | 9 +- util/numeric/int128_test.cc | 2 +- util/posix/spawn_subprocess.cc | 6 +- util/process/process_memory_mac_test.cc | 8 +- util/process/process_memory_test.cc | 72 ++-- util/stream/base94_output_stream_test.cc | 18 +- util/stream/zlib_output_stream_test.cc | 18 +- util/synchronization/scoped_spin_guard.h | 17 +- util/win/exception_handler_server.cc | 11 +- util/win/module_version.cc | 12 +- util/win/ntstatus_logging.cc | 24 ++ util/win/ntstatus_logging.h | 9 + util/win/process_info.cc | 46 +-- util/win/process_info_test.cc | 24 +- util/win/registration_protocol_win_test.cc | 2 +- 127 files changed, 1321 insertions(+), 931 deletions(-) create mode 100644 build/config/fuchsia/gn_configs.gni delete mode 100755 build/fuchsia/gen_build_defs.py create mode 100755 build/fuchsia_envs.py create mode 100644 client/crashpad_info_test.cc create mode 100644 doc/appengine/go.mod create mode 100644 doc/appengine/go.sum diff --git a/.gitignore b/.gitignore index 7913935994..aa7162e52b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Keep sorted + *.Makefile *.ninja *.pyc @@ -19,18 +21,21 @@ *.xcodeproj *~ .*.sw? -.cache .DS_Store +.cache .gdb_history .gdbinit /Makefile +/build/fuchsia /out /third_party/edo/edo +/third_party/fuchsia-gn-sdk /third_party/fuchsia/.cipd /third_party/fuchsia/clang /third_party/fuchsia/qemu /third_party/fuchsia/sdk /third_party/googletest/googletest +/third_party/gyp/gyp /third_party/libfuzzer /third_party/linux/.cipd /third_party/linux/clang diff --git a/BUILD.gn b/BUILD.gn index 83c4a32c07..8be9eee759 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -39,7 +39,8 @@ if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) { if (crashpad_is_in_fuchsia) { # TODO(fuchsia:46559): Fix the leaks and remove this. deps += [ "//build/config/sanitizers:suppress-lsan.DO-NOT-USE-THIS" ] - # TODO(fxbug.dev/108368): Remove this once the underlying issue is addressed. + # TODO(fxbug.dev/42059784): Remove this once the underlying issue is + # addressed. exclude_toolchain_tags = [ "hwasan" ] } if (crashpad_is_android) { diff --git a/CMakeLists.txt b/CMakeLists.txt index edf23ce251..1075c21d28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,7 @@ else() enable_language(ASM) endif() -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(crashpad_interface INTERFACE) diff --git a/DEPS b/DEPS index 80c1aabf36..b4fe4fff5b 100644 --- a/DEPS +++ b/DEPS @@ -29,7 +29,7 @@ vars = { deps = { 'buildtools': Var('chromium_git') + '/chromium/src/buildtools.git@' + - '8b16338d17cd71b04a6ba28da7322ab6739892c2', + '8919328651a559f8a974641d40fe712062cc6718', 'buildtools/clang_format/script': Var('chromium_git') + '/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@' + @@ -47,7 +47,7 @@ deps = { '9719c1e1e676814c456b55f5f070eabad6709d31', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - '9e21183c1ea369398d6f6ddd302c8db580bd19c4', + 'bd56f6933f2fa021a44766ced638a18f477ef1c1', 'crashpad/third_party/libfuzzer/src': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' + 'fda403cf93ecb8792cb1d061564d89a6553ca020', @@ -86,6 +86,16 @@ deps = { 'dep_type': 'cipd', 'condition': 'host_os == "win"', }, + 'crashpad/build/fuchsia': { + 'packages': [ + { + 'package': 'chromium/fuchsia/test-scripts', + 'version': 'latest', + } + ], + 'condition': 'checkout_fuchsia', + 'dep_type': 'cipd', + }, 'crashpad/third_party/linux/clang/linux-amd64': { 'packages': [ { @@ -100,7 +110,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/third_party/clang/mac-amd64', - 'version': 'MAOjNhwTu5JU3P_0C9dITiyCTtQ1n7lRJnMfB9hhvOkC', + 'version': 'latest', }, ], 'condition': 'checkout_fuchsia and host_os == "mac"', @@ -110,25 +120,20 @@ deps = { 'packages': [ { 'package': 'fuchsia/third_party/clang/linux-amd64', - 'version': 'Tpc85d1ZwSlZ6UKl2d96GRUBGNA5JKholOKe24sRDr0C', + 'version': 'latest', }, ], 'condition': 'checkout_fuchsia and host_os == "linux"', 'dep_type': 'cipd' }, 'crashpad/third_party/fuchsia-gn-sdk': { - 'url': Var('chromium_git') + '/chromium/src/third_party/fuchsia-gn-sdk.git@' + - '0d6902558d92fe3d49ba9a8f638ddea829be595b', - 'condition': 'checkout_fuchsia', - }, - 'crashpad/third_party/fuchsia/sdk/mac-amd64': { 'packages': [ { - 'package': 'fuchsia/sdk/core/mac-amd64', + 'package': 'chromium/fuchsia/gn-sdk', 'version': 'latest' }, ], - 'condition': 'checkout_fuchsia and host_os == "mac"', + 'condition': 'checkout_fuchsia', 'dep_type': 'cipd' }, 'crashpad/third_party/fuchsia/sdk/linux-amd64': { @@ -254,12 +259,25 @@ hooks = [ 'crashpad/build/install_linux_sysroot.py', ], }, + { + # Avoid introducing unnecessary PRESUBMIT.py file from build/fuchsia. + # Never fail and ignore the error if the file does not exist. + 'name': 'Remove the PRESUBMIT.py from build/fuchsia', + 'pattern': '.', + 'condition': 'checkout_fuchsia', + 'action': [ + 'rm', + '-f', + 'crashpad/build/fuchsia/PRESUBMIT.py', + ], + }, { 'name': 'Generate Fuchsia Build Definitions', 'pattern': '.', 'condition': 'checkout_fuchsia', 'action': [ 'python3', + 'crashpad/build/fuchsia_envs.py', 'crashpad/build/fuchsia/gen_build_defs.py' ], }, diff --git a/build/BUILD.gn b/build/BUILD.gn index 7d7e08bbd3..664e498249 100644 --- a/build/BUILD.gn +++ b/build/BUILD.gn @@ -72,4 +72,17 @@ if (crashpad_is_ios) { ] } } + + if (crashpad_is_in_chromium) { + import("//build/config/ios/ios_sdk.gni") + crashpad_is_ios_app_extension = ios_is_app_extension + } else { + crashpad_is_ios_app_extension = false + } + + config("crashpad_is_ios_app_extension") { + if (crashpad_is_ios_app_extension) { + defines = [ "CRASHPAD_IS_IOS_APP_EXTENSION" ] + } + } } diff --git a/build/BUILDCONFIG.gn b/build/BUILDCONFIG.gn index f2ea1cb9d2..ef36cf6336 100644 --- a/build/BUILDCONFIG.gn +++ b/build/BUILDCONFIG.gn @@ -69,6 +69,14 @@ if (crashpad_use_libfuzzer) { _default_configs += [ "//build/config:crashpad_fuzzer_flags" ] } +if (current_os == "fuchsia") { + _default_configs += [ + "//third_party/fuchsia-gn-sdk/src/config:compiler", + "//third_party/fuchsia-gn-sdk/src/config:runtime_library", + ] + import("//third_party/fuchsia-gn-sdk/src/gn_configs.gni") +} + _default_executable_configs = _default_configs + [ "$_mini_chromium_dir/build/config:executable", "$_mini_chromium_dir/build/config:win_console", diff --git a/build/config/fuchsia/gn_configs.gni b/build/config/fuchsia/gn_configs.gni new file mode 100644 index 0000000000..6cbf4ef34f --- /dev/null +++ b/build/config/fuchsia/gn_configs.gni @@ -0,0 +1,62 @@ +# Copyright 2024 The Crashpad Authors +# +# 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 file is copied from +# https://crsrc.org/c/build/config/fuchsia/gn_configs.gni?q=gn_configs.gni +# with some local modifications to match the crashpad setup. + +# Path to the fuchsia SDK. This is intended for use in other templates & +# rules to reference the contents of the fuchsia SDK. +fuchsia_sdk = "//third_party/fuchsia/sdk/linux-amd64" + +# ID uniquely identifying the Fuchsia IDK build. This is exposed as a +# property so it can be used to locate images and packages on GCS and +# as a marker to indicate the "version" of the IDK. +# Defaults to the id found in the manifest.json file of the SDK. +fuchsia_sdk_id = "" + +# The target API level for this repository. Embedders should override this +# value to specify the API level the packages produced from this repository +# should be targeting, e.g. in their top-level //.gn file. A value of -1 +# means that no API level will be passed to the tools that consumes it. +fuchsia_target_api_level = 18 + +# The SDK manifest file. This is useful to include as a dependency +# for some targets in order to cause a rebuild when the version of the +# SDK is changed. +fuchsia_sdk_manifest_file = "${fuchsia_sdk}/meta/manifest.json" + +# fuchsia_tool_dir is used to specify the directory in the SDK to locate +# tools for the host cpu architecture. If the host_cpu is not recognized, +# then tool dir defaults to x64. +fuchsia_tool_dir = "${fuchsia_sdk}/tools/${host_cpu}" + +if (fuchsia_sdk_id == "") { + # Note: If we need to expose more than just the id in the future, + # we should consider exposing the entire json object for the metadata vs. + # adding a bunch of variables. + _meta = read_file(fuchsia_sdk_manifest_file, "json") + fuchsia_sdk_id = _meta.id +} + +declare_args() { + # Specify a readelf_exec path to use. If not specified, the host's system + # executable will be used. Passed to populate_build_id_dir.py and + # prepare_package_inputs.py via the --readelf-exec flag. + # Must be a GN path (not an absolute path) since it is adjusted with + # rebase_path(). + if (!defined(fuchsia_sdk_readelf_exec)) { + fuchsia_sdk_readelf_exec = "" + } +} diff --git a/build/crashpad_buildconfig.gni b/build/crashpad_buildconfig.gni index 4e9091a2c2..96e81b3bd2 100644 --- a/build/crashpad_buildconfig.gni +++ b/build/crashpad_buildconfig.gni @@ -83,6 +83,9 @@ if (crashpad_is_in_chromium) { crashpad_is_posix = mini_chromium_is_posix crashpad_is_clang = mini_chromium_is_clang + + # fuchsia-gn-sdk from chromium uses "is_fuchsia" condition. + is_fuchsia = crashpad_is_fuchsia } crashpad_flock_always_supported = !(crashpad_is_android || crashpad_is_fuchsia) @@ -106,7 +109,7 @@ template("crashpad_executable") { if (crashpad_is_in_fuchsia) { conversion_config = [ "//build/config:Wno-conversion" ] if (configs + conversion_config - conversion_config == configs) { - # TODO(https://fxbug.dev/58162): Decide if these are worth enabling. + # TODO(https://fxbug.dev/42136089): Decide if these are worth enabling. configs += conversion_config } } @@ -132,7 +135,7 @@ template("crashpad_loadable_module") { if (crashpad_is_in_fuchsia) { conversion_config = [ "//build/config:Wno-conversion" ] if (configs + conversion_config - conversion_config == configs) { - # TODO(https://fxbug.dev/58162): Decide if these are worth enabling. + # TODO(https://fxbug.dev/42136089): Decide if these are worth enabling. configs += conversion_config } } @@ -158,7 +161,7 @@ template("crashpad_static_library") { if (crashpad_is_in_fuchsia) { conversion_config = [ "//build/config:Wno-conversion" ] if (configs + conversion_config - conversion_config == configs) { - # TODO(https://fxbug.dev/58162): Decide if these are worth enabling. + # TODO(https://fxbug.dev/42136089): Decide if these are worth enabling. configs += conversion_config } } diff --git a/build/fuchsia/gen_build_defs.py b/build/fuchsia/gen_build_defs.py deleted file mode 100755 index 22414d1c10..0000000000 --- a/build/fuchsia/gen_build_defs.py +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/env vpython3 -# Copyright 2023 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -# -# Generates a single BUILD.gn file with build targets generated using the -# manifest files in the SDK. - -import json -import logging -import os -import shutil -import sys - - -DIR_SRC_ROOT = os.path.abspath( - os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) - -def GetHostOS(): - """Get host operating system.""" - - host_platform = sys.platform - if host_platform.startswith('linux'): - return 'linux' - if host_platform.startswith('darwin'): - return 'mac' - raise Exception('Unsupported host platform: %s' % host_platform) - - -# Inserted at the top of the generated BUILD.gn file. -_GENERATED_PREAMBLE = """# DO NOT EDIT! This file was generated by -# //build/fuchsia/gen_build_def.py. -# Any changes made to this file will be discarded. - -import("//third_party/fuchsia/sdk/{host_os}-amd64/build/fidl_library.gni") -import("//third_party/fuchsia/sdk/{host_os}-amd64/build/fuchsia_sdk_pkg.gni") - -""".format(host_os=GetHostOS()) - -SDK_ROOT = os.path.join(DIR_SRC_ROOT, 'third_party', 'fuchsia', 'sdk', - f'{GetHostOS()}-amd64') - - -def ReformatTargetName(dep_name): - """"Substitutes characters in |dep_name| which are not valid in GN target - names (e.g. dots become hyphens).""" - return dep_name - - -def FormatGNTarget(fields): - """Returns a GN target definition as a string. - - |fields|: The GN fields to include in the target body. - 'target_name' and 'type' are mandatory.""" - - output = '%s("%s") {\n' % (fields['type'], fields['target_name']) - del fields['target_name'] - del fields['type'] - - # Ensure that fields with no ordering requirement are sorted. - for field in ['sources', 'public_deps']: - if field in fields: - fields[field].sort() - - for key, val in fields.items(): - if isinstance(val, str): - val_serialized = '\"%s\"' % val - elif isinstance(val, list): - # Serialize a list of strings in the prettiest possible manner. - if len(val) == 0: - val_serialized = '[]' - elif len(val) == 1: - val_serialized = '[ \"%s\" ]' % val[0] - else: - val_serialized = '[\n ' + ',\n '.join(['\"%s\"' % x - for x in val]) + '\n ]' - else: - raise Exception('Could not serialize %r' % val) - - output += ' %s = %s\n' % (key, val_serialized) - output += '}' - - return output - - -def MetaRootRelativePaths(sdk_relative_paths, meta_root): - return [os.path.relpath(path, meta_root) for path in sdk_relative_paths] - - -def ConvertCommonFields(json): - """Extracts fields from JSON manifest data which are used across all - target types. Note that FIDL packages do their own processing.""" - - meta_root = json['root'] - - converted = {'target_name': ReformatTargetName(json['name'])} - - if 'deps' in json: - converted['public_deps'] = MetaRootRelativePaths(json['deps'], - os.path.dirname(meta_root)) - - # FIDL bindings dependencies are relative to the "fidl" sub-directory. - if 'fidl_binding_deps' in json: - for entry in json['fidl_binding_deps']: - converted['public_deps'] += MetaRootRelativePaths([ - 'fidl/' + dep + ':' + os.path.basename(dep) + '_' + - entry['binding_type'] for dep in entry['deps'] - ], meta_root) - - return converted - - -def ConvertFidlLibrary(json): - """Converts a fidl_library manifest entry to a GN target. - - Arguments: - json: The parsed manifest JSON. - Returns: - The GN target definition, represented as a string.""" - - meta_root = json['root'] - - converted = ConvertCommonFields(json) - converted['type'] = 'fidl_library' - converted['sources'] = MetaRootRelativePaths(json['sources'], meta_root) - converted['library_name'] = json['name'] - - return converted - - -def ConvertCcPrebuiltLibrary(json): - """Converts a cc_prebuilt_library manifest entry to a GN target. - - Arguments: - json: The parsed manifest JSON. - Returns: - The GN target definition, represented as a string.""" - - meta_root = json['root'] - - converted = ConvertCommonFields(json) - converted['type'] = 'fuchsia_sdk_pkg' - - converted['sources'] = MetaRootRelativePaths(json['headers'], meta_root) - - converted['include_dirs'] = MetaRootRelativePaths([json['include_dir']], - meta_root) - - if json['format'] == 'shared': - converted['shared_libs'] = [json['name']] - else: - converted['static_libs'] = [json['name']] - - return converted - - -def ConvertCcSourceLibrary(json): - """Converts a cc_source_library manifest entry to a GN target. - - Arguments: - json: The parsed manifest JSON. - Returns: - The GN target definition, represented as a string.""" - - meta_root = json['root'] - - converted = ConvertCommonFields(json) - converted['type'] = 'fuchsia_sdk_pkg' - - # Headers and source file paths can be scattered across "sources", "headers", - # and "files". Merge them together into one source list. - converted['sources'] = MetaRootRelativePaths(json['sources'], meta_root) - if 'headers' in json: - converted['sources'] += MetaRootRelativePaths(json['headers'], meta_root) - if 'files' in json: - converted['sources'] += MetaRootRelativePaths(json['files'], meta_root) - converted['sources'] = list(set(converted['sources'])) - - converted['include_dirs'] = MetaRootRelativePaths([json['include_dir']], - meta_root) - - return converted - - -def ConvertLoadableModule(json): - """Converts a loadable module manifest entry to GN targets. - - Arguments: - json: The parsed manifest JSON. - Returns: - A list of GN target definitions.""" - - name = json['name'] - if name != 'vulkan_layers': - raise RuntimeError('Unsupported loadable_module: %s' % name) - - # Copy resources and binaries - resources = json['resources'] - - binaries = json['binaries'] - - def _filename_no_ext(name): - return os.path.splitext(os.path.basename(name))[0] - - # Pair each json resource with its corresponding binary. Each such pair - # is a "layer". We only need to check one arch because each arch has the - # same list of binaries. - arch = next(iter(binaries)) - binary_names = binaries[arch] - local_pkg = json['root'] - vulkan_targets = [] - - for res in resources: - layer_name = _filename_no_ext(res) - - # Filter binaries for a matching name. - filtered = [n for n in binary_names if _filename_no_ext(n) == layer_name] - - if not filtered: - # If the binary could not be found then do not generate a - # target for this layer. The missing targets will cause a - # mismatch with the "golden" outputs. - continue - - # Replace hardcoded arch in the found binary filename. - binary = filtered[0].replace('/' + arch + '/', "/${target_cpu}/") - - target = {} - target['name'] = layer_name - target['config'] = os.path.relpath(res, start=local_pkg) - target['binary'] = os.path.relpath(binary, start=local_pkg) - - vulkan_targets.append(target) - - converted = [] - all_target = {} - all_target['target_name'] = 'all' - all_target['type'] = 'group' - all_target['data_deps'] = [] - for target in vulkan_targets: - config_target = {} - config_target['target_name'] = target['name'] + '_config' - config_target['type'] = 'copy' - config_target['sources'] = [target['config']] - config_target['outputs'] = ['${root_gen_dir}/' + target['config']] - converted.append(config_target) - lib_target = {} - lib_target['target_name'] = target['name'] + '_lib' - lib_target['type'] = 'copy' - lib_target['sources'] = [target['binary']] - lib_target['outputs'] = ['${root_out_dir}/lib/{{source_file_part}}'] - converted.append(lib_target) - group_target = {} - group_target['target_name'] = target['name'] - group_target['type'] = 'group' - group_target['data_deps'] = [ - ':' + target['name'] + '_config', ':' + target['name'] + '_lib' - ] - converted.append(group_target) - all_target['data_deps'].append(':' + target['name']) - converted.append(all_target) - return converted - - -def ConvertNoOp(json): - """Null implementation of a conversion function. No output is generated.""" - - return None - - -"""Maps manifest types to conversion functions.""" -_CONVERSION_FUNCTION_MAP = { - 'fidl_library': ConvertFidlLibrary, - 'cc_source_library': ConvertCcSourceLibrary, - 'cc_prebuilt_library': ConvertCcPrebuiltLibrary, - 'loadable_module': ConvertLoadableModule, - - # No need to build targets for these types yet. - 'companion_host_tool': ConvertNoOp, - 'component_manifest': ConvertNoOp, - 'config': ConvertNoOp, - 'dart_library': ConvertNoOp, - 'data': ConvertNoOp, - 'device_profile': ConvertNoOp, - 'documentation': ConvertNoOp, - 'ffx_tool': ConvertNoOp, - 'host_tool': ConvertNoOp, - 'image': ConvertNoOp, - 'sysroot': ConvertNoOp, -} - - -def ConvertMeta(meta_path): - parsed = json.load(open(meta_path)) - if 'type' not in parsed: - return - - convert_function = _CONVERSION_FUNCTION_MAP.get(parsed['type']) - if convert_function is None: - logging.warning('Unexpected SDK artifact type %s in %s.' % - (parsed['type'], meta_path)) - return - - converted = convert_function(parsed) - if not converted: - return - output_path = os.path.join(os.path.dirname(meta_path), 'BUILD.gn') - if os.path.exists(output_path): - os.unlink(output_path) - with open(output_path, 'w') as buildfile: - buildfile.write(_GENERATED_PREAMBLE) - - # Loadable modules have multiple targets - if convert_function != ConvertLoadableModule: - buildfile.write(FormatGNTarget(converted) + '\n\n') - else: - for target in converted: - buildfile.write(FormatGNTarget(target) + '\n\n') - - -def ProcessSdkManifest(): - toplevel_meta = json.load( - open(os.path.join(SDK_ROOT, 'meta', 'manifest.json'))) - - for part in toplevel_meta['parts']: - meta_path = os.path.join(SDK_ROOT, part['meta']) - ConvertMeta(meta_path) - - -def main(): - - # Exit if there's no Fuchsia support for this platform. - try: - GetHostOS() - except: - logging.warning('Fuchsia SDK is not supported on this platform.') - return 0 - - # TODO(crbug/1432399): Remove this when links to these files inside the sdk - # directory have been redirected. - shutil.copytree(os.path.join(DIR_SRC_ROOT, 'third_party', 'fuchsia-gn-sdk', - 'src'), - os.path.join(SDK_ROOT, 'build'), - dirs_exist_ok=True) - - ProcessSdkManifest() - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/build/fuchsia_envs.py b/build/fuchsia_envs.py new file mode 100755 index 0000000000..8d95b78beb --- /dev/null +++ b/build/fuchsia_envs.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +# Copyright 2024 The Crashpad Authors +# +# 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. + +import os +import platform +import subprocess +import sys + + +def main(args): + """ + Executes the test-scripts with required environment variables. It acts like + /usr/bin/env, but provides some extra functionality to dynamically set up + the environment variables. + + Args: + args: the command line arguments without the script name itself. + """ + os.environ['SRC_ROOT'] = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')) + + assert platform.system() == 'Linux', 'Unsupported OS ' + platform.system() + os.environ['FUCHSIA_SDK_ROOT'] = os.path.join( + os.environ['SRC_ROOT'], 'third_party/fuchsia/sdk/linux-amd64/') + os.environ['FUCHSIA_GN_SDK_ROOT'] = os.path.join( + os.environ['SRC_ROOT'], 'third_party/fuchsia-gn-sdk/src') + + return subprocess.run(args).returncode + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/build/ios/setup_ios_gn.config b/build/ios/setup_ios_gn.config index 4e8a1371d0..1a5e2251e7 100644 --- a/build/ios/setup_ios_gn.config +++ b/build/ios/setup_ios_gn.config @@ -12,13 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -[goma] -# Controls whether goma is enabled or not. If you generally use goma but -# want to disable goma for a single build, consider using the environment -# variable GOMA_DISABLED. -enabled = False -install = "$GOMA_DIR" - [xcode] # Controls settings for the generated Xcode project. If jobs is non-zero # it will be passed to the ninja invocation in Xcode project. diff --git a/build/run_tests.py b/build/run_tests.py index e03e06e78d..9079da40bd 100755 --- a/build/run_tests.py +++ b/build/run_tests.py @@ -313,7 +313,7 @@ def _adb_shell(command_args, env={}): def _RunOnIOSTarget(binary_dir, test, is_xcuitest=False, gtest_filter=None): - """Runs the given iOS |test| app on iPhone 8 with the default OS version.""" + """Runs the given iOS |test| app on a simulator with the default OS version.""" def xctest(binary_dir, test, gtest_filter=None): """Returns a dict containing the xctestrun data needed to run an @@ -368,11 +368,11 @@ def xcuitest(binary_dir, test): with tempfile.NamedTemporaryFile() as f: import plistlib - xctestrun_path = f.name + xctestrun_path = f.name + ".xctestrun" print(xctestrun_path) command = [ 'xcodebuild', 'test-without-building', '-xctestrun', xctestrun_path, - '-destination', 'platform=iOS Simulator,name=iPhone 8', + '-destination', 'platform=iOS Simulator,OS=15.5,name=iPhone 13', ] with open(xctestrun_path, 'wb') as fp: if is_xcuitest: diff --git a/client/BUILD.gn b/client/BUILD.gn index bc67b32f1f..bd150ab94e 100644 --- a/client/BUILD.gn +++ b/client/BUILD.gn @@ -174,6 +174,7 @@ source_set("client_test") { "annotation_list_test.cc", "annotation_test.cc", "crash_report_database_test.cc", + "crashpad_info_test.cc", "length_delimited_ring_buffer_test.cc", "prune_crash_reports_test.cc", "ring_buffer_annotation_test.cc", diff --git a/client/annotation_list.cc b/client/annotation_list.cc index bcf7ca76af..c73660772c 100644 --- a/client/annotation_list.cc +++ b/client/annotation_list.cc @@ -19,6 +19,46 @@ namespace crashpad { +template +T* AnnotationList::IteratorBase::operator*() const { + CHECK_NE(curr_, tail_); + return curr_; +} + +template +T* AnnotationList::IteratorBase::operator->() const { + CHECK_NE(curr_, tail_); + return curr_; +} + +template +AnnotationList::IteratorBase& AnnotationList::IteratorBase::operator++() { + CHECK_NE(curr_, tail_); + curr_ = curr_->GetLinkNode(); + return *this; +} + +template +AnnotationList::IteratorBase AnnotationList::IteratorBase::operator++( + int) { + T* const old_curr = curr_; + ++(*this); + return IteratorBase(old_curr, tail_); +} + +template +bool AnnotationList::IteratorBase::operator!=( + const IteratorBase& other) const { + return !(*this == other); +} + +template +AnnotationList::IteratorBase::IteratorBase(T* head, const Annotation* tail) + : curr_(head), tail_(tail) {} + +template class AnnotationList::IteratorBase; +template class AnnotationList::IteratorBase; + AnnotationList::AnnotationList() : tail_pointer_(&tail_), head_(Annotation::Type::kInvalid, nullptr, nullptr), @@ -65,49 +105,6 @@ void AnnotationList::Add(Annotation* annotation) { } } -AnnotationList::Iterator::Iterator(Annotation* head, const Annotation* tail) - : curr_(head), tail_(tail) {} - -AnnotationList::Iterator::~Iterator() = default; - -Annotation* AnnotationList::Iterator::operator*() const { - CHECK_NE(curr_, tail_); - return curr_; -} - -AnnotationList::Iterator& AnnotationList::Iterator::operator++() { - CHECK_NE(curr_, tail_); - curr_ = curr_->GetLinkNode(); - return *this; -} - -bool AnnotationList::Iterator::operator==( - const AnnotationList::Iterator& other) const { - return curr_ == other.curr_; -} - -AnnotationList::ConstIterator::ConstIterator(const Annotation* head, - const Annotation* tail) - : curr_(head), tail_(tail) {} - -AnnotationList::ConstIterator::~ConstIterator() = default; - -const Annotation* AnnotationList::ConstIterator::operator*() const { - CHECK_NE(curr_, tail_); - return curr_; -} - -AnnotationList::ConstIterator& AnnotationList::ConstIterator::operator++() { - CHECK_NE(curr_, tail_); - curr_ = curr_->GetLinkNode(); - return *this; -} - -bool AnnotationList::ConstIterator::operator==( - const AnnotationList::ConstIterator& other) const { - return curr_ == other.curr_; -} - AnnotationList::Iterator AnnotationList::begin() { return Iterator(head_.GetLinkNode(), tail_pointer_); } diff --git a/client/annotation_list.h b/client/annotation_list.h index eec7fb4c13..ce1f861397 100644 --- a/client/annotation_list.h +++ b/client/annotation_list.h @@ -15,6 +15,8 @@ #ifndef CRASHPAD_CLIENT_ANNOTATION_LIST_H_ #define CRASHPAD_CLIENT_ANNOTATION_LIST_H_ +#include + #include "build/build_config.h" #include "client/annotation.h" @@ -61,47 +63,46 @@ class AnnotationList { void Add(Annotation* annotation); //! \brief An InputIterator for the AnnotationList. - class Iterator { + template + class IteratorBase { public: - ~Iterator(); + using difference_type = signed int; + using value_type = T*; + using reference = T*; + using pointer = void; + using iterator_category = std::input_iterator_tag; - Annotation* operator*() const; - Iterator& operator++(); - bool operator==(const Iterator& other) const; - bool operator!=(const Iterator& other) const { return !(*this == other); } + IteratorBase(const IteratorBase& other) = default; + IteratorBase(IteratorBase&& other) = default; - private: - friend class AnnotationList; - Iterator(Annotation* head, const Annotation* tail); + ~IteratorBase() = default; - Annotation* curr_; - const Annotation* const tail_; + IteratorBase& operator=(const IteratorBase& other) = default; + IteratorBase& operator=(IteratorBase&& other) = default; - // Copy and assign are required. - }; + T* operator*() const; + T* operator->() const; - //! \brief An InputIterator for iterating a const AnnotationList. - class ConstIterator { - public: - ~ConstIterator(); + IteratorBase& operator++(); + IteratorBase operator++(int); - const Annotation* operator*() const; - ConstIterator& operator++(); - bool operator==(const ConstIterator& other) const; - bool operator!=(const ConstIterator& other) const { - return !(*this == other); + bool operator==(const IteratorBase& other) const { + return curr_ == other.curr_; } + bool operator!=(const IteratorBase& other) const; + private: friend class AnnotationList; - ConstIterator(const Annotation* head, const Annotation* tail); + IteratorBase(T* head, const Annotation* tail); - const Annotation* curr_; - const Annotation* const tail_; - - // Copy and assign are required. + T* curr_ = nullptr; + const Annotation* tail_ = nullptr; }; + using Iterator = IteratorBase; + using ConstIterator = IteratorBase; + //! \brief Returns an iterator to the first element of the annotation list. Iterator begin(); ConstIterator begin() const { return cbegin(); } diff --git a/client/annotation_list_test.cc b/client/annotation_list_test.cc index 0ac87ffaef..41ecfa05ac 100644 --- a/client/annotation_list_test.cc +++ b/client/annotation_list_test.cc @@ -14,7 +14,10 @@ #include "client/annotation.h" +#include +#include #include +#include #include #include "base/rand_util.h" @@ -27,6 +30,52 @@ namespace crashpad { namespace test { namespace { +#if (__cplusplus >= 202002L) +template + requires std::input_iterator +void VerifyIsInputIterator(Iterator) {} +#else +template +struct IsLegacyIteratorImpl { + static constexpr bool value = + std::is_copy_constructible_v && + std::is_copy_assignable_v && std::is_destructible_v && + std::is_swappable_v && + // check that std::iterator_traits has the necessary types (check only one + // needed as std::iterator is required to define only if all are defined) + !std::is_same_v::reference, + void> && + std::is_same_v()), Iterator&> && + !std::is_same_v()), void>; +}; + +template +struct IsLegacyInputIteratorImpl { + static constexpr bool value = + IsLegacyIteratorImpl::value && + std::is_base_of_v< + std::input_iterator_tag, + typename std::iterator_traits::iterator_category> && + std::is_convertible_v() != + std::declval()), + bool> && + std::is_convertible_v() == + std::declval()), + bool> && + std::is_same_v()), + typename std::iterator_traits::reference> && + std::is_same_v()), Iterator&> && + std::is_same_v()++), Iterator> && + std::is_same_v())), + typename std::iterator_traits::reference>; +}; + +template +void VerifyIsInputIterator(Iterator) { + static_assert(IsLegacyInputIteratorImpl::value); +} +#endif + TEST(AnnotationListStatic, Register) { ASSERT_FALSE(AnnotationList::Get()); EXPECT_TRUE(AnnotationList::Register()); @@ -222,6 +271,23 @@ TEST_F(AnnotationList, IteratorMultipleAnnotationsInsertedAndRemoved) { EXPECT_EQ(const_iterator, annotations_.cend()); } +TEST_F(AnnotationList, IteratorIsInputIterator) { + one_.Set("1"); + two_.Set("2"); + + // Check explicitly that the iterators meet the interface of an input + // iterator. + VerifyIsInputIterator(annotations_.begin()); + VerifyIsInputIterator(annotations_.cbegin()); + VerifyIsInputIterator(annotations_.end()); + VerifyIsInputIterator(annotations_.cend()); + + // Additionally verify that std::distance accepts the iterators. It requires + // the iterators to comply to the input iterator interface. + EXPECT_EQ(std::distance(annotations_.begin(), annotations_.end()), 2); + EXPECT_EQ(std::distance(annotations_.cbegin(), annotations_.cend()), 2); +} + class RaceThread : public Thread { public: explicit RaceThread(test::AnnotationList* test) : Thread(), test_(test) {} diff --git a/client/crashpad_client_ios.cc b/client/crashpad_client_ios.cc index a34cc15e3c..663a17c432 100644 --- a/client/crashpad_client_ios.cc +++ b/client/crashpad_client_ios.cc @@ -53,6 +53,40 @@ namespace crashpad { namespace { +// Thread-safe version of `base::apple::ScopedMachReceiveRight` which allocates +// the Mach port upon construction and deallocates it upon destruction. +class ThreadSafeScopedMachPortWithReceiveRight { + public: + ThreadSafeScopedMachPortWithReceiveRight() + : port_(NewMachPort(MACH_PORT_RIGHT_RECEIVE)) {} + + ThreadSafeScopedMachPortWithReceiveRight( + const ThreadSafeScopedMachPortWithReceiveRight&) = delete; + ThreadSafeScopedMachPortWithReceiveRight& operator=( + const ThreadSafeScopedMachPortWithReceiveRight&) = delete; + + ~ThreadSafeScopedMachPortWithReceiveRight() { reset(); } + + mach_port_t get() { return port_.load(); } + void reset() { + mach_port_t old_port = port_.exchange(MACH_PORT_NULL); + if (old_port == MACH_PORT_NULL) { + // Already reset, nothing to do. + return; + } + kern_return_t kr = mach_port_mod_refs( + mach_task_self(), old_port, MACH_PORT_RIGHT_RECEIVE, -1); + MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) + << "ThreadSafeScopedMachPortWithReceiveRight mach_port_mod_refs"; + kr = mach_port_deallocate(mach_task_self(), old_port); + MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) + << "ThreadSafeScopedMachPortWithReceiveRight mach_port_deallocate"; + } + + private: + std::atomic port_; +}; + // A base class for signal handler and Mach exception server. class CrashHandler : public Thread, public UniversalMachExcServer::Interface, @@ -169,14 +203,14 @@ class CrashHandler : public Thread, } bool InstallMachExceptionHandler() { - exception_port_.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE)); - if (!exception_port_.is_valid()) { + mach_port_t exception_port = exception_port_.get(); + if (exception_port == MACH_PORT_NULL) { return false; } kern_return_t kr = mach_port_insert_right(mach_task_self(), - exception_port_.get(), - exception_port_.get(), + exception_port, + exception_port, MACH_MSG_TYPE_MAKE_SEND); if (kr != KERN_SUCCESS) { MACH_LOG(ERROR, kr) << "mach_port_insert_right"; @@ -194,7 +228,7 @@ class CrashHandler : public Thread, if (!exception_ports.GetExceptionPorts(mask, &original_handlers_) || !exception_ports.SetExceptionPort( mask, - exception_port_.get(), + exception_port, EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE)) { return false; @@ -393,7 +427,7 @@ class CrashHandler : public Thread, Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, old_action); } - base::apple::ScopedMachReceiveRight exception_port_; + ThreadSafeScopedMachPortWithReceiveRight exception_port_; ExceptionPorts::ExceptionHandlerVector original_handlers_; struct sigaction old_action_ = {}; internal::InProcessHandler in_process_handler_; diff --git a/client/crashpad_client_linux_test.cc b/client/crashpad_client_linux_test.cc index 5d492009c3..ae76a7e4bf 100644 --- a/client/crashpad_client_linux_test.cc +++ b/client/crashpad_client_linux_test.cc @@ -765,7 +765,7 @@ class StartHandlerForChildTest : public Multiprocess { __builtin_trap(); - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); } StartHandlerForClientTest test_state_; diff --git a/client/crashpad_info.cc b/client/crashpad_info.cc index cd6f234818..781c0e3825 100644 --- a/client/crashpad_info.cc +++ b/client/crashpad_info.cc @@ -16,6 +16,7 @@ #include +#include "base/numerics/safe_conversions.h" #include "build/build_config.h" #include "util/misc/address_sanitizer.h" #include "util/misc/from_pointer_cast.h" @@ -33,6 +34,21 @@ namespace { // understand new versions. constexpr uint32_t kCrashpadInfoVersion = 1; +// Creates a `UserDataMinidumpStreamListEntry` with the given fields, and +// returns a pointer to it. The caller takes ownership of the returned object. +crashpad::internal::UserDataMinidumpStreamListEntry* CreateListEntry( + uint64_t next, + uint32_t stream_type, + const void* data, + size_t size) { + auto to_be_added = new crashpad::internal::UserDataMinidumpStreamListEntry(); + to_be_added->next = next; + to_be_added->stream_type = stream_type; + to_be_added->base_address = crashpad::FromPointerCast(data); + to_be_added->size = base::checked_cast(size); + return to_be_added; +} + } // namespace namespace crashpad { @@ -123,16 +139,50 @@ CrashpadInfo::CrashpadInfo() user_data_minidump_stream_head_(nullptr), annotations_list_(nullptr) {} -void CrashpadInfo::AddUserDataMinidumpStream(uint32_t stream_type, - const void* data, - size_t size) { - auto to_be_added = new internal::UserDataMinidumpStreamListEntry(); - to_be_added->next = - FromPointerCast(user_data_minidump_stream_head_); - to_be_added->stream_type = stream_type; - to_be_added->base_address = FromPointerCast(data); - to_be_added->size = base::checked_cast(size); - user_data_minidump_stream_head_ = to_be_added; +UserDataMinidumpStreamHandle* CrashpadInfo::AddUserDataMinidumpStream( + uint32_t stream_type, + const void* data, + size_t size) { + user_data_minidump_stream_head_ = CreateListEntry( + crashpad::FromPointerCast(user_data_minidump_stream_head_), + stream_type, + data, + size); + return user_data_minidump_stream_head_; +} + +UserDataMinidumpStreamHandle* CrashpadInfo::UpdateUserDataMinidumpStream( + UserDataMinidumpStreamHandle* stream_to_update, + uint32_t stream_type, + const void* data, + size_t size) { + // Create a new stream that points to the node `stream_to_update` points to. + const auto new_stream = + CreateListEntry(stream_to_update->next, stream_type, data, size); + + // If `stream_to_update` is head of the list, replace the head with + // `new_stream`. + if (stream_to_update == user_data_minidump_stream_head_) { + user_data_minidump_stream_head_ = new_stream; + } else { + // Otherwise, find the node before `stream_to_update`, and make it point to + // `new_stream` instead. + auto current = user_data_minidump_stream_head_; + while (current) { + auto next = reinterpret_cast( + current->next); + if (next == stream_to_update) { + current->next = FromPointerCast(new_stream); + break; + } + current = next; + } + CHECK(current) + << "Tried to update a UserDataMinidumpStream that doesn't exist"; + } + + delete stream_to_update; + return new_stream; } } // namespace crashpad diff --git a/client/crashpad_info.h b/client/crashpad_info.h index ebfe8fe889..7d894cb0c3 100644 --- a/client/crashpad_info.h +++ b/client/crashpad_info.h @@ -56,6 +56,8 @@ struct UserDataMinidumpStreamListEntry { } // namespace internal +using UserDataMinidumpStreamHandle = internal::UserDataMinidumpStreamListEntry; + //! \brief A structure that can be used by a Crashpad-enabled program to //! provide information to the Crashpad crash handler. //! @@ -221,9 +223,41 @@ struct CrashpadInfo { //! which is `0xffff`. //! \param[in] data The base pointer of the stream data. //! \param[in] size The size of the stream data. - void AddUserDataMinidumpStream(uint32_t stream_type, - const void* data, - size_t size); + //! \return A handle to the added stream, for use in calling + //! UpdateUserDataMinidumpStream() if needed. + UserDataMinidumpStreamHandle* AddUserDataMinidumpStream(uint32_t stream_type, + const void* data, + size_t size); + + //! \brief Replaces the given stream with an updated stream. + //! + //! Creates a new memory block referencing the given \a data and \a size with + //! type \a stream_type. The memory referred to be \a data and \a size is + //! owned by the caller and must remain valid while it is in effect for the + //! CrashpadInfo object. + //! + //! Frees \a stream_to_update and returns a new handle to the updated stream. + //! + //! \param[in] stream_to_update A handle to the stream to be updated, received + //! from either AddUserDataMinidumpStream() or previous calls to this + //! function. + //! \param[in] stream_type The stream type identifier to use. This should be + //! normally be larger than `MINIDUMP_STREAM_TYPE::LastReservedStream` + //! which is `0xffff`. + //! \param[in] data The base pointer of the stream data. + //! \param[in] size The size of the stream data. + //! \return A handle to the new memory block that references the updated data, + //! for use in calling this method again if needed. + UserDataMinidumpStreamHandle* UpdateUserDataMinidumpStream( + UserDataMinidumpStreamHandle* stream_to_update, + uint32_t stream_type, + const void* data, + size_t size); + + internal::UserDataMinidumpStreamListEntry* + GetUserDataMinidumpStreamHeadForTesting() { + return user_data_minidump_stream_head_; + } enum : uint32_t { kSignature = 'CPad', diff --git a/client/crashpad_info_test.cc b/client/crashpad_info_test.cc new file mode 100644 index 0000000000..8ea7f8a155 --- /dev/null +++ b/client/crashpad_info_test.cc @@ -0,0 +1,142 @@ +// Copyright 2024 The Crashpad Authors +// +// 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 "client/crashpad_info.h" + +#include + +#include "gtest/gtest.h" + +namespace crashpad { +namespace test { +namespace { + +constexpr uint32_t kTestStreamType = 0x33333; + +class CrashpadInfoTest : public testing::Test { + protected: + CrashpadInfo& crashpad_info() { return crashpad_info_; } + + // Returns the current head of the list of streams in `crashpad_info_`. Note + // that the returned pointer is invalidated if a stream is added or updated. + internal::UserDataMinidumpStreamListEntry* GetCurrentHead() { + return crashpad_info().GetUserDataMinidumpStreamHeadForTesting(); + } + + // Returns a pointer to the next node in the list after the given `node`. + internal::UserDataMinidumpStreamListEntry* GetNext( + internal::UserDataMinidumpStreamListEntry* node) { + return reinterpret_cast( + node->next); + } + + internal::UserDataMinidumpStreamListEntry* initial_head() { + return initial_head_; + } + + internal::UserDataMinidumpStreamListEntry* initial_tail() { + return initial_tail_; + } + + private: + void SetUp() override { + ASSERT_EQ(nullptr, GetCurrentHead()); + + // Create a simple test list with the structure + // `initial_head_` -> `initial_tail_`. + initial_tail_ = AddStream(0x11111, kInitialTailData); + initial_head_ = AddStream(0x22222, kInitialHeadData); + + // Validate the list's contents. + auto current = GetCurrentHead(); + ASSERT_EQ(initial_head_, current); + ASSERT_EQ(kInitialHeadData, reinterpret_cast(current->base_address)); + current = GetNext(current); + ASSERT_EQ(initial_tail_, current); + ASSERT_EQ(nullptr, GetNext(current)); + } + + void TearDown() override { + // Free the list. The list lives until process exit in production, but must + // be freed in tests as multiple tests run in the same process. + auto current = GetCurrentHead(); + while (current) { + auto next = GetNext(current); + delete current; + current = next; + } + } + + internal::UserDataMinidumpStreamListEntry* AddStream(uint32_t stream_type, + const char* data) { + return reinterpret_cast( + crashpad_info().AddUserDataMinidumpStream( + stream_type, data, strlen(data))); + } + + CrashpadInfo crashpad_info_; + + static constexpr char kInitialHeadData[] = "head"; + static constexpr char kInitialTailData[] = "tail"; + + internal::UserDataMinidumpStreamListEntry* initial_head_ = nullptr; + internal::UserDataMinidumpStreamListEntry* initial_tail_ = nullptr; +}; + +// Tests that updating the head of the list updates the head pointer, the new +// head contains the updated data, and the updated node points to the next node. +TEST_F(CrashpadInfoTest, UpdateUserDataMinidumpStreamHead) { + const std::string new_data = "this is a new string"; + const auto new_entry = crashpad_info().UpdateUserDataMinidumpStream( + initial_head(), kTestStreamType, new_data.data(), new_data.size()); + const auto head = GetCurrentHead(); + EXPECT_EQ(new_entry, head); + EXPECT_EQ(new_data.data(), reinterpret_cast(head->base_address)); + EXPECT_EQ(new_data.size(), head->size); + EXPECT_EQ(kTestStreamType, head->stream_type); + EXPECT_EQ(initial_tail(), GetNext(head)); +} + +// Tests that updating the tail of the list results in a tail pointing to +// nullptr, and that the node before the updated node points to it. +TEST_F(CrashpadInfoTest, UpdateUserDataMinidumpStreamTail) { + const std::string new_data = "new"; + const auto new_entry = crashpad_info().UpdateUserDataMinidumpStream( + initial_tail(), kTestStreamType, new_data.data(), new_data.size()); + const auto tail = GetNext(GetCurrentHead()); + EXPECT_EQ(new_entry, tail); + EXPECT_EQ(nullptr, GetNext(tail)); +} + +// Tests that the handle returned from updating an entry is usable for updating +// the entry again. +TEST_F(CrashpadInfoTest, UpdateUserDataMinidumpStreamMultipleTimes) { + // Update the entry at the head; the updated entry should become the new head. + const std::string new_data = "new"; + const auto new_entry_1 = crashpad_info().UpdateUserDataMinidumpStream( + initial_head(), kTestStreamType, new_data.data(), new_data.size()); + EXPECT_EQ(new_entry_1, GetCurrentHead()); + + // Update the updated entry again; another new entry should replace it as + // head. + const auto new_entry_2 = crashpad_info().UpdateUserDataMinidumpStream( + new_entry_1, kTestStreamType, new_data.data(), new_data.size()); + EXPECT_NE(new_entry_1, new_entry_2); + EXPECT_EQ(new_entry_2, GetCurrentHead()); + EXPECT_EQ(initial_tail(), GetNext(GetCurrentHead())); +} + +} // namespace +} // namespace test +} // namespace crashpad diff --git a/client/ios_handler/exception_processor.mm b/client/ios_handler/exception_processor.mm index 470b0e76f7..0268b3a128 100644 --- a/client/ios_handler/exception_processor.mm +++ b/client/ios_handler/exception_processor.mm @@ -43,7 +43,6 @@ #include #include -#include "base/bit_cast.h" #include "base/format_macros.h" #include "base/logging.h" #include "base/memory/free_deleter.h" @@ -552,7 +551,7 @@ id ObjcExceptionPreprocessor(id exception) { LoggingUnwStep(&cursor) > 0 && unw_get_proc_info(&cursor, &caller_frame_info) == UNW_ESUCCESS) { auto uiwindowimp_lambda = [](IMP* max) { - IMP min = *max = bit_cast(nullptr); + IMP min = *max = nullptr; unsigned int method_count = 0; std::unique_ptr method_list( class_copyMethodList(NSClassFromString(@"UIWindow"), diff --git a/client/ios_handler/in_process_handler.cc b/client/ios_handler/in_process_handler.cc index dfdc03c9b7..be12692098 100644 --- a/client/ios_handler/in_process_handler.cc +++ b/client/ios_handler/in_process_handler.cc @@ -468,9 +468,12 @@ InProcessHandler::ScopedReport::ScopedReport( num_frames_(num_frames), rootMap_(writer) { DCHECK(writer); + // Grab the report creation time before writing the report. + uint64_t report_time_nanos = ClockMonotonicNanoseconds(); InProcessIntermediateDumpHandler::WriteHeader(writer); InProcessIntermediateDumpHandler::WriteProcessInfo(writer, annotations); - InProcessIntermediateDumpHandler::WriteSystemInfo(writer, system_data); + InProcessIntermediateDumpHandler::WriteSystemInfo( + writer, system_data, report_time_nanos); } InProcessHandler::ScopedReport::~ScopedReport() { diff --git a/client/ios_handler/in_process_intermediate_dump_handler.cc b/client/ios_handler/in_process_intermediate_dump_handler.cc index a7ac5dae18..5e6c42df61 100644 --- a/client/ios_handler/in_process_intermediate_dump_handler.cc +++ b/client/ios_handler/in_process_intermediate_dump_handler.cc @@ -415,7 +415,7 @@ void MaybeCaptureMemoryAround(IOSIntermediateDumpWriter* writer, IOSIntermediateDumpWriter::ScopedArrayMap memory_region(writer); WriteProperty( - writer, IntermediateDumpKey::kThreadContextMemoryRegionAddress, &address); + writer, IntermediateDumpKey::kThreadContextMemoryRegionAddress, &target); // Don't use WritePropertyBytes, this one will fail regularly if |target| // cannot be read. writer->AddPropertyBytes(IntermediateDumpKey::kThreadContextMemoryRegionData, @@ -446,7 +446,7 @@ void CaptureMemoryPointedToByThreadState(IOSIntermediateDumpWriter* writer, MaybeCaptureMemoryAround(writer, thread_state.__r15); MaybeCaptureMemoryAround(writer, thread_state.__rip); #elif defined(ARCH_CPU_ARM_FAMILY) - MaybeCaptureMemoryAround(writer, thread_state.__pc); + MaybeCaptureMemoryAround(writer, arm_thread_state64_get_pc(thread_state)); for (size_t i = 0; i < std::size(thread_state.__x); ++i) { MaybeCaptureMemoryAround(writer, thread_state.__x[i]); } @@ -616,7 +616,8 @@ void InProcessIntermediateDumpHandler::WriteProcessInfo( // static void InProcessIntermediateDumpHandler::WriteSystemInfo( IOSIntermediateDumpWriter* writer, - const IOSSystemDataCollector& system_data) { + const IOSSystemDataCollector& system_data, + uint64_t report_time_nanos) { IOSIntermediateDumpWriter::ScopedMap system_map( writer, IntermediateDumpKey::kSystemInfo); @@ -702,6 +703,11 @@ void InProcessIntermediateDumpHandler::WriteSystemInfo( } else { CRASHPAD_RAW_LOG("host_statistics"); } + + uint64_t crashpad_uptime_nanos = + report_time_nanos - system_data.InitializationTime(); + WriteProperty( + writer, IntermediateDumpKey::kCrashpadUptime, &crashpad_uptime_nanos); } // static @@ -870,7 +876,7 @@ void InProcessIntermediateDumpHandler::WriteThreadInfo( #if defined(ARCH_CPU_X86_64) vm_address_t stack_pointer = thread_state.__rsp; #elif defined(ARCH_CPU_ARM64) - vm_address_t stack_pointer = thread_state.__sp; + vm_address_t stack_pointer = arm_thread_state64_get_sp(thread_state); #endif vm_size_t stack_region_size; @@ -917,12 +923,12 @@ void InProcessIntermediateDumpHandler::WriteModuleInfo( uint32_t image_count = image_infos->infoArrayCount; const dyld_image_info* image_array = image_infos->infoArray; - for (uint32_t image_index = 0; image_index < image_count; ++image_index) { + for (int32_t image_index = image_count - 1; image_index >= 0; --image_index) { IOSIntermediateDumpWriter::ScopedArrayMap modules(writer); ScopedVMRead image; if (!image.Read(&image_array[image_index])) { CRASHPAD_RAW_LOG("Unable to dyld_image_info"); - return; + continue; } if (image->imageFilePath) { @@ -961,19 +967,19 @@ void InProcessIntermediateDumpHandler::WriteExceptionFromSignal( WriteProperty(writer, IntermediateDumpKey::kSignalNumber, &siginfo->si_signo); WriteProperty(writer, IntermediateDumpKey::kSignalCode, &siginfo->si_code); WriteProperty(writer, IntermediateDumpKey::kSignalAddress, &siginfo->si_addr); + #if defined(ARCH_CPU_X86_64) - WriteProperty( - writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss); - WriteProperty( - writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__fs); + x86_thread_state64_t thread_state = context->uc_mcontext->__ss; + x86_float_state64_t float_state = context->uc_mcontext->__fs; #elif defined(ARCH_CPU_ARM64) - WriteProperty( - writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss); - WriteProperty( - writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__ns); + arm_thread_state64_t thread_state = context->uc_mcontext->__ss; + arm_neon_state64_t float_state = context->uc_mcontext->__ns; #else #error Port to your CPU architecture #endif + WriteProperty(writer, IntermediateDumpKey::kThreadState, &thread_state); + WriteProperty(writer, IntermediateDumpKey::kFloatState, &float_state); + CaptureMemoryPointedToByThreadState(writer, thread_state); // Thread ID. thread_identifier_info identifier_info; diff --git a/client/ios_handler/in_process_intermediate_dump_handler.h b/client/ios_handler/in_process_intermediate_dump_handler.h index 83ebff227f..1cf9180c74 100644 --- a/client/ios_handler/in_process_intermediate_dump_handler.h +++ b/client/ios_handler/in_process_intermediate_dump_handler.h @@ -56,8 +56,12 @@ class InProcessIntermediateDumpHandler final { //! \brief Write SystemSnapshot data to the intermediate dump. //! //! \param[in] writer The dump writer + //! \param[in] system_data An object containing various system data points. + //! \param[in] report_time Report creation time in nanoseconds as returned by + //! ClockMonotonicNanoseconds(). static void WriteSystemInfo(IOSIntermediateDumpWriter* writer, - const IOSSystemDataCollector& system_data); + const IOSSystemDataCollector& system_data, + uint64_t report_time_nanos); //! \brief Write ThreadSnapshot data to the intermediate dump. //! diff --git a/client/ios_handler/in_process_intermediate_dump_handler_test.cc b/client/ios_handler/in_process_intermediate_dump_handler_test.cc index 3b007fcfa9..27179bb3af 100644 --- a/client/ios_handler/in_process_intermediate_dump_handler_test.cc +++ b/client/ios_handler/in_process_intermediate_dump_handler_test.cc @@ -61,8 +61,8 @@ class InProcessIntermediateDumpHandlerTest : public testing::Test { InProcessIntermediateDumpHandler::WriteHeader(writer_.get()); InProcessIntermediateDumpHandler::WriteProcessInfo( writer_.get(), {{"before_dump", "pre"}}); - InProcessIntermediateDumpHandler::WriteSystemInfo(writer_.get(), - system_data_); + InProcessIntermediateDumpHandler::WriteSystemInfo( + writer_.get(), system_data_, ClockMonotonicNanoseconds()); InProcessIntermediateDumpHandler::WriteThreadInfo(writer_.get(), 0, 0); InProcessIntermediateDumpHandler::WriteModuleInfo(writer_.get()); } @@ -89,6 +89,18 @@ class InProcessIntermediateDumpHandlerTest : public testing::Test { const auto& path() const { return path_; } auto writer() const { return writer_.get(); } +#if TARGET_OS_SIMULATOR + // macOS 14.0 is 23A344, macOS 13.6.5 is 22G621, so if the first two + // characters in the kern.osversion are > 22, this build will reproduce the + // simulator bug in crbug.com/328282286 + bool IsMacOSVersion143OrGreaterAndiOS16OrLess() { + if (__builtin_available(iOS 17, *)) { + return false; + } + return std::stoi(system_data_.Build().substr(0, 2)) > 22; + } +#endif + private: std::unique_ptr writer_; internal::IOSSystemDataCollector system_data_; @@ -125,6 +137,15 @@ TEST_F(InProcessIntermediateDumpHandlerTest, TestSystem) { } TEST_F(InProcessIntermediateDumpHandlerTest, TestAnnotations) { +#if TARGET_OS_SIMULATOR + // This test will fail on older ( all_annotations_simple_map; std::vector all_annotations; diff --git a/client/prune_crash_reports.cc b/client/prune_crash_reports.cc index 889f567165..6e4c7b9c65 100644 --- a/client/prune_crash_reports.cc +++ b/client/prune_crash_reports.cc @@ -123,7 +123,7 @@ bool BinaryPruneCondition::ShouldPruneReport( case OR: return lhs_->ShouldPruneReport(report) || rhs_->ShouldPruneReport(report); default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; } } diff --git a/client/settings.cc b/client/settings.cc index 5e4119e217..420fbfc958 100644 --- a/client/settings.cc +++ b/client/settings.cc @@ -292,7 +292,7 @@ FileHandle Settings::GetHandleFromOptions( return OpenFileForReadAndWrite( file_path, options.mode, options.permissions); } - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return kInvalidFileHandle; } diff --git a/doc/appengine/README b/doc/appengine/README index ee0e319adb..7beefc6167 100644 --- a/doc/appengine/README +++ b/doc/appengine/README @@ -9,26 +9,37 @@ To work on this app, obtain the following packages: instructions were tested with Go 1.14 locally but a Go 1.11 runtime when deployed), but if problems are encountered, it would be wise to use the same version for both local development and AppEngine deployment. - - The Google Cloud SDK from, https://cloud.google.com/sdk/docs. This is - necessary for both local development and for AppEngine deployment. Unpacking - this package produces a google-cloud-sdk directory, whose bin child directory - may be added to $PATH for convenience, although this is not strictly - necessary. + - The Google Cloud SDK (gcloud CLI) from + https://cloud.google.com/sdk/docs/install-sdk. This is necessary for both + local development and for AppEngine deployment. Unpacking this package + produces a google-cloud-sdk directory, whose bin child directory may be + added to $PATH for convenience, although this is not strictly necessary. The commands in this README are expected to be run from the directory containing -it. $GOPATH must also be set to include this directory: - -% export GOPATH="$(go env GOPATH):$(pwd)" +it. To test locally: -% go get -d crashpad-home -% …/google-cloud-sdk/bin/dev_appserver.py src/crashpad-home +% go get -d ./src/crashpad-home +% python3 …/google-cloud-sdk/bin/dev_appserver.py src/crashpad-home + +dev_appserver.py must be invoked using Python 3, but internally will use Python +2, and a Python 2 interpreter must be available in the PATH as python2. Look for the “Starting module "default" running at: http://localhost:8080” line, which tells you the URL of the local running instance of the app. Test -http://localhost:8080/ and http://localhost:8080/doxygen to ensure that they -work. +http://localhost:8080/ to ensure that it works. + +It would be good to test http://localhost:8080/doxygen as well, but it may fail +with HTTP status 500 and the following error returned as the HTTP response body +because memcache seems to not be available in the local dev_appserver +environment: + +service bridge HTTP failed: Post "http://appengine.googleapis.internal:10001/rpc_http": dial tcp: lookup appengine.googleapis.internal: no such host + +The /doxygen URL can be tested in a verison of the app that’s been deployed +before traffic has been migrated to it by visiting the staged deployed version +from the App Engine console. To deploy: diff --git a/doc/appengine/go.mod b/doc/appengine/go.mod new file mode 100644 index 0000000000..398c008b25 --- /dev/null +++ b/doc/appengine/go.mod @@ -0,0 +1,10 @@ +module src/crashpad-home + +go 1.21.6 + +require google.golang.org/appengine/v2 v2.0.5 + +require ( + github.com/golang/protobuf v1.5.2 // indirect + google.golang.org/protobuf v1.30.0 // indirect +) diff --git a/doc/appengine/go.sum b/doc/appengine/go.sum new file mode 100644 index 0000000000..987d3692bb --- /dev/null +++ b/doc/appengine/go.sum @@ -0,0 +1,37 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine/v2 v2.0.5 h1:4C+F3Cd3L2nWEfSmFEZDPjQvDwL8T0YCeZBysZifP3k= +google.golang.org/appengine/v2 v2.0.5/go.mod h1:WoEXGoXNfa0mLvaH5sV3ZSGXwVmy8yf7Z1JKf3J3wLI= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/doc/appengine/src/crashpad-home/app.yaml b/doc/appengine/src/crashpad-home/app.yaml index 9af1577b12..2966ba0d1b 100644 --- a/doc/appengine/src/crashpad-home/app.yaml +++ b/doc/appengine/src/crashpad-home/app.yaml @@ -12,7 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -runtime: go111 +runtime: go121 +app_engine_apis: true handlers: - url: /.* diff --git a/doc/appengine/src/crashpad-home/main.go b/doc/appengine/src/crashpad-home/main.go index d988af3ceb..dced1e8001 100644 --- a/doc/appengine/src/crashpad-home/main.go +++ b/doc/appengine/src/crashpad-home/main.go @@ -25,9 +25,9 @@ import ( "strings" "time" - "google.golang.org/appengine" - "google.golang.org/appengine/memcache" - "google.golang.org/appengine/urlfetch" + "google.golang.org/appengine/v2" + "google.golang.org/appengine/v2/memcache" + "google.golang.org/appengine/v2/urlfetch" ) func main() { diff --git a/handler/crash_report_upload_thread.cc b/handler/crash_report_upload_thread.cc index 7cea398e1b..991013a264 100644 --- a/handler/crash_report_upload_thread.cc +++ b/handler/crash_report_upload_thread.cc @@ -239,7 +239,7 @@ void CrashReportUploadThread::ProcessPendingReport( return; case CrashReportDatabase::kCannotRequestUpload: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return; } diff --git a/handler/linux/cros_crash_report_exception_handler.cc b/handler/linux/cros_crash_report_exception_handler.cc index bfccd1f2ef..25637408df 100644 --- a/handler/linux/cros_crash_report_exception_handler.cc +++ b/handler/linux/cros_crash_report_exception_handler.cc @@ -44,14 +44,13 @@ const std::string GetProcessNameFromPid(pid_t pid) { // Symlink to process binary is at /proc/###/exe. std::string link_path = "/proc/" + std::to_string(pid) + "/exe"; - constexpr int kMaxSize = 4096; - std::unique_ptr buf(new char[kMaxSize]); - ssize_t size = readlink(link_path.c_str(), buf.get(), kMaxSize); - std::string result; + std::string result(4096, '\0'); + ssize_t size = readlink(link_path.c_str(), result.data(), result.size()); if (size < 0) { PLOG(ERROR) << "Failed to readlink " << link_path; + result.clear(); } else { - result.assign(buf.get(), size); + result.resize(size); size_t last_slash_pos = result.rfind('/'); if (last_slash_pos != std::string::npos) { result = result.substr(last_slash_pos + 1); diff --git a/handler/linux/cros_crash_report_exception_handler.h b/handler/linux/cros_crash_report_exception_handler.h index 864de93c4f..0ac0c29f8d 100644 --- a/handler/linux/cros_crash_report_exception_handler.h +++ b/handler/linux/cros_crash_report_exception_handler.h @@ -15,6 +15,8 @@ #ifndef CRASHPAD_HANDLER_LINUX_CROS_CRASH_REPORT_EXCEPTION_HANDLER_H_ #define CRASHPAD_HANDLER_LINUX_CROS_CRASH_REPORT_EXCEPTION_HANDLER_H_ +#include + #include #include diff --git a/handler/win/hanging_program.cc b/handler/win/hanging_program.cc index 72f903f21f..00eaf17162 100644 --- a/handler/win/hanging_program.cc +++ b/handler/win/hanging_program.cc @@ -40,13 +40,13 @@ DWORD WINAPI Thread1(LPVOID context) { Sleep(INFINITE); - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; } DWORD WINAPI Thread2(LPVOID dummy) { Sleep(INFINITE); - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; } @@ -65,7 +65,7 @@ DWORD WINAPI Thread3(LPVOID context) { if (!FreeLibrary(dll)) PLOG(FATAL) << "FreeLibrary"; - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; } diff --git a/infra/config/generated/commit-queue.cfg b/infra/config/generated/commit-queue.cfg index 95b31824f3..1a17e5c964 100644 --- a/infra/config/generated/commit-queue.cfg +++ b/infra/config/generated/commit-queue.cfg @@ -2,7 +2,7 @@ # Do not modify manually. # # For the schema of this file, see Config message: -# https://luci-config.appspot.com/schemas/projects:commit-queue.cfg +# https://config.luci.app/schemas/projects:commit-queue.cfg cq_status_host: "chromium-cq-status.appspot.com" submit_options { diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index a22e2411d9..0ab25244f6 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg @@ -2,7 +2,7 @@ # Do not modify manually. # # For the schema of this file, see BuildbucketCfg message: -# https://luci-config.appspot.com/schemas/projects:buildbucket.cfg +# https://config.luci.app/schemas/projects:buildbucket.cfg buckets { name: "ci" @@ -23,7 +23,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -57,7 +57,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -91,7 +91,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -124,7 +124,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -156,7 +156,7 @@ buckets { name: "crashpad_ios_arm64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -193,7 +193,7 @@ buckets { name: "crashpad_ios_arm64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -230,7 +230,7 @@ buckets { name: "crashpad_ios_x64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -266,7 +266,7 @@ buckets { name: "crashpad_ios_x64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -303,7 +303,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -336,7 +336,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -368,7 +368,7 @@ buckets { name: "crashpad_mac_x64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -404,7 +404,7 @@ buckets { name: "crashpad_mac_x64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -451,7 +451,7 @@ buckets { properties: '{' ' "$depot_tools/windows_sdk": {' - ' "version": "uploaded:2021-04-28"' + ' "version": "uploaded:2024-01-11"' ' },' ' "$gatekeeper": {' ' "group": "client.crashpad"' @@ -487,7 +487,7 @@ buckets { properties: '{' ' "$depot_tools/windows_sdk": {' - ' "version": "uploaded:2021-04-28"' + ' "version": "uploaded:2024-01-11"' ' },' ' "$gatekeeper": {' ' "group": "client.crashpad"' @@ -537,7 +537,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -568,7 +568,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -599,7 +599,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -629,7 +629,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -658,7 +658,7 @@ buckets { name: "crashpad_ios_arm64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -692,7 +692,7 @@ buckets { name: "crashpad_ios_arm64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -726,7 +726,7 @@ buckets { name: "crashpad_ios_x64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -759,7 +759,7 @@ buckets { name: "crashpad_ios_x64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -793,7 +793,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -823,7 +823,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -852,7 +852,7 @@ buckets { name: "crashpad_mac_x64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -885,7 +885,7 @@ buckets { name: "crashpad_mac_x64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-12" + dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -929,7 +929,7 @@ buckets { properties: '{' ' "$depot_tools/windows_sdk": {' - ' "version": "uploaded:2021-04-28"' + ' "version": "uploaded:2024-01-11"' ' },' ' "$kitchen": {' ' "devshell": true,' @@ -962,7 +962,7 @@ buckets { properties: '{' ' "$depot_tools/windows_sdk": {' - ' "version": "uploaded:2021-04-28"' + ' "version": "uploaded:2024-01-11"' ' },' ' "$kitchen": {' ' "devshell": true,' diff --git a/infra/config/generated/luci-logdog.cfg b/infra/config/generated/luci-logdog.cfg index adc75bef49..01a391261d 100644 --- a/infra/config/generated/luci-logdog.cfg +++ b/infra/config/generated/luci-logdog.cfg @@ -2,7 +2,7 @@ # Do not modify manually. # # For the schema of this file, see ProjectConfig message: -# https://luci-config.appspot.com/schemas/projects:luci-logdog.cfg +# https://config.luci.app/schemas/projects:luci-logdog.cfg reader_auth_groups: "all" writer_auth_groups: "luci-logdog-chromium-writers" diff --git a/infra/config/generated/luci-milo.cfg b/infra/config/generated/luci-milo.cfg index 6c891b14d5..9a78f93fb9 100644 --- a/infra/config/generated/luci-milo.cfg +++ b/infra/config/generated/luci-milo.cfg @@ -2,7 +2,7 @@ # Do not modify manually. # # For the schema of this file, see Project message: -# https://luci-config.appspot.com/schemas/projects:luci-milo.cfg +# https://config.luci.app/schemas/projects:luci-milo.cfg consoles { id: "main" diff --git a/infra/config/generated/luci-scheduler.cfg b/infra/config/generated/luci-scheduler.cfg index a2251eb899..6e6e8e19cf 100644 --- a/infra/config/generated/luci-scheduler.cfg +++ b/infra/config/generated/luci-scheduler.cfg @@ -2,7 +2,7 @@ # Do not modify manually. # # For the schema of this file, see ProjectConfig message: -# https://luci-config.appspot.com/schemas/projects:luci-scheduler.cfg +# https://config.luci.app/schemas/projects:luci-scheduler.cfg job { id: "crashpad_fuchsia_arm64_dbg" diff --git a/infra/config/generated/project.cfg b/infra/config/generated/project.cfg index d40ae0db55..59369e1839 100644 --- a/infra/config/generated/project.cfg +++ b/infra/config/generated/project.cfg @@ -2,12 +2,12 @@ # Do not modify manually. # # For the schema of this file, see ProjectCfg message: -# https://luci-config.appspot.com/schemas/projects:project.cfg +# https://config.luci.app/schemas/projects:project.cfg name: "crashpad" access: "group:all" lucicfg { - version: "1.32.1" + version: "1.43.6" package_dir: ".." config_dir: "generated" entry_point: "main.star" diff --git a/infra/config/generated/realms.cfg b/infra/config/generated/realms.cfg index 8dc05f6b5a..b7abb3eb3e 100644 --- a/infra/config/generated/realms.cfg +++ b/infra/config/generated/realms.cfg @@ -2,7 +2,7 @@ # Do not modify manually. # # For the schema of this file, see RealmsCfg message: -# https://luci-config.appspot.com/schemas/projects:realms.cfg +# https://config.luci.app/schemas/projects:realms.cfg realms { name: "@root" diff --git a/infra/config/main.star b/infra/config/main.star index ae0e8fc3b1..3c719e9294 100755 --- a/infra/config/main.star +++ b/infra/config/main.star @@ -156,13 +156,13 @@ def crashpad_dimensions(platform, bucket): dimensions["pool"] = "luci.flex." + bucket if platform == "fuchsia": - dimensions["os"] = "Ubuntu-18.04" + dimensions["os"] = "Ubuntu-22.04" elif platform == "ios": - dimensions["os"] = "Mac-12" + dimensions["os"] = "Mac-13|Mac-14" elif platform == "linux": - dimensions["os"] = "Ubuntu-18.04" + dimensions["os"] = "Ubuntu-22.04" elif platform == "mac": - dimensions["os"] = "Mac-12" + dimensions["os"] = "Mac-13|Mac-14" elif platform == "win": dimensions["os"] = "Windows-10" @@ -184,7 +184,7 @@ def crashpad_properties(platform, cpu, config, bucket): if platform == "win": properties["$depot_tools/windows_sdk"] = { - "version": "uploaded:2021-04-28", + "version": "uploaded:2024-01-11", } if bucket == "ci": diff --git a/minidump/minidump_context_writer.cc b/minidump/minidump_context_writer.cc index 12942c1845..4a6130b63e 100644 --- a/minidump/minidump_context_writer.cc +++ b/minidump/minidump_context_writer.cc @@ -367,36 +367,11 @@ size_t MinidumpContextAMD64Writer::ContextSize() const { bool MinidumpXSaveAMD64CetU::InitializeFromSnapshot( const CPUContextX86_64* context_snapshot) { -#ifdef SENTRY_DISABLED - DCHECK_EQ(context_snapshot->xstate.cet_u.cetmsr, 1ull); -#else - // TODO(supervacuus): this DCHECK led to multiple user inquiries because it - // ends up killing the crashpad_handler (when using a DEBUG build) which in - // turn keeps the crashpad client waiting indefinitely. - // - // It seems that crashpad devs put a DCHECK here because they already check - // at the call-site that the CET_U flag is enabled in the XSAVE feature set. - // However, that this flag is set, only means that the CET_U registers in - // XSAVE are valid, not necessarily that the SH_STK_EN bit is set. - // - // I couldn't find anything in the Intel (SDM 13.1) or AMD (PR 11.5.2, - // 18.11/12/13) CET/SS spec that would signal that SH_STK_EN(=cetmsr[0]) - // cannot be 0 at this point. Ideally, if SH_STK_EN is not set, then SSP - // should be set to 0 too (which means both are in their initial state). But - // even that should not lead to fatally exit the crashpad_handler (even in - // DEBUG), but rather produce a log and result in something that can be - // analysed in the backend. - // - // Any validation based on these register contents must check SH_STK_EN - // anyway or check SSP for !NULL and as a valid base like it is done here: - // https://chromium.googlesource.com/crashpad/crashpad/+/6278690abe6ef0dda047e67dc1d0c49ce7af3811/snapshot/win/thread_snapshot_win.cc#130 - if (!(context_snapshot->xstate.cet_u.cetmsr & 1ull)) { - LOG(WARNING) << "CET MSR enabled flag is not set (" - << context_snapshot->xstate.cet_u.cetmsr - << "); SSP = " - << context_snapshot->xstate.cet_u.ssp; - } -#endif + // Exception records do not carry CET registers but we have to provide the + // same shaped context for threads and exception contexts, so both 0 (no ssp + // present) and 1 (ssp present) are expected. + DCHECK(context_snapshot->xstate.cet_u.cetmsr == 0ull || + context_snapshot->xstate.cet_u.cetmsr == 1ull); cet_u_.cetmsr = context_snapshot->xstate.cet_u.cetmsr; cet_u_.ssp = context_snapshot->xstate.cet_u.ssp; return true; diff --git a/minidump/minidump_context_writer_test.cc b/minidump/minidump_context_writer_test.cc index 9eebe81b29..8eaae83148 100644 --- a/minidump/minidump_context_writer_test.cc +++ b/minidump/minidump_context_writer_test.cc @@ -56,7 +56,7 @@ class TestTypeNames { if (std::is_same()) { return "RVA64"; } - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return ""; } }; diff --git a/minidump/minidump_exception_writer.cc b/minidump/minidump_exception_writer.cc index 3057c6a745..cd3a139d9f 100644 --- a/minidump/minidump_exception_writer.cc +++ b/minidump/minidump_exception_writer.cc @@ -34,13 +34,19 @@ MinidumpExceptionWriter::~MinidumpExceptionWriter() { void MinidumpExceptionWriter::InitializeFromSnapshot( const ExceptionSnapshot* exception_snapshot, - const MinidumpThreadIDMap& thread_id_map) { + const MinidumpThreadIDMap& thread_id_map, + bool allow_missing_thread_id_from_map) { DCHECK_EQ(state(), kStateMutable); DCHECK(!context_); auto thread_id_it = thread_id_map.find(exception_snapshot->ThreadID()); - DCHECK(thread_id_it != thread_id_map.end()); - SetThreadID(thread_id_it->second); + bool thread_id_missing = thread_id_it == thread_id_map.end(); + if (allow_missing_thread_id_from_map && thread_id_missing) { + SetThreadID(static_cast(exception_snapshot->ThreadID())); + } else { + DCHECK(!thread_id_missing); + SetThreadID(thread_id_it->second); + } SetExceptionCode(exception_snapshot->Exception()); SetExceptionFlags(exception_snapshot->ExceptionInfo()); diff --git a/minidump/minidump_exception_writer.h b/minidump/minidump_exception_writer.h index 8e6847e98f..4c71112721 100644 --- a/minidump/minidump_exception_writer.h +++ b/minidump/minidump_exception_writer.h @@ -50,12 +50,17 @@ class MinidumpExceptionWriter final : public internal::MinidumpStreamWriter { //! \param[in] thread_id_map A MinidumpThreadIDMap to be consulted to //! determine the 32-bit minidump thread ID to use for the thread //! identified by \a exception_snapshot. + //! \param[in] allow_missing_thread_id_from_map Whether it is valid + //! for \a exception_snapshot->ThreadID() to be absent from the + //! \a thread_id_map, such as in an incomplete iOS intermediate dump. When + //! false a missing thread id is considered invalid and will DCHECK. //! //! \note Valid in #kStateMutable. No mutator methods may be called before //! this method, and it is not normally necessary to call any mutator //! methods after this method. void InitializeFromSnapshot(const ExceptionSnapshot* exception_snapshot, - const MinidumpThreadIDMap& thread_id_map); + const MinidumpThreadIDMap& thread_id_map, + bool allow_missing_thread_id_from_map); //! \brief Arranges for MINIDUMP_EXCEPTION_STREAM::ThreadContext to point to //! the CPU context to be written by \a context. diff --git a/minidump/minidump_exception_writer_test.cc b/minidump/minidump_exception_writer_test.cc index 9b5e1f9f9c..06a921eaa4 100644 --- a/minidump/minidump_exception_writer_test.cc +++ b/minidump/minidump_exception_writer_test.cc @@ -235,7 +235,10 @@ TEST(MinidumpExceptionWriter, InitializeFromSnapshot) { thread_id_map[kThreadID] = expect_exception.ThreadId; auto exception_writer = std::make_unique(); - exception_writer->InitializeFromSnapshot(&exception_snapshot, thread_id_map); + exception_writer->InitializeFromSnapshot( + &exception_snapshot, + thread_id_map, + /*allow_missing_thread_id_from_map=*/false); MinidumpFileWriter minidump_file_writer; ASSERT_TRUE(minidump_file_writer.AddStream(std::move(exception_writer))); diff --git a/minidump/minidump_file_writer.cc b/minidump/minidump_file_writer.cc index 29a9e5f0e3..47235c7082 100644 --- a/minidump/minidump_file_writer.cc +++ b/minidump/minidump_file_writer.cc @@ -18,6 +18,7 @@ #include "base/check_op.h" #include "base/logging.h" +#include "build/build_config.h" #include "minidump/minidump_crashpad_info_writer.h" #include "minidump/minidump_exception_writer.h" #include "minidump/minidump_handle_writer.h" @@ -117,7 +118,16 @@ void MinidumpFileWriter::InitializeFromSnapshot( const ExceptionSnapshot* exception_snapshot = process_snapshot->Exception(); if (exception_snapshot) { auto exception = std::make_unique(); - exception->InitializeFromSnapshot(exception_snapshot, thread_id_map); +#if BUILDFLAG(IS_IOS) + // It's expected that iOS intermediate dumps can be written with missing + // information, but it's better to try and report as much as possible + // rather than drop the incomplete minidump. + constexpr bool allow_missing_thread_id_from_map = true; +#else + constexpr bool allow_missing_thread_id_from_map = false; +#endif + exception->InitializeFromSnapshot( + exception_snapshot, thread_id_map, allow_missing_thread_id_from_map); add_stream_result = AddStream(std::move(exception)); DCHECK(add_stream_result); } diff --git a/minidump/minidump_string_writer_test.cc b/minidump/minidump_string_writer_test.cc index 1487b1386c..573eac6996 100644 --- a/minidump/minidump_string_writer_test.cc +++ b/minidump/minidump_string_writer_test.cc @@ -42,7 +42,7 @@ class TestTypeNames { if (std::is_same()) { return "RVA64"; } - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return ""; } }; diff --git a/minidump/minidump_system_info_writer.cc b/minidump/minidump_system_info_writer.cc index e2ab775ae7..9fe3ac0e6b 100644 --- a/minidump/minidump_system_info_writer.cc +++ b/minidump/minidump_system_info_writer.cc @@ -136,7 +136,7 @@ void MinidumpSystemInfoWriter::InitializeFromSnapshot( cpu_architecture = kMinidumpCPUArchitectureRISCV64Breakpad; break; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); cpu_architecture = kMinidumpCPUArchitectureUnknown; break; } @@ -185,7 +185,7 @@ void MinidumpSystemInfoWriter::InitializeFromSnapshot( operating_system = kMinidumpOSIOS; break; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); operating_system = kMinidumpOSUnknown; break; } diff --git a/snapshot/BUILD.gn b/snapshot/BUILD.gn index a364f95615..2ae944c3e8 100644 --- a/snapshot/BUILD.gn +++ b/snapshot/BUILD.gn @@ -507,7 +507,8 @@ crashpad_loadable_module("crashpad_snapshot_test_module") { "../client", ] if (crashpad_is_in_fuchsia) { - # TODO(fxbug.dev/108368): Remove this once the underlying issue is addressed. + # TODO(fxbug.dev/42059784): Remove this once the underlying issue is + # addressed. exclude_toolchain_tags = [ "hwasan" ] } } @@ -526,7 +527,8 @@ crashpad_loadable_module("crashpad_snapshot_test_module_large") { deps += [ "$mini_chromium_source_parent:base" ] if (crashpad_is_in_fuchsia) { - # TODO(fxbug.dev/108368): Remove this once the underlying issue is addressed. + # TODO(fxbug.dev/42059784): Remove this once the underlying issue is + # addressed. exclude_toolchain_tags = [ "hwasan" ] } } @@ -545,7 +547,8 @@ crashpad_loadable_module("crashpad_snapshot_test_module_small") { deps += [ "$mini_chromium_source_parent:base" ] if (crashpad_is_in_fuchsia) { - # TODO(fxbug.dev/108368): Remove this once the underlying issue is addressed. + # TODO(fxbug.dev/42059784): Remove this once the underlying issue is + # addressed. exclude_toolchain_tags = [ "hwasan" ] } } @@ -560,7 +563,8 @@ if ((crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) && ldflags = [ "-Wl,--hash-style=both" ] if (crashpad_is_in_fuchsia) { - # TODO(fxbug.dev/108368): Remove this once the underlying issue is addressed. + # TODO(fxbug.dev/42059784): Remove this once the underlying issue is + # addressed. exclude_toolchain_tags = [ "hwasan" ] } } diff --git a/snapshot/capture_memory.cc b/snapshot/capture_memory.cc index c1c6fba58f..f2ff5d74bb 100644 --- a/snapshot/capture_memory.cc +++ b/snapshot/capture_memory.cc @@ -22,9 +22,10 @@ #include #include -#include +#include "base/containers/heap_array.h" #include "base/logging.h" +#include "build/build_config.h" #include "snapshot/memory_snapshot.h" namespace crashpad { @@ -140,16 +141,16 @@ void CaptureMemory::PointedToByMemoryRange(const MemorySnapshot& memory, return; } - std::unique_ptr buffer(new uint8_t[memory.Size()]); - if (!delegate->ReadMemory(memory.Address(), memory.Size(), buffer.get())) { + auto buffer = base::HeapArray::Uninit(memory.Size()); + if (!delegate->ReadMemory(memory.Address(), memory.Size(), buffer.data())) { LOG(ERROR) << "ReadMemory"; return; } if (delegate->Is64Bit()) - CaptureAtPointersInRange(buffer.get(), memory.Size(), delegate); + CaptureAtPointersInRange(buffer.data(), buffer.size(), delegate); else - CaptureAtPointersInRange(buffer.get(), memory.Size(), delegate); + CaptureAtPointersInRange(buffer.data(), buffer.size(), delegate); } } // namespace internal diff --git a/snapshot/cpu_context.cc b/snapshot/cpu_context.cc index 492a0f7f91..71bf4ace4c 100644 --- a/snapshot/cpu_context.cc +++ b/snapshot/cpu_context.cc @@ -174,7 +174,7 @@ uint64_t CPUContext::InstructionPointer() const { case kCPUArchitectureRISCV64: return riscv64->pc; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return ~0ull; } } @@ -192,7 +192,7 @@ uint64_t CPUContext::StackPointer() const { case kCPUArchitectureRISCV64: return riscv64->regs[1]; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return ~0ull; } } @@ -202,12 +202,12 @@ uint64_t CPUContext::ShadowStackPointer() const { case kCPUArchitectureX86: case kCPUArchitectureARM: case kCPUArchitectureARM64: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; case kCPUArchitectureX86_64: return x86_64->xstate.cet_u.ssp; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return ~0ull; } } @@ -221,7 +221,7 @@ bool CPUContext::HasShadowStack() const { case kCPUArchitectureX86_64: return x86_64->xstate.cet_u.cetmsr != 0; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; } } @@ -238,7 +238,7 @@ bool CPUContext::Is64Bit() const { case kCPUArchitectureMIPSEL: return false; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; } } diff --git a/snapshot/fuchsia/exception_snapshot_fuchsia.cc b/snapshot/fuchsia/exception_snapshot_fuchsia.cc index be71ca22ac..c595b92bde 100644 --- a/snapshot/fuchsia/exception_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/exception_snapshot_fuchsia.cc @@ -74,7 +74,7 @@ bool ExceptionSnapshotFuchsia::Initialize( #if defined(ARCH_CPU_X86_64) context_.architecture = kCPUArchitectureX86_64; context_.x86_64 = &context_arch_; - // TODO(fxbug.dev/5496): Add vector context. + // TODO(fxbug.dev/42132536): Add vector context. InitializeCPUContextX86_64( t->general_registers, t->fp_registers, context_.x86_64); #elif defined(ARCH_CPU_ARM64) diff --git a/snapshot/fuchsia/process_reader_fuchsia.cc b/snapshot/fuchsia/process_reader_fuchsia.cc index 5bf2acf7d2..8b10e2cccc 100644 --- a/snapshot/fuchsia/process_reader_fuchsia.cc +++ b/snapshot/fuchsia/process_reader_fuchsia.cc @@ -47,12 +47,12 @@ void GetStackRegions( #error Port #endif - // TODO(fxbug.dev/74897): make this work for stack overflows, e.g., by looking - // up using the initial stack pointer (sp) when the thread was created. Right - // now, it gets the stack by getting the mapping that contains the current sp. - // But in the case of stack overflows, the current sp is by definition outside - // of the stack so the mapping returned is not the stack and fails the type - // check, at least on arm64. + // TODO(fxbug.dev/42154629): make this work for stack overflows, e.g., by + // looking up using the initial stack pointer (sp) when the thread was + // created. Right now, it gets the stack by getting the mapping that contains + // the current sp. But in the case of stack overflows, the current sp is by + // definition outside of the stack so the mapping returned is not the stack + // and fails the type check, at least on arm64. zx_info_maps_t range_with_sp; if (!memory_map.FindMappingForAddress(sp, &range_with_sp)) { LOG(ERROR) << "stack pointer not found in mapping"; @@ -235,8 +235,8 @@ void ProcessReaderFuchsia::InitializeModules() { // Crashpad needs to use the same module name at run time for symbol // resolution to work properly. // - // TODO: https://fxbug.dev/6057 - once Crashpad switches to elf-search, the - // following overwrites won't be necessary as only shared libraries will + // TODO: https://fxbug.dev/42138764 - once Crashpad switches to elf-search, + // the following overwrites won't be necessary as only shared libraries will // have a soname at runtime, just like at build time. // // * For shared libraries, the soname is used as module name at build time, diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.cc b/snapshot/fuchsia/process_snapshot_fuchsia.cc index f1a7e7b19c..1f51a4c900 100644 --- a/snapshot/fuchsia/process_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/process_snapshot_fuchsia.cc @@ -114,7 +114,8 @@ crashpad::ProcessID ProcessSnapshotFuchsia::ProcessID() const { crashpad::ProcessID ProcessSnapshotFuchsia::ParentProcessID() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196 + // TODO(scottmg): https://crashpad.chromium.org/bug/196 + NOTREACHED_IN_MIGRATION(); return 0; } diff --git a/snapshot/fuchsia/system_snapshot_fuchsia.cc b/snapshot/fuchsia/system_snapshot_fuchsia.cc index 81a9d30184..a764e855a0 100644 --- a/snapshot/fuchsia/system_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/system_snapshot_fuchsia.cc @@ -75,7 +75,7 @@ uint32_t SystemSnapshotFuchsia::CPURevision() const { #if defined(ARCH_CPU_X86_64) return cpuid_.Revision(); #else - // TODO: https://fxbug.dev/5561 - Read actual revision. + // TODO: https://fxbug.dev/42133257 - Read actual revision. return 0; #endif } @@ -90,7 +90,7 @@ std::string SystemSnapshotFuchsia::CPUVendor() const { #if defined(ARCH_CPU_X86_64) return cpuid_.Vendor(); #else - // TODO: https://fxbug.dev/5561 - Read actual vendor. + // TODO: https://fxbug.dev/42133257 - Read actual vendor. return std::string(); #endif } @@ -108,7 +108,7 @@ uint32_t SystemSnapshotFuchsia::CPUX86Signature() const { #if defined(ARCH_CPU_X86_64) return cpuid_.Signature(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -118,7 +118,7 @@ uint64_t SystemSnapshotFuchsia::CPUX86Features() const { #if defined(ARCH_CPU_X86_64) return cpuid_.Features(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -128,7 +128,7 @@ uint64_t SystemSnapshotFuchsia::CPUX86ExtendedFeatures() const { #if defined(ARCH_CPU_X86_64) return cpuid_.ExtendedFeatures(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -137,7 +137,7 @@ uint32_t SystemSnapshotFuchsia::CPUX86Leaf7Features() const { #if defined(ARCH_CPU_X86_64) return cpuid_.Leaf7Features(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -147,7 +147,7 @@ bool SystemSnapshotFuchsia::CPUX86SupportsDAZ() const { #if defined(ARCH_CPU_X86_64) return cpuid_.SupportsDAZ(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; #endif } @@ -193,7 +193,7 @@ bool SystemSnapshotFuchsia::NXEnabled() const { #if defined(ARCH_CPU_X86_64) return cpuid_.NXEnabled(); #else - // TODO: https://fxbug.dev/5561 - Read actual NX bit value. + // TODO: https://fxbug.dev/42133257 - Read actual NX bit value. return false; #endif } diff --git a/snapshot/fuchsia/thread_snapshot_fuchsia.cc b/snapshot/fuchsia/thread_snapshot_fuchsia.cc index 759895254a..587e6a91f0 100644 --- a/snapshot/fuchsia/thread_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/thread_snapshot_fuchsia.cc @@ -40,7 +40,7 @@ bool ThreadSnapshotFuchsia::Initialize( #if defined(ARCH_CPU_X86_64) context_.architecture = kCPUArchitectureX86_64; context_.x86_64 = &context_arch_; - // TODO(fxbug.dev/5496): Add vector context. + // TODO(fxbug.dev/42132536): Add vector context. InitializeCPUContextX86_64( thread.general_registers, thread.fp_registers, context_.x86_64); #elif defined(ARCH_CPU_ARM64) diff --git a/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc b/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc index e34784540d..9f1852a61c 100644 --- a/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc +++ b/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc @@ -149,6 +149,33 @@ bool ExceptionSnapshotIOSIntermediateDump::InitializeFromSignal( GetDataValueFromMap(exception_data, Key::kSignalCode, &code); codes_.push_back(code); + const IOSIntermediateDumpList* thread_context_memory_regions = + GetListFromMap(exception_data, Key::kThreadContextMemoryRegions); + if (thread_context_memory_regions) { + for (auto& region : *thread_context_memory_regions) { + vm_address_t address; + const IOSIntermediateDumpData* region_data = + region->GetAsData(Key::kThreadContextMemoryRegionData); + if (!region_data) + continue; + if (GetDataValueFromMap( + region.get(), Key::kThreadContextMemoryRegionAddress, &address)) { + const std::vector& bytes = region_data->bytes(); + vm_size_t data_size = bytes.size(); + if (data_size == 0) + continue; + + const vm_address_t data = + reinterpret_cast(bytes.data()); + + auto memory = + std::make_unique(); + memory->Initialize(address, data, data_size); + extra_memory_.push_back(std::move(memory)); + } + } + } + INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -281,8 +308,11 @@ const std::vector& ExceptionSnapshotIOSIntermediateDump::Codes() std::vector ExceptionSnapshotIOSIntermediateDump::ExtraMemory() const { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return std::vector(); + std::vector extra_memory; + for (const auto& memory : extra_memory_) { + extra_memory.push_back(memory.get()); + } + return extra_memory; } void ExceptionSnapshotIOSIntermediateDump::LoadContextFromThread( diff --git a/snapshot/ios/exception_snapshot_ios_intermediate_dump.h b/snapshot/ios/exception_snapshot_ios_intermediate_dump.h index 90966df1f7..dc9d5954da 100644 --- a/snapshot/ios/exception_snapshot_ios_intermediate_dump.h +++ b/snapshot/ios/exception_snapshot_ios_intermediate_dump.h @@ -23,6 +23,7 @@ #include "build/build_config.h" #include "snapshot/cpu_context.h" #include "snapshot/exception_snapshot.h" +#include "snapshot/ios/memory_snapshot_ios_intermediate_dump.h" #include "util/ios/ios_intermediate_dump_map.h" #include "util/mach/mach_extensions.h" #include "util/misc/initialization_state_dcheck.h" @@ -106,6 +107,8 @@ class ExceptionSnapshotIOSIntermediateDump final : public ExceptionSnapshot { uintptr_t exception_address_; uint32_t exception_; uint32_t exception_info_; + std::vector> + extra_memory_; InitializationStateDcheck initialized_; }; diff --git a/snapshot/ios/process_snapshot_ios_intermediate_dump.cc b/snapshot/ios/process_snapshot_ios_intermediate_dump.cc index c502b3c024..609ea654cd 100644 --- a/snapshot/ios/process_snapshot_ios_intermediate_dump.cc +++ b/snapshot/ios/process_snapshot_ios_intermediate_dump.cc @@ -122,6 +122,9 @@ bool ProcessSnapshotIOSIntermediateDump::InitializeWithFileInterface( } system_.Initialize(system_info); + annotations_simple_map_["crashpad_uptime_ns"] = + std::to_string(system_.CrashpadUptime()); + // Threads const IOSIntermediateDumpList* thread_list = GetListFromMap(root_map, Key::kThreads); diff --git a/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc b/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc index 6d64b1d073..69cb43ed6b 100644 --- a/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc +++ b/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc @@ -160,6 +160,10 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { EXPECT_TRUE(writer->AddProperty(Key::kWired, &count)); EXPECT_TRUE(writer->AddProperty(Key::kFree, &count)); } + + uint64_t crashpad_report_time_nanos = 1234567890; + EXPECT_TRUE( + writer->AddProperty(Key::kCrashpadUptime, &crashpad_report_time_nanos)); } void WriteAnnotations(IOSIntermediateDumpWriter* writer, @@ -491,6 +495,9 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { ExpectModules( snapshot.Modules(), expect_module_path, expect_long_annotations); ExpectMachException(*snapshot.Exception()); + + auto map = snapshot.AnnotationsSimpleMap(); + EXPECT_EQ(map["crashpad_uptime_ns"], "1234567890"); } void CloseWriter() { EXPECT_TRUE(writer_->Close()); } @@ -570,6 +577,18 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, EmptySignalDump) { IOSIntermediateDumpWriter::ScopedMap map(writer(), Key::kSignalException); uint64_t thread_id = 1; EXPECT_TRUE(writer()->AddProperty(Key::kThreadID, &thread_id)); + { + IOSIntermediateDumpWriter::ScopedArray contextMemoryRegions( + writer(), Key::kThreadContextMemoryRegions); + IOSIntermediateDumpWriter::ScopedArrayMap memoryMap(writer()); + + std::string random_data("random_data"); + EXPECT_TRUE(writer()->AddProperty( + Key::kThreadContextMemoryRegionAddress, &thread_id)); + EXPECT_TRUE(writer()->AddProperty(Key::kThreadContextMemoryRegionData, + random_data.c_str(), + random_data.length())); + } } { IOSIntermediateDumpWriter::ScopedArray threadArray(writer(), @@ -582,6 +601,12 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, EmptySignalDump) { CloseWriter(); ProcessSnapshotIOSIntermediateDump process_snapshot; ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), annotations())); + EXPECT_EQ(process_snapshot.Exception()->ExtraMemory().size(), 1u); + ReadToString delegate; + for (auto memory : process_snapshot.Exception()->ExtraMemory()) { + memory->Read(&delegate); + EXPECT_STREQ(delegate.result.c_str(), "random_data"); + } EXPECT_FALSE(IsRegularFile(path())); EXPECT_TRUE(DumpSnapshot(process_snapshot)); } @@ -768,6 +793,22 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, FuzzTestCases) { EXPECT_TRUE(process_snapshot4.InitializeWithFilePath(fuzz_path, {})); } +TEST_F(ProcessSnapshotIOSIntermediateDumpTest, WriteNoThreads) { + { + IOSIntermediateDumpWriter::ScopedRootMap rootMap(writer()); + uint8_t version = 1; + EXPECT_TRUE(writer()->AddProperty(Key::kVersion, &version)); + WriteSystemInfo(writer()); + WriteProcessInfo(writer()); + WriteMachException(writer()); + } + CloseWriter(); + ProcessSnapshotIOSIntermediateDump process_snapshot; + ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), annotations())); + EXPECT_FALSE(IsRegularFile(path())); + EXPECT_TRUE(DumpSnapshot(process_snapshot)); +} + } // namespace } // namespace test } // namespace crashpad diff --git a/snapshot/ios/system_snapshot_ios_intermediate_dump.cc b/snapshot/ios/system_snapshot_ios_intermediate_dump.cc index 15f66992be..6a9f2c1c52 100644 --- a/snapshot/ios/system_snapshot_ios_intermediate_dump.cc +++ b/snapshot/ios/system_snapshot_ios_intermediate_dump.cc @@ -119,6 +119,8 @@ void SystemSnapshotIOSIntermediateDump::Initialize( } } + GetDataValueFromMap(system_data, Key::kCrashpadUptime, &crashpad_uptime_ns_); + INITIALIZATION_STATE_SET_VALID(initialized_); } @@ -249,5 +251,10 @@ uint64_t SystemSnapshotIOSIntermediateDump::AddressMask() const { return address_mask_; } +uint64_t SystemSnapshotIOSIntermediateDump::CrashpadUptime() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return crashpad_uptime_ns_; +} + } // namespace internal } // namespace crashpad diff --git a/snapshot/ios/system_snapshot_ios_intermediate_dump.h b/snapshot/ios/system_snapshot_ios_intermediate_dump.h index 6cc09ac78d..339139b7c7 100644 --- a/snapshot/ios/system_snapshot_ios_intermediate_dump.h +++ b/snapshot/ios/system_snapshot_ios_intermediate_dump.h @@ -75,6 +75,10 @@ class SystemSnapshotIOSIntermediateDump final : public SystemSnapshot { std::string* daylight_name) const override; uint64_t AddressMask() const override; + //! \brief Returns the number of nanoseconds between Crashpad initialization + //! and snapshot generation. + uint64_t CrashpadUptime() const; + private: std::string os_version_build_; std::string machine_description_; @@ -93,6 +97,7 @@ class SystemSnapshotIOSIntermediateDump final : public SystemSnapshot { std::string standard_name_; std::string daylight_name_; uint64_t address_mask_; + uint64_t crashpad_uptime_ns_; InitializationStateDcheck initialized_; }; diff --git a/snapshot/linux/exception_snapshot_linux_test.cc b/snapshot/linux/exception_snapshot_linux_test.cc index 94f45f1eb9..b351ccaa7f 100644 --- a/snapshot/linux/exception_snapshot_linux_test.cc +++ b/snapshot/linux/exception_snapshot_linux_test.cc @@ -66,8 +66,9 @@ void InitializeContext(NativeCPUContext* context) { void ExpectContext(const CPUContext& actual, const NativeCPUContext& expected) { EXPECT_EQ(actual.architecture, kCPUArchitectureX86); - EXPECT_EQ(actual.x86->eax, - bit_cast(expected.ucontext.uc_mcontext.gregs[REG_EAX])); + EXPECT_EQ( + actual.x86->eax, + base::bit_cast(expected.ucontext.uc_mcontext.gregs[REG_EAX])); for (unsigned int byte_offset = 0; byte_offset < sizeof(actual.x86->fxsave); ++byte_offset) { SCOPED_TRACE(base::StringPrintf("byte offset = %u\n", byte_offset)); @@ -87,7 +88,7 @@ void InitializeContext(NativeCPUContext* context) { void ExpectContext(const CPUContext& actual, const NativeCPUContext& expected) { EXPECT_EQ(actual.architecture, kCPUArchitectureX86_64); EXPECT_EQ(actual.x86_64->rax, - bit_cast(expected.uc_mcontext.gregs[REG_RAX])); + base::bit_cast(expected.uc_mcontext.gregs[REG_RAX])); for (unsigned int byte_offset = 0; byte_offset < sizeof(actual.x86_64->fxsave); ++byte_offset) { diff --git a/snapshot/linux/process_reader_linux_test.cc b/snapshot/linux/process_reader_linux_test.cc index a9cc11e1d2..9c008edc14 100644 --- a/snapshot/linux/process_reader_linux_test.cc +++ b/snapshot/linux/process_reader_linux_test.cc @@ -52,6 +52,7 @@ #include "util/misc/address_sanitizer.h" #include "util/misc/from_pointer_cast.h" #include "util/misc/memory_sanitizer.h" +#include "util/posix/scoped_mmap.h" #include "util/synchronization/semaphore.h" #if BUILDFLAG(IS_ANDROID) @@ -180,14 +181,21 @@ class TestThreadPool { << ErrnoMessage("pthread_attr_init"); if (stack_size > 0) { - void* stack_ptr; - errno = posix_memalign(&stack_ptr, getpagesize(), stack_size); - ASSERT_EQ(errno, 0) << ErrnoMessage("posix_memalign"); - - thread->stack.reset(reinterpret_cast(stack_ptr)); - - ASSERT_EQ(pthread_attr_setstack(&attr, thread->stack.get(), stack_size), - 0) + const size_t page_size = getpagesize(); + DCHECK_EQ(stack_size % page_size, 0u); + size_t stack_alloc_size = 2 * page_size + stack_size; + + ASSERT_TRUE(thread->stack.ResetMmap(nullptr, + stack_alloc_size, + PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, + 0)); + char* stack_ptr = thread->stack.addr_as() + page_size; + ASSERT_EQ(mprotect(stack_ptr, stack_size, PROT_READ | PROT_WRITE), 0) + << "mprotect"; + + ASSERT_EQ(pthread_attr_setstack(&attr, stack_ptr, stack_size), 0) << ErrnoMessage("pthread_attr_setstack"); thread->expectation.max_stack_size = stack_size; } @@ -238,7 +246,7 @@ class TestThreadPool { pthread_t pthread; ThreadExpectation expectation; - std::unique_ptr stack; + ScopedMmap stack; Semaphore ready_semaphore; Semaphore exit_semaphore; pid_t tid; diff --git a/snapshot/linux/system_snapshot_linux.cc b/snapshot/linux/system_snapshot_linux.cc index b32f22d784..3eb91b4f40 100644 --- a/snapshot/linux/system_snapshot_linux.cc +++ b/snapshot/linux/system_snapshot_linux.cc @@ -276,7 +276,7 @@ uint32_t SystemSnapshotLinux::CPUX86Signature() const { #if defined(ARCH_CPU_X86_FAMILY) return cpuid_.Signature(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -286,7 +286,7 @@ uint64_t SystemSnapshotLinux::CPUX86Features() const { #if defined(ARCH_CPU_X86_FAMILY) return cpuid_.Features(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -296,7 +296,7 @@ uint64_t SystemSnapshotLinux::CPUX86ExtendedFeatures() const { #if defined(ARCH_CPU_X86_FAMILY) return cpuid_.ExtendedFeatures(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -306,7 +306,7 @@ uint32_t SystemSnapshotLinux::CPUX86Leaf7Features() const { #if defined(ARCH_CPU_X86_FAMILY) return cpuid_.Leaf7Features(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -316,7 +316,7 @@ bool SystemSnapshotLinux::CPUX86SupportsDAZ() const { #if defined(ARCH_CPU_X86_FAMILY) return cpuid_.SupportsDAZ(); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; #endif // ARCH_CPU_X86_FMAILY } diff --git a/snapshot/mac/cpu_context_mac.cc b/snapshot/mac/cpu_context_mac.cc index 69a54bafd0..c8eddfcd3d 100644 --- a/snapshot/mac/cpu_context_mac.cc +++ b/snapshot/mac/cpu_context_mac.cc @@ -196,7 +196,7 @@ thread_state_flavor_t InitializeCPUContextX86Flavor( } default: { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return THREAD_STATE_NONE; } } @@ -377,7 +377,7 @@ thread_state_flavor_t InitializeCPUContextX86_64Flavor( } default: { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return THREAD_STATE_NONE; } } @@ -553,7 +553,7 @@ thread_state_flavor_t InitializeCPUContextARM64Flavor( } default: { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return THREAD_STATE_NONE; } } diff --git a/snapshot/mac/process_types.cc b/snapshot/mac/process_types.cc index bc30317369..b977b78f36 100644 --- a/snapshot/mac/process_types.cc +++ b/snapshot/mac/process_types.cc @@ -19,8 +19,8 @@ #include #include -#include +#include "base/containers/heap_array.h" #include "snapshot/mac/process_types/internal.h" #include "util/process/process_memory_mac.h" @@ -245,8 +245,9 @@ inline void Assign(UInt64Array4* destination, mach_vm_address_t address, \ size_t count, \ struct_name* generic) { \ - std::unique_ptr specific(new T[count]); \ - if (!T::ReadArrayInto(process_reader, address, count, &specific[0])) { \ + auto specific = base::HeapArray::Uninit(count); \ + if (!T::ReadArrayInto( \ + process_reader, address, specific.size(), specific.data())) { \ return false; \ } \ for (size_t index = 0; index < count; ++index) { \ diff --git a/snapshot/mac/system_snapshot_mac.cc b/snapshot/mac/system_snapshot_mac.cc index 334627ffe4..933626fc66 100644 --- a/snapshot/mac/system_snapshot_mac.cc +++ b/snapshot/mac/system_snapshot_mac.cc @@ -204,7 +204,7 @@ uint32_t SystemSnapshotMac::CPUX86Signature() const { #if defined(ARCH_CPU_X86_FAMILY) return ReadIntSysctlByName("machdep.cpu.signature", 0); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -215,7 +215,7 @@ uint64_t SystemSnapshotMac::CPUX86Features() const { #if defined(ARCH_CPU_X86_FAMILY) return ReadIntSysctlByName("machdep.cpu.feature_bits", 0); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -226,7 +226,7 @@ uint64_t SystemSnapshotMac::CPUX86ExtendedFeatures() const { #if defined(ARCH_CPU_X86_FAMILY) return ReadIntSysctlByName("machdep.cpu.extfeature_bits", 0); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -251,7 +251,7 @@ uint32_t SystemSnapshotMac::CPUX86Leaf7Features() const { CallCPUID(7, &eax, &ebx, &ecx, &edx); return ebx; #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -290,7 +290,7 @@ bool SystemSnapshotMac::CPUX86SupportsDAZ() const { // Test the DAZ bit. return fxsave.mxcsr_mask & (1 << 6); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; #endif } diff --git a/snapshot/memory_snapshot_generic.h b/snapshot/memory_snapshot_generic.h index 0187ada68e..dd03bdbb89 100644 --- a/snapshot/memory_snapshot_generic.h +++ b/snapshot/memory_snapshot_generic.h @@ -18,6 +18,7 @@ #include #include +#include "base/containers/heap_array.h" #include "base/logging.h" #include "base/numerics/safe_math.h" #include "snapshot/memory_snapshot.h" @@ -79,11 +80,11 @@ class MemorySnapshotGeneric final : public MemorySnapshot { return delegate->MemorySnapshotDelegateRead(nullptr, size_); } - std::unique_ptr buffer(new uint8_t[size_]); - if (!process_memory_->Read(address_, size_, buffer.get())) { + auto buffer = base::HeapArray::Uninit(size_); + if (!process_memory_->Read(address_, buffer.size(), buffer.data())) { return false; } - return delegate->MemorySnapshotDelegateRead(buffer.get(), size_); + return delegate->MemorySnapshotDelegateRead(buffer.data(), buffer.size()); } const MemorySnapshot* MergeWithOtherSnapshot( diff --git a/snapshot/minidump/module_snapshot_minidump.cc b/snapshot/minidump/module_snapshot_minidump.cc index 50e5ea8597..8d461b3570 100644 --- a/snapshot/minidump/module_snapshot_minidump.cc +++ b/snapshot/minidump/module_snapshot_minidump.cc @@ -228,14 +228,14 @@ std::vector ModuleSnapshotMinidump::AnnotationObjects() std::set> ModuleSnapshotMinidump::ExtraMemoryRanges() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return std::set>(); } std::vector ModuleSnapshotMinidump::CustomMinidumpStreams() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return std::vector(); } diff --git a/snapshot/minidump/process_snapshot_minidump.cc b/snapshot/minidump/process_snapshot_minidump.cc index 03f321719b..472e025764 100644 --- a/snapshot/minidump/process_snapshot_minidump.cc +++ b/snapshot/minidump/process_snapshot_minidump.cc @@ -135,7 +135,7 @@ crashpad::ProcessID ProcessSnapshotMinidump::ProcessID() const { crashpad::ProcessID ProcessSnapshotMinidump::ParentProcessID() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return 0; } @@ -208,7 +208,7 @@ std::vector ProcessSnapshotMinidump::Modules() const { std::vector ProcessSnapshotMinidump::UnloadedModules() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return unloaded_modules_; } @@ -229,7 +229,7 @@ std::vector ProcessSnapshotMinidump::MemoryMap() std::vector ProcessSnapshotMinidump::Handles() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return std::vector(); } diff --git a/snapshot/minidump/system_snapshot_minidump.cc b/snapshot/minidump/system_snapshot_minidump.cc index 58bd7b3647..cfdedadf2d 100644 --- a/snapshot/minidump/system_snapshot_minidump.cc +++ b/snapshot/minidump/system_snapshot_minidump.cc @@ -100,36 +100,36 @@ std::string SystemSnapshotMinidump::CPUVendor() const { void SystemSnapshotMinidump::CPUFrequency(uint64_t* current_hz, uint64_t* max_hz) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 } uint32_t SystemSnapshotMinidump::CPUX86Signature() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // 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 + NOTREACHED_IN_MIGRATION(); // 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 + NOTREACHED_IN_MIGRATION(); // 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 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return 0; } bool SystemSnapshotMinidump::CPUX86SupportsDAZ() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return false; } @@ -178,13 +178,13 @@ std::string SystemSnapshotMinidump::OSVersionFull() const { std::string SystemSnapshotMinidump::MachineDescription() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // 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 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return false; } @@ -194,12 +194,12 @@ void SystemSnapshotMinidump::TimeZone(DaylightSavingTimeStatus* dst_status, std::string* standard_name, std::string* daylight_name) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 } uint64_t SystemSnapshotMinidump::AddressMask() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + NOTREACHED_IN_MIGRATION(); // https://crashpad.chromium.org/bug/10 return 0; } diff --git a/snapshot/sanitized/module_snapshot_sanitized.cc b/snapshot/sanitized/module_snapshot_sanitized.cc index 0ad2ee9754..c76722683d 100644 --- a/snapshot/sanitized/module_snapshot_sanitized.cc +++ b/snapshot/sanitized/module_snapshot_sanitized.cc @@ -99,9 +99,11 @@ ModuleSnapshotSanitized::AnnotationsSimpleMap() const { std::map annotations = snapshot_->AnnotationsSimpleMap(); if (allowed_annotations_) { - for (auto kv = annotations.begin(); kv != annotations.end(); ++kv) { - if (!KeyIsAllowed(kv->first, *allowed_annotations_)) { - annotations.erase(kv); + for (auto kv = annotations.begin(); kv != annotations.end();) { + if (KeyIsAllowed(kv->first, *allowed_annotations_)) { + ++kv; + } else { + kv = annotations.erase(kv); } } } diff --git a/snapshot/sanitized/process_snapshot_sanitized_test.cc b/snapshot/sanitized/process_snapshot_sanitized_test.cc index 329c3c760f..e9a835b1fb 100644 --- a/snapshot/sanitized/process_snapshot_sanitized_test.cc +++ b/snapshot/sanitized/process_snapshot_sanitized_test.cc @@ -129,7 +129,7 @@ void ChildTestFunction() { CRASHPAD_CHILD_TEST_MAIN(ChildToBeSanitized) { ChildTestFunction(); - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return EXIT_SUCCESS; } diff --git a/snapshot/snapshot_constants.h b/snapshot/snapshot_constants.h index d33d30a62d..2006e7b5c6 100644 --- a/snapshot/snapshot_constants.h +++ b/snapshot/snapshot_constants.h @@ -21,7 +21,7 @@ namespace crashpad { //! a client process. //! //! \note This maximum was chosen arbitrarily and may change in the future. -constexpr size_t kMaxNumberOfAnnotations = 200; +constexpr size_t kMaxNumberOfAnnotations = 400; } // namespace crashpad diff --git a/snapshot/win/pe_image_reader.cc b/snapshot/win/pe_image_reader.cc index e86c06e8cf..5ca53f2f24 100644 --- a/snapshot/win/pe_image_reader.cc +++ b/snapshot/win/pe_image_reader.cc @@ -19,8 +19,8 @@ #include #include -#include +#include "base/containers/heap_array.h" #include "base/logging.h" #include "base/strings/stringprintf.h" #include "client/crashpad_info.h" @@ -183,17 +183,17 @@ bool PEImageReader::DebugDirectoryInformation(UUID* uuid, continue; } - std::unique_ptr data(new char[debug_directory.SizeOfData]); + auto data = base::HeapArray::Uninit(debug_directory.SizeOfData); if (!module_subrange_reader_.ReadMemory( Address() + debug_directory.AddressOfRawData, - debug_directory.SizeOfData, - data.get())) { + data.size(), + data.data())) { LOG(WARNING) << "could not read debug directory from " << module_subrange_reader_.name(); return false; } - if (*reinterpret_cast(data.get()) != + if (*reinterpret_cast(data.data()) != CodeViewRecordPDB70::kSignature) { LOG(WARNING) << "encountered non-7.0 CodeView debug record in " << module_subrange_reader_.name(); @@ -201,7 +201,7 @@ bool PEImageReader::DebugDirectoryInformation(UUID* uuid, } CodeViewRecordPDB70* codeview = - reinterpret_cast(data.get()); + reinterpret_cast(data.data()); *uuid = codeview->uuid; *age = codeview->age; // This is a NUL-terminated string encoded in the codepage of the system diff --git a/snapshot/win/system_snapshot_win.cc b/snapshot/win/system_snapshot_win.cc index 1eaad8a968..65d06b27fe 100644 --- a/snapshot/win/system_snapshot_win.cc +++ b/snapshot/win/system_snapshot_win.cc @@ -360,7 +360,7 @@ uint32_t SystemSnapshotWin::CPUX86Signature() const { __cpuid(cpu_info, 1); return cpu_info[0]; #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -375,7 +375,7 @@ uint64_t SystemSnapshotWin::CPUX86Features() const { return (static_cast(cpu_info[2]) << 32) | static_cast(cpu_info[3]); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -391,7 +391,7 @@ uint64_t SystemSnapshotWin::CPUX86ExtendedFeatures() const { return (static_cast(cpu_info[2]) << 32) | static_cast(cpu_info[3]); #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -410,7 +410,7 @@ uint32_t SystemSnapshotWin::CPUX86Leaf7Features() const { __cpuidex(cpu_info, 7, 0); return cpu_info[1]; #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } @@ -441,7 +441,7 @@ bool SystemSnapshotWin::CPUX86SupportsDAZ() const { // Test the DAZ bit. return (mxcsr_mask & (1 << 6)) != 0; #else - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return 0; #endif } diff --git a/test/ios/crash_type_xctest.mm b/test/ios/crash_type_xctest.mm index 8d4038db0f..646c9dfd4d 100644 --- a/test/ios/crash_type_xctest.mm +++ b/test/ios/crash_type_xctest.mm @@ -14,6 +14,7 @@ #import #include +#include #include @@ -21,9 +22,30 @@ #include "build/build_config.h" #include "client/length_delimited_ring_buffer.h" #import "test/ios/host/cptest_shared_object.h" +#include "util/mac/sysctl.h" #include "util/mach/exception_types.h" #include "util/mach/mach_extensions.h" +namespace crashpad { +namespace { + +#if TARGET_OS_SIMULATOR +// macOS 14.0 is 23A344, macOS 13.6.5 is 22G621, so if the first two characters +// in the kern.osversion are > 22, this build will reproduce the simulator bug +// in crbug.com/328282286 +bool IsMacOSVersion143OrGreaterAndiOS16OrLess() { + if (__builtin_available(iOS 17, *)) { + return false; + } + + std::string build = crashpad::ReadStringSysctlByName("kern.osversion", false); + return std::stoi(build.substr(0, 2)) > 22; +} +#endif + +} // namespace +} // namespace crashpad + @interface CPTestTestCase : XCTestCase { XCUIApplication* app_; CPTestSharedObject* rootObject_; @@ -148,7 +170,10 @@ - (void)testException { [rootObject_ crashException]; // After https://reviews.llvm.org/D141222 exceptions call // __libcpp_verbose_abort, which Chromium sets to `brk 0` in release. -#if defined(CRASHPAD_IS_IN_CHROMIUM) && defined(NDEBUG) + // After https://crrev.com/c/5375084, Chromium does not set `brk 0` for local + // release builds and official DCHECK builds. +#if defined(CRASHPAD_IS_IN_CHROMIUM) && defined(NDEBUG) && \ + defined(OFFICIAL_BUILD) && !defined(DCHECK_ALWAYS_ON) [self verifyCrashReportException:SIGABRT]; #else [self verifyCrashReportException:EXC_SOFT_SIGNAL]; @@ -317,6 +342,14 @@ - (void)testCrashWithDyldErrorString { #endif - (void)testCrashWithAnnotations { +#if TARGET_OS_SIMULATOR + // This test will fail on older (* threads) { // TODO(jperaza): Implement this if/when it's needed. - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; } ssize_t FakePtraceConnection::ReadUpTo(VMAddress address, size_t size, void* buffer) { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return false; } diff --git a/test/multiprocess_posix_test.cc b/test/multiprocess_posix_test.cc index c7015b857a..02bdb7b29b 100644 --- a/test/multiprocess_posix_test.cc +++ b/test/multiprocess_posix_test.cc @@ -157,7 +157,7 @@ class TestMultiprocessClosePipe final : public Multiprocess { who_closes_(who_closes), what_closes_(what_closes) { // Fails under "threadsafe" mode on macOS 10.11. - testing::GTEST_FLAG(death_test_style) = "fast"; + GTEST_FLAG_SET(death_test_style, "fast"); } TestMultiprocessClosePipe(const TestMultiprocessClosePipe&) = delete; diff --git a/test/scoped_guarded_page_test.cc b/test/scoped_guarded_page_test.cc index 2be2d51bd3..d8fc6749d1 100644 --- a/test/scoped_guarded_page_test.cc +++ b/test/scoped_guarded_page_test.cc @@ -23,7 +23,7 @@ namespace test { namespace { TEST(ScopedGuardedPage, BasicFunctionality) { - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + GTEST_FLAG_SET(death_test_style, "threadsafe"); ScopedGuardedPage page; char* address = (char*)page.Pointer(); diff --git a/test/win/win_child_process.cc b/test/win/win_child_process.cc index d4d9a462a1..e31a977d09 100644 --- a/test/win/win_child_process.cc +++ b/test/win/win_child_process.cc @@ -44,7 +44,6 @@ bool GetSwitch(const char* switch_name, std::string* value) { ScopedLocalAlloc scoped_args(args); // Take ownership. if (!args) { PLOG(FATAL) << "CommandLineToArgvW"; - return false; } std::string switch_name_with_equals(switch_name); diff --git a/third_party/cpp-httplib/README.crashpad b/third_party/cpp-httplib/README.crashpad index a1ba93aaae..8246a7358c 100644 --- a/third_party/cpp-httplib/README.crashpad +++ b/third_party/cpp-httplib/README.crashpad @@ -14,3 +14,4 @@ Local Modifications: - Exclude test/ and example/ subdirs. - Patch httplib.h to use #include "third_party/zlib/zlib_crashpad.h" instead of . +- Make `this` capture explicit to avoid errors in C++20. diff --git a/third_party/cpp-httplib/cpp-httplib/httplib.h b/third_party/cpp-httplib/cpp-httplib/httplib.h index dadab1d8e8..1165e26016 100644 --- a/third_party/cpp-httplib/cpp-httplib/httplib.h +++ b/third_party/cpp-httplib/cpp-httplib/httplib.h @@ -1684,7 +1684,7 @@ inline bool Server::listen_internal() } // TODO: Use thread pool... - std::thread([=]() { + std::thread([=, this]() { { std::lock_guard guard(running_threads_mutex_); running_threads_++; @@ -1861,7 +1861,7 @@ inline bool Client::is_valid() const inline socket_t Client::create_client_socket() const { return detail::create_socket(host_.c_str(), port_, - [=](socket_t sock, struct addrinfo& ai) -> bool { + [this](socket_t sock, struct addrinfo& ai) -> bool { detail::set_nonblocking(sock, true); auto ret = connect(sock, ai.ai_addr, ai.ai_addrlen); diff --git a/third_party/mini_chromium/CMakeLists.txt b/third_party/mini_chromium/CMakeLists.txt index 48bfbe8df9..338b051fa4 100644 --- a/third_party/mini_chromium/CMakeLists.txt +++ b/third_party/mini_chromium/CMakeLists.txt @@ -15,7 +15,10 @@ mc_append_sources( check.h check_op.h compiler_specific.h + containers/checked_iterators.h + containers/dynamic_extent.h containers/span.h + containers/util.h debug/alias.cc debug/alias.h files/file_path.cc @@ -24,15 +27,19 @@ mc_append_sources( files/scoped_file.cc files/scoped_file.h format_macros.h + immediate_crash.h logging.cc logging.h memory/free_deleter.h memory/page_size.h + memory/raw_ptr_exclusion.h memory/scoped_policy.h metrics/histogram_functions.h metrics/histogram_macros.h metrics/persistent_histogram_allocator.h notreached.h + numerics/basic_ops_impl.h + numerics/byte_conversions.h numerics/checked_math.h numerics/checked_math_impl.h numerics/clamped_math.h @@ -76,6 +83,7 @@ mc_append_sources( threading/thread_local_storage.cc threading/thread_local_storage.h types/cxx23_to_underlying.h + types/to_address.h ) if(NOT MINGW) diff --git a/third_party/mini_chromium/mini_chromium b/third_party/mini_chromium/mini_chromium index 9e21183c1e..bd56f6933f 160000 --- a/third_party/mini_chromium/mini_chromium +++ b/third_party/mini_chromium/mini_chromium @@ -1 +1 @@ -Subproject commit 9e21183c1ea369398d6f6ddd302c8db580bd19c4 +Subproject commit bd56f6933f2fa021a44766ced638a18f477ef1c1 diff --git a/tools/tool_support.cc b/tools/tool_support.cc index 61d4bf8543..cd83366adb 100644 --- a/tools/tool_support.cc +++ b/tools/tool_support.cc @@ -16,9 +16,9 @@ #include -#include #include +#include "base/containers/heap_array.h" #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -77,7 +77,7 @@ void ToolSupport::UsageHint(const std::string& me, const char* hint) { // static int ToolSupport::Wmain(int argc, wchar_t* argv[], int (*entry)(int, char* [])) { - std::unique_ptr argv_as_utf8(new char*[argc + 1]); + auto argv_as_utf8 = base::HeapArray::Uninit(argc + 1); std::vector storage; storage.reserve(argc); for (int i = 0; i < argc; ++i) { @@ -85,7 +85,7 @@ int ToolSupport::Wmain(int argc, wchar_t* argv[], int (*entry)(int, char* [])) { argv_as_utf8[i] = &storage[i][0]; } argv_as_utf8[argc] = nullptr; - return entry(argc, argv_as_utf8.get()); + return entry(argc, argv_as_utf8.data()); } #endif // BUILDFLAG(IS_WIN) diff --git a/util/BUILD.gn b/util/BUILD.gn index 7e06fcdacb..d4f4b2d015 100644 --- a/util/BUILD.gn +++ b/util/BUILD.gn @@ -33,12 +33,6 @@ if (crashpad_is_apple) { "mach/mig_gen.py", ] - if (crashpad_is_in_fuchsia) { - # TODO(https://fxbug.dev/68780): Remove suppression when fixed. - hermetic_deps = false - all_outputs_fresh = false - } - if (crashpad_is_mac) { sources = [ "$sysroot/usr/include/mach/exc.defs", @@ -319,6 +313,8 @@ crashpad_static_library("util") { if (crashpad_is_apple) { sources += [ + "mac/sysctl.cc", + "mac/sysctl.h", "mac/xattr.cc", "mac/xattr.h", "mach/composite_mach_message_server.cc", @@ -355,8 +351,6 @@ crashpad_static_library("util") { "mac/mac_util.h", "mac/service_management.cc", "mac/service_management.h", - "mac/sysctl.cc", - "mac/sysctl.h", "mach/bootstrap.cc", "mach/bootstrap.h", "mach/child_port_handshake.cc", @@ -603,6 +597,10 @@ crashpad_static_library("util") { ] } + if (crashpad_is_ios) { + configs += [ "../build:crashpad_is_ios_app_extension" ] + } + if (crashpad_is_win) { libs = [ "user32.lib", diff --git a/util/file/file_io_posix.cc b/util/file/file_io_posix.cc index 6d02462bd5..37e923ac50 100644 --- a/util/file/file_io_posix.cc +++ b/util/file/file_io_posix.cc @@ -276,7 +276,7 @@ FileHandle StdioFileHandle(StdioStream stdio_stream) { return STDERR_FILENO; } - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return kInvalidFileHandle; } diff --git a/util/file/file_io_win.cc b/util/file/file_io_win.cc index cb9ea14741..876f578355 100644 --- a/util/file/file_io_win.cc +++ b/util/file/file_io_win.cc @@ -230,7 +230,7 @@ FileOffset LoggingSeekFile(FileHandle file, FileOffset offset, int whence) { method = FILE_END; break; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); break; } @@ -283,7 +283,7 @@ FileHandle StdioFileHandle(StdioStream stdio_stream) { standard_handle = STD_ERROR_HANDLE; break; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return INVALID_HANDLE_VALUE; } diff --git a/util/file/output_stream_file_writer.cc b/util/file/output_stream_file_writer.cc index 9cab03db1e..8d9cb976ed 100644 --- a/util/file/output_stream_file_writer.cc +++ b/util/file/output_stream_file_writer.cc @@ -56,7 +56,7 @@ bool OutputStreamFileWriter::WriteIoVec(std::vector* iovecs) { } FileOffset OutputStreamFileWriter::Seek(FileOffset offset, int whence) { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return -1; } diff --git a/util/ios/ios_intermediate_dump_format.h b/util/ios/ios_intermediate_dump_format.h index 9fe7ccf9a2..2f0a898078 100644 --- a/util/ios/ios_intermediate_dump_format.h +++ b/util/ios/ios_intermediate_dump_format.h @@ -86,6 +86,7 @@ namespace internal { TD(kInactive, 5018) \ TD(kWired, 5019) \ TD(kAddressMask, 5020) \ + TD(kCrashpadUptime, 5021) \ TD(kThreads, 6000) \ TD(kDebugState, 6001) \ TD(kFloatState, 6002) \ diff --git a/util/ios/ios_system_data_collector.h b/util/ios/ios_system_data_collector.h index 2dfc373a1f..7bef9a2e52 100644 --- a/util/ios/ios_system_data_collector.h +++ b/util/ios/ios_system_data_collector.h @@ -44,6 +44,7 @@ class IOSSystemDataCollector { const std::string& DaylightName() const { return daylight_name_; } bool IsApplicationActive() const { return active_; } uint64_t AddressMask() const { return address_mask_; } + uint64_t InitializationTime() const { return initialization_time_ns_; } // Currently unused by minidump. int Orientation() const { return orientation_; } @@ -82,6 +83,12 @@ class IOSSystemDataCollector { std::string daylight_name_; ActiveApplicationCallback active_application_callback_; uint64_t address_mask_; + + // Time in nanoseconds as returned by ClockMonotonicNanoseconds() to store the + // crashpad start time. This clock increments monotonically but pauses while + // the system is asleep. It should not be compared to other system time + // sources. + uint64_t initialization_time_ns_; }; } // namespace internal diff --git a/util/ios/ios_system_data_collector.mm b/util/ios/ios_system_data_collector.mm index 28ede18244..104f3cd512 100644 --- a/util/ios/ios_system_data_collector.mm +++ b/util/ios/ios_system_data_collector.mm @@ -22,33 +22,16 @@ #import #include "base/apple/mach_logging.h" +#include "base/notreached.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "build/build_config.h" +#include "util/mac/sysctl.h" +#include "util/misc/clock.h" namespace { -std::string ReadStringSysctlByName(const char* name) { - size_t buf_len; - if (sysctlbyname(name, nullptr, &buf_len, nullptr, 0) != 0) { - PLOG(WARNING) << "sysctlbyname (size) " << name; - return std::string(); - } - - if (buf_len == 0) { - return std::string(); - } - - std::string value(buf_len - 1, '\0'); - if (sysctlbyname(name, &value[0], &buf_len, nullptr, 0) != 0) { - PLOG(WARNING) << "sysctlbyname " << name; - return std::string(); - } - - return value; -} - template void AddObserver(CFStringRef notification_name, T* observer) { CFNotificationCenterAddObserver( @@ -86,7 +69,8 @@ void AddObserver(CFStringRef notification_name, T* observer) { standard_offset_seconds_(0), daylight_offset_seconds_(0), standard_name_(), - daylight_name_() { + daylight_name_(), + initialization_time_ns_(ClockMonotonicNanoseconds()) { NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion]; major_version_ = base::saturated_cast(version.majorVersion); @@ -94,13 +78,20 @@ void AddObserver(CFStringRef notification_name, T* observer) { patch_version_ = base::saturated_cast(version.patchVersion); processor_count_ = base::saturated_cast([[NSProcessInfo processInfo] processorCount]); - build_ = ReadStringSysctlByName("kern.osversion"); + build_ = ReadStringSysctlByName("kern.osversion", false); bundle_identifier_ = base::SysNSStringToUTF8([[NSBundle mainBundle] bundleIdentifier]); +// If CRASHPAD_IS_IOS_APP_EXTENSION is defined, then the code is compiled with +// -fapplication-extension and can only be used in an app extension. Otherwise +// check at runtime whether the code is executing in an app extension or not. +#if defined(CRASHPAD_IS_IOS_APP_EXTENSION) + is_extension_ = true; +#else is_extension_ = [[NSBundle mainBundle].bundlePath hasSuffix:@"appex"]; +#endif #if defined(ARCH_CPU_X86_64) - cpu_vendor_ = ReadStringSysctlByName("machdep.cpu.vendor"); + cpu_vendor_ = ReadStringSysctlByName("machdep.cpu.vendor", false); #endif uint32_t addressable_bits = 0; size_t len = sizeof(uint32_t); @@ -170,6 +161,7 @@ void AddObserver(CFStringRef notification_name, T* observer) { (__bridge CFStringRef)UIDeviceOrientationDidChangeNotification, this); OrientationDidChangeNotification(); +#if !defined(CRASHPAD_IS_IOS_APP_EXTENSION) // Foreground/Background. Extensions shouldn't use UIApplication*. if (!is_extension_) { AddObserver< @@ -183,6 +175,7 @@ void AddObserver(CFStringRef notification_name, T* observer) { this); ApplicationDidChangeActiveNotification(); } +#endif } void IOSSystemDataCollector::SystemTimeZoneDidChangeNotification() { @@ -226,6 +219,9 @@ void AddObserver(CFStringRef notification_name, T* observer) { } void IOSSystemDataCollector::ApplicationDidChangeActiveNotification() { +#if defined(CRASHPAD_IS_IOS_APP_EXTENSION) + NOTREACHED_NORETURN(); +#else dispatch_assert_queue_debug(dispatch_get_main_queue()); bool old_active = active_; active_ = [UIApplication sharedApplication].applicationState == @@ -233,6 +229,7 @@ void AddObserver(CFStringRef notification_name, T* observer) { if (active_ != old_active && active_application_callback_) { active_application_callback_(active_); } +#endif } } // namespace internal diff --git a/util/linux/auxiliary_vector_test.cc b/util/linux/auxiliary_vector_test.cc index 0c97781faa..f171ef84c4 100644 --- a/util/linux/auxiliary_vector_test.cc +++ b/util/linux/auxiliary_vector_test.cc @@ -187,13 +187,13 @@ TEST(AuxiliaryVector, SignedBit) { constexpr uint64_t type = 0x0000000012345678; constexpr int32_t neg1_32 = -1; - aux.Insert(type, bit_cast(neg1_32)); + aux.Insert(type, base::bit_cast(neg1_32)); int32_t outval32s; ASSERT_TRUE(aux.GetValue(type, &outval32s)); EXPECT_EQ(outval32s, neg1_32); constexpr int32_t int32_max = std::numeric_limits::max(); - aux.Insert(type, bit_cast(int32_max)); + aux.Insert(type, base::bit_cast(int32_max)); ASSERT_TRUE(aux.GetValue(type, &outval32s)); EXPECT_EQ(outval32s, int32_max); @@ -204,13 +204,13 @@ TEST(AuxiliaryVector, SignedBit) { EXPECT_EQ(outval32u, uint32_max); constexpr int64_t neg1_64 = -1; - aux.Insert(type, bit_cast(neg1_64)); + aux.Insert(type, base::bit_cast(neg1_64)); int64_t outval64s; ASSERT_TRUE(aux.GetValue(type, &outval64s)); EXPECT_EQ(outval64s, neg1_64); constexpr int64_t int64_max = std::numeric_limits::max(); - aux.Insert(type, bit_cast(int64_max)); + aux.Insert(type, base::bit_cast(int64_max)); ASSERT_TRUE(aux.GetValue(type, &outval64s)); EXPECT_EQ(outval64s, int64_max); diff --git a/util/linux/memory_map.cc b/util/linux/memory_map.cc index 58de835ed1..5838357372 100644 --- a/util/linux/memory_map.cc +++ b/util/linux/memory_map.cc @@ -18,7 +18,6 @@ #include #include -#include "base/bit_cast.h" #include "base/check_op.h" #include "base/files/file_path.h" #include "base/logging.h" diff --git a/util/mac/mac_util.cc b/util/mac/mac_util.cc index cef238729a..37b595b607 100644 --- a/util/mac/mac_util.cc +++ b/util/mac/mac_util.cc @@ -207,7 +207,7 @@ int MacOSVersionNumber() { #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_13_4 // On macOS 10.13.4 and later, the sysctlbyname above should have been // successful. - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return -1; #else // DT >= 10.13.4 // The Darwin major version is always 4 greater than the macOS minor version diff --git a/util/mach/child_port_handshake.cc b/util/mach/child_port_handshake.cc index afbf55f195..3402d2daaf 100644 --- a/util/mach/child_port_handshake.cc +++ b/util/mach/child_port_handshake.cc @@ -256,7 +256,7 @@ mach_port_t ChildPortHandshakeServer::RunServer( break; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); break; } } diff --git a/util/mach/exc_client_variants.cc b/util/mach/exc_client_variants.cc index f7cb763af3..a2c63139d7 100644 --- a/util/mach/exc_client_variants.cc +++ b/util/mach/exc_client_variants.cc @@ -123,7 +123,7 @@ kern_return_t UniversalExceptionRaise(exception_behavior_t behavior, new_state_count); default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); return KERN_INVALID_ARGUMENT; } } diff --git a/util/mach/exception_ports.cc b/util/mach/exception_ports.cc index b983cc6c53..0f80887a1a 100644 --- a/util/mach/exception_ports.cc +++ b/util/mach/exception_ports.cc @@ -80,7 +80,7 @@ ExceptionPorts::ExceptionPorts(TargetType target_type, mach_port_t target_port) break; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); get_exception_ports_ = nullptr; set_exception_ports_ = nullptr; target_name_ = nullptr; diff --git a/util/mach/exception_ports_test.cc b/util/mach/exception_ports_test.cc index b37a99a24b..a6d065bc7e 100644 --- a/util/mach/exception_ports_test.cc +++ b/util/mach/exception_ports_test.cc @@ -188,7 +188,7 @@ class TestExceptionPorts : public MachMultiprocess, } else if (who_crashes_ == kOtherThreadCrashes) { expect_behavior = EXCEPTION_STATE_IDENTITY; } else { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); expect_behavior = 0; } @@ -286,7 +286,7 @@ class TestExceptionPorts : public MachMultiprocess, } default: { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); } } } @@ -369,7 +369,7 @@ class TestExceptionPorts : public MachMultiprocess, break; } default: { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); } } } @@ -520,7 +520,7 @@ class TestExceptionPorts : public MachMultiprocess, } default: { - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); } } } diff --git a/util/mach/symbolic_constants_mach.cc b/util/mach/symbolic_constants_mach.cc index eb90bd7892..7a5919016d 100644 --- a/util/mach/symbolic_constants_mach.cc +++ b/util/mach/symbolic_constants_mach.cc @@ -299,14 +299,11 @@ bool StringToExceptionMask(const base::StringPiece& string, size_t pos = -1; do { ++pos; - const char* substring_begin = string.begin() + pos; + const size_t start = pos; pos = string.find('|', pos); - const char* substring_end = (pos == base::StringPiece::npos) - ? string.end() - : (string.begin() + pos); - base::StringPiece substring = string.substr( - substring_begin - string.begin(), substring_end - substring_begin); - + base::StringPiece substring = (pos == base::StringPiece::npos) + ? string.substr(start) + : string.substr(start, pos - start); exception_mask_t temp_mask; if (!StringToExceptionMask(substring, options, &temp_mask)) { return false; diff --git a/util/misc/arm64_pac_bti.S b/util/misc/arm64_pac_bti.S index 85da8b5649..77961d410e 100644 --- a/util/misc/arm64_pac_bti.S +++ b/util/misc/arm64_pac_bti.S @@ -34,7 +34,7 @@ #endif #if defined(__ARM_FEATURE_PAC_DEFAULT) -#if ((__ARM_FEATURE_PAC_DEFAULT & ((1<<0)|(1<<2))) == 0) +#if ((__ARM_FEATURE_PAC_DEFAULT & ((1<<0)|(1<<1))) == 0) #error Pointer authentication defines no valid key! #endif #define GNU_PROPERTY_AARCH64_PAC 1 // Has PAC diff --git a/util/misc/clock_mac.cc b/util/misc/clock_mac.cc index 81e53170b7..2b4dccd0c4 100644 --- a/util/misc/clock_mac.cc +++ b/util/misc/clock_mac.cc @@ -14,32 +14,12 @@ #include "util/misc/clock.h" -#include - -#include "base/apple/mach_logging.h" - -namespace { - -mach_timebase_info_data_t* TimebaseInternal() { - mach_timebase_info_data_t* timebase_info = new mach_timebase_info_data_t; - kern_return_t kr = mach_timebase_info(timebase_info); - MACH_CHECK(kr == KERN_SUCCESS, kr) << "mach_timebase_info"; - return timebase_info; -} - -mach_timebase_info_data_t* Timebase() { - static mach_timebase_info_data_t* timebase_info = TimebaseInternal(); - return timebase_info; -} - -} // namespace +#include namespace crashpad { uint64_t ClockMonotonicNanoseconds() { - uint64_t absolute_time = mach_absolute_time(); - mach_timebase_info_data_t* timebase_info = Timebase(); - return absolute_time * timebase_info->numer / timebase_info->denom; + return clock_gettime_nsec_np(CLOCK_UPTIME_RAW); } } // namespace crashpad diff --git a/util/misc/reinterpret_bytes_test.cc b/util/misc/reinterpret_bytes_test.cc index ba72bc526f..80bb979b98 100644 --- a/util/misc/reinterpret_bytes_test.cc +++ b/util/misc/reinterpret_bytes_test.cc @@ -75,27 +75,27 @@ TEST(ReinterpretBytes, ToSigned) { ExpectReinterpret(from64, &to64, static_cast(0)); to32 = -1; - from64 = bit_cast(to32); + from64 = base::bit_cast(to32); ExpectReinterpret(from64, &to32, to32); to32 = std::numeric_limits::max(); - from64 = bit_cast(to32); + from64 = base::bit_cast(to32); ExpectReinterpret(from64, &to32, to32); to32 = std::numeric_limits::min(); - from64 = bit_cast(to32); + from64 = base::bit_cast(to32); ExpectReinterpret(from64, &to32, to32); to64 = -1; - from64 = bit_cast(to64); + from64 = base::bit_cast(to64); ExpectReinterpret(from64, &to64, to64); to64 = std::numeric_limits::max(); - from64 = bit_cast(to64); + from64 = base::bit_cast(to64); ExpectReinterpret(from64, &to64, to64); to64 = std::numeric_limits::min(); - from64 = bit_cast(to64); + from64 = base::bit_cast(to64); ExpectReinterpret(from64, &to64, to64); } diff --git a/util/misc/uuid.cc b/util/misc/uuid.cc index 15870709e3..fb27f27c1a 100644 --- a/util/misc/uuid.cc +++ b/util/misc/uuid.cc @@ -23,13 +23,15 @@ #include #include +#include #include #include +#include "base/containers/span.h" +#include "base/numerics/byte_conversions.h" #include "base/rand_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/sys_byteorder.h" #include "build/build_config.h" #if BUILDFLAG(IS_APPLE) @@ -39,7 +41,9 @@ namespace crashpad { static_assert(sizeof(UUID) == 16, "UUID must be 16 bytes"); -static_assert(std::is_pod::value, "UUID must be POD"); +static_assert(std::is_standard_layout::value, + "UUID must be a standard-layout type"); +static_assert(std::is_trivial::value, "UUID must be a trivial type"); bool UUID::operator==(const UUID& that) const { return memcmp(this, &that, sizeof(*this)) == 0; @@ -53,11 +57,15 @@ void UUID::InitializeToZero() { memset(this, 0, sizeof(*this)); } -void UUID::InitializeFromBytes(const uint8_t* bytes) { - memcpy(this, bytes, sizeof(*this)); - data_1 = base::NetToHost32(data_1); - data_2 = base::NetToHost16(data_2); - data_3 = base::NetToHost16(data_3); +void UUID::InitializeFromBytes(const uint8_t* bytes_ptr) { + // TODO(crbug.com/40284755): This span construction is unsound. The caller + // should provide a span instead of an unbounded pointer. + base::span bytes(bytes_ptr, sizeof(UUID)); + data_1 = base::numerics::U32FromBigEndian(bytes.subspan<0u, 4u>()); + data_2 = base::numerics::U16FromBigEndian(bytes.subspan<4u, 2u>()); + data_3 = base::numerics::U16FromBigEndian(bytes.subspan<6u, 2u>()); + std::ranges::copy(bytes.subspan<8u, 2u>(), data_4); + std::ranges::copy(bytes.subspan<10u, 6u>(), data_5); } bool UUID::InitializeFromString(const base::StringPiece& string) { @@ -108,7 +116,7 @@ bool UUID::InitializeWithNew() { // from libuuid is not available everywhere. // On Windows, do not use UuidCreate() to avoid a dependency on rpcrt4, so // that this function is usable early in DllMain(). - base::RandBytes(this, sizeof(*this)); + base::RandBytes(base::byte_span_from_ref(*this)); // Set six bits per RFC 4122 §4.4 to identify this as a pseudo-random UUID. data_3 = (4 << 12) | (data_3 & 0x0fff); // §4.1.3 diff --git a/util/net/http_body_gzip_test.cc b/util/net/http_body_gzip_test.cc index a9438e0caf..6fed433ab3 100644 --- a/util/net/http_body_gzip_test.cc +++ b/util/net/http_body_gzip_test.cc @@ -21,8 +21,9 @@ #include #include -#include "base/rand_util.h" +#include "base/containers/heap_array.h" #include "base/numerics/safe_conversions.h" +#include "base/rand_util.h" #include "gtest/gtest.h" #include "third_party/zlib/zlib_crashpad.h" #include "util/misc/zlib.h" @@ -54,17 +55,16 @@ void GzipInflate(const std::string& compressed, decompressed->clear(); // There’s got to be at least a small buffer. - buf_size = std::max(buf_size, static_cast(1)); - - std::unique_ptr buf(new uint8_t[buf_size]); + auto buf = base::HeapArray::Uninit( + std::max(buf_size, static_cast(1))); z_stream zlib = {}; zlib.zalloc = Z_NULL; zlib.zfree = Z_NULL; zlib.opaque = Z_NULL; zlib.next_in = reinterpret_cast(const_cast(&compressed[0])); zlib.avail_in = base::checked_cast(compressed.size()); - zlib.next_out = buf.get(); - zlib.avail_out = base::checked_cast(buf_size); + zlib.next_out = buf.data(); + zlib.avail_out = base::checked_cast(buf.size()); int zr = inflateInit2(&zlib, ZlibWindowBitsWithGzipWrapper(0)); ASSERT_EQ(zr, Z_OK) << "inflateInit2: " << ZlibErrorString(zr); @@ -73,9 +73,9 @@ void GzipInflate(const std::string& compressed, zr = inflate(&zlib, Z_FINISH); ASSERT_EQ(zr, Z_STREAM_END) << "inflate: " << ZlibErrorString(zr); - ASSERT_LE(zlib.avail_out, buf_size); - decompressed->assign(reinterpret_cast(buf.get()), - buf_size - zlib.avail_out); + ASSERT_LE(zlib.avail_out, buf.size()); + decompressed->assign(reinterpret_cast(buf.data()), + buf.size() - zlib.avail_out); } void TestGzipDeflateInflate(const std::string& string) { @@ -94,17 +94,17 @@ void TestGzipDeflateInflate(const std::string& string) { size_t buf_size = string.size() + kGzipHeaderSize + (string.empty() ? 2 : (((string.size() + 16383) / 16384) * 5)); - std::unique_ptr buf(new uint8_t[buf_size]); + auto buf = base::HeapArray::Uninit(buf_size); FileOperationResult compressed_bytes = - gzip_stream.GetBytesBuffer(buf.get(), buf_size); + gzip_stream.GetBytesBuffer(buf.data(), buf.size()); ASSERT_NE(compressed_bytes, -1); - ASSERT_LE(static_cast(compressed_bytes), buf_size); + ASSERT_LE(static_cast(compressed_bytes), buf.size()); // Make sure that the stream is really at EOF. uint8_t eof_buf[16]; ASSERT_EQ(gzip_stream.GetBytesBuffer(eof_buf, sizeof(eof_buf)), 0); - std::string compressed(reinterpret_cast(buf.get()), compressed_bytes); + std::string compressed(reinterpret_cast(buf.data()), compressed_bytes); ASSERT_GE(compressed.size(), kGzipHeaderSize); EXPECT_EQ(compressed[0], '\37'); diff --git a/util/net/http_body_test_util.cc b/util/net/http_body_test_util.cc index b011f4e377..960eb62a71 100644 --- a/util/net/http_body_test_util.cc +++ b/util/net/http_body_test_util.cc @@ -16,8 +16,7 @@ #include -#include - +#include "base/containers/heap_array.h" #include "gtest/gtest.h" #include "util/file/file_io.h" #include "util/net/http_body.h" @@ -30,17 +29,17 @@ std::string ReadStreamToString(HTTPBodyStream* stream) { } std::string ReadStreamToString(HTTPBodyStream* stream, size_t buffer_size) { - std::unique_ptr buf(new uint8_t[buffer_size]); + auto buf = base::HeapArray::Uninit(buffer_size); std::string result; FileOperationResult bytes_read; - while ((bytes_read = stream->GetBytesBuffer(buf.get(), buffer_size)) != 0) { + while ((bytes_read = stream->GetBytesBuffer(buf.data(), buf.size())) != 0) { if (bytes_read < 0) { ADD_FAILURE() << "Failed to read from stream: " << bytes_read; return std::string(); } - result.append(reinterpret_cast(buf.get()), bytes_read); + result.append(reinterpret_cast(buf.data()), bytes_read); } return result; diff --git a/util/numeric/int128_test.cc b/util/numeric/int128_test.cc index 2166c9a43f..5bc9e4159c 100644 --- a/util/numeric/int128_test.cc +++ b/util/numeric/int128_test.cc @@ -33,7 +33,7 @@ TEST(Int128, UInt128) { uint128_struct uint128; static_assert(sizeof(uint128) == sizeof(kBytes), "sizes must be equal"); - uint128 = bit_cast(kBytes); + uint128 = base::bit_cast(kBytes); EXPECT_EQ(uint128.lo, 0x0706050403020100u); EXPECT_EQ(uint128.hi, 0x0f0e0d0c0b0a0908u); diff --git a/util/posix/spawn_subprocess.cc b/util/posix/spawn_subprocess.cc index df5b4a3f06..8f1f13d169 100644 --- a/util/posix/spawn_subprocess.cc +++ b/util/posix/spawn_subprocess.cc @@ -190,7 +190,8 @@ bool SpawnSubprocess(const std::vector& argv, auto execve_fp = use_path ? execvpe : execve; execve_fp(argv_for_spawn[0], argv_for_spawn, envp_for_spawn); - PLOG(FATAL) << (use_path ? "execvpe" : "execve"); + PLOG(FATAL) << (use_path ? "execvpe" : "execve") << " " + << argv_for_spawn[0]; #else #if BUILDFLAG(IS_APPLE) PosixSpawnAttr attr; @@ -218,7 +219,8 @@ bool SpawnSubprocess(const std::vector& argv, attr_p, argv_for_spawn, envp_for_spawn)) != 0) { - PLOG(FATAL) << (use_path ? "posix_spawnp" : "posix_spawn"); + PLOG(FATAL) << (use_path ? "posix_spawnp" : "posix_spawn") << " " + << argv_for_spawn[0]; } // _exit() instead of exit(), because fork() was called. diff --git a/util/process/process_memory_mac_test.cc b/util/process/process_memory_mac_test.cc index 296b536df8..08e897b7c9 100644 --- a/util/process/process_memory_mac_test.cc +++ b/util/process/process_memory_mac_test.cc @@ -23,6 +23,7 @@ #include "base/apple/scoped_mach_port.h" #include "base/apple/scoped_mach_vm.h" +#include "base/containers/heap_array.h" #include "gtest/gtest.h" #include "test/mac/mach_errors.h" #include "util/misc/from_pointer_cast.h" @@ -259,13 +260,12 @@ TEST(ProcessMemoryMac, MappedMemoryDeallocates) { // This is the same but with a big buffer that’s definitely larger than a // single page. This makes sure that the whole mapped region winds up being // deallocated. - const size_t kBigSize = 4 * PAGE_SIZE; - std::unique_ptr big_buffer(new char[kBigSize]); + auto big_buffer = base::HeapArray::Uninit(4 * PAGE_SIZE); test_address = FromPointerCast(&big_buffer[0]); - ASSERT_TRUE((mapped = memory.ReadMapped(test_address, kBigSize))); + ASSERT_TRUE((mapped = memory.ReadMapped(test_address, big_buffer.size()))); mapped_address = reinterpret_cast(mapped->data()); - vm_address_t mapped_last_address = mapped_address + kBigSize - 1; + vm_address_t mapped_last_address = mapped_address + big_buffer.size() - 1; EXPECT_TRUE(IsAddressMapped(mapped_address)); EXPECT_TRUE(IsAddressMapped(mapped_address + PAGE_SIZE)); EXPECT_TRUE(IsAddressMapped(mapped_last_address)); diff --git a/util/process/process_memory_test.cc b/util/process/process_memory_test.cc index 11558e4078..07b42535ee 100644 --- a/util/process/process_memory_test.cc +++ b/util/process/process_memory_test.cc @@ -16,8 +16,7 @@ #include -#include - +#include "base/containers/heap_array.h" #include "base/memory/page_size.h" #include "build/build_config.h" #include "gtest/gtest.h" @@ -105,22 +104,20 @@ class MultiprocessAdaptor : public MultiprocessExec { }; #endif // BUILDFLAG(IS_APPLE) -void DoChildReadTestSetup(size_t* region_size, - std::unique_ptr* region) { - *region_size = 4 * base::GetPageSize(); - region->reset(new char[*region_size]); - for (size_t index = 0; index < *region_size; ++index) { - (*region)[index] = static_cast(index % 256); +base::HeapArray DoChildReadTestSetup() { + auto region = base::HeapArray::Uninit(4 * base::GetPageSize()); + for (size_t index = 0; index < region.size(); ++index) { + region[index] = static_cast(index % 256); } + return region; } CRASHPAD_CHILD_TEST_MAIN(ReadTestChild) { - size_t region_size; - std::unique_ptr region; - DoChildReadTestSetup(®ion_size, ®ion); + auto region = DoChildReadTestSetup(); + auto region_size = region.size(); FileHandle out = MultiprocessAdaptor::OutputHandle(); CheckedWriteFile(out, ®ion_size, sizeof(region_size)); - VMAddress address = FromPointerCast(region.get()); + VMAddress address = FromPointerCast(region.data()); CheckedWriteFile(out, &address, sizeof(address)); CheckedReadFileAtEOF(MultiprocessAdaptor::InputHandle()); return 0; @@ -136,12 +133,10 @@ class ReadTest : public MultiprocessAdaptor { ReadTest& operator=(const ReadTest&) = delete; void RunAgainstSelf() { - size_t region_size; - std::unique_ptr region; - DoChildReadTestSetup(®ion_size, ®ion); + auto region = DoChildReadTestSetup(); DoTest(GetSelfProcess(), - region_size, - FromPointerCast(region.get())); + region.size(), + FromPointerCast(region.data())); } void RunAgainstChild() { Run(); } @@ -167,50 +162,50 @@ class ReadTest : public MultiprocessAdaptor { #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || // BUILDFLAG(IS_CHROMEOS) - std::unique_ptr result(new char[region_size]); + auto result = base::HeapArray::Uninit(region_size); // Ensure that the entire region can be read. - ASSERT_TRUE(memory.Read(address, region_size, result.get())); - for (size_t i = 0; i < region_size; ++i) { + ASSERT_TRUE(memory.Read(address, result.size(), result.data())); + for (size_t i = 0; i < result.size(); ++i) { EXPECT_EQ(result[i], static_cast(i % 256)); } // Ensure that a read of length 0 succeeds and doesn’t touch the result. - memset(result.get(), '\0', region_size); - ASSERT_TRUE(memory.Read(address, 0, result.get())); - for (size_t i = 0; i < region_size; ++i) { + memset(result.data(), '\0', result.size()); + ASSERT_TRUE(memory.Read(address, 0, result.data())); + for (size_t i = 0; i < result.size(); ++i) { EXPECT_EQ(result[i], 0); } // Ensure that a read starting at an unaligned address works. - ASSERT_TRUE(memory.Read(address + 1, region_size - 1, result.get())); - for (size_t i = 0; i < region_size - 1; ++i) { + ASSERT_TRUE(memory.Read(address + 1, result.size() - 1, result.data())); + for (size_t i = 0; i < result.size() - 1; ++i) { EXPECT_EQ(result[i], static_cast((i + 1) % 256)); } // Ensure that a read ending at an unaligned address works. - ASSERT_TRUE(memory.Read(address, region_size - 1, result.get())); - for (size_t i = 0; i < region_size - 1; ++i) { + ASSERT_TRUE(memory.Read(address, result.size() - 1, result.data())); + for (size_t i = 0; i < result.size() - 1; ++i) { EXPECT_EQ(result[i], static_cast(i % 256)); } // Ensure that a read starting and ending at unaligned addresses works. - ASSERT_TRUE(memory.Read(address + 1, region_size - 2, result.get())); - for (size_t i = 0; i < region_size - 2; ++i) { + ASSERT_TRUE(memory.Read(address + 1, result.size() - 2, result.data())); + for (size_t i = 0; i < result.size() - 2; ++i) { EXPECT_EQ(result[i], static_cast((i + 1) % 256)); } // Ensure that a read of exactly one page works. size_t page_size = base::GetPageSize(); - ASSERT_GE(region_size, page_size + page_size); - ASSERT_TRUE(memory.Read(address + page_size, page_size, result.get())); + ASSERT_GE(result.size(), page_size + page_size); + ASSERT_TRUE(memory.Read(address + page_size, page_size, result.data())); for (size_t i = 0; i < page_size; ++i) { EXPECT_EQ(result[i], static_cast((i + page_size) % 256)); } // Ensure that reading exactly a single byte works. result[1] = 'J'; - ASSERT_TRUE(memory.Read(address + 2, 1, result.get())); + ASSERT_TRUE(memory.Read(address + 2, 1, result.data())); EXPECT_EQ(result[0], 2); EXPECT_EQ(result[1], 'J'); } @@ -437,14 +432,13 @@ class ReadUnmappedTest : public MultiprocessAdaptor { VMAddress page_addr1 = address; VMAddress page_addr2 = page_addr1 + base::GetPageSize(); - std::unique_ptr result(new char[base::GetPageSize() * 2]); - EXPECT_TRUE(memory.Read(page_addr1, base::GetPageSize(), result.get())); - EXPECT_TRUE(memory.Read(page_addr2 - 1, 1, result.get())); + auto result = base::HeapArray::Uninit(base::GetPageSize() * 2); + EXPECT_TRUE(memory.Read(page_addr1, base::GetPageSize(), result.data())); + EXPECT_TRUE(memory.Read(page_addr2 - 1, 1, result.data())); - EXPECT_FALSE( - memory.Read(page_addr1, base::GetPageSize() * 2, result.get())); - EXPECT_FALSE(memory.Read(page_addr2, base::GetPageSize(), result.get())); - EXPECT_FALSE(memory.Read(page_addr2 - 1, 2, result.get())); + EXPECT_FALSE(memory.Read(page_addr1, result.size(), result.data())); + EXPECT_FALSE(memory.Read(page_addr2, base::GetPageSize(), result.data())); + EXPECT_FALSE(memory.Read(page_addr2 - 1, 2, result.data())); } }; diff --git a/util/stream/base94_output_stream_test.cc b/util/stream/base94_output_stream_test.cc index 1043840d86..09f6b00956 100644 --- a/util/stream/base94_output_stream_test.cc +++ b/util/stream/base94_output_stream_test.cc @@ -20,6 +20,7 @@ #include #include +#include "base/containers/heap_array.h" #include "base/rand_util.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -71,17 +72,16 @@ class Base94OutputStreamTest : public testing::Test { } const uint8_t* BuildDeterministicInput(size_t size) { - deterministic_input_ = std::make_unique(size); - uint8_t* deterministic_input_base = deterministic_input_.get(); + deterministic_input_ = base::HeapArray::WithSize(size); while (size-- > 0) - deterministic_input_base[size] = static_cast(size); - return deterministic_input_base; + deterministic_input_[size] = static_cast(size); + return deterministic_input_.data(); } const uint8_t* BuildRandomInput(size_t size) { - input_ = std::make_unique(size); - base::RandBytes(&input_[0], size); - return input_.get(); + input_ = base::HeapArray::Uninit(size); + base::RandBytes(input_); + return input_.data(); } Base94OutputStream* round_trip() const { return round_trip_.get(); } @@ -127,8 +127,8 @@ class Base94OutputStreamTest : public testing::Test { TestOutputStream* encode_test_output_stream_; TestOutputStream* decode_test_output_stream_; TestOutputStream* round_trip_test_output_stream_; - std::unique_ptr input_; - std::unique_ptr deterministic_input_; + base::HeapArray input_; + base::HeapArray deterministic_input_; }; TEST_F(Base94OutputStreamTest, Encoding) { diff --git a/util/stream/zlib_output_stream_test.cc b/util/stream/zlib_output_stream_test.cc index 768851683a..25de62ad6d 100644 --- a/util/stream/zlib_output_stream_test.cc +++ b/util/stream/zlib_output_stream_test.cc @@ -19,6 +19,7 @@ #include #include +#include "base/containers/heap_array.h" #include "base/rand_util.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -46,17 +47,16 @@ class ZlibOutputStreamTest : public testing::Test { ZlibOutputStreamTest& operator=(const ZlibOutputStreamTest&) = delete; const uint8_t* BuildDeterministicInput(size_t size) { - deterministic_input_ = std::make_unique(size); - uint8_t* deterministic_input_base = deterministic_input_.get(); + deterministic_input_ = base::HeapArray::WithSize(size); while (size-- > 0) - deterministic_input_base[size] = static_cast(size); - return deterministic_input_base; + deterministic_input_[size] = static_cast(size); + return deterministic_input_.data(); } const uint8_t* BuildRandomInput(size_t size) { - input_ = std::make_unique(size); - base::RandBytes(&input_[0], size); - return input_.get(); + input_ = base::HeapArray::Uninit(size); + base::RandBytes(input_); + return input_.data(); } const TestOutputStream& test_output_stream() const { @@ -69,8 +69,8 @@ class ZlibOutputStreamTest : public testing::Test { private: std::unique_ptr zlib_output_stream_; - std::unique_ptr input_; - std::unique_ptr deterministic_input_; + base::HeapArray input_; + base::HeapArray deterministic_input_; TestOutputStream* test_output_stream_; // weak, owned by zlib_output_stream_ }; diff --git a/util/synchronization/scoped_spin_guard.h b/util/synchronization/scoped_spin_guard.h index f924d991a1..0814192224 100644 --- a/util/synchronization/scoped_spin_guard.h +++ b/util/synchronization/scoped_spin_guard.h @@ -73,10 +73,17 @@ class ScopedSpinGuard final { ClockMonotonicNanoseconds() + timeout_nanos; while (true) { bool expected_current_value = false; - if (state.locked.compare_exchange_weak(expected_current_value, - true, - std::memory_order_acquire, - std::memory_order_relaxed)) { + // `std::atomic::compare_exchange_weak()` is allowed to spuriously fail on + // architectures like ARM, which can cause timeouts even for + // single-threaded cases (https://crbug.com/340980960, + // http://b/296082201). + // + // Use `std::compare_exchange_strong()` instead to avoid spurious failures + // in the common case. + if (state.locked.compare_exchange_strong(expected_current_value, + true, + std::memory_order_acquire, + std::memory_order_relaxed)) { return std::make_optional(state); } if (ClockMonotonicNanoseconds() >= clock_end_time_nanos) { @@ -85,7 +92,7 @@ class ScopedSpinGuard final { SleepNanoseconds(kSpinGuardSleepTimeNanos); } - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); } ~ScopedSpinGuard() { diff --git a/util/win/exception_handler_server.cc b/util/win/exception_handler_server.cc index 32d767df7c..bb5b90a1dc 100644 --- a/util/win/exception_handler_server.cc +++ b/util/win/exception_handler_server.cc @@ -22,6 +22,7 @@ #include #include "base/check.h" +#include "base/containers/heap_array.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/rand_util.h" @@ -295,16 +296,16 @@ void ExceptionHandlerServer::InitializeWithInheritedDataForInitialClient( first_pipe_instance_.reset(initial_client_data.first_pipe_instance()); // TODO(scottmg): Vista+. Might need to pass through or possibly find an Nt*. - size_t bytes = sizeof(wchar_t) * _MAX_PATH + sizeof(FILE_NAME_INFO); - std::unique_ptr data(new uint8_t[bytes]); + auto data = base::HeapArray::Uninit(sizeof(wchar_t) * _MAX_PATH + + sizeof(FILE_NAME_INFO)); if (!GetFileInformationByHandleEx(first_pipe_instance_.get(), FileNameInfo, - data.get(), - static_cast(bytes))) { + data.data(), + static_cast(data.size()))) { PLOG(FATAL) << "GetFileInformationByHandleEx"; } FILE_NAME_INFO* file_name_info = - reinterpret_cast(data.get()); + reinterpret_cast(data.data()); pipe_name_ = L"\\\\.\\pipe" + std::wstring(file_name_info->FileName, file_name_info->FileNameLength / diff --git a/util/win/module_version.cc b/util/win/module_version.cc index ca7aef8362..e06236694e 100644 --- a/util/win/module_version.cc +++ b/util/win/module_version.cc @@ -17,8 +17,7 @@ #include #include -#include - +#include "base/containers/heap_array.h" #include "base/logging.h" #include "base/strings/utf_string_conversions.h" @@ -33,15 +32,18 @@ bool GetModuleVersionAndType(const base::FilePath& path, return false; } - std::unique_ptr data(new uint8_t[size]); - if (!GetFileVersionInfo(path.value().c_str(), 0, size, data.get())) { + auto data = base::HeapArray::Uninit(size); + if (!GetFileVersionInfo(path.value().c_str(), + 0, + static_cast(data.size()), + data.data())) { PLOG(WARNING) << "GetFileVersionInfo: " << base::WideToUTF8(path.value()); return false; } VS_FIXEDFILEINFO* fixed_file_info; UINT ffi_size; - if (!VerQueryValue(data.get(), + if (!VerQueryValue(data.data(), L"\\", reinterpret_cast(&fixed_file_info), &ffi_size)) { diff --git a/util/win/ntstatus_logging.cc b/util/win/ntstatus_logging.cc index a1a9e37130..d4cd72c475 100644 --- a/util/win/ntstatus_logging.cc +++ b/util/win/ntstatus_logging.cc @@ -17,7 +17,10 @@ #include #include +#include "base/immediate_crash.h" +#include "base/scoped_clear_last_error.h" #include "base/strings/stringprintf.h" +#include "build/build_config.h" namespace { @@ -68,8 +71,29 @@ NtstatusLogMessage::NtstatusLogMessage( } NtstatusLogMessage::~NtstatusLogMessage() { + AppendError(); +} + +void NtstatusLogMessage::AppendError() { + // Don't let actions from this method affect the system error after returning. + base::ScopedClearLastError scoped_clear_last_error; + stream() << ": " << FormatNtstatus(ntstatus_) << base::StringPrintf(" (0x%08lx)", ntstatus_); } +#if defined(COMPILER_MSVC) +// Ignore warning that ~NtStatusLogMessageFatal never returns. +#pragma warning(push) +#pragma warning(disable : 4722) +#endif // COMPILER_MSVC +NtstatusLogMessageFatal::~NtstatusLogMessageFatal() { + AppendError(); + Flush(); + base::ImmediateCrash(); +} +#if defined(COMPILER_MSVC) +#pragma warning(pop) // C4722 +#endif // COMPILER_MSVC + } // namespace logging diff --git a/util/win/ntstatus_logging.h b/util/win/ntstatus_logging.h index dfcac5d03d..183c906787 100644 --- a/util/win/ntstatus_logging.h +++ b/util/win/ntstatus_logging.h @@ -37,10 +37,19 @@ class NtstatusLogMessage : public logging::LogMessage { ~NtstatusLogMessage(); + protected: + void AppendError(); + private: DWORD ntstatus_; }; +class NtstatusLogMessageFatal final : public NtstatusLogMessage { + public: + using NtstatusLogMessage::NtstatusLogMessage; + [[noreturn]] ~NtstatusLogMessageFatal() override; +}; + } // namespace logging #define NTSTATUS_LOG_STREAM(severity, ntstatus) \ diff --git a/util/win/process_info.cc b/util/win/process_info.cc index 6c23cd0093..1290e22cfc 100644 --- a/util/win/process_info.cc +++ b/util/win/process_info.cc @@ -24,6 +24,7 @@ #include #include "base/check_op.h" +#include "base/containers/heap_array.h" #include "base/logging.h" #include "base/memory/free_deleter.h" #include "base/process/memory.h" @@ -147,33 +148,34 @@ MEMORY_BASIC_INFORMATION64 MemoryBasicInformationToMemoryBasicInformation64( // NtQueryObject with a retry for size mismatch as well as a minimum size to // retrieve (and expect). -std::unique_ptr QueryObject( +base::HeapArray QueryObject( HANDLE handle, OBJECT_INFORMATION_CLASS object_information_class, ULONG minimum_size) { - ULONG size = minimum_size; ULONG return_length; - std::unique_ptr buffer(new uint8_t[size]); - NTSTATUS status = crashpad::NtQueryObject( - handle, object_information_class, buffer.get(), size, &return_length); + auto buffer = base::HeapArray::Uninit(minimum_size); + NTSTATUS status = crashpad::NtQueryObject(handle, + object_information_class, + buffer.data(), + (ULONG)buffer.size(), + &return_length); if (status == STATUS_INFO_LENGTH_MISMATCH) { - DCHECK_GT(return_length, size); - size = return_length; - - // Free the old buffer before attempting to allocate a new one. - buffer.reset(); - - buffer.reset(new uint8_t[size]); - status = crashpad::NtQueryObject( - handle, object_information_class, buffer.get(), size, &return_length); + DCHECK_GT(return_length, buffer.size()); + + buffer = base::HeapArray::Uninit(return_length); + status = crashpad::NtQueryObject(handle, + object_information_class, + buffer.data(), + (ULONG)buffer.size(), + &return_length); } if (!NT_SUCCESS(status)) { NTSTATUS_LOG(ERROR, status) << "NtQueryObject"; - return nullptr; + return base::HeapArray(); } - DCHECK_LE(return_length, size); + DCHECK_LE(return_length, buffer.size()); DCHECK_GE(return_length, minimum_size); return buffer; } @@ -413,14 +415,14 @@ std::vector ProcessInfo::BuildHandleVector( // information, but include the information that we do have already. ScopedKernelHANDLE scoped_dup_handle(dup_handle); - std::unique_ptr object_basic_information_buffer = + auto object_basic_information_buffer = QueryObject(dup_handle, ObjectBasicInformation, sizeof(PUBLIC_OBJECT_BASIC_INFORMATION)); - if (object_basic_information_buffer) { + if (!object_basic_information_buffer.empty()) { PUBLIC_OBJECT_BASIC_INFORMATION* object_basic_information = reinterpret_cast( - object_basic_information_buffer.get()); + object_basic_information_buffer.data()); // The Attributes and GrantedAccess sometimes differ slightly between // the data retrieved in SYSTEM_HANDLE_INFORMATION_EX and // PUBLIC_OBJECT_TYPE_INFORMATION. We prefer the values in @@ -439,14 +441,14 @@ std::vector ProcessInfo::BuildHandleVector( result_handle.handle_count = object_basic_information->HandleCount - 1; } - std::unique_ptr object_type_information_buffer = + auto object_type_information_buffer = QueryObject(dup_handle, ObjectTypeInformation, sizeof(PUBLIC_OBJECT_TYPE_INFORMATION)); - if (object_type_information_buffer) { + if (!object_type_information_buffer.empty()) { PUBLIC_OBJECT_TYPE_INFORMATION* object_type_information = reinterpret_cast( - object_type_information_buffer.get()); + object_type_information_buffer.data()); DCHECK_EQ(object_type_information->TypeName.Length % sizeof(result_handle.type_name[0]), diff --git a/util/win/process_info_test.cc b/util/win/process_info_test.cc index a4a5a57dc1..edd4c417d5 100644 --- a/util/win/process_info_test.cc +++ b/util/win/process_info_test.cc @@ -20,6 +20,7 @@ #include +#include "base/containers/heap_array.h" #include "base/files/file_path.h" #include "base/logging.h" #include "base/strings/stringprintf.h" @@ -507,26 +508,23 @@ TEST(ProcessInfo, ReadableRanges) { // Also make sure what we think we can read corresponds with what we can // actually read. - std::unique_ptr into(new unsigned char[kBlockSize * 6]); + auto into = base::HeapArray::Uninit(kBlockSize * 6); SIZE_T bytes_read; EXPECT_TRUE(ReadProcessMemory( - current_process, readable1, into.get(), kBlockSize, &bytes_read)); + current_process, readable1, into.data(), kBlockSize, &bytes_read)); EXPECT_EQ(bytes_read, kBlockSize); EXPECT_TRUE(ReadProcessMemory( - current_process, readable2, into.get(), kBlockSize * 2, &bytes_read)); + current_process, readable2, into.data(), kBlockSize * 2, &bytes_read)); EXPECT_EQ(bytes_read, kBlockSize * 2); EXPECT_FALSE(ReadProcessMemory( - current_process, no_access, into.get(), kBlockSize, &bytes_read)); + current_process, no_access, into.data(), kBlockSize, &bytes_read)); EXPECT_FALSE(ReadProcessMemory( - current_process, reserve_region, into.get(), kBlockSize, &bytes_read)); - EXPECT_FALSE(ReadProcessMemory(current_process, - reserve_region, - into.get(), - kBlockSize * 6, - &bytes_read)); + current_process, reserve_region, into.data(), kBlockSize, &bytes_read)); + EXPECT_FALSE(ReadProcessMemory( + current_process, reserve_region, into.data(), into.size(), &bytes_read)); } TEST(ProcessInfo, Handles) { @@ -633,15 +631,15 @@ TEST(ProcessInfo, Handles) { } TEST(ProcessInfo, OutOfRangeCheck) { - constexpr size_t kAllocationSize = 12345; - std::unique_ptr safe_memory(new char[kAllocationSize]); + auto safe_memory = base::HeapArray::Uninit(12345); ProcessInfo info; info.Initialize(GetCurrentProcess()); EXPECT_TRUE( info.LoggingRangeIsFullyReadable(CheckedRange( - FromPointerCast(safe_memory.get()), kAllocationSize))); + FromPointerCast(safe_memory.data()), + safe_memory.size()))); EXPECT_FALSE(info.LoggingRangeIsFullyReadable( CheckedRange(0, 1024))); } diff --git a/util/win/registration_protocol_win_test.cc b/util/win/registration_protocol_win_test.cc index 20c7523986..9ce265ac1a 100644 --- a/util/win/registration_protocol_win_test.cc +++ b/util/win/registration_protocol_win_test.cc @@ -98,7 +98,7 @@ void CheckAce(PACL acl, mask = label_ace->Mask; } break; default: - NOTREACHED(); + NOTREACHED_IN_MIGRATION(); break; }