From 96446cba1de6cbc588c08657a77ed78515a12b58 Mon Sep 17 00:00:00 2001 From: Marek Roszko Date: Mon, 15 Aug 2022 20:48:53 -0400 Subject: [PATCH] Update sentry sdk --- thirdparty/sentry-native/CHANGELOG.md | 93 + thirdparty/sentry-native/CMakeLists.txt | 13 +- thirdparty/sentry-native/CONTRIBUTING.md | 6 + thirdparty/sentry-native/README.md | 19 +- thirdparty/sentry-native/examples/example.c | 77 +- .../sentry-native/external/CMakeLists.txt | 19 +- .../breakpad/.github/workflows/coverity.yml | 7 +- .../external/breakpad/Makefile.am | 2 + .../external/breakpad/Makefile.in | 51 +- .../external/breakpad/aclocal.m4 | 76 +- .../external/breakpad/docs/symbol_files.md | 121 +- .../client/linux/handler/exception_handler.cc | 2 +- .../microdump_writer/microdump_writer.cc | 2 +- .../linux/minidump_writer/linux_dumper.cc | 2 + .../linux_ptrace_dumper_unittest.cc | 2 + .../linux/minidump_writer/minidump_writer.cc | 109 +- .../minidump_writer_unittest.cc | 2 + .../client/linux/minidump_writer/pe_file.cc | 148 + .../client/linux/minidump_writer/pe_file.h | 77 + .../client/linux/minidump_writer/pe_structs.h | 226 + .../client/mac/handler/minidump_generator.cc | 4 +- .../solaris/handler/minidump_generator.cc | 1 + .../breakpad/src/common/dwarf/dwarf2reader.cc | 2 +- .../src/common/dwarf_cfi_to_module.cc | 4 +- .../breakpad/src/common/dwarf_cu_to_module.cc | 101 +- .../breakpad/src/common/linux/dump_symbols.cc | 4 +- .../breakpad/src/common/linux/file_id.cc | 2 + .../breakpad/src/common/linux/file_id.h | 2 + .../src/common/linux/file_id_unittest.cc | 2 + .../src/common/mac/SymbolCollectorClient.h | 3 +- .../src/common/mac/SymbolCollectorClient.m | 18 +- .../breakpad/src/common/mac/dump_syms.cc | 57 +- .../breakpad/src/common/mac/dump_syms.h | 36 +- .../breakpad/src/common/mac/file_id.cc | 47 +- .../breakpad/src/common/mac/file_id.h | 25 +- .../breakpad/src/common/mac/macho_id.cc | 148 +- .../breakpad/src/common/mac/macho_id.h | 26 +- .../external/breakpad/src/common/module.cc | 43 +- .../external/breakpad/src/common/module.h | 35 +- .../src/common/solaris/dump_symbols.cc | 2 +- .../breakpad/src/common/solaris/file_id.cc | 11 +- .../breakpad/src/common/solaris/file_id.h | 2 + .../common/windows/pdb_source_line_writer.cc | 353 +- .../common/windows/pdb_source_line_writer.h | 141 +- .../breakpad/src/common/windows/pe_util.cc | 11 +- .../common/windows/sym_upload_v2_protocol.cc | 88 + .../common/windows/sym_upload_v2_protocol.h | 64 + .../common/windows/symbol_collector_client.cc | 26 +- .../common/windows/symbol_collector_client.h | 15 +- .../google_breakpad/common/minidump_format.h | 24 + .../src/google_breakpad/processor/minidump.h | 81 + .../processor/process_result.h | 6 +- .../google_breakpad/processor/process_state.h | 7 + .../google_breakpad/processor/stack_frame.h | 20 +- .../processor/stack_frame_cpu.h | 5 +- .../sentry-native/external/crashpad/.gn | 1 + .../sentry-native/external/crashpad/.vpython3 | 32 + .../sentry-native/external/crashpad/BUILD.gn | 5 +- .../external/crashpad/CMakeLists.txt | 19 +- .../sentry-native/external/crashpad/DEPS | 51 +- .../build/ios/convert_gn_xcodeproj.py | 334 +- .../crashpad/build/ios/setup_ios_gn.py | 579 +-- .../build/ios/xcodescheme-testable.template | 10 + .../crashpad/build/ios/xcodescheme.template | 80 + .../external/crashpad/build/run_tests.py | 31 +- .../external/crashpad/client/annotation.h | 9 +- .../crashpad/client/annotation_list.h | 4 +- .../crashpad/client/crash_report_database.cc | 29 +- .../client/crash_report_database_generic.cc | 24 +- .../client/crash_report_database_mac.mm | 47 +- .../client/crash_report_database_test.cc | 45 +- .../client/crash_report_database_win.cc | 27 +- .../crashpad/client/crashpad_client.h | 63 +- .../crashpad/client/crashpad_client_ios.cc | 235 +- .../client/crashpad_client_ios_test.mm | 102 +- .../crashpad/client/crashpad_client_linux.cc | 133 +- .../client/crashpad_client_linux_test.cc | 97 +- .../crashpad/client/crashpad_client_mac.cc | 6 +- .../crashpad/client/crashpad_client_win.cc | 19 +- .../external/crashpad/client/crashpad_info.cc | 17 +- .../external/crashpad/client/crashpad_info.h | 8 +- .../crashpad/client/crashpad_info_note.S | 2 +- .../client/ios_handler/exception_processor.h | 29 +- .../client/ios_handler/exception_processor.mm | 231 +- .../client/ios_handler/in_process_handler.cc | 320 +- .../client/ios_handler/in_process_handler.h | 175 +- .../ios_handler/in_process_handler_test.cc | 3 +- .../in_process_intermediate_dump_handler.cc | 42 +- ..._process_intermediate_dump_handler_test.cc | 22 +- ...rmediate_dumps_and_crash_reports_thread.cc | 24 +- ...ermediate_dumps_and_crash_reports_thread.h | 4 + .../external/crashpad/client/settings.cc | 45 +- .../external/crashpad/client/settings.h | 31 +- .../external/crashpad/client/settings_test.cc | 2 +- .../client/simple_string_dictionary_test.cc | 12 +- .../external/crashpad/client/simulate_crash.h | 8 +- .../crashpad/client/simulate_crash_mac.cc | 7 +- .../client/simulate_crash_mac_test.cc | 9 +- .../external/crashpad/compat/non_elf/elf.h | 20 - .../crashpad/compat/non_win/dbghelp.h | 48 + .../external/crashpad/compat/non_win/winnt.h | 11 + .../external/crashpad/doc/developing.md | 5 +- .../crashpad/doc/support/generate_doxygen.py | 2 +- .../handler/crash_report_upload_thread.cc | 34 +- .../handler/crash_report_upload_thread.h | 8 +- .../crashpad_handler_test_extended_handler.cc | 8 +- .../external/crashpad/handler/handler_main.cc | 306 +- .../external/crashpad/handler/handler_main.h | 2 +- .../linux/crash_report_exception_handler.cc | 4 +- .../handler/linux/exception_handler_server.cc | 2 +- .../linux/exception_handler_server_test.cc | 2 +- .../handler/mac/file_limit_annotation.cc | 4 +- .../external/crashpad/handler/main.cc | 8 +- .../handler/win/crash_other_program.cc | 3 +- .../handler/win/crashy_test_program.cc | 6 +- .../crashpad/handler/win/hanging_program.cc | 5 +- .../infra/config/generated/cr-buildbucket.cfg | 60 +- .../infra/config/generated/luci-scheduler.cfg | 28 +- .../infra/config/generated/project.cfg | 3 +- .../external/crashpad/infra/config/main.star | 22 +- .../external/crashpad/minidump/BUILD.gn | 3 + .../external/crashpad/minidump/CMakeLists.txt | 2 + .../minidump/minidump_annotation_writer.cc | 7 +- .../minidump_annotation_writer_test.cc | 4 +- .../minidump_byte_array_writer_test.cc | 6 +- .../crashpad/minidump/minidump_context.h | 47 +- .../minidump/minidump_context_writer.cc | 115 +- .../minidump/minidump_context_writer.h | 39 + .../minidump/minidump_context_writer_test.cc | 125 +- .../minidump_exception_writer_test.cc | 4 +- .../crashpad/minidump/minidump_extensions.h | 5 + .../crashpad/minidump/minidump_file_writer.cc | 20 + .../minidump/minidump_file_writer_test.cc | 13 +- .../minidump/minidump_memory_writer_test.cc | 8 +- .../minidump/minidump_misc_info_writer.cc | 83 +- .../minidump/minidump_misc_info_writer.h | 3 + .../minidump_misc_info_writer_test.cc | 59 +- ...nidump_module_crashpad_info_writer_test.cc | 8 +- .../minidump/minidump_module_writer_test.cc | 12 +- .../minidump/minidump_rva_list_writer_test.cc | 6 +- .../minidump/minidump_string_writer_test.cc | 81 +- .../minidump/minidump_system_info_writer.cc | 5 +- .../minidump_system_info_writer_test.cc | 4 +- .../minidump/minidump_thread_id_map_test.cc | 7 +- .../minidump_thread_name_list_writer.cc | 191 + .../minidump_thread_name_list_writer.h | 152 + .../minidump_thread_name_list_writer_test.cc | 310 ++ .../minidump/minidump_thread_writer_test.cc | 12 +- .../crashpad/minidump/minidump_writable.cc | 76 +- .../crashpad/minidump/minidump_writable.h | 9 + .../minidump/minidump_writable_test.cc | 237 +- .../test/minidump_context_test_util.cc | 83 +- .../test/minidump_string_writer_test_util.cc | 73 +- .../test/minidump_string_writer_test_util.h | 22 + .../test/minidump_writable_test_util.cc | 66 +- .../test/minidump_writable_test_util.h | 54 +- .../external/crashpad/snapshot/BUILD.gn | 7 +- .../crashpad/snapshot/capture_memory.cc | 13 +- .../external/crashpad/snapshot/cpu_context.cc | 36 +- .../external/crashpad/snapshot/cpu_context.h | 20 + .../crashpad/snapshot/cpu_context_test.cc | 23 +- .../crashpad_info_client_options_test.cc | 28 +- ...rashpad_info_client_options_test_module.cc | 10 +- .../crashpad_info_size_test_module.cc | 29 +- .../snapshot/crashpad_info_size_test_note.S | 2 +- .../crashpad_types/crashpad_info_reader.cc | 6 +- .../crashpad_info_reader_test.cc | 4 +- .../image_annotation_reader_test.cc | 4 +- .../crashpad/snapshot/elf/elf_image_reader.cc | 4 +- .../snapshot/elf/elf_image_reader_test.cc | 23 +- .../snapshot/elf/elf_image_reader_test_note.S | 2 +- .../memory_map_region_snapshot_fuchsia.cc | 5 +- .../fuchsia/process_reader_fuchsia_test.cc | 36 +- .../fuchsia/process_snapshot_fuchsia_test.cc | 17 +- .../fuchsia/thread_snapshot_fuchsia.cc | 7 + .../fuchsia/thread_snapshot_fuchsia.h | 4 + ...xception_snapshot_ios_intermediate_dump.cc | 19 +- .../memory_snapshot_ios_intermediate_dump.cc | 25 + .../memory_snapshot_ios_intermediate_dump.h | 8 + ...ory_snapshot_ios_intermediate_dump_test.cc | 161 + .../module_snapshot_ios_intermediate_dump.cc | 14 +- ...ess_snapshot_ios_intermediate_dump_test.cc | 129 +- .../ios/testdata/crash-6605504629637120 | Bin 0 -> 42751 bytes .../thread_snapshot_ios_intermediate_dump.cc | 12 + .../thread_snapshot_ios_intermediate_dump.h | 4 + .../linux/capture_memory_delegate_linux.cc | 16 +- .../snapshot/linux/debug_rendezvous.cc | 6 +- .../snapshot/linux/debug_rendezvous_test.cc | 14 +- .../linux/exception_snapshot_linux.cc | 19 +- .../snapshot/linux/exception_snapshot_linux.h | 3 +- .../linux/exception_snapshot_linux_test.cc | 22 +- .../snapshot/linux/process_reader_linux.cc | 29 +- .../snapshot/linux/process_reader_linux.h | 1 + .../linux/process_reader_linux_test.cc | 81 +- .../snapshot/linux/process_snapshot_linux.cc | 26 +- .../crashpad/snapshot/linux/signal_context.h | 4 +- .../snapshot/linux/system_snapshot_linux.cc | 19 +- .../linux/system_snapshot_linux_test.cc | 4 +- .../snapshot/linux/thread_snapshot_linux.cc | 7 + .../snapshot/linux/thread_snapshot_linux.h | 2 + .../snapshot/mac/mach_o_image_reader.cc | 7 +- .../mac/mach_o_image_segment_reader_test.cc | 9 +- .../snapshot/mac/process_reader_mac.cc | 15 + .../snapshot/mac/process_reader_mac.h | 1 + .../snapshot/mac/process_reader_mac_test.cc | 86 +- .../crashpad/snapshot/mac/process_types.cc | 4 +- .../snapshot/mac/process_types/custom.cc | 9 +- .../snapshot/mac/process_types_test.cc | 8 +- .../snapshot/mac/thread_snapshot_mac.cc | 7 + .../snapshot/mac/thread_snapshot_mac.h | 4 + .../minidump/minidump_context_converter.cc | 19 +- .../minidump/minidump_string_reader.cc | 32 +- .../minidump/minidump_string_reader.h | 17 + .../minidump/module_snapshot_minidump.cc | 10 +- .../minidump/process_snapshot_minidump.cc | 74 +- .../minidump/process_snapshot_minidump.h | 5 + .../process_snapshot_minidump_test.cc | 133 +- .../minidump/thread_snapshot_minidump.cc | 18 +- .../minidump/thread_snapshot_minidump.h | 9 +- .../crashpad/snapshot/posix/timezone.cc | 12 +- .../crashpad/snapshot/posix/timezone_test.cc | 4 +- .../process_snapshot_sanitized_test.cc | 7 +- .../sanitization_information_test.cc | 7 +- .../sanitized/thread_snapshot_sanitized.cc | 4 + .../sanitized/thread_snapshot_sanitized.h | 3 + .../snapshot/test/test_cpu_context.cc | 35 +- .../snapshot/test/test_thread_snapshot.cc | 4 + .../snapshot/test/test_thread_snapshot.h | 6 + .../crashpad/snapshot/thread_snapshot.h | 5 +- .../win/capture_memory_delegate_win.cc | 16 +- .../crashpad/snapshot/win/cpu_context_win.cc | 178 +- .../crashpad/snapshot/win/cpu_context_win.h | 19 +- .../snapshot/win/cpu_context_win_test.cc | 15 +- .../crashpad_snapshot_test_image_reader.cc | 9 +- .../crashpad/snapshot/win/end_to_end_test.py | 20 +- .../snapshot/win/exception_snapshot_win.cc | 39 +- .../snapshot/win/exception_snapshot_win.h | 5 +- .../win/exception_snapshot_win_test.cc | 1 - .../win/pe_image_annotations_reader.cc | 6 +- .../crashpad/snapshot/win/pe_image_reader.cc | 4 +- .../snapshot/win/process_reader_win.cc | 132 +- .../snapshot/win/process_reader_win.h | 40 +- .../snapshot/win/process_reader_win_test.cc | 61 +- .../snapshot/win/process_snapshot_win.cc | 64 +- .../snapshot/win/process_snapshot_win.h | 3 +- .../snapshot/win/system_snapshot_win.cc | 127 +- .../snapshot/win/thread_snapshot_win.cc | 63 +- .../snapshot/win/thread_snapshot_win.h | 1 + .../crashpad/snapshot/x86/cpuid_reader.cc | 13 +- .../external/crashpad/test/BUILD.gn | 15 +- .../external/crashpad/test/errors.cc | 10 +- .../external/crashpad/test/errors.h | 2 +- .../external/crashpad/test/file.cc | 32 +- .../external/crashpad/test/file.h | 6 + .../external/crashpad/test/filesystem.cc | 37 +- .../external/crashpad/test/filesystem.h | 4 +- .../external/crashpad/test/gtest_death.h | 8 +- .../external/crashpad/test/gtest_main.cc | 32 +- .../external/crashpad/test/hex_string.h | 4 +- .../external/crashpad/test/hex_string_test.cc | 5 +- .../crashpad/test/ios/crash_type_xctest.mm | 192 +- .../external/crashpad/test/ios/host/BUILD.gn | 3 + .../ios/host/cptest_application_delegate.mm | 231 +- .../test/ios/host/cptest_shared_object.h | 45 +- .../ios/host/handler_forbidden_allocators.cc | 295 ++ .../ios/host/handler_forbidden_allocators.h | 31 + .../crashpad/test/mac/mach_multiprocess.cc | 4 +- .../external/crashpad/test/multiprocess.h | 18 +- .../crashpad/test/multiprocess_exec.cc | 3 +- .../crashpad/test/multiprocess_exec.h | 6 +- .../crashpad/test/multiprocess_exec_posix.cc | 8 +- .../crashpad/test/multiprocess_exec_test.cc | 4 +- .../test/multiprocess_exec_test_child.cc | 18 +- .../crashpad/test/multiprocess_posix.cc | 12 +- .../external/crashpad/test/process_type.cc | 14 +- .../external/crashpad/test/process_type.h | 18 +- .../crashpad/test/scoped_module_handle.cc | 5 +- .../crashpad/test/scoped_module_handle.h | 8 +- .../crashpad/test/scoped_set_thread_name.h | 46 + .../test/scoped_set_thread_name_fuchsia.cc | 61 + .../test/scoped_set_thread_name_posix.cc | 80 + .../test/scoped_set_thread_name_win.cc | 56 + .../crashpad/test/scoped_temp_dir_posix.cc | 2 +- .../crashpad/test/scoped_temp_dir_test.cc | 14 +- .../external/crashpad/test/test_paths.cc | 56 +- .../external/crashpad/test/test_paths.h | 8 +- .../crashpad/third_party/edo/BUILD.gn | 10 +- .../crashpad/third_party/glibc/BUILD.gn | 17 - .../crashpad/third_party/glibc/COPYING.LIB | 502 --- .../third_party/glibc/README.crashpad | 16 - .../crashpad/third_party/glibc/elf/elf.h | 4003 ----------------- .../crashpad/third_party/googletest/BUILD.gn | 32 +- .../external/crashpad/third_party/lss/lss.h | 2 +- .../crashpad/third_party/lss/lss/DIR_METADATA | 12 + .../crashpad/third_party/lss/lss/LICENSE | 28 + .../crashpad/third_party/lss/lss/OWNERS | 2 + .../crashpad/third_party/lss/lss/README.md | 2 +- .../lss/lss/linux_syscall_support.h | 406 +- .../third_party/lss/lss/tests/fallocate.c | 2 + .../third_party/lss/lss/tests/getrandom.c | 59 + .../third_party/lss/lss/tests/lstat.c | 97 + .../third_party/lss/lss/tests/sigaction.c | 54 + .../crashpad/third_party/lss/lss/tests/stat.c | 67 + .../third_party/lss/lss/tests/test_skel.h | 4 + .../third_party/mini_chromium/CMakeLists.txt | 1 - .../mini_chromium/build/chromeos_buildflags.h | 4 +- .../mini_chromium/mini_chromium/.style.yapf | 7 + .../mini_chromium/mini_chromium/base/BUILD.gn | 1 - .../mini_chromium/base/atomicops.h | 8 +- .../mini_chromium/base/compiler_specific.h | 34 +- .../mini_chromium/base/files/file_path.h | 29 +- .../mini_chromium/base/files/file_util.h | 4 +- .../mini_chromium/base/files/scoped_file.cc | 6 +- .../mini_chromium/base/files/scoped_file.h | 8 +- .../mini_chromium/base/format_macros.h | 8 +- .../mini_chromium/base/ignore_result.h | 14 - .../mini_chromium/base/logging.cc | 121 +- .../mini_chromium/base/logging.h | 22 +- .../mini_chromium/base/mac/foundation_util.h | 4 +- .../mini_chromium/base/mac/foundation_util.mm | 4 +- .../mini_chromium/base/mac/mach_logging.cc | 8 +- .../mini_chromium/base/mac/mach_logging.h | 4 +- .../base/mac/scoped_nsautorelease_pool.h | 10 +- .../mini_chromium/base/mac/scoped_typeref.h | 5 +- .../base/numerics/checked_math.h | 8 +- .../mini_chromium/base/posix/eintr_wrapper.h | 4 +- .../mini_chromium/base/posix/safe_strerror.cc | 4 +- .../mini_chromium/base/process/memory.h | 5 +- .../mini_chromium/base/rand_util.cc | 18 +- .../base/scoped_clear_last_error.h | 6 +- .../mini_chromium/base/scoped_generic.h | 4 +- .../mini_chromium/base/strings/string_util.h | 5 +- .../base/strings/stringprintf.cc | 5 +- .../base/strings/sys_string_conversions.h | 4 +- .../base/synchronization/lock.cc | 4 +- .../mini_chromium/base/synchronization/lock.h | 8 +- .../base/synchronization/lock_impl.h | 8 +- .../mini_chromium/base/sys_byteorder.h | 16 +- .../base/threading/thread_local_storage.cc | 6 +- .../base/threading/thread_local_storage.h | 13 +- .../mini_chromium/build/BUILD.gn | 3 +- .../mini_chromium/build/build_config.h | 82 +- .../mini_chromium/build/buildflag.h | 9 +- .../mini_chromium/build/config/BUILD.gn | 13 +- .../build/ios/XCTRunnerAddition+Info.plist | 2 +- .../mini_chromium/build/ios/codesign.py | 236 +- .../build/ios/find_signing_identity.py | 91 +- .../mini_chromium/build/ios/ios_sdk.gni | 19 +- .../mini_chromium/build/ios/plist_util.py | 125 +- .../mini_chromium/build/ios/rules.gni | 26 +- .../mini_chromium/build/ios/sdk_info.py | 116 +- .../mini_chromium/build/ios/strip_arm64e.py | 7 +- .../mini_chromium/build/win_helper.py | 44 +- .../build/write_buildflag_header.py | 120 +- .../external/crashpad/tools/base94_encoder.cc | 8 +- .../crashpad/tools/crashpad_database_util.cc | 18 +- .../crashpad/tools/crashpad_http_upload.cc | 9 +- .../external/crashpad/tools/generate_dump.cc | 38 +- .../tools/mac/catch_exception_tool.cc | 2 + .../crashpad/tools/mac/exception_port_tool.cc | 2 + .../tools/mac/on_demand_service_tool.mm | 2 + .../crashpad/tools/run_with_crashpad.cc | 14 +- .../external/crashpad/tools/tool_support.cc | 21 +- .../external/crashpad/tools/tool_support.h | 8 +- .../external/crashpad/util/BUILD.gn | 11 +- .../external/crashpad/util/CMakeLists.txt | 17 +- .../util/file/delimited_file_reader.cc | 4 +- .../util/file/delimited_file_reader_test.cc | 8 +- .../crashpad/util/file/directory_reader.h | 14 +- .../util/file/directory_reader_test.cc | 13 +- .../external/crashpad/util/file/file_io.h | 20 +- .../crashpad/util/file/file_io_posix.cc | 10 +- .../crashpad/util/file/file_io_test.cc | 17 +- .../crashpad/util/file/file_writer.cc | 18 +- .../external/crashpad/util/file/file_writer.h | 3 +- .../crashpad/util/file/filesystem_posix.cc | 4 +- .../crashpad/util/file/filesystem_test.cc | 38 +- .../util/ios/ios_intermediate_dump_format.h | 1 + .../util/ios/ios_intermediate_dump_reader.cc | 6 + .../ios/ios_intermediate_dump_reader_test.cc | 1 + .../util/ios/ios_intermediate_dump_writer.cc | 14 +- .../util/ios/ios_intermediate_dump_writer.h | 6 +- .../ios/ios_intermediate_dump_writer_test.cc | 1 + .../util/ios/ios_system_data_collector.h | 32 +- .../util/ios/ios_system_data_collector.mm | 82 +- .../external/crashpad/util/ios/raw_logging.cc | 20 +- .../external/crashpad/util/ios/raw_logging.h | 7 + .../util/ios/scoped_background_task.h | 40 + .../util/ios/scoped_background_task.mm | 58 + .../util/linux/auxiliary_vector_test.cc | 4 +- .../util/linux/exception_handler_client.cc | 2 +- .../util/linux/exception_handler_protocol.cc | 12 +- .../util/linux/exception_handler_protocol.h | 2 +- .../crashpad/util/linux/memory_map.cc | 10 +- .../crashpad/util/linux/memory_map_test.cc | 18 +- .../crashpad/util/linux/proc_stat_reader.cc | 5 +- .../crashpad/util/linux/proc_task_reader.cc | 5 +- .../crashpad/util/linux/ptrace_client.cc | 4 +- .../crashpad/util/linux/thread_info.h | 7 +- .../mac/checked_mach_address_range_test.cc | 8 +- .../crashpad/util/mac/launchd_test.mm | 10 +- .../util/mach/child_port_handshake.cc | 6 +- .../crashpad/util/mach/child_port_handshake.h | 4 +- .../crashpad/util/mach/child_port_server.cc | 5 +- .../composite_mach_message_server_test.cc | 15 +- .../util/mach/exc_client_variants_test.cc | 11 +- .../crashpad/util/mach/exc_server_variants.cc | 12 +- .../util/mach/exc_server_variants_test.cc | 51 +- .../util/mach/exception_behaviors_test.cc | 5 +- .../util/mach/exception_types_test.cc | 9 +- .../crashpad/util/mach/mach_extensions.cc | 12 +- .../util/mach/mach_extensions_test.cc | 12 +- .../crashpad/util/mach/mach_message.cc | 9 +- .../crashpad/util/mach/mach_message.h | 4 +- .../util/mach/mach_message_server_test.cc | 4 +- .../crashpad/util/mach/mach_message_test.cc | 10 +- .../external/crashpad/util/mach/mig.py | 2 +- .../external/crashpad/util/mach/mig_fix.py | 40 +- .../external/crashpad/util/mach/mig_gen.py | 2 +- .../crashpad/util/mach/notify_server.cc | 5 +- .../util/mach/symbolic_constants_mach.cc | 28 +- .../util/mach/symbolic_constants_mach_test.cc | 50 +- .../crashpad/util/misc/address_types.h | 16 +- .../{arm64_bti_note.S => arm64_pac_bti.S} | 49 +- .../external/crashpad/util/misc/arraysize.h | 6 +- .../crashpad/util/misc/arraysize_test.cc | 31 +- .../crashpad/util/misc/capture_context.h | 20 +- .../util/misc/capture_context_linux.S | 7 +- .../util/misc/capture_context_test.cc | 4 +- .../misc/capture_context_test_util_win.cc | 11 +- .../crashpad/util/misc/clock_posix.cc | 2 +- .../external/crashpad/util/misc/clock_test.cc | 13 +- .../util/misc/initialization_state_dcheck.h | 15 +- .../external/crashpad/util/misc/metrics.cc | 12 +- .../external/crashpad/util/misc/metrics.h | 4 +- .../crashpad/util/misc/no_cfi_icall.h | 18 +- .../crashpad/util/misc/no_cfi_icall_test.cc | 6 +- .../external/crashpad/util/misc/paths_win.cc | 11 +- .../crashpad/util/misc/random_string_test.cc | 6 +- .../util/misc/scoped_forbid_return_test.cc | 10 +- .../external/crashpad/util/misc/time.h | 12 +- .../external/crashpad/util/misc/time_test.cc | 9 +- .../external/crashpad/util/misc/uuid.cc | 23 +- .../external/crashpad/util/misc/uuid.h | 14 +- .../external/crashpad/util/misc/uuid_test.cc | 17 +- .../util/net/http_transport_socket.cc | 13 +- .../crashpad/util/net/http_transport_test.cc | 6 +- .../util/net/http_transport_test_server.cc | 6 +- .../crashpad/util/net/http_transport_win.cc | 5 +- .../util/numeric/checked_address_range.cc | 21 +- .../numeric/checked_address_range_test.cc | 8 +- .../util/numeric/checked_range_test.cc | 12 +- .../crashpad/util/posix/close_multiple.cc | 21 +- .../crashpad/util/posix/close_stdio.cc | 5 +- .../crashpad/util/posix/drop_privileges.cc | 4 +- .../crashpad/util/posix/process_info.h | 16 +- .../crashpad/util/posix/process_info_mac.cc | 11 +- .../crashpad/util/posix/process_info_test.cc | 21 +- .../crashpad/util/posix/scoped_mmap.cc | 4 +- .../crashpad/util/posix/scoped_mmap_test.cc | 17 +- .../external/crashpad/util/posix/signals.cc | 33 +- .../crashpad/util/posix/signals_test.cc | 41 +- .../util/posix/symbolic_constants_posix.cc | 21 +- .../posix/symbolic_constants_posix_test.cc | 66 +- .../crashpad/util/process/process_id.h | 12 +- .../crashpad/util/process/process_memory.h | 4 +- .../util/process/process_memory_native.h | 16 +- .../util/process/process_memory_range_test.cc | 21 +- .../process/process_memory_sanitized_test.cc | 13 +- .../util/process/process_memory_test.cc | 33 +- .../crashpad/util/stdlib/aligned_allocator.cc | 24 +- .../util/stdlib/aligned_allocator_test.cc | 18 +- .../stdlib/string_number_conversion_test.cc | 6 +- .../crashpad/util/stdlib/strlcpy_test.cc | 14 +- .../external/crashpad/util/stdlib/strnlen.cc | 4 +- .../external/crashpad/util/stdlib/strnlen.h | 4 +- .../util/stdlib/thread_safe_vector_test.cc | 11 +- .../util/stream/base94_output_stream_test.cc | 4 +- .../crashpad/util/stream/file_encoder.cc | 4 +- .../util/stream/zlib_output_stream.cc | 9 +- .../util/stream/zlib_output_stream_test.cc | 4 +- .../crashpad/util/synchronization/semaphore.h | 12 +- .../util/synchronization/semaphore_posix.cc | 7 +- .../util/synchronization/semaphore_test.cc | 40 +- .../external/crashpad/util/thread/thread.h | 24 +- .../util/thread/thread_log_messages_test.cc | 9 +- .../crashpad/util/thread/thread_posix.cc | 10 + .../util/thread/worker_thread_test.cc | 3 +- .../crashpad/util/win/command_line_test.cc | 17 +- .../crashpad/util/win/exception_codes.h | 37 + .../util/win/exception_handler_server.cc | 6 +- .../crashpad/util/win/ntstatus_logging.cc | 4 +- .../util/win/registration_protocol_win.cc | 10 +- .../util/win/safe_terminate_process_test.cc | 6 +- thirdparty/sentry-native/include/sentry.h | 180 +- thirdparty/sentry-native/src/CMakeLists.txt | 11 +- .../src/backends/sentry_backend_breakpad.cpp | 84 +- .../src/backends/sentry_backend_crashpad.cpp | 126 +- .../src/backends/sentry_backend_inproc.c | 311 +- .../sentry_modulefinder_windows.c | 77 +- thirdparty/sentry-native/src/sentry_backend.h | 1 + thirdparty/sentry-native/src/sentry_core.c | 88 +- thirdparty/sentry-native/src/sentry_core.h | 11 +- .../sentry-native/src/sentry_database.c | 35 +- .../sentry-native/src/sentry_database.h | 10 + .../sentry-native/src/sentry_envelope.c | 16 +- .../sentry-native/src/sentry_envelope.h | 2 - thirdparty/sentry-native/src/sentry_info.c | 19 + thirdparty/sentry-native/src/sentry_options.c | 23 +- thirdparty/sentry-native/src/sentry_options.h | 4 +- thirdparty/sentry-native/src/sentry_scope.c | 18 +- thirdparty/sentry-native/src/sentry_scope.h | 4 - thirdparty/sentry-native/src/sentry_tracing.c | 4 +- thirdparty/sentry-native/src/sentry_tracing.h | 1 - thirdparty/sentry-native/src/sentry_utils.c | 18 +- thirdparty/sentry-native/src/sentry_utils.h | 2 +- thirdparty/sentry-native/src/sentry_uuid.c | 10 +- thirdparty/sentry-native/src/sentry_uuid.h | 3 - thirdparty/sentry-native/src/sentry_value.c | 12 +- thirdparty/sentry-native/src/sentry_value.h | 2 - thirdparty/sentry-native/tests/assertions.py | 35 +- thirdparty/sentry-native/tests/cmake.py | 4 +- .../sentry-native/tests/requirements.txt | 2 +- .../tests/test_integration_crashpad.py | 133 +- .../tests/test_integration_http.py | 4 +- .../tests/test_integration_stdout.py | 152 +- .../sentry-native/tests/unit/CMakeLists.txt | 2 +- thirdparty/sentry-native/tests/unit/fuzz.c | 2 - .../tests/unit/test_attachments.c | 1 - .../sentry-native/tests/unit/test_basic.c | 124 +- .../tests/unit/test_concurrency.c | 2 +- .../sentry-native/tests/unit/test_consent.c | 1 - .../sentry-native/tests/unit/test_envelopes.c | 1 - .../sentry-native/tests/unit/test_failures.c | 1 - .../tests/unit/test_fuzzfailures.c | 2 +- .../sentry-native/tests/unit/test_info.c | 16 + .../sentry-native/tests/unit/test_logger.c | 1 - .../tests/unit/test_modulefinder.c | 1 - .../sentry-native/tests/unit/test_mpack.c | 1 - .../sentry-native/tests/unit/test_path.c | 1 - .../tests/unit/test_ratelimiter.c | 1 - .../sentry-native/tests/unit/test_session.c | 7 +- .../sentry-native/tests/unit/test_slice.c | 1 - .../tests/unit/test_symbolizer.c | 1 - .../sentry-native/tests/unit/test_uninit.c | 1 - .../sentry-native/tests/unit/test_unwinder.c | 1 - .../sentry-native/tests/unit/test_utils.c | 31 +- .../sentry-native/tests/unit/test_uuid.c | 4 +- .../sentry-native/tests/unit/test_value.c | 19 +- thirdparty/sentry-native/tests/unit/tests.inc | 7 + 550 files changed, 12924 insertions(+), 8971 deletions(-) create mode 100644 thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.cc create mode 100644 thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.h create mode 100644 thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_structs.h create mode 100644 thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.cc create mode 100644 thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.h create mode 100644 thirdparty/sentry-native/external/crashpad/.vpython3 create mode 100644 thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme-testable.template create mode 100644 thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme.template delete mode 100644 thirdparty/sentry-native/external/crashpad/compat/non_elf/elf.h create mode 100644 thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.cc create mode 100644 thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.h create mode 100644 thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer_test.cc create mode 100644 thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump_test.cc create mode 100644 thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-6605504629637120 create mode 100644 thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.cc create mode 100644 thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.h create mode 100644 thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name.h create mode 100644 thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_fuchsia.cc create mode 100644 thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_posix.cc create mode 100644 thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_win.cc delete mode 100644 thirdparty/sentry-native/external/crashpad/third_party/glibc/BUILD.gn delete mode 100644 thirdparty/sentry-native/external/crashpad/third_party/glibc/COPYING.LIB delete mode 100644 thirdparty/sentry-native/external/crashpad/third_party/glibc/README.crashpad delete mode 100644 thirdparty/sentry-native/external/crashpad/third_party/glibc/elf/elf.h create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/DIR_METADATA create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/LICENSE create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/OWNERS create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getrandom.c create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/lstat.c create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/sigaction.c create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/stat.c create mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/.style.yapf delete mode 100644 thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/ignore_result.h create mode 100644 thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.h create mode 100644 thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.mm rename thirdparty/sentry-native/external/crashpad/util/misc/{arm64_bti_note.S => arm64_pac_bti.S} (63%) create mode 100644 thirdparty/sentry-native/external/crashpad/util/win/exception_codes.h create mode 100644 thirdparty/sentry-native/src/sentry_info.c create mode 100644 thirdparty/sentry-native/tests/unit/test_info.c diff --git a/thirdparty/sentry-native/CHANGELOG.md b/thirdparty/sentry-native/CHANGELOG.md index 0a7a13d4ec..192102553f 100644 --- a/thirdparty/sentry-native/CHANGELOG.md +++ b/thirdparty/sentry-native/CHANGELOG.md @@ -1,5 +1,98 @@ # Changelog +## 0.5.0 + +**Features** + +- Provide `on_crash()` callback to allow clients to act on detected crashes. + Users often inquired about distinguishing between crashes and "normal" events in the `before_send()` hook. + `on_crash()` can be considered a replacement for `before_send()` for crash events, where the goal is to use + `before_send()` only for normal events, while `on_crash()` is only invoked for crashes. This change is backward + compatible for current users of `before_send()` and allows gradual migration to `on_crash()` + ([see the docs for details](https://docs.sentry.io/platforms/native/configuration/filtering/)). + ([#724](https://github.com/getsentry/sentry-native/pull/724), + [#734](https://github.com/getsentry/sentry-native/pull/734)) + +**Fixes** + +- Make Windows ModuleFinder more resilient to missing Debug Info + ([#732](https://github.com/getsentry/sentry-native/pull/732)) +- Aligned pre-send event processing in `sentry_capture_event()` with the + [cross-SDK session filter order](https://develop.sentry.dev/sdk/sessions/#filter-order) + ([#729](https://github.com/getsentry/sentry-native/pull/729)) +- Align the default value initialization for the `environment` payload attribute with the + [developer documentation](https://develop.sentry.dev/sdk/event-payloads/#optional-attribute) + ([#739](https://github.com/getsentry/sentry-native/pull/739)) +- Iterate all debug directory entries when parsing PE modules for a valid CodeView record + ([#740](https://github.com/getsentry/sentry-native/pull/740)) + +**Thank you**: + +Features, fixes and improvements in this release have been contributed by: + +- [@espkk](https://github.com/espkk) + +## 0.4.18 + +**Features**: + +- The crashpad backend now captures thread names. ([#725](https://github.com/getsentry/sentry-native/pull/725)) +- The inproc backend now captures the context registers. ([#714](https://github.com/getsentry/sentry-native/pull/714)) +- A new set of APIs to get the sentry SDK version at runtime. ([#726](https://github.com/getsentry/sentry-native/pull/726)) +- Add more convenient APIs to attach stack traces to exception or thread values. ([#723](https://github.com/getsentry/sentry-native/pull/723)) +- Allow disabling the crash reporting backend at runtime. ([#717](https://github.com/getsentry/sentry-native/pull/717)) + +**Fixes**: + +- Improved heuristics flagging sessions as "crashed". ([#719](https://github.com/getsentry/sentry-native/pull/719)) + +**Internal**: + +- Updated Breakpad and Crashpad backends to 2022-06-14. ([#725](https://github.com/getsentry/sentry-native/pull/725)) + +**Thank you**: + +Features, fixes and improvements in this release have been contributed by: + +- [@olback](https://github.com/olback) + +## 0.4.17 + +**Fixes**: + +- sentry-native now successfully builds when examples aren't included. ([#702](https://github.com/getsentry/sentry-native/pull/702)) + +**Thank you**: + +Features, fixes and improvements in this release have been contributed by: + +- [@AenBleidd](https://github.com/AenBleidd) + +## 0.4.16 + +**Features**: + +- Removed the `SENTRY_PERFORMANCE_MONITORING` compile flag requirement to access performance monitoring in the Sentry SDK. Performance monitoring is now available to everybody who has opted into the experimental API. +- New API to check whether the application has crashed in the previous run: `sentry_get_crashed_last_run()` and `sentry_clear_crashed_last_run()` ([#685](https://github.com/getsentry/sentry-native/pull/685)). +- Allow overriding the SDK name at build time - set the `SENTRY_SDK_NAME` CMake cache variable. +- More aggressively prune the Crashpad database. ([#698](https://github.com/getsentry/sentry-native/pull/698)) + +**Internal**: + +- Project IDs are now treated as opaque strings instead of integer values. ([#690](https://github.com/getsentry/sentry-native/pull/690)) +- Updated Breakpad and Crashpad backends to 2022-04-12. ([#696](https://github.com/getsentry/sentry-native/pull/696)) + +**Fixes**: + +- Updated CI as well as list of supported platforms to reflect Windows Server 2016, and therefore MSVC 2017 losing active support. +- Correctly free Windows Mutexes in Crashpad backend. + +**Thank you**: + +Features, fixes and improvements in this release have been contributed by: + +- [@zhaowq32](https://github.com/zhaowq32) + ## 0.4.15 **Fixes**: diff --git a/thirdparty/sentry-native/CMakeLists.txt b/thirdparty/sentry-native/CMakeLists.txt index 12f1cc2590..31861875aa 100644 --- a/thirdparty/sentry-native/CMakeLists.txt +++ b/thirdparty/sentry-native/CMakeLists.txt @@ -30,7 +30,7 @@ if(NOT CMAKE_C_STANDARD) endif() if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 14) + set(CMAKE_CXX_STANDARD 17) endif() include(GNUInstallDirs) @@ -151,9 +151,12 @@ if(SENTRY_BACKEND_CRASHPAD AND ANDROID) message(FATAL_ERROR "The Crashpad backend is not currently supported on Android") endif() +set(SENTRY_SDK_NAME "" CACHE STRING "The SDK name to report when sending events.") + message(STATUS "SENTRY_TRANSPORT=${SENTRY_TRANSPORT}") message(STATUS "SENTRY_BACKEND=${SENTRY_BACKEND}") message(STATUS "SENTRY_LIBRARY_TYPE=${SENTRY_LIBRARY_TYPE}") +message(STATUS "SENTRY_SDK_NAME=${SENTRY_SDK_NAME}") if(ANDROID) set(SENTRY_WITH_LIBUNWINDSTACK TRUE) @@ -221,6 +224,10 @@ target_sources(sentry PRIVATE "${PROJECT_SOURCE_DIR}/include/sentry.h") add_library(sentry::sentry ALIAS sentry) add_subdirectory(src) +if (NOT SENTRY_SDK_NAME STREQUAL "") + target_compile_definitions(sentry PRIVATE SENTRY_SDK_NAME="${SENTRY_SDK_NAME}") +endif() + # we do not need this on android, only linux if(LINUX) target_sources(sentry PRIVATE @@ -559,8 +566,6 @@ if(SENTRY_BUILD_EXAMPLES) add_executable(sentry_example examples/example.c) target_link_libraries(sentry_example PRIVATE sentry) - target_compile_definitions(sentry_example PRIVATE SENTRY_PERFORMANCE_MONITORING) - if(MSVC) target_compile_options(sentry_example PRIVATE $) endif() @@ -575,4 +580,4 @@ if(SENTRY_BUILD_EXAMPLES) endif() add_test(NAME sentry_example COMMAND sentry_example) -endif() \ No newline at end of file +endif() diff --git a/thirdparty/sentry-native/CONTRIBUTING.md b/thirdparty/sentry-native/CONTRIBUTING.md index 005c304351..b6e81c408f 100644 --- a/thirdparty/sentry-native/CONTRIBUTING.md +++ b/thirdparty/sentry-native/CONTRIBUTING.md @@ -12,6 +12,7 @@ Building and testing `sentry-native` currently requires the following tools: - **CMake** and a supported C/C++ compiler, to actually build the code. - **python** and **pytest**, to run integration tests. - **clang-format** and **black**, to format the C/C++ and python code respectively. +- **curl** and **zlib** libraries (e.g. on Ubuntu: libcurl4-openssl-dev, libz-dev) `pytest` and `black` are installed as virtualenv dependencies automatically. @@ -138,3 +139,8 @@ The example currently supports the following commends: - `capture-multiple`: Captures a number of events. - `sleep`: Introduces a 10 second sleep. - `add-stacktrace`: Adds the current thread stacktrace to the captured event. +- `disable-backend`: Disables the build-configured crash-handler backend. +- `before-send`: Installs a `before_send()` callback that retains the event. +- `discarding-before-send`: Installs a `before_send()` callback that retains the event. +- `on-crash`: Installs an `on_crash()` callback that retains the crash event. +- `discarding-on-crash`: Installs an `on_crash()` callback that discards the crash event. diff --git a/thirdparty/sentry-native/README.md b/thirdparty/sentry-native/README.md index 0261cb3aa3..f4a866aa9b 100644 --- a/thirdparty/sentry-native/README.md +++ b/thirdparty/sentry-native/README.md @@ -1,8 +1,11 @@

- - + + + + + Sentry + -

# Official Sentry SDK for C/C++ @@ -58,8 +61,8 @@ The SDK currently supports and is tested on the following OS/Compiler variations - 64bit Linux with GCC 9 - 64bit Linux with clang 9 - 32bit Linux with GCC 7 (cross compiled from 64bit host) -- 64bit Windows with MSVC 2019 -- 32bit Windows with MSVC 2017 +- 32bit Windows with MSVC 2019 +- 64bit Windows with MSVC 2022 - macOS Catalina with most recent Compiler toolchain - Android API29 built by NDK21 toolchain - Android API16 built by NDK19 toolchain @@ -264,13 +267,17 @@ Legend: - `SENTRY_FOLDER` (Default: not defined): Sets the sentry-native projects folder name for generators which support project hierarchy (like Microsoft Visual Studio). - To use this feature you need to enable hierarchy via [`USE_FOLDERS` property](https://cmake.org/cmake/help/latest/prop_gbl/USE_FOLDERS.html) + To use this feature you need to enable hierarchy via [`USE_FOLDERS` property](https://cmake.org/cmake/help/latest/prop_gbl/USE_FOLDERS.html) - `CRASHPAD_ENABLE_STACKTRACE` (Default: OFF): This enables client-side stackwalking when using the crashpad backend. Stack unwinding will happen on the client's machine and the result will be submitted to Sentry attached to the generated minidump. Note that this feature is still experimental. +- `SENTRY_SDK_NAME` (Default: sentry.native or sentry.native.android): + Sets the SDK name that should be included in the reported events. If you're overriding this, make sure to also define + the same value using `target_compile_definitions()` on your own targets that include `sentry.h`. + ### Build Targets - `sentry`: This is the main library and the only default build target. diff --git a/thirdparty/sentry-native/examples/example.c b/thirdparty/sentry-native/examples/example.c index 93065580de..d5d42cdada 100644 --- a/thirdparty/sentry-native/examples/example.c +++ b/thirdparty/sentry-native/examples/example.c @@ -23,6 +23,54 @@ # define sleep_s(SECONDS) sleep(SECONDS) #endif +static sentry_value_t +before_send_callback(sentry_value_t event, void *hint, void *closure) +{ + (void)hint; + (void)closure; + + // make our mark on the event + sentry_value_set_by_key( + event, "adapted_by", sentry_value_new_string("before_send")); + + // tell the backend to proceed with the event + return event; +} + +static sentry_value_t +discarding_before_send_callback(sentry_value_t event, void *hint, void *closure) +{ + (void)hint; + (void)closure; + + // discard event and signal backend to stop further processing + sentry_value_decref(event); + return sentry_value_new_null(); +} + +static sentry_value_t +discarding_on_crash_callback( + const sentry_ucontext_t *uctx, sentry_value_t event, void *closure) +{ + (void)uctx; + (void)closure; + + // discard event and signal backend to stop further processing + sentry_value_decref(event); + return sentry_value_new_null(); +} + +static sentry_value_t +on_crash_callback( + const sentry_ucontext_t *uctx, sentry_value_t event, void *closure) +{ + (void)uctx; + (void)closure; + + // tell the backend to retain the event + return event; +} + static void print_envelope(sentry_envelope_t *envelope, void *unused_state) { @@ -65,6 +113,10 @@ main(int argc, char **argv) { sentry_options_t *options = sentry_options_new(); + if (has_arg(argc, argv, "disable-backend")) { + sentry_options_set_backend(options, NULL); + } + // this is an example. for real usage, make sure to set this explicitly to // an app specific cache location. sentry_options_set_database_path(options, ".sentry-native"); @@ -93,7 +145,6 @@ main(int argc, char **argv) options, sentry_transport_new(print_envelope)); } -#ifdef SENTRY_PERFORMANCE_MONITORING if (has_arg(argc, argv, "capture-transaction")) { sentry_options_set_traces_sample_rate(options, 1.0); } @@ -101,7 +152,24 @@ main(int argc, char **argv) if (has_arg(argc, argv, "child-spans")) { sentry_options_set_max_spans(options, 5); } -#endif + + if (has_arg(argc, argv, "before-send")) { + sentry_options_set_before_send(options, before_send_callback, NULL); + } + + if (has_arg(argc, argv, "discarding-before-send")) { + sentry_options_set_before_send( + options, discarding_before_send_callback, NULL); + } + + if (has_arg(argc, argv, "on-crash")) { + sentry_options_set_on_crash(options, on_crash_callback, NULL); + } + + if (has_arg(argc, argv, "discarding-on-crash")) { + sentry_options_set_on_crash( + options, discarding_on_crash_callback, NULL); + } sentry_init(options); @@ -209,8 +277,7 @@ main(int argc, char **argv) sentry_value_t exc = sentry_value_new_exception( "ParseIntError", "invalid digit found in string"); if (has_arg(argc, argv, "add-stacktrace")) { - sentry_value_t stacktrace = sentry_value_new_stacktrace(NULL, 0); - sentry_value_set_by_key(exc, "stacktrace", stacktrace); + sentry_value_set_stacktrace(exc, NULL, 0); } sentry_value_t event = sentry_value_new_event(); sentry_event_add_exception(event, exc); @@ -218,7 +285,6 @@ main(int argc, char **argv) sentry_capture_event(event); } -#ifdef SENTRY_PERFORMANCE_MONITORING if (has_arg(argc, argv, "capture-transaction")) { sentry_transaction_context_t *tx_ctx = sentry_transaction_context_new("little.teapot", @@ -253,7 +319,6 @@ main(int argc, char **argv) sentry_transaction_finish(tx); } -#endif // make sure everything flushes sentry_close(); diff --git a/thirdparty/sentry-native/external/CMakeLists.txt b/thirdparty/sentry-native/external/CMakeLists.txt index 569ccb18cc..ca807f71c8 100644 --- a/thirdparty/sentry-native/external/CMakeLists.txt +++ b/thirdparty/sentry-native/external/CMakeLists.txt @@ -74,6 +74,9 @@ set(BREAKPAD_SOURCES_CLIENT_LINUX breakpad/src/client/linux/minidump_writer/linux_dumper.cc breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper.cc breakpad/src/client/linux/minidump_writer/minidump_writer.cc + breakpad/src/client/linux/minidump_writer/pe_file.cc + breakpad/src/client/linux/minidump_writer/pe_file.h + breakpad/src/client/linux/minidump_writer/pe_structs.h ) set(BREAKPAD_SOURCES_CLIENT_WINDOWS @@ -91,13 +94,13 @@ set(BREAKPAD_SOURCES_CLIENT_APPLE breakpad/src/client/mac/handler/breakpad_nlist_64.h breakpad/src/client/mac/handler/dynamic_images.cc breakpad/src/client/mac/handler/dynamic_images.h - breakpad/src/client/mac/handler/exception_handler.cc - breakpad/src/client/mac/handler/exception_handler.h breakpad/src/client/mac/handler/minidump_generator.cc breakpad/src/client/mac/handler/minidump_generator.h ) set(BREAKPAD_SOURCES_CLIENT_MAC + breakpad/src/client/mac/handler/exception_handler.cc + breakpad/src/client/mac/handler/exception_handler.h breakpad/src/client/mac/crash_generation/crash_generation_client.cc breakpad/src/client/mac/crash_generation/crash_generation_client.h ) @@ -115,12 +118,12 @@ set(BREAKPAD_SOURCES_CLIENT_IOS breakpad/src/client/mac/handler/ucontext_compat.h ) - add_library(breakpad_client STATIC) target_sources(breakpad_client PRIVATE ${BREAKPAD_SOURCES_COMMON}) if(LINUX OR ANDROID) target_sources(breakpad_client PRIVATE ${BREAKPAD_SOURCES_COMMON_LINUX} ${BREAKPAD_SOURCES_CLIENT_LINUX}) + if(ANDROID) target_sources(breakpad_client PRIVATE ${BREAKPAD_SOURCES_COMMON_ANDROID}) target_include_directories(breakpad_client PRIVATE breakpad/src/common/android/include) @@ -128,6 +131,7 @@ if(LINUX OR ANDROID) include(CheckFunctionExists) check_function_exists(getcontext HAVE_GETCONTEXT) + if(HAVE_GETCONTEXT) target_compile_definitions(breakpad_client PRIVATE HAVE_GETCONTEXT) else() @@ -141,6 +145,7 @@ if(APPLE) target_sources(breakpad_client PRIVATE ${BREAKPAD_SOURCES_COMMON_APPLE} ${BREAKPAD_SOURCES_CLIENT_APPLE}) + if(NOT IOS) target_sources(breakpad_client PRIVATE ${BREAKPAD_SOURCES_COMMON_MAC} @@ -167,8 +172,8 @@ endif() # which are being resolved correctly when we add the current directory to # the include directories. A giant hack, yes, but it works target_include_directories(breakpad_client - PRIVATE - "$" - PUBLIC - "$" + PRIVATE + "$" + PUBLIC + "$" ) diff --git a/thirdparty/sentry-native/external/breakpad/.github/workflows/coverity.yml b/thirdparty/sentry-native/external/breakpad/.github/workflows/coverity.yml index cfa0f2ab55..06f8e27631 100644 --- a/thirdparty/sentry-native/external/breakpad/.github/workflows/coverity.yml +++ b/thirdparty/sentry-native/external/breakpad/.github/workflows/coverity.yml @@ -1,7 +1,7 @@ # GitHub actions workflow. # https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions -# https://scan.coverity.com/projects/gentoo-pax-utils +# https://scan.coverity.com/projects/google-breakpad name: Coverity Scan on: @@ -36,9 +36,8 @@ jobs: - run: ./configure --disable-silent-rules working-directory: src - - uses: vapier/coverity-scan-action@v0 + - uses: vapier/coverity-scan-action@v1 with: - project: google%2Fbreakpad command: make -C src -O -j$(getconf _NPROCESSORS_CONF) - email: google-breakpad-dev@googlegroups.com + email: ${{ secrets.COVERITY_SCAN_EMAIL }} token: ${{ secrets.COVERITY_SCAN_TOKEN }} diff --git a/thirdparty/sentry-native/external/breakpad/Makefile.am b/thirdparty/sentry-native/external/breakpad/Makefile.am index e7dc06ac71..2cde864933 100644 --- a/thirdparty/sentry-native/external/breakpad/Makefile.am +++ b/thirdparty/sentry-native/external/breakpad/Makefile.am @@ -168,6 +168,7 @@ src_client_linux_libbreakpad_client_a_SOURCES = \ src/client/linux/minidump_writer/linux_dumper.cc \ src/client/linux/minidump_writer/linux_ptrace_dumper.cc \ src/client/linux/minidump_writer/minidump_writer.cc \ + src/client/linux/minidump_writer/pe_file.cc \ src/client/minidump_file_writer-inl.h \ src/client/minidump_file_writer.cc \ src/client/minidump_file_writer.h \ @@ -491,6 +492,7 @@ src_client_linux_linux_client_unittest_shlib_SOURCES = \ src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc \ src/client/linux/minidump_writer/minidump_writer_unittest.cc \ src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc \ + src/client/linux/minidump_writer/pe_file.cc \ src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc \ src/common/linux/elf_core_dump.cc \ src/common/linux/linux_libc_support_unittest.cc \ diff --git a/thirdparty/sentry-native/external/breakpad/Makefile.in b/thirdparty/sentry-native/external/breakpad/Makefile.in index 87377f3ac9..aaf7913394 100644 --- a/thirdparty/sentry-native/external/breakpad/Makefile.in +++ b/thirdparty/sentry-native/external/breakpad/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.3 from Makefile.am. +# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -360,6 +360,7 @@ am__src_client_linux_libbreakpad_client_a_SOURCES_DIST = \ src/client/linux/minidump_writer/linux_dumper.cc \ src/client/linux/minidump_writer/linux_ptrace_dumper.cc \ src/client/linux/minidump_writer/minidump_writer.cc \ + src/client/linux/minidump_writer/pe_file.cc \ src/client/minidump_file_writer-inl.h \ src/client/minidump_file_writer.cc \ src/client/minidump_file_writer.h src/common/convert_UTF.cc \ @@ -387,6 +388,7 @@ am__dirstamp = $(am__leading_dot)dirstamp @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_dumper.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_ptrace_dumper.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/minidump_writer.$(OBJEXT) \ +@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/pe_file.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/client/minidump_file_writer.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/convert_UTF.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/md5.$(OBJEXT) \ @@ -632,6 +634,7 @@ am__src_client_linux_linux_client_unittest_shlib_SOURCES_DIST = \ src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc \ src/client/linux/minidump_writer/minidump_writer_unittest.cc \ src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc \ + src/client/linux/minidump_writer/pe_file.cc \ src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc \ src/common/linux/elf_core_dump.cc \ src/common/linux/linux_libc_support_unittest.cc \ @@ -665,6 +668,7 @@ am__src_client_linux_linux_client_unittest_shlib_SOURCES_DIST = \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_client_unittest_shlib-linux_ptrace_dumper_unittest.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_client_unittest_shlib-minidump_writer_unittest.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_client_unittest_shlib-minidump_writer_unittest_utils.$(OBJEXT) \ +@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/linux/client_linux_linux_client_unittest_shlib-elf_core_dump.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/linux/client_linux_linux_client_unittest_shlib-linux_libc_support_unittest.$(OBJEXT) \ @@ -1645,12 +1649,14 @@ am__depfiles_remade = src/client/$(DEPDIR)/minidump_file_writer.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-linux_ptrace_dumper_unittest.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest_utils.Po \ + src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_core_dumper.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper_unittest_helper-linux_dumper_unittest_helper.Po \ src/client/linux/minidump_writer/$(DEPDIR)/linux_ptrace_dumper.Po \ src/client/linux/minidump_writer/$(DEPDIR)/minidump_writer.Po \ + src/client/linux/minidump_writer/$(DEPDIR)/pe_file.Po \ src/common/$(DEPDIR)/client_linux_linux_client_unittest_shlib-memory_allocator_unittest.Po \ src/common/$(DEPDIR)/convert_UTF.Po \ src/common/$(DEPDIR)/dumper_unittest-byte_cursor_unittest.Po \ @@ -2101,9 +2107,6 @@ am__define_uniq_tagged_files = \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope AM_RECURSIVE_TARGETS = cscope check recheck am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ @@ -2291,9 +2294,9 @@ am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/autotools/missing \ $(top_srcdir)/autotools/test-driver \ $(top_srcdir)/src/config.h.in AUTHORS ChangeLog INSTALL NEWS \ - autotools/ar-lib autotools/compile autotools/config.guess \ - autotools/config.sub autotools/depcomp autotools/install-sh \ - autotools/ltmain.sh autotools/missing + README.md autotools/ar-lib autotools/compile \ + autotools/config.guess autotools/config.sub autotools/depcomp \ + autotools/install-sh autotools/ltmain.sh autotools/missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -2329,6 +2332,8 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ @@ -2339,6 +2344,7 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ @@ -2513,6 +2519,7 @@ CLEANFILES = $(am__append_12) @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_dumper.cc \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_ptrace_dumper.cc \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/minidump_writer.cc \ +@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/pe_file.cc \ @LINUX_HOST_TRUE@ src/client/minidump_file_writer-inl.h \ @LINUX_HOST_TRUE@ src/client/minidump_file_writer.cc \ @LINUX_HOST_TRUE@ src/client/minidump_file_writer.h \ @@ -2718,6 +2725,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS) @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/minidump_writer_unittest.cc \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc \ +@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/pe_file.cc \ @LINUX_HOST_TRUE@ src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc \ @LINUX_HOST_TRUE@ src/common/linux/elf_core_dump.cc \ @LINUX_HOST_TRUE@ src/common/linux/linux_libc_support_unittest.cc \ @@ -4151,6 +4159,9 @@ src/client/linux/minidump_writer/linux_ptrace_dumper.$(OBJEXT): \ src/client/linux/minidump_writer/minidump_writer.$(OBJEXT): \ src/client/linux/minidump_writer/$(am__dirstamp) \ src/client/linux/minidump_writer/$(DEPDIR)/$(am__dirstamp) +src/client/linux/minidump_writer/pe_file.$(OBJEXT): \ + src/client/linux/minidump_writer/$(am__dirstamp) \ + src/client/linux/minidump_writer/$(DEPDIR)/$(am__dirstamp) src/client/$(am__dirstamp): @$(MKDIR_P) src/client @: > src/client/$(am__dirstamp) @@ -4452,6 +4463,9 @@ src/client/linux/minidump_writer/linux_client_unittest_shlib-minidump_writer_uni src/client/linux/minidump_writer/linux_client_unittest_shlib-minidump_writer_unittest_utils.$(OBJEXT): \ src/client/linux/minidump_writer/$(am__dirstamp) \ src/client/linux/minidump_writer/$(DEPDIR)/$(am__dirstamp) +src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.$(OBJEXT): \ + src/client/linux/minidump_writer/$(am__dirstamp) \ + src/client/linux/minidump_writer/$(DEPDIR)/$(am__dirstamp) src/client/linux/minidump_writer/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.$(OBJEXT): \ src/client/linux/minidump_writer/$(am__dirstamp) \ src/client/linux/minidump_writer/$(DEPDIR)/$(am__dirstamp) @@ -5357,12 +5371,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-linux_ptrace_dumper_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest_utils.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_core_dumper.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper_unittest_helper-linux_dumper_unittest_helper.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/linux_ptrace_dumper.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/minidump_writer.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/client/linux/minidump_writer/$(DEPDIR)/pe_file.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/client_linux_linux_client_unittest_shlib-memory_allocator_unittest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/convert_UTF.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/dumper_unittest-byte_cursor_unittest.Po@am__quote@ # am--include-marker @@ -5921,6 +5937,20 @@ src/client/linux/minidump_writer/linux_client_unittest_shlib-minidump_writer_uni @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/client/linux/minidump_writer/linux_client_unittest_shlib-minidump_writer_unittest_utils.obj `if test -f 'src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc'; then $(CYGPATH_W) 'src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc'; else $(CYGPATH_W) '$(srcdir)/src/client/linux/minidump_writer/minidump_writer_unittest_utils.cc'; fi` +src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.o: src/client/linux/minidump_writer/pe_file.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.o -MD -MP -MF src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Tpo -c -o src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.o `test -f 'src/client/linux/minidump_writer/pe_file.cc' || echo '$(srcdir)/'`src/client/linux/minidump_writer/pe_file.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Tpo src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/client/linux/minidump_writer/pe_file.cc' object='src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.o `test -f 'src/client/linux/minidump_writer/pe_file.cc' || echo '$(srcdir)/'`src/client/linux/minidump_writer/pe_file.cc + +src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.obj: src/client/linux/minidump_writer/pe_file.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.obj -MD -MP -MF src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Tpo -c -o src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.obj `if test -f 'src/client/linux/minidump_writer/pe_file.cc'; then $(CYGPATH_W) 'src/client/linux/minidump_writer/pe_file.cc'; else $(CYGPATH_W) '$(srcdir)/src/client/linux/minidump_writer/pe_file.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Tpo src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/client/linux/minidump_writer/pe_file.cc' object='src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/client/linux/minidump_writer/linux_client_unittest_shlib-pe_file.obj `if test -f 'src/client/linux/minidump_writer/pe_file.cc'; then $(CYGPATH_W) 'src/client/linux/minidump_writer/pe_file.cc'; else $(CYGPATH_W) '$(srcdir)/src/client/linux/minidump_writer/pe_file.cc'; fi` + src/client/linux/minidump_writer/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.o: src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_client_linux_linux_client_unittest_shlib_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/client/linux/minidump_writer/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.o -MD -MP -MF src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.Tpo -c -o src/client/linux/minidump_writer/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.o `test -f 'src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc' || echo '$(srcdir)/'`src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.Tpo src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.Po @@ -9131,7 +9161,6 @@ src/processor/minidump_stackwalk_machine_readable_test.log: src/processor/minidu @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am @@ -9427,12 +9456,14 @@ distclean: distclean-am -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-linux_ptrace_dumper_unittest.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest_utils.Po + -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_core_dumper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper_unittest_helper-linux_dumper_unittest_helper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_ptrace_dumper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/minidump_writer.Po + -rm -f src/client/linux/minidump_writer/$(DEPDIR)/pe_file.Po -rm -f src/common/$(DEPDIR)/client_linux_linux_client_unittest_shlib-memory_allocator_unittest.Po -rm -f src/common/$(DEPDIR)/convert_UTF.Po -rm -f src/common/$(DEPDIR)/dumper_unittest-byte_cursor_unittest.Po @@ -9770,12 +9801,14 @@ maintainer-clean: maintainer-clean-am -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-linux_ptrace_dumper_unittest.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-minidump_writer_unittest_utils.Po + -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-pe_file.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_client_unittest_shlib-proc_cpuinfo_reader_unittest.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_core_dumper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_dumper_unittest_helper-linux_dumper_unittest_helper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/linux_ptrace_dumper.Po -rm -f src/client/linux/minidump_writer/$(DEPDIR)/minidump_writer.Po + -rm -f src/client/linux/minidump_writer/$(DEPDIR)/pe_file.Po -rm -f src/common/$(DEPDIR)/client_linux_linux_client_unittest_shlib-memory_allocator_unittest.Po -rm -f src/common/$(DEPDIR)/convert_UTF.Po -rm -f src/common/$(DEPDIR)/dumper_unittest-byte_cursor_unittest.Po diff --git a/thirdparty/sentry-native/external/breakpad/aclocal.m4 b/thirdparty/sentry-native/external/breakpad/aclocal.m4 index be219b4217..009cc48edb 100644 --- a/thirdparty/sentry-native/external/breakpad/aclocal.m4 +++ b/thirdparty/sentry-native/external/breakpad/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.3 -*- Autoconf -*- +# generated automatically by aclocal 1.16.5 -*- Autoconf -*- -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,13 +14,13 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, +[m4_warning([this file was generated for autoconf 2.71. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2020 Free Software Foundation, Inc. +# Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.3], [], +m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,12 +51,12 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.3])dnl +[AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -# Copyright (C) 2011-2020 Free Software Foundation, Inc. +# Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -118,7 +118,7 @@ AC_SUBST([AR])dnl # Figure out how to run the assembler. -*- Autoconf -*- -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -138,7 +138,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -190,7 +190,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2020 Free Software Foundation, Inc. +# Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -221,7 +221,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -412,7 +412,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -480,7 +480,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -508,6 +508,10 @@ m4_defn([AC_PROG_CC]) # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl +m4_ifdef([_$0_ALREADY_INIT], + [m4_fatal([$0 expanded multiple times +]m4_defn([_$0_ALREADY_INIT]))], + [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -544,7 +548,7 @@ m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl @@ -596,6 +600,20 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) +# Variables for tags utilities; see am/tags.am +if test -z "$CTAGS"; then + CTAGS=ctags +fi +AC_SUBST([CTAGS]) +if test -z "$ETAGS"; then + ETAGS=etags +fi +AC_SUBST([ETAGS]) +if test -z "$CSCOPE"; then + CSCOPE=cscope +fi +AC_SUBST([CSCOPE]) + AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This @@ -677,7 +695,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -698,7 +716,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2020 Free Software Foundation, Inc. +# Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -720,7 +738,7 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -755,7 +773,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -798,7 +816,7 @@ AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2020 Free Software Foundation, Inc. +# Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -834,7 +852,7 @@ fi # Obsolete and "removed" macros, that must however still report explicit # error messages when used, to smooth transition. # -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -861,7 +879,7 @@ AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES]) # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -890,7 +908,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -937,7 +955,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -956,7 +974,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1037,7 +1055,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2020 Free Software Foundation, Inc. +# Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1097,7 +1115,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2020 Free Software Foundation, Inc. +# Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1125,7 +1143,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2020 Free Software Foundation, Inc. +# Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1144,7 +1162,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2020 Free Software Foundation, Inc. +# Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/thirdparty/sentry-native/external/breakpad/docs/symbol_files.md b/thirdparty/sentry-native/external/breakpad/docs/symbol_files.md index 237b6567f1..e05b455bbb 100644 --- a/thirdparty/sentry-native/external/breakpad/docs/symbol_files.md +++ b/thirdparty/sentry-native/external/breakpad/docs/symbol_files.md @@ -33,8 +33,15 @@ restrictions, these may appear in any order. * A `FILE` record gives a source file name, and assigns it a number by which other records can refer to it. +* An `INLINE_ORIGIN` record holds an inline function name for `INLINE` records + to refer to. + * A `FUNC` record describes a function present in the source code. +* An `INLINE` record describes the inline function's nest level, call site + line and call site source file to which the given ranges of machine code + should be attributed. + * A line record indicates to which source file and line a given range of machine code should be attributed. The line is attributed to the function defined by the most recent `FUNC` record. @@ -62,16 +69,25 @@ for _name_. * The _operatingsystem_ field names the operating system on which the executable or shared library was intended to run. This field should have one - of the following values: | **Value** | **Meaning** | - |:----------|:--------------------| | Linux | Linux | | mac | Macintosh OSX - | | windows | Microsoft Windows | + of the following values: + + | **Value** | **Meaning** | + |:----------|:--------------------| + | Linux | Linux | + | mac | Macintosh OSX | + | windows | Microsoft Windows | * The _architecture_ field indicates what processor architecture the executable or shared library contains machine code for. This field should - have one of the following values: | **Value** | **Instruction Set - Architecture** | |:----------|:---------------------------------| | x86 | - Intel IA-32 | | x86\_64 | AMD64/Intel 64 | | ppc | 32-bit PowerPC | | ppc64 - | 64-bit PowerPC | | unknown | unknown | + have one of the following values: + + | **Value** | **Instruction Set Architecture** | + |:----------|:---------------------------------| + | x86 | Intel IA-32 | + | x86\_64 | AMD64/Intel 64 | + | ppc | 32-bit PowerPC | + | ppc64 | 64-bit PowerPC | + | unknown | unknown | * The _id_ field is a sequence of hexadecimal digits that identifies the exact executable or library whose contents the symbol file describes. The way in @@ -96,6 +112,22 @@ which other records (line records, in particular) can use to refer to that file name. The _number_ field is a decimal number. The _name_ field is the name of the file; it may contain spaces. +# `INLINE_ORIGIN` records + +An `INLINE_ORIGIN` record holds an inline function name for `INLINE` records to +refer to. It has the form: + +> `INLINE_ORIGIN` _number_ _name_ + +For example: `INLINE_ORIGIN 2 nsQueryInterfaceWithError::operator()(nsID const&, +void**) const +` + +An `INLINE_ORIGIN` record provides the name of an inline function, and assigns +it a number which other records (`INLINE` records, in particular) can use to +refer to that function name. The _number_ field is a decimal number. The _name_ +field is the name of the inline function; it may contain spaces. + # `FUNC` records A `FUNC` record describes a source-language function. It has the form: @@ -127,6 +159,49 @@ The _name_ field is the name of the function. In languages that use linker symbol name mangling like C++, this should be the source language name (the "unmangled" form). This field may contain spaces. +# `INLINE` records + +An `INLINE` record describes the inline function's nest level, call site line +and call site source file to which the given ranges of machine code should be +attributed. It has the form: + +> `INLINE` _inline_nest_level_ _call_site_line_ _call_site_file_num_ +> _origin_num_ [_address_ _size_]+ + +For example: `INLINE 0 10 3 4 d30 2a fa1 b +` + +The _inline_nest_level_ field is a decimal number that means it's inlined at the +function described by a previous `INLINE` record which has _inline_nest_level_ +one less than its. In the example below, first and third `INLINE` records have +_inline_nest_level_ 0, which means they are inlined inside the function +described by the `FUNC` record. The second `INLINE` record has +_inline_nest_level_ 1 means that it's inlined at the inline function described +by first `INLINE` record. +``` +FUNC ... +INLINE 0 ... +INLINE 1 ... +INLINE 0 ... +``` + +The _call_site_line_ and _call_site_file_num_ fields are decimal numbers +indicating where this inline function being called at. + +The _origin_num_ field refers to an `INLINE_ORIGIN` record that has the name +of the inline function. + +The _address_ and _size_ fields are hexadecimal numbers indicating the start +address and length in bytes of the machine code. The address is relative to the +module's load address. There could be more than one [_address_ _size_] range +pair, since inline functions could have discontinuous address ranges. The ranges +of an `INLINE` record are always inside the ranges described by its parent +record (a `FUNC` record or an `INLINE` record). + +The `INLINE` record is assumed to belong to the function described by the last +preceding `FUNC` record. `INLINE` records may not appear before the first `FUNC` +record. + # Line records A line record describes the source file and line number to which a given range @@ -396,14 +471,14 @@ func+22: pc = *sp; sp += 4 ; pop return address and jump to it The following table would describe the function above: -**code address** | **.cfa** | **r0 (on Google Code)** | **r1 (on Google Code)** | ... | **.ra** -:--------------- | :------- | :---------------------- | :---------------------- | :-- | :------- -func+0 | sp | | | | `cfa[0]` -func+1 | sp+16 | | | | `cfa[0]` -func+2 | sp+16 | `cfa[-4]` | | | `cfa[0]` -func+11 | sp+20 | `cfa[-4]` | | | `cfa[0]` -func+21 | sp+20 | | | | `cfa[0]` -func+22 | sp | | | | `cfa[0]` +| **code address** | **.cfa** | **r0 (on Google Code)** | **r1 (on Google Code)** | ... | **.ra** | +|:-----------------|:---------|:------------------------|:------------------------|:----|:---------| +| func+0 | sp | | | | `cfa[0]` | +| func+1 | sp+16 | | | | `cfa[0]` | +| func+2 | sp+16 | `cfa[-4]` | | | `cfa[0]` | +| func+11 | sp+20 | `cfa[-4]` | | | `cfa[0]` | +| func+21 | sp+20 | | | | `cfa[0]` | +| func+22 | sp | | | | `cfa[0]` | Some things to note here: @@ -438,14 +513,14 @@ To save space, the most common type of CFI record only mentions the table entries at which changes take place. So for the above, the CFI data would only actually mention the non-blank entries here: -**insn** | **cfa** | **r0 (on Google Code)** | **r1 (on Google Code)** | ... | **ra** -:------- | :------ | :---------------------- | :---------------------- | :-- | :------- -func+0 | sp | | | | `cfa[0]` -func+1 | sp+16 | | | | -func+2 | | `cfa[-4]` | | | -func+11 | sp+20 | | | | -func+21 | | r0 (on Google Code) | | | -func+22 | sp | | | | +| **insn** | **cfa** | **r0 (on Google Code)** | **r1 (on Google Code)** | ... | **ra** | +|:---------|:--------|:------------------------|:------------------------|:----|:---------| +| func+0 | sp | | | | `cfa[0]` | +| func+1 | sp+16 | | | | | +| func+2 | | `cfa[-4]` | | | | +| func+11 | sp+20 | | | | | +| func+21 | | r0 (on Google Code) | | | | +| func+22 | sp | | | | | A `STACK CFI INIT` record indicates that, at the machine instruction at _address_, belonging to some function, the value that _registern_ had diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/handler/exception_handler.cc b/thirdparty/sentry-native/external/breakpad/src/client/linux/handler/exception_handler.cc index d9760d1987..499be0a986 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/linux/handler/exception_handler.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/handler/exception_handler.cc @@ -138,7 +138,7 @@ void InstallAlternateStackLocked() { // SIGSTKSZ may be too small to prevent the signal handlers from overrunning // the alternative stack. Ensure that the size of the alternative stack is // large enough. - static const unsigned kSigStackSize = std::max(16384, (int)SIGSTKSZ); + const unsigned kSigStackSize = std::max(16384, SIGSTKSZ); // Only set an alternative stack if there isn't already one, or if the current // one is too small. diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/microdump_writer/microdump_writer.cc b/thirdparty/sentry-native/external/breakpad/src/client/linux/microdump_writer/microdump_writer.cc index fa3c1713a5..22edb1b8dd 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/linux/microdump_writer/microdump_writer.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/microdump_writer/microdump_writer.cc @@ -49,8 +49,8 @@ namespace { using google_breakpad::auto_wasteful_vector; +using google_breakpad::elf::kDefaultBuildIdSize; using google_breakpad::ExceptionHandler; -using google_breakpad::kDefaultBuildIdSize; using google_breakpad::LinuxDumper; using google_breakpad::LinuxPtraceDumper; using google_breakpad::MappingInfo; diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_dumper.cc b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_dumper.cc index 7fd6532ad2..44430c4e96 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_dumper.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_dumper.cc @@ -53,6 +53,8 @@ #include "google_breakpad/common/minidump_exception_linux.h" #include "third_party/lss/linux_syscall_support.h" +using google_breakpad::elf::FileID; + #if defined(__ANDROID__) // Android packed relocations definitions are not yet available from the diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc index da71e15dc0..11c392d83d 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/linux_ptrace_dumper_unittest.cc @@ -63,6 +63,8 @@ #endif using namespace google_breakpad; +using google_breakpad::elf::FileID; +using google_breakpad::elf::kDefaultBuildIdSize; namespace { diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer.cc b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer.cc index 32634ef002..7ce9ac5702 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer.cc @@ -71,6 +71,8 @@ #include "client/linux/minidump_writer/line_reader.h" #include "client/linux/minidump_writer/linux_dumper.h" #include "client/linux/minidump_writer/linux_ptrace_dumper.h" +#include "client/linux/minidump_writer/pe_file.h" +#include "client/linux/minidump_writer/pe_structs.h" #include "client/linux/minidump_writer/proc_cpuinfo_reader.h" #include "client/minidump_file_writer.h" #include "common/linux/file_id.h" @@ -83,9 +85,9 @@ namespace { using google_breakpad::AppMemoryList; using google_breakpad::auto_wasteful_vector; +using google_breakpad::elf::kDefaultBuildIdSize; using google_breakpad::ExceptionHandler; using google_breakpad::CpuSet; -using google_breakpad::kDefaultBuildIdSize; using google_breakpad::LineReader; using google_breakpad::LinuxDumper; using google_breakpad::LinuxPtraceDumper; @@ -95,8 +97,11 @@ using google_breakpad::MappingInfo; using google_breakpad::MappingList; using google_breakpad::MinidumpFileWriter; using google_breakpad::PageAllocator; +using google_breakpad::PEFile; +using google_breakpad::PEFileFormat; using google_breakpad::ProcCpuInfoReader; using google_breakpad::RawContextCPU; +using google_breakpad::RSDS_DEBUG_FORMAT; using google_breakpad::ThreadInfo; using google_breakpad::TypedMDRVA; using google_breakpad::UContextReader; @@ -632,40 +637,88 @@ class MinidumpWriter { mod->base_of_image = mapping.start_addr; mod->size_of_image = mapping.size; - auto_wasteful_vector identifier_bytes( - dumper_->allocator()); + char file_name[NAME_MAX]; + char file_path[NAME_MAX]; - if (identifier) { - // GUID was provided by caller. - identifier_bytes.insert(identifier_bytes.end(), - identifier, - identifier + sizeof(MDGUID)); + dumper_->GetMappingEffectiveNameAndPath(mapping, file_path, + sizeof(file_path), file_name, + sizeof(file_name)); + + RSDS_DEBUG_FORMAT rsds; + PEFileFormat file_format = PEFile::TryGetDebugInfo(file_path, &rsds); + + if (file_format == PEFileFormat::notPeCoff) { + // The module is not a PE/COFF file, process as an ELF. + auto_wasteful_vector identifier_bytes( + dumper_->allocator()); + + if (identifier) { + // GUID was provided by caller. + identifier_bytes.insert(identifier_bytes.end(), identifier, + identifier + sizeof(MDGUID)); + } else { + // Note: ElfFileIdentifierForMapping() can manipulate the + // |mapping.name|, that is why we need to call the method + // GetMappingEffectiveNameAndPath again. + dumper_->ElfFileIdentifierForMapping(mapping, member, mapping_id, + identifier_bytes); + dumper_->GetMappingEffectiveNameAndPath(mapping, file_path, + sizeof(file_path), file_name, + sizeof(file_name)); + } + + if (!identifier_bytes.empty()) { + UntypedMDRVA cv(&minidump_writer_); + if (!cv.Allocate(MDCVInfoELF_minsize + identifier_bytes.size())) + return false; + + const uint32_t cv_signature = MD_CVINFOELF_SIGNATURE; + cv.Copy(&cv_signature, sizeof(cv_signature)); + cv.Copy(cv.position() + sizeof(cv_signature), &identifier_bytes[0], + identifier_bytes.size()); + + mod->cv_record = cv.location(); + } } else { - // Note: ElfFileIdentifierForMapping() can manipulate the |mapping.name|. - dumper_->ElfFileIdentifierForMapping(mapping, - member, - mapping_id, - identifier_bytes); - } - - if (!identifier_bytes.empty()) { - UntypedMDRVA cv(&minidump_writer_); - if (!cv.Allocate(MDCVInfoELF_minsize + identifier_bytes.size())) + // The module is a PE/COFF file. Create MDCVInfoPDB70 struct for it. + size_t file_name_length = strlen(file_name); + TypedMDRVA cv(&minidump_writer_); + if (!cv.AllocateObjectAndArray(file_name_length + 1, sizeof(uint8_t))) return false; - - const uint32_t cv_signature = MD_CVINFOELF_SIGNATURE; - cv.Copy(&cv_signature, sizeof(cv_signature)); - cv.Copy(cv.position() + sizeof(cv_signature), &identifier_bytes[0], - identifier_bytes.size()); + if (!cv.CopyIndexAfterObject(0, file_name, file_name_length)) + return false; + MDCVInfoPDB70* cv_ptr = cv.get(); + cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE; + if (file_format == PEFileFormat::peWithBuildId) { + // Populate BuildId and age using RSDS instance. + cv_ptr->signature.data1 = static_cast(rsds.guid[0]) << 24 | + static_cast(rsds.guid[1]) << 16 | + static_cast(rsds.guid[2]) << 8 | + static_cast(rsds.guid[3]); + cv_ptr->signature.data2 = + static_cast(rsds.guid[4]) << 8 | rsds.guid[5]; + cv_ptr->signature.data3 = + static_cast(rsds.guid[6]) << 8 | rsds.guid[7]; + cv_ptr->signature.data4[0] = rsds.guid[8]; + cv_ptr->signature.data4[1] = rsds.guid[9]; + cv_ptr->signature.data4[2] = rsds.guid[10]; + cv_ptr->signature.data4[3] = rsds.guid[11]; + cv_ptr->signature.data4[4] = rsds.guid[12]; + cv_ptr->signature.data4[5] = rsds.guid[13]; + cv_ptr->signature.data4[6] = rsds.guid[14]; + cv_ptr->signature.data4[7] = rsds.guid[15]; + // The Age field should be reverted as well. + cv_ptr->age = static_cast(rsds.age[0]) << 24 | + static_cast(rsds.age[1]) << 16 | + static_cast(rsds.age[2]) << 8 | + static_cast(rsds.age[3]); + } else { + cv_ptr->age = 0; + } mod->cv_record = cv.location(); } - char file_name[NAME_MAX]; - char file_path[NAME_MAX]; - dumper_->GetMappingEffectiveNameAndPath( - mapping, file_path, sizeof(file_path), file_name, sizeof(file_name)); - MDLocationDescriptor ld; if (!minidump_writer_.WriteString(file_path, my_strlen(file_path), &ld)) return false; diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc index d192e5cbb7..b7a2c61e13 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/minidump_writer_unittest.cc @@ -54,6 +54,8 @@ #include "google_breakpad/processor/minidump.h" using namespace google_breakpad; +using google_breakpad::elf::FileID; +using google_breakpad::elf::kDefaultBuildIdSize; namespace { diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.cc b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.cc new file mode 100644 index 0000000000..4a8f1936e9 --- /dev/null +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.cc @@ -0,0 +1,148 @@ +// Copyright (c) 2022, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include "client/linux/minidump_writer/pe_file.h" +#include "client/linux/minidump_writer/pe_structs.h" +#include "common/linux/memory_mapped_file.h" + +namespace google_breakpad { + +PEFileFormat PEFile::TryGetDebugInfo(const char* filename, + PRSDS_DEBUG_FORMAT debug_info) { + MemoryMappedFile mapped_file(filename, 0); + if (!mapped_file.data()) + return PEFileFormat::notPeCoff; + const void* base = mapped_file.data(); + const size_t file_size = mapped_file.size(); + + const IMAGE_DOS_HEADER* header = + TryReadStruct(base, 0, file_size); + if (!header || (header->e_magic != IMAGE_DOS_SIGNATURE)) { + return PEFileFormat::notPeCoff; + } + + // NTHeader is at position 'e_lfanew'. + DWORD nt_header_offset = header->e_lfanew; + // First, read a common IMAGE_NT_HEADERS structure. It should contain a + // special flag marking whether PE module is x64 (OptionalHeader.Magic) + // and so-called NT_SIGNATURE in Signature field. + const IMAGE_NT_HEADERS* nt_header = + TryReadStruct(base, nt_header_offset, file_size); + if (!nt_header || (nt_header->Signature != IMAGE_NT_SIGNATURE) + || ((nt_header->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) + && (nt_header->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC))) + return PEFileFormat::notPeCoff; + + bool x64 = nt_header->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC; + WORD sections_number = nt_header->FileHeader.NumberOfSections; + DWORD debug_offset; + DWORD debug_size; + DWORD section_offset; + if (x64) { + const IMAGE_NT_HEADERS64* header_64 = + TryReadStruct(base, nt_header_offset, file_size); + if (!header_64) + return PEFileFormat::peWithoutBuildId; + debug_offset = + header_64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] + .VirtualAddress; + debug_size = + header_64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] + .Size; + section_offset = nt_header_offset + sizeof(IMAGE_NT_HEADERS64); + } else { + const IMAGE_NT_HEADERS32* header_32 = + TryReadStruct(base, nt_header_offset, file_size); + if (!header_32) + return PEFileFormat::peWithoutBuildId; + debug_offset = + header_32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] + .VirtualAddress; + debug_size = + header_32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] + .Size; + section_offset = nt_header_offset + sizeof(IMAGE_NT_HEADERS32); + } + + DWORD debug_end_pos = debug_offset + debug_size; + while (debug_offset < debug_end_pos) { + for (WORD i = 0; i < sections_number; ++i) { + // Section headers are placed sequentially after the NT_HEADER (32/64). + const IMAGE_SECTION_HEADER* section = + TryReadStruct(base, section_offset, file_size); + if (!section) + return PEFileFormat::peWithoutBuildId; + + section_offset += sizeof(IMAGE_SECTION_HEADER); + + // Current `debug_offset` should be inside a section, stop if we find + // a suitable one (we don't consider any malformed sections here). + if ((section->VirtualAddress <= debug_offset) && + (debug_offset < section->VirtualAddress + section->SizeOfRawData)) { + DWORD offset = + section->PointerToRawData + debug_offset - section->VirtualAddress; + // Go to the position of current ImageDebugDirectory (offset). + const IMAGE_DEBUG_DIRECTORY* debug_directory = + TryReadStruct(base, offset, file_size); + if (!debug_directory) + return PEFileFormat::peWithoutBuildId; + // Process ImageDebugDirectory with CodeViewRecord type and skip + // all others. + if (debug_directory->Type == IMAGE_DEBUG_TYPE_CODEVIEW) { + DWORD debug_directory_size = debug_directory->SizeOfData; + if (debug_directory_size < sizeof(RSDS_DEBUG_FORMAT)) + // RSDS section is malformed. + return PEFileFormat::peWithoutBuildId; + // Go to the position of current ImageDebugDirectory Raw Data + // (debug_directory->PointerToRawData) and read the RSDS section. + const RSDS_DEBUG_FORMAT* rsds = + TryReadStruct( + base, debug_directory->PointerToRawData, file_size); + + if (!rsds) + return PEFileFormat::peWithoutBuildId; + + memcpy(debug_info->guid, rsds->guid, sizeof(rsds->guid)); + memcpy(debug_info->age, rsds->age, sizeof(rsds->age)); + return PEFileFormat::peWithBuildId; + } + + break; + } + } + + debug_offset += sizeof(IMAGE_DEBUG_DIRECTORY); + } + + return PEFileFormat::peWithoutBuildId; +} + +} // namespace google_breakpad \ No newline at end of file diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.h b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.h new file mode 100644 index 0000000000..cc7ed0807e --- /dev/null +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_file.h @@ -0,0 +1,77 @@ +// Copyright (c) 2022, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CLIENT_LINUX_MINIDUMP_WRITER_PE_FILE_H_ +#define CLIENT_LINUX_MINIDUMP_WRITER_PE_FILE_H_ + +#include "client/linux/minidump_writer/pe_structs.h" + +namespace google_breakpad { + +typedef enum { + notPeCoff = 0, + peWithoutBuildId = 1, + peWithBuildId = 2 +} PEFileFormat; + +class PEFile { + public: + /** + * Attempts to parse RSDS_DEBUG_FORMAT record from a PE (Portable + * Executable) file. To do this we check whether the loaded file is a PE + * file, and if it is - try to find IMAGE_DEBUG_DIRECTORY structure with + * its type set to IMAGE_DEBUG_TYPE_CODEVIEW. + * + * @param filename Filename for the module to parse. + * @param debug_info RSDS_DEBUG_FORMAT struct to be populated with PE debug + * info (GUID and age). + * @return + * notPeCoff: not PE/COFF file; + * peWithoutBuildId: a PE/COFF file but build-id is not set; + * peWithBuildId: a PE/COFF file and build-id is set. + */ + static PEFileFormat TryGetDebugInfo(const char* filename, + PRSDS_DEBUG_FORMAT debug_info); + + private: + template + static const TStruct* TryReadStruct(const void* base, + const DWORD position, + const size_t file_size) { + if (position + sizeof(TStruct) >= file_size){ + return nullptr; + } + + const void* ptr = static_cast(base) + position; + return reinterpret_cast(ptr); + } +}; + +} // namespace google_breakpad +#endif // CLIENT_LINUX_MINIDUMP_WRITER_PE_FILE_H_ \ No newline at end of file diff --git a/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_structs.h b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_structs.h new file mode 100644 index 0000000000..843bd517ae --- /dev/null +++ b/thirdparty/sentry-native/external/breakpad/src/client/linux/minidump_writer/pe_structs.h @@ -0,0 +1,226 @@ +// Copyright (c) 2022, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CLIENT_LINUX_MINIDUMP_WRITER_PE_STRUCTS_H_ +#define CLIENT_LINUX_MINIDUMP_WRITER_PE_STRUCTS_H_ + +#include + +namespace google_breakpad { + +typedef uint8_t BYTE; +typedef uint16_t WORD; +typedef uint32_t DWORD; +typedef uint64_t ULONGLONG; + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +#define IMAGE_DEBUG_TYPE_CODEVIEW 2 + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 + +typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header + WORD e_magic; // Magic number + WORD e_cblp; // Bytes on last page of file + WORD e_cp; // Pages in file + WORD e_crlc; // Relocations + WORD e_cparhdr; // Size of header in paragraphs + WORD e_minalloc; // Minimum extra paragraphs needed + WORD e_maxalloc; // Maximum extra paragraphs needed + WORD e_ss; // Initial (relative) SS value + WORD e_sp; // Initial SP value + WORD e_csum; // Checksum + WORD e_ip; // Initial IP value + WORD e_cs; // Initial (relative) CS value + WORD e_lfarlc; // File address of relocation table + WORD e_ovno; // Overlay number + WORD e_res[4]; // Reserved words + WORD e_oemid; // OEM identifier (for e_oeminfo) + WORD e_oeminfo; // OEM information; e_oemid specific + WORD e_res2[10]; // Reserved words + DWORD e_lfanew; // File address of new exe header +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + + +typedef struct _IMAGE_DEBUG_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Type; + DWORD SizeOfData; + DWORD AddressOfRawData; + DWORD PointerToRawData; +} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; + +typedef struct _IMAGE_OPTIONAL_HEADER64 { + // + // Standard fields - Magic. + // + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + // + // NT additional fields. + // + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +typedef struct _IMAGE_OPTIONAL_HEADER { + // + // Standard fields. + // + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + // + // NT additional fields. + // + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; + +typedef struct _IMAGE_NT_HEADERS64 { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + +typedef struct _IMAGE_NT_HEADERS32 { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; + +typedef struct _IMAGE_NT_HEADERS { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +typedef struct _RSDS_DEBUG_FORMAT { + DWORD signature; + BYTE guid[16]; + BYTE age[4]; + char pdbpath[1]; +} RSDS_DEBUG_FORMAT, *PRSDS_DEBUG_FORMAT; + +} // namespace google_breakpad + +#endif // CLIENT_LINUX_MINIDUMP_WRITER_PE_STRUCTS_H_ \ No newline at end of file diff --git a/thirdparty/sentry-native/external/breakpad/src/client/mac/handler/minidump_generator.cc b/thirdparty/sentry-native/external/breakpad/src/client/mac/handler/minidump_generator.cc index e0351c4bbf..05d91b08e9 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/mac/handler/minidump_generator.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/mac/handler/minidump_generator.cc @@ -62,6 +62,8 @@ using MacStringUtils::IntegerValueAtIndex; namespace google_breakpad { +using mach_o::FileID; + #if defined(__LP64__) && __LP64__ #define LC_SEGMENT_ARCH LC_SEGMENT_64 #else @@ -1449,7 +1451,7 @@ bool MinidumpGenerator::WriteCVRecord(MDRawModule* module, int cpu_type, unsigned char identifier[16]; bool result = false; if (in_memory) { - MacFileUtilities::MachoID macho(module_path, + MacFileUtilities::MachoID macho( reinterpret_cast(module->base_of_image), static_cast(module->size_of_image)); result = macho.UUIDCommand(cpu_type, CPU_SUBTYPE_MULTIPLE, identifier); diff --git a/thirdparty/sentry-native/external/breakpad/src/client/solaris/handler/minidump_generator.cc b/thirdparty/sentry-native/external/breakpad/src/client/solaris/handler/minidump_generator.cc index 5675666558..81a535870c 100644 --- a/thirdparty/sentry-native/external/breakpad/src/client/solaris/handler/minidump_generator.cc +++ b/thirdparty/sentry-native/external/breakpad/src/client/solaris/handler/minidump_generator.cc @@ -47,6 +47,7 @@ namespace { using namespace google_breakpad; +using namespace google_breakpad::elf::FileID; // Argument for the writer function. struct WriterArgument { diff --git a/thirdparty/sentry-native/external/breakpad/src/common/dwarf/dwarf2reader.cc b/thirdparty/sentry-native/external/breakpad/src/common/dwarf/dwarf2reader.cc index aa4ec2b67b..bf6758d8ad 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/dwarf/dwarf2reader.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/dwarf/dwarf2reader.cc @@ -1793,7 +1793,7 @@ bool RangeListReader::ReadRanges(enum DwarfForm form, uint64_t data) { } } else if (form == DW_FORM_rnglistx) { offset_array_ = cu_info_->ranges_base_; - uint64_t index_offset = reader_->AddressSize() * data; + uint64_t index_offset = reader_->OffsetSize() * data; uint64_t range_list_offset = reader_->ReadOffset(cu_info_->buffer_ + offset_array_ + index_offset); diff --git a/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cfi_to_module.cc b/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cfi_to_module.cc index d7d19834b5..739b9fe0dd 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cfi_to_module.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cfi_to_module.cc @@ -184,9 +184,7 @@ string DwarfCFIToModule::RegisterName(int i) { return register_names_[reg]; reporter_->UnnamedRegister(entry_offset_, reg); - char buf[30]; - sprintf(buf, "unnamed_register%u", reg); - return buf; + return string("unnamed_register") + std::to_string(reg); } void DwarfCFIToModule::Record(Module::Address address, int reg, diff --git a/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cu_to_module.cc b/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cu_to_module.cc index 04d19479b7..bf78fda15a 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cu_to_module.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/dwarf_cu_to_module.cc @@ -254,9 +254,6 @@ struct DwarfCUToModule::CUContext { // A map of function pointers to the its forward specification DIE's offset. map spec_function_offsets; - - // From file index to vector of subprogram's offset in this CU. - map> inline_origins; }; // Information about the context of a particular DIE. This is for @@ -289,6 +286,7 @@ class DwarfCUToModule::GenericDIEHandler: public DIEHandler { offset_(offset), declaration_(false), specification_(NULL), + no_specification(false), abstract_origin_(NULL), forward_ref_die_offset_(0), specification_offset_(0) { } @@ -334,6 +332,10 @@ class DwarfCUToModule::GenericDIEHandler: public DIEHandler { // Otherwise, this is NULL. Specification* specification_; + // If this DIE has DW_AT_specification with offset smaller than this DIE and + // we can't find that in the specification map. + bool no_specification; + // If this DIE has a DW_AT_abstract_origin attribute, this is the // AbstractOrigin structure for the DIE the attribute refers to. // Otherwise, this is NULL. @@ -396,7 +398,7 @@ void DwarfCUToModule::GenericDIEHandler::ProcessAttributeReference( } else if (data > offset_) { forward_ref_die_offset_ = data; } else { - cu_context_->reporter->UnknownSpecification(offset_, data); + no_specification = true; } specification_offset_ = data; break; @@ -482,7 +484,7 @@ StringView DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() { // counts; otherwise, use this DIE's context. if (specification_) { enclosing_name = &specification_->enclosing_name; - } else { + } else if (parent_context_) { enclosing_name = &parent_context_->name; } } @@ -561,7 +563,8 @@ class DwarfCUToModule::InlineHandler : public GenericDIEHandler { DwarfForm high_pc_form_; // DW_AT_high_pc can be length or address. DwarfForm ranges_form_; // DW_FORM_sec_offset or DW_FORM_rnglistx uint64_t ranges_data_; // DW_AT_ranges - int call_site_line_; + int call_site_line_; // DW_AT_call_line + int call_site_file_id_; // DW_AT_call_file int inline_nest_level_; // A vector of inlines in the same nest level. It's owned by its parent // function/inline. At Finish(), add this inline into the vector. @@ -589,6 +592,9 @@ void DwarfCUToModule::InlineHandler::ProcessAttributeUnsigned( case DW_AT_call_line: call_site_line_ = data; break; + case DW_AT_call_file: + call_site_file_id_ = data; + break; default: GenericDIEHandler::ProcessAttributeUnsigned(attr, form, data); break; @@ -600,7 +606,7 @@ DIEHandler* DwarfCUToModule::InlineHandler::FindChildHandler( enum DwarfTag tag) { switch (tag) { case DW_TAG_inlined_subroutine: - return new InlineHandler(cu_context_, new DIEContext(), offset, + return new InlineHandler(cu_context_, nullptr, offset, inline_nest_level_ + 1, child_inlines_); default: return NULL; @@ -652,6 +658,11 @@ void DwarfCUToModule::InlineHandler::Finish() { } } + // Ignore DW_TAG_inlined_subroutine with empty range. + if (ranges.empty()) { + return; + } + // Every DW_TAG_inlined_subroutine should have a DW_AT_abstract_origin. assert(specification_offset_ != 0); @@ -661,11 +672,29 @@ void DwarfCUToModule::InlineHandler::Finish() { cu_context_->file_context->module_->inline_origin_map .GetOrCreateInlineOrigin(specification_offset_, name_); unique_ptr in( - new Module::Inline(origin, ranges, call_site_line_, inline_nest_level_, - std::move(child_inlines_))); + new Module::Inline(origin, ranges, call_site_line_, call_site_file_id_, + inline_nest_level_, std::move(child_inlines_))); inlines_.push_back(std::move(in)); } +// A handler for DIEs that contain functions and contribute a +// component to their names: namespaces, classes, etc. +class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler { + public: + NamedScopeHandler(CUContext* cu_context, + DIEContext* parent_context, + uint64_t offset, + bool handle_inline) + : GenericDIEHandler(cu_context, parent_context, offset), + handle_inline_(handle_inline) {} + bool EndAttributes(); + DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag); + + private: + DIEContext child_context_; // A context for our children. + bool handle_inline_; +}; + // A handler class for DW_TAG_subprogram DIEs. class DwarfCUToModule::FuncHandler: public GenericDIEHandler { public: @@ -679,7 +708,6 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler { high_pc_form_(DW_FORM_addr), ranges_form_(DW_FORM_sec_offset), ranges_data_(0), - decl_file_data_(UINT64_MAX), inline_(false), handle_inline_(handle_inline) {} @@ -700,12 +728,11 @@ class DwarfCUToModule::FuncHandler: public GenericDIEHandler { uint64_t low_pc_, high_pc_; // DW_AT_low_pc, DW_AT_high_pc DwarfForm high_pc_form_; // DW_AT_high_pc can be length or address. DwarfForm ranges_form_; // DW_FORM_sec_offset or DW_FORM_rnglistx - uint64_t ranges_data_; // DW_AT_ranges - // DW_AT_decl_file, value of UINT64_MAX means undefined. - uint64_t decl_file_data_; + uint64_t ranges_data_; // DW_AT_ranges bool inline_; vector> child_inlines_; bool handle_inline_; + DIEContext child_context_; // A context for our children. }; void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned( @@ -727,9 +754,6 @@ void DwarfCUToModule::FuncHandler::ProcessAttributeUnsigned( ranges_data_ = data; ranges_form_ = form; break; - case DW_AT_decl_file: - decl_file_data_ = data; - break; default: GenericDIEHandler::ProcessAttributeUnsigned(attr, form, data); break; @@ -757,8 +781,13 @@ DIEHandler* DwarfCUToModule::FuncHandler::FindChildHandler( switch (tag) { case DW_TAG_inlined_subroutine: if (handle_inline_) - return new InlineHandler(cu_context_, new DIEContext(), offset, 0, + return new InlineHandler(cu_context_, nullptr, offset, 0, child_inlines_); + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + return new NamedScopeHandler(cu_context_, &child_context_, offset, + handle_inline_); default: return NULL; } @@ -770,6 +799,10 @@ bool DwarfCUToModule::FuncHandler::EndAttributes() { if (name_.empty() && abstract_origin_) { name_ = abstract_origin_->name; } + child_context_.name = name_; + if (name_.empty() && no_specification) { + cu_context_->reporter->UnknownSpecification(offset_, specification_offset_); + } return true; } @@ -857,8 +890,7 @@ void DwarfCUToModule::FuncHandler::Finish() { // Only keep track of DW_TAG_subprogram which have the attributes we are // interested. - if (handle_inline_ && - (!empty_range || inline_ || decl_file_data_ != UINT64_MAX)) { + if (handle_inline_ && (!empty_range || inline_)) { StringView name = name_.empty() ? name_omitted : name_; uint64_t offset = specification_offset_ != 0 ? specification_offset_ : offset_; @@ -866,29 +898,14 @@ void DwarfCUToModule::FuncHandler::Finish() { offset); cu_context_->file_context->module_->inline_origin_map .GetOrCreateInlineOrigin(offset_, name); - if (decl_file_data_ != UINT64_MAX) - cu_context_->inline_origins[decl_file_data_].push_back(offset_); } } -// A handler for DIEs that contain functions and contribute a -// component to their names: namespaces, classes, etc. -class DwarfCUToModule::NamedScopeHandler: public GenericDIEHandler { - public: - NamedScopeHandler(CUContext* cu_context, DIEContext* parent_context, - uint64_t offset, bool handle_inline) - : GenericDIEHandler(cu_context, parent_context, offset), - handle_inline_(handle_inline) { } - bool EndAttributes(); - DIEHandler* FindChildHandler(uint64_t offset, enum DwarfTag tag); - - private: - DIEContext child_context_; // A context for our children. - bool handle_inline_; -}; - bool DwarfCUToModule::NamedScopeHandler::EndAttributes() { child_context_.name = ComputeQualifiedName(); + if (child_context_.name.empty() && no_specification) { + cu_context_->reporter->UnknownSpecification(offset_, specification_offset_); + } return true; } @@ -1450,10 +1467,12 @@ void DwarfCUToModule::AssignLinesToFunctions() { } void DwarfCUToModule::AssignFilesToInlines() { - for (auto iter : files_) { - cu_context_->file_context->module_->inline_origin_map - .AssignFilesToInlineOrigins(cu_context_->inline_origins[iter.first], - iter.second); + // Assign File* to Inlines inside this CU. + auto assignFile = [this](unique_ptr& in) { + in->call_site_file = files_[in->call_site_file_id]; + }; + for (auto func : cu_context_->functions) { + Module::Inline::InlineDFS(func->inlines, assignFile); } } diff --git a/thirdparty/sentry-native/external/breakpad/src/common/linux/dump_symbols.cc b/thirdparty/sentry-native/external/breakpad/src/common/linux/dump_symbols.cc index ac53ea286e..75a4ceed27 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/linux/dump_symbols.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/linux/dump_symbols.cc @@ -87,11 +87,11 @@ using google_breakpad::DwarfRangeListHandler; using google_breakpad::ElfClass; using google_breakpad::ElfClass32; using google_breakpad::ElfClass64; -using google_breakpad::FileID; +using google_breakpad::elf::FileID; using google_breakpad::FindElfSectionByName; using google_breakpad::GetOffset; using google_breakpad::IsValidElf; -using google_breakpad::kDefaultBuildIdSize; +using google_breakpad::elf::kDefaultBuildIdSize; using google_breakpad::Module; using google_breakpad::PageAllocator; #ifndef NO_STABS_SUPPORT diff --git a/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.cc b/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.cc index 9944af7aec..b483eb5c02 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.cc @@ -49,6 +49,7 @@ #include "third_party/lss/linux_syscall_support.h" namespace google_breakpad { +namespace elf { // Used in a few places for backwards-compatibility. const size_t kMDGUIDSize = sizeof(MDGUID); @@ -198,4 +199,5 @@ string FileID::ConvertIdentifierToString( return bytes_to_hex_string(&identifier[0], identifier.size()); } +} // elf } // namespace google_breakpad diff --git a/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.h b/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.h index 4aff021ded..8556a2e5ae 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id.h @@ -41,6 +41,7 @@ #include "common/using_std_string.h" namespace google_breakpad { +namespace elf { // GNU binutils' ld defaults to 'sha1', which is 160 bits == 20 bytes, // so this is enough to fit that, which most binaries will use. @@ -83,6 +84,7 @@ class FileID { string path_; }; +} // namespace elf } // namespace google_breakpad #endif // COMMON_LINUX_FILE_ID_H__ diff --git a/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id_unittest.cc b/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id_unittest.cc index 8225e5ac8b..43c9af7b58 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id_unittest.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/linux/file_id_unittest.cc @@ -50,6 +50,8 @@ #include "breakpad_googletest_includes.h" using namespace google_breakpad; +using google_breakpad::elf::FileID; +using google_breakpad::elf::kDefaultBuildIdSize; using google_breakpad::synth_elf::ELF; using google_breakpad::synth_elf::Notes; using google_breakpad::test_assembler::kLittleEndian; diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.h b/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.h index 9e955c8e20..8848cca6a8 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.h @@ -96,7 +96,8 @@ typedef NS_ENUM(NSInteger, SymbolStatus) { withUploadKey:(NSString*)uploadKey withDebugFile:(NSString*)debugFile withDebugID:(NSString*)debugID - withType:(NSString*)type; + withType:(NSString*)type + withProductName:(NSString*)productName; @end diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.m b/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.m index 5926d2ad2c..5465056dd0 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.m +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/SymbolCollectorClient.m @@ -190,18 +190,22 @@ withUploadKey:(NSString*)uploadKey withDebugFile:(NSString*)debugFile withDebugID:(NSString*)debugID - withType:(NSString*)type { + withType:(NSString*)type + withProductName:(NSString*)productName { NSURL* URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/v1/uploads/%@:complete?key=%@", APIURL, uploadKey, APIKey]]; - NSDictionary* symbolIdDictionary = - [NSDictionary dictionaryWithObjectsAndKeys:debugFile, @"debug_file", - debugID, @"debug_id", nil]; - NSDictionary* jsonDictionary = [NSDictionary - dictionaryWithObjectsAndKeys:symbolIdDictionary, @"symbol_id", type, - @"symbol_upload_type", nil]; + NSMutableDictionary* jsonDictionary = [@{ + @"symbol_id" : @{@"debug_file" : debugFile, @"debug_id" : debugID}, + @"symbol_upload_type" : type, @"use_async_processing" : @"true" + } mutableCopy]; + + if (productName != nil) { + jsonDictionary[@"metadata"] = @{@"product_name": productName}; + } + NSError* error = nil; NSData* jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.cc b/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.cc index 6df32bc10b..c62caed288 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.cc @@ -78,8 +78,8 @@ using google_breakpad::ByteReader; using google_breakpad::DwarfCUToModule; using google_breakpad::DwarfLineToModule; using google_breakpad::DwarfRangeListHandler; -using google_breakpad::FileID; using google_breakpad::mach_o::FatReader; +using google_breakpad::mach_o::FileID; using google_breakpad::mach_o::Section; using google_breakpad::mach_o::Segment; using google_breakpad::Module; @@ -128,10 +128,11 @@ bool DumpSymbols::Read(const string& filename) { return false; } - input_pathname_ = filename; + from_disk_ = true; // Does this filename refer to a dSYM bundle? - string contents_path = input_pathname_ + "/Contents/Resources/DWARF"; + string contents_path = filename + "/Contents/Resources/DWARF"; + string object_filename; if (S_ISDIR(st.st_mode) && access(contents_path.c_str(), F_OK) == 0) { // If there's one file under Contents/Resources/DWARF then use that, @@ -139,30 +140,31 @@ bool DumpSymbols::Read(const string& filename) { const vector entries = list_directory(contents_path); if (entries.size() == 0) { fprintf(stderr, "Unable to find DWARF-bearing file in bundle: %s\n", - input_pathname_.c_str()); + filename.c_str()); return false; } if (entries.size() > 1) { fprintf(stderr, "Too many DWARF files in bundle: %s\n", - input_pathname_.c_str()); + filename.c_str()); return false; } - object_filename_ = entries[0]; + object_filename = entries[0]; } else { - object_filename_ = input_pathname_; + object_filename = filename; } // Read the file's contents into memory. bool read_ok = true; string error; - if (stat(object_filename_.c_str(), &st) != -1) { - FILE* f = fopen(object_filename_.c_str(), "rb"); + scoped_array contents; + off_t total = 0; + if (stat(object_filename.c_str(), &st) != -1) { + FILE* f = fopen(object_filename.c_str(), "rb"); if (f) { - contents_.reset(new uint8_t[st.st_size]); - off_t total = 0; + contents.reset(new uint8_t[st.st_size]); while (total < st.st_size && !feof(f)) { - size_t read = fread(&contents_[0] + total, 1, st.st_size - total, f); + size_t read = fread(&contents[0] + total, 1, st.st_size - total, f); if (read == 0) { if (ferror(f)) { read_ok = false; @@ -180,16 +182,22 @@ bool DumpSymbols::Read(const string& filename) { if (!read_ok) { fprintf(stderr, "Error reading object file: %s: %s\n", - object_filename_.c_str(), - error.c_str()); + object_filename.c_str(), error.c_str()); return false; } + return ReadData(contents.release(), total, object_filename); +} + +bool DumpSymbols::ReadData(uint8_t* contents, size_t size, + const std::string& filename) { + contents_.reset(contents); + size_ = size; + object_filename_ = filename; // Get the list of object files present in the file. FatReader::Reporter fat_reporter(object_filename_); FatReader fat_reader(&fat_reporter); - if (!fat_reader.Read(&contents_[0], - st.st_size)) { + if (!fat_reader.Read(contents_.get(), size)) { return false; } @@ -283,7 +291,13 @@ SuperFatArch* DumpSymbols::FindBestMatchForArchitecture( } string DumpSymbols::Identifier() { - FileID file_id(object_filename_.c_str()); + scoped_ptr file_id; + + if (from_disk_) { + file_id.reset(new FileID(object_filename_.c_str())); + } else { + file_id.reset(new FileID(contents_.get(), size_)); + } unsigned char identifier_bytes[16]; scoped_ptr module; if (!selected_object_file_) { @@ -292,7 +306,7 @@ string DumpSymbols::Identifier() { } cpu_type_t cpu_type = selected_object_file_->cputype; cpu_subtype_t cpu_subtype = selected_object_file_->cpusubtype; - if (!file_id.MachoIdentifier(cpu_type, cpu_subtype, identifier_bytes)) { + if (!file_id->MachoIdentifier(cpu_type, cpu_subtype, identifier_bytes)) { fprintf(stderr, "Unable to calculate UUID of mach-o binary %s!\n", object_filename_.c_str()); return ""; @@ -399,6 +413,13 @@ bool DumpSymbols::CreateEmptyModule(scoped_ptr& module) { google_breakpad::BreakpadGetArchInfoFromCpuType( selected_object_file_->cputype, selected_object_file_->cpusubtype); + // In certain cases, it is possible that architecture info can't be reliably + // determined, e.g. new architectures that breakpad is unware of. In that + // case, avoid crashing and return false instead. + if (selected_arch_info == NULL) { + return false; + } + const char* selected_arch_name = selected_arch_info->name; if (strcmp(selected_arch_name, "i386") == 0) selected_arch_name = "x86"; diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.h b/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.h index 4365e2944c..34ba14bc0e 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/dump_syms.h @@ -57,21 +57,30 @@ class DumpSymbols { DumpSymbols(SymbolData symbol_data, bool handle_inter_cu_refs) : symbol_data_(symbol_data), handle_inter_cu_refs_(handle_inter_cu_refs), - input_pathname_(), object_filename_(), contents_(), + size_(0), + from_disk_(false), object_files_(), selected_object_file_(), - selected_object_name_() { } + selected_object_name_() {} ~DumpSymbols() { } // Prepare to read debugging information from |filename|. |filename| may be - // the name of a universal binary, a Mach-O file, or a dSYM bundle - // containing either of the above. On success, return true; if there is a - // problem reading |filename|, report it and return false. + // the name of a fat file, a Mach-O file, or a dSYM bundle containing either + // of the above. On success, return true; if there is a problem reading + // |filename|, report it and return false. bool Read(const std::string& filename); + // Prepare to read debugging information from |contents|. |contents| is + // expected to be the data obtained from reading a fat file, or a Mach-O file. + // |filename| is used to determine the object filename in the generated + // output; there will not be an attempt to open this file as the data + // is already expected to be in memory. On success, return true; if there is a + // problem reading |contents|, report it and return false. + bool ReadData(uint8_t* contents, size_t size, const std::string& filename); + // If this dumper's file includes an object file for |cpu_type| and // |cpu_subtype|, then select that object file for dumping, and return // true. Otherwise, return false, and leave this dumper's selected @@ -162,19 +171,22 @@ class DumpSymbols { // Whether to handle references between compilation units. const bool handle_inter_cu_refs_; - // The name of the file or bundle whose symbols this will dump. - // This is the path given to Read, for use in error messages. - std::string input_pathname_; - // The name of the file this DumpSymbols will actually read debugging - // information from. Normally, this is the same as input_pathname_, but if - // filename refers to a dSYM bundle, then this is the resource file - // within that bundle. + // information from. If the filename passed to Read refers to a dSYM bundle, + // then this is the resource file within that bundle. std::string object_filename_; // The complete contents of object_filename_, mapped into memory. scoped_array contents_; + // The size of contents_. + size_t size_; + + // Indicates which entry point to DumpSymbols was used, i.e. Read vs ReadData. + // This is used to indicate that downstream code paths can/should also read + // from disk or not. + bool from_disk_; + // A vector of SuperFatArch structures describing the object files // object_filename_ contains. If object_filename_ refers to a fat binary, // this may have more than one element; if it refers to a Mach-O file, this diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.cc b/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.cc index 4661d5d625..9ed65e5c85 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.cc @@ -33,53 +33,41 @@ // // Author: Dan Waylonis +#include "common/mac/file_id.h" + #include #include #include -#include -#include "common/mac/file_id.h" #include "common/mac/macho_id.h" +#include "common/scoped_ptr.h" using MacFileUtilities::MachoID; namespace google_breakpad { - -FileID::FileID(const char *path) { +namespace mach_o { +// Constructs a FileID given a path to a file +FileID::FileID(const char* path) : memory_(nullptr), size_(0) { snprintf(path_, sizeof(path_), "%s", path); } -bool FileID::FileIdentifier(unsigned char identifier[16]) { - int fd = open(path_, O_RDONLY); - if (fd == -1) - return false; - - MD5Context md5; - MD5Init(&md5); - - // Read 4k x 2 bytes at a time. This is faster than just 4k bytes, but - // doesn't seem to be an unreasonable size for the stack. - unsigned char buffer[4096 * 2]; - size_t buffer_size = sizeof(buffer); - while ((buffer_size = read(fd, buffer, buffer_size) > 0)) { - MD5Update(&md5, buffer, static_cast(buffer_size)); - } - - close(fd); - MD5Final(identifier, &md5); - - return true; -} +// Constructs a FileID given the contents of a file and its size +FileID::FileID(void* memory, size_t size) + : path_(), memory_(memory), size_(size) {} bool FileID::MachoIdentifier(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, unsigned char identifier[16]) { - MachoID macho(path_); - - if (macho.UUIDCommand(cpu_type, cpu_subtype, identifier)) + scoped_ptr macho; + if (memory_) { + macho.reset(new MachoID(memory_, size_)); + } else { + macho.reset(new MachoID(path_)); + } + if (macho->UUIDCommand(cpu_type, cpu_subtype, identifier)) return true; - return macho.MD5(cpu_type, cpu_subtype, identifier); + return macho->MD5(cpu_type, cpu_subtype, identifier); } // static @@ -103,4 +91,5 @@ void FileID::ConvertIdentifierToString(const unsigned char identifier[16], buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0; } +} // namespace mach_o } // namespace google_breakpad diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.h b/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.h index 5d60e84c9a..fc1821e7f7 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/file_id.h @@ -36,19 +36,19 @@ #include #include +#include namespace google_breakpad { +namespace mach_o { class FileID { public: - FileID(const char *path); - ~FileID() {} + // Constructs a FileID given a path to a file + FileID(const char* path); - // Load the identifier for the file path specified in the constructor into - // |identifier|. Return false if the identifier could not be created for the - // file. - // The current implementation will return the MD5 hash of the file's bytes. - bool FileIdentifier(unsigned char identifier[16]); + // Constructs a FileID given the contents of a file and its size. + FileID(void* memory, size_t size); + ~FileID() {} // Treat the file as a mach-o file that will contain one or more archicture. // Accepted values for |cpu_type| and |cpu_subtype| (e.g., CPU_TYPE_X86 or @@ -74,8 +74,19 @@ class FileID { private: // Storage for the path specified char path_[PATH_MAX]; + + // Storage for contents of a file if this instance is used to operate on in + // memory file data rather than directly from a filesystem. If memory_ is + // null, the file represented by path_ will be opened/read. If memory_ is + // non-null, it is assumed to contain valid data, and no file operations will + // occur. + void* memory_; + + // Size of memory_ + size_t size_; }; +} // namespace mach_o } // namespace google_breakpad #endif // COMMON_MAC_FILE_ID_H__ diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.cc b/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.cc index 3cf1d4b5f7..9b7ca24f34 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.cc @@ -37,11 +37,7 @@ #include #include #include -#include #include -#include -#include -#include #include "common/mac/macho_id.h" #include "common/mac/macho_walker.h" @@ -54,73 +50,18 @@ using google_breakpad::MD5Update; using google_breakpad::MD5Final; MachoID::MachoID(const char* path) - : memory_(0), - memory_size_(0), - crc_(0), - md5_context_(), - update_function_(NULL) { + : memory_(0), memory_size_(0), md5_context_(), update_function_(NULL) { snprintf(path_, sizeof(path_), "%s", path); } -MachoID::MachoID(const char* path, void* memory, size_t size) - : memory_(memory), - memory_size_(size), - crc_(0), - md5_context_(), - update_function_(NULL) { - snprintf(path_, sizeof(path_), "%s", path); -} +MachoID::MachoID(void* memory, size_t size) + : path_(), + memory_(memory), + memory_size_(size), + md5_context_(), + update_function_(NULL) {} -MachoID::~MachoID() { -} - -// The CRC info is from http://en.wikipedia.org/wiki/Adler-32 -// With optimizations from http://www.zlib.net/ - -// The largest prime smaller than 65536 -#define MOD_ADLER 65521 -// MAX_BLOCK is the largest n such that 255n(n+1)/2 + (n+1)(MAX_BLOCK-1) <= 2^32-1 -#define MAX_BLOCK 5552 - -void MachoID::UpdateCRC(unsigned char* bytes, size_t size) { -// Unrolled loops for summing -#define DO1(buf,i) {sum1 += (buf)[i]; sum2 += sum1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - // Split up the crc - uint32_t sum1 = crc_ & 0xFFFF; - uint32_t sum2 = (crc_ >> 16) & 0xFFFF; - - // Do large blocks - while (size >= MAX_BLOCK) { - size -= MAX_BLOCK; - int block_count = MAX_BLOCK / 16; - do { - DO16(bytes); - bytes += 16; - } while (--block_count); - sum1 %= MOD_ADLER; - sum2 %= MOD_ADLER; - } - - // Do remaining bytes - if (size) { - while (size >= 16) { - size -= 16; - DO16(bytes); - bytes += 16; - } - while (size--) { - sum1 += *bytes++; - sum2 += sum1; - } - sum1 %= MOD_ADLER; - sum2 %= MOD_ADLER; - crc_ = (sum2 << 16) | sum1; - } -} +MachoID::~MachoID() {} void MachoID::UpdateMD5(unsigned char* bytes, size_t size) { MD5Update(&md5_context_, bytes, static_cast(size)); @@ -169,59 +110,6 @@ bool MachoID::UUIDCommand(cpu_type_t cpu_type, return false; } -bool MachoID::IDCommand(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]) { - struct dylib_command dylib_cmd; - dylib_cmd.cmd = 0; - if (!WalkHeader(cpu_type, cpu_subtype, IDWalkerCB, &dylib_cmd)) - return false; - - // If we found the command, we'll have initialized the dylib_command - // structure - if (dylib_cmd.cmd == LC_ID_DYLIB) { - // Take the hashed filename, version, and compatability version bytes - // to form the first 12 bytes, pad the rest with zeros - - // create a crude hash of the filename to generate the first 4 bytes - identifier[0] = 0; - identifier[1] = 0; - identifier[2] = 0; - identifier[3] = 0; - - for (int j = 0, i = (int)strlen(path_)-1; i>=0 && path_[i]!='/'; ++j, --i) { - identifier[j%4] += path_[i]; - } - - identifier[4] = (dylib_cmd.dylib.current_version >> 24) & 0xFF; - identifier[5] = (dylib_cmd.dylib.current_version >> 16) & 0xFF; - identifier[6] = (dylib_cmd.dylib.current_version >> 8) & 0xFF; - identifier[7] = dylib_cmd.dylib.current_version & 0xFF; - identifier[8] = (dylib_cmd.dylib.compatibility_version >> 24) & 0xFF; - identifier[9] = (dylib_cmd.dylib.compatibility_version >> 16) & 0xFF; - identifier[10] = (dylib_cmd.dylib.compatibility_version >> 8) & 0xFF; - identifier[11] = dylib_cmd.dylib.compatibility_version & 0xFF; - identifier[12] = (cpu_type >> 24) & 0xFF; - identifier[13] = (cpu_type >> 16) & 0xFF; - identifier[14] = (cpu_type >> 8) & 0xFF; - identifier[15] = cpu_type & 0xFF; - - return true; - } - - return false; -} - -uint32_t MachoID::Adler32(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype) { - update_function_ = &MachoID::UpdateCRC; - crc_ = 0; - - if (!WalkHeader(cpu_type, cpu_subtype, WalkerCB, this)) - return 0; - - return crc_; -} - bool MachoID::MD5(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype, unsigned char identifier[16]) { update_function_ = &MachoID::UpdateMD5; @@ -346,24 +234,4 @@ bool MachoID::UUIDWalkerCB(MachoWalker* walker, load_command* cmd, off_t offset, // Continue processing return true; } - -// static -bool MachoID::IDWalkerCB(MachoWalker* walker, load_command* cmd, off_t offset, - bool swap, void* context) { - if (cmd->cmd == LC_ID_DYLIB) { - struct dylib_command* dylib_cmd = (struct dylib_command*)context; - - if (!walker->ReadBytes(dylib_cmd, sizeof(struct dylib_command), offset)) - return false; - - if (swap) - breakpad_swap_dylib_command(dylib_cmd); - - return false; - } - - // Continue processing - return true; -} - } // namespace MacFileUtilities diff --git a/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.h b/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.h index e8874c37cd..0262697d41 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/mac/macho_id.h @@ -46,7 +46,7 @@ namespace MacFileUtilities { class MachoID { public: MachoID(const char* path); - MachoID(const char* path, void* memory, size_t size); + MachoID(void* memory, size_t size); ~MachoID(); // For the given |cpu_type| and |cpu_subtype|, return a UUID from the LC_UUID @@ -56,19 +56,6 @@ class MachoID { cpu_subtype_t cpu_subtype, unsigned char identifier[16]); - // For the given |cpu_type| and |cpu_subtype|, return a UUID from the - // LC_ID_DYLIB command. - // Return false if there isn't a LC_ID_DYLIB command. - bool IDCommand(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype, - unsigned char identifier[16]); - - // For the given |cpu_type| and |cpu_subtype|, return the Adler32 CRC for the - // mach-o data segment(s). - // Return 0 on error (e.g., if the file is not a mach-o file) - uint32_t Adler32(cpu_type_t cpu_type, - cpu_subtype_t cpu_subtype); - // For the given |cpu_type|, and |cpu_subtype| return the MD5 for the mach-o // data segment(s). // Return true on success, false otherwise @@ -80,10 +67,6 @@ class MachoID { // Signature of class member function to be called with data read from file typedef void (MachoID::*UpdateFunction)(unsigned char* bytes, size_t size); - // Update the CRC value by examining |size| |bytes| and applying the algorithm - // to each byte. - void UpdateCRC(unsigned char* bytes, size_t size); - // Update the MD5 value by examining |size| |bytes| and applying the algorithm // to each byte. void UpdateMD5(unsigned char* bytes, size_t size); @@ -103,10 +86,6 @@ class MachoID { static bool UUIDWalkerCB(MachoWalker* walker, load_command* cmd, off_t offset, bool swap, void* context); - // The callback from the MachoWalker for LC_ID_DYLIB - static bool IDWalkerCB(MachoWalker* walker, load_command* cmd, off_t offset, - bool swap, void* context); - // File path char path_[PATH_MAX]; @@ -116,9 +95,6 @@ class MachoID { // Size of the memory region size_t memory_size_; - // The current crc value - uint32_t crc_; - // The MD5 context google_breakpad::MD5Context md5_context_; diff --git a/thirdparty/sentry-native/external/breakpad/src/common/module.cc b/thirdparty/sentry-native/external/breakpad/src/common/module.cc index 3945e2dd3f..13c229eb4f 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/module.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/module.cc @@ -97,17 +97,6 @@ void Module::InlineOriginMap::SetReference(uint64_t offset, references_[offset] = specification_offset; } -void Module::InlineOriginMap::AssignFilesToInlineOrigins( - const vector& inline_origin_offsets, - Module::File* file) { - for (uint64_t offset : inline_origin_offsets) - if (references_.find(offset) != references_.end()) { - auto origin = inline_origins_.find(references_[offset]); - if (origin != inline_origins_.end()) - origin->second->file = file; - } -} - Module::Module(const string& name, const string& os, const string& architecture, const string& id, const string& code_id /* = "" */) : @@ -276,13 +265,19 @@ void Module::AssignSourceIds( line_it != func->lines.end(); ++line_it) line_it->file->source_id = 0; } - // Also mark all files cited by inline functions by setting each one's source + + // Also mark all files cited by inline callsite by setting each one's source // id to zero. - for (InlineOrigin* origin : inline_origins) + auto markInlineFiles = [](unique_ptr& in) { // There are some artificial inline functions which don't belong to // any file. Those will have file id -1. - if (origin->file) - origin->file->source_id = 0; + if (in->call_site_file) { + in->call_site_file->source_id = 0; + } + }; + for (auto func : functions_) { + Inline::InlineDFS(func->inlines, markInlineFiles); + } // Finally, assign source ids to those files that have been marked. // We could have just assigned source id numbers while traversing @@ -296,15 +291,6 @@ void Module::AssignSourceIds( } } -static void InlineDFS( - vector>& inlines, - std::function&)> const& forEach) { - for (unique_ptr& in : inlines) { - forEach(in); - InlineDFS(in->child_inlines, forEach); - } -} - void Module::CreateInlineOrigins( set& inline_origins) { // Only add origins that have file and deduplicate origins with same name and @@ -317,7 +303,7 @@ void Module::CreateInlineOrigins( in->origin = *it; }; for (Function* func : functions_) - InlineDFS(func->inlines, addInlineOrigins); + Module::Inline::InlineDFS(func->inlines, addInlineOrigins); int next_id = 0; for (InlineOrigin* origin : inline_origins) { origin->id = next_id++; @@ -381,8 +367,7 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { } // Write out inline origins. for (InlineOrigin* origin : inline_origins) { - stream << "INLINE_ORIGIN " << origin->id << " " << origin->getFileID() - << " " << origin->name << "\n"; + stream << "INLINE_ORIGIN " << origin->id << " " << origin->name << "\n"; if (!stream.good()) return ReportError(); } @@ -407,12 +392,12 @@ bool Module::Write(std::ostream& stream, SymbolData symbol_data) { auto write_inline = [&](unique_ptr& in) { stream << "INLINE "; stream << in->inline_nest_level << " " << in->call_site_line << " " - << in->origin->id << hex; + << in->getCallSiteFileID() << " " << in->origin->id << hex; for (const Range& r : in->ranges) stream << " " << (r.address - load_address_) << " " << r.size; stream << dec << "\n"; }; - InlineDFS(func->inlines, write_inline); + Module::Inline::InlineDFS(func->inlines, write_inline); if (!stream.good()) return ReportError(); diff --git a/thirdparty/sentry-native/external/breakpad/src/common/module.h b/thirdparty/sentry-native/external/breakpad/src/common/module.h index c5e0abfc5d..01ecfa8aae 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/module.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/module.h @@ -38,6 +38,7 @@ #ifndef COMMON_LINUX_MODULE_H__ #define COMMON_LINUX_MODULE_H__ +#include #include #include #include @@ -131,7 +132,7 @@ class Module { }; struct InlineOrigin { - explicit InlineOrigin(StringView name): id(-1), name(name), file(nullptr) {} + explicit InlineOrigin(StringView name) : id(-1), name(name) {} // A unique id for each InlineOrigin object. INLINE records use the id to // refer to its INLINE_ORIGIN record. @@ -150,11 +151,14 @@ class Module { Inline(InlineOrigin* origin, const vector& ranges, int call_site_line, + int call_site_file_id, int inline_nest_level, vector> child_inlines) : origin(origin), ranges(ranges), call_site_line(call_site_line), + call_site_file_id(call_site_file_id), + call_site_file(nullptr), inline_nest_level(inline_nest_level), child_inlines(std::move(child_inlines)) {} @@ -165,10 +169,29 @@ class Module { int call_site_line; + // The id is only meanful inside a CU. It's only used for looking up real + // File* after scanning a CU. + int call_site_file_id; + + File* call_site_file; + int inline_nest_level; // A list of inlines which are children of this inline. vector> child_inlines; + + int getCallSiteFileID() const { + return call_site_file ? call_site_file->source_id : -1; + } + + static void InlineDFS( + vector>& inlines, + std::function&)> const& forEach) { + for (std::unique_ptr& in : inlines) { + forEach(in); + InlineDFS(in->child_inlines, forEach); + } + } }; typedef map InlineOriginByOffset; @@ -182,9 +205,7 @@ class Module { // value of its DW_AT_specification or equals to offset if // DW_AT_specification doesn't exist in that DIE. void SetReference(uint64_t offset, uint64_t specification_offset); - void AssignFilesToInlineOrigins( - const vector& inline_origin_offsets, - File* file); + ~InlineOriginMap() { for (const auto& iter : inline_origins_) { delete iter.second; @@ -261,10 +282,8 @@ class Module { }; struct InlineOriginCompare { - bool operator() (const InlineOrigin* lhs, const InlineOrigin* rhs) const { - if (lhs->getFileID() == rhs->getFileID()) - return lhs->name < rhs->name; - return lhs->getFileID() < rhs->getFileID(); + bool operator()(const InlineOrigin* lhs, const InlineOrigin* rhs) const { + return lhs->name < rhs->name; } }; diff --git a/thirdparty/sentry-native/external/breakpad/src/common/solaris/dump_symbols.cc b/thirdparty/sentry-native/external/breakpad/src/common/solaris/dump_symbols.cc index 9524a18b57..93aeed2437 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/solaris/dump_symbols.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/solaris/dump_symbols.cc @@ -492,7 +492,7 @@ bool WriteModuleInfo(int fd, GElf_Half arch, const std::string& obj_file) { } unsigned char identifier[16]; - google_breakpad::FileID file_id(obj_file.c_str()); + google_breakpad::elf::FileID file_id(obj_file.c_str()); if (file_id.ElfFileIdentifier(identifier)) { char identifier_str[40]; file_id.ConvertIdentifierToString(identifier, diff --git a/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.cc b/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.cc index c32c73bb04..837793c866 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.cc @@ -128,10 +128,6 @@ static bool FindElfTextSection(int fd, const void* elf_base, return false; } -FileID::FileID(const char* path) { - strcpy(path_, path); -} - class AutoCloser { public: AutoCloser(int fd) : fd_(fd) {} @@ -140,6 +136,12 @@ class AutoCloser { int fd_; }; +namespace elf { + +FileID::FileID(const char* path) { + strcpy(path_, path); +} + bool FileID::ElfFileIdentifier(unsigned char identifier[16]) { int fd = 0; if ((fd = open(path_, O_RDONLY)) < 0) @@ -194,4 +196,5 @@ bool FileID::ConvertIdentifierToString(const unsigned char identifier[16], return true; } +} // elf } // namespace google_breakpad diff --git a/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.h b/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.h index 375e857512..cacf17a967 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/solaris/file_id.h @@ -37,6 +37,7 @@ #include namespace google_breakpad { +namespace elf { class FileID { public: @@ -61,6 +62,7 @@ class FileID { char path_[PATH_MAX]; }; +} // elf } // namespace google_breakpad #endif // COMMON_SOLARIS_FILE_ID_H__ diff --git a/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.cc b/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.cc index 08d52635ba..25a1ca053b 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.cc @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,8 @@ namespace google_breakpad { namespace { +using std::set; +using std::unique_ptr; using std::vector; // The symbol (among possibly many) selected to represent an rva. @@ -208,9 +211,162 @@ void StripLlvmSuffixAndUndecorate(BSTR* name) { } // namespace -PDBSourceLineWriter::PDBSourceLineWriter() : output_(NULL) { +PDBSourceLineWriter::Inline::Inline(int inline_nest_level) + : inline_nest_level_(inline_nest_level) {} + +void PDBSourceLineWriter::Inline::SetOriginId(int origin_id) { + origin_id_ = origin_id; } +void PDBSourceLineWriter::Inline::ExtendRanges(const Line& line) { + if (ranges_.empty()) { + ranges_[line.rva] = line.length; + return; + } + auto iter = ranges_.lower_bound(line.rva); + // There is no overlap if this function is called with inlinee lines from + // the same callsite. + if (iter == ranges_.begin()) { + return; + } + if (line.rva + line.length == iter->first) { + // If they are connected, merge their ranges into one. + DWORD length = line.length + iter->second; + ranges_.erase(iter); + ranges_[line.rva] = length; + } else { + --iter; + if (iter->first + iter->second == line.rva) { + ranges_[iter->first] = iter->second + line.length; + } else { + ranges_[line.rva] = line.length; + } + } +} + +void PDBSourceLineWriter::Inline::SetCallSiteLine(DWORD call_site_line) { + call_site_line_ = call_site_line; +} + +void PDBSourceLineWriter::Inline::SetCallSiteFileId(DWORD call_site_file_id) { + call_site_file_id_ = call_site_file_id; +} + +void PDBSourceLineWriter::Inline::SetChildInlines( + vector> child_inlines) { + child_inlines_ = std::move(child_inlines); +} + +void PDBSourceLineWriter::Inline::Print(FILE* output) const { + // Ignore INLINE record that doesn't have any range. + if (ranges_.empty()) + return; + fprintf(output, "INLINE %d %lu %lu %d", inline_nest_level_, call_site_line_, + call_site_file_id_, origin_id_); + for (const auto& r : ranges_) { + fprintf(output, " %lx %lx", r.first, r.second); + } + fprintf(output, "\n"); + for (const unique_ptr& in : child_inlines_) { + in->Print(output); + } +} + +const PDBSourceLineWriter::Line* PDBSourceLineWriter::Lines::GetLine( + DWORD rva) const { + auto iter = line_map_.find(rva); + if (iter == line_map_.end()) { + // If not found exact rva, check if it's within any range. + iter = line_map_.lower_bound(rva); + if (iter == line_map_.begin()) + return nullptr; + --iter; + auto l = iter->second; + // This happens when there is no top level lines cover this rva (e.g. empty + // lines found for the function). Then we don't know the call site line + // number for this inlined function. + if (rva >= l.rva + l.length) + return nullptr; + } + return &iter->second; +} + +DWORD PDBSourceLineWriter::Lines::GetLineNum(DWORD rva) const { + const Line* line = GetLine(rva); + return line ? line->line_num : 0; +} + +DWORD PDBSourceLineWriter::Lines::GetFileId(DWORD rva) const { + const Line* line = GetLine(rva); + return line ? line->file_id : 0; +} + +void PDBSourceLineWriter::Lines::AddLine(const Line& line) { + if (line_map_.empty()) { + line_map_[line.rva] = line; + return; + } + + // Given an existing line in line_map_, remove it from line_map_ if it + // overlaps with the line and add a new line for the non-overlap range. Return + // true if there is an overlap. + auto intercept = [&](Line old_line) { + DWORD end = old_line.rva + old_line.length; + // No overlap. + if (old_line.rva >= line.rva + line.length || line.rva >= end) + return false; + // old_line is within the line. + if (old_line.rva >= line.rva && end <= line.rva + line.length) { + line_map_.erase(old_line.rva); + return true; + } + // Then there is a overlap. + if (old_line.rva < line.rva) { + old_line.length -= end - line.rva; + if (end > line.rva + line.length) { + Line new_line = old_line; + new_line.rva = line.rva + line.length; + new_line.length = end - new_line.rva; + line_map_[new_line.rva] = new_line; + } + } else { + line_map_.erase(old_line.rva); + old_line.length -= line.rva + line.length - old_line.rva; + old_line.rva = line.rva + line.length; + } + line_map_[old_line.rva] = old_line; + return true; + }; + + bool is_intercept; + // Use a loop in cases that there are multiple lines within the given line. + do { + auto iter = line_map_.lower_bound(line.rva); + if (iter == line_map_.end()) { + if (!line_map_.empty()) { + --iter; + intercept(iter->second); + } + break; + } + is_intercept = false; + if (iter != line_map_.begin()) { + // Check if the given line overlaps a line with smaller in the map. + auto prev = line_map_.lower_bound(line.rva); + --prev; + is_intercept = intercept(prev->second); + } + // Check if the given line overlaps a line with greater or equal rva in the + // map. Using operator |= here since it's possible that there are multiple + // lines with greater rva in the map overlap with the given line. + is_intercept |= intercept(iter->second); + } while (is_intercept); + line_map_[line.rva] = line; +} + +PDBSourceLineWriter::PDBSourceLineWriter(bool handle_inline) + : output_(NULL), handle_inline_(handle_inline) {} + PDBSourceLineWriter::~PDBSourceLineWriter() { Close(); } @@ -280,50 +436,63 @@ bool PDBSourceLineWriter::Open(const wstring& file, FileFormat format) { return true; } -bool PDBSourceLineWriter::PrintLines(IDiaEnumLineNumbers* lines) { - // The line number format is: - // +bool PDBSourceLineWriter::GetLine(IDiaLineNumber* dia_line, Line* line) const { + if (FAILED(dia_line->get_relativeVirtualAddress(&line->rva))) { + fprintf(stderr, "failed to get line rva\n"); + return false; + } + + if (FAILED(dia_line->get_length(&line->length))) { + fprintf(stderr, "failed to get line code length\n"); + return false; + } + + DWORD dia_source_id; + if (FAILED(dia_line->get_sourceFileId(&dia_source_id))) { + fprintf(stderr, "failed to get line source file id\n"); + return false; + } + // duplicate file names are coalesced to share one ID + line->file_id = GetRealFileID(dia_source_id); + + if (FAILED(dia_line->get_lineNumber(&line->line_num))) { + fprintf(stderr, "failed to get line number\n"); + return false; + } + return true; +} + +bool PDBSourceLineWriter::GetLines(IDiaEnumLineNumbers* lines, + Lines* line_list) const { CComPtr line; ULONG count; while (SUCCEEDED(lines->Next(1, &line, &count)) && count == 1) { - DWORD rva; - if (FAILED(line->get_relativeVirtualAddress(&rva))) { - fprintf(stderr, "failed to get line rva\n"); + Line l; + if (!GetLine(line, &l)) return false; - } - - DWORD length; - if (FAILED(line->get_length(&length))) { - fprintf(stderr, "failed to get line code length\n"); - return false; - } - - DWORD dia_source_id; - if (FAILED(line->get_sourceFileId(&dia_source_id))) { - fprintf(stderr, "failed to get line source file id\n"); - return false; - } - // duplicate file names are coalesced to share one ID - DWORD source_id = GetRealFileID(dia_source_id); - - DWORD line_num; - if (FAILED(line->get_lineNumber(&line_num))) { - fprintf(stderr, "failed to get line number\n"); - return false; - } - - AddressRangeVector ranges; - MapAddressRange(image_map_, AddressRange(rva, length), &ranges); - for (size_t i = 0; i < ranges.size(); ++i) { - fprintf(output_, "%lx %lx %lu %lu\n", ranges[i].rva, ranges[i].length, - line_num, source_id); - } + // Silently ignore zero-length lines. + if (l.length != 0) + line_list->AddLine(l); line.Release(); } return true; } +void PDBSourceLineWriter::PrintLines(const Lines& lines) const { + // The line number format is: + // + for (const auto& kv : lines.GetLineMap()) { + const Line& l = kv.second; + AddressRangeVector ranges; + MapAddressRange(image_map_, AddressRange(l.rva, l.length), &ranges); + for (auto& range : ranges) { + fprintf(output_, "%lx %lx %lu %lu\n", range.rva, range.length, l.line_num, + l.file_id); + } + } +} + bool PDBSourceLineWriter::PrintFunction(IDiaSymbol* function, IDiaSymbol* block, bool has_multiple_symbols) { @@ -372,9 +541,20 @@ bool PDBSourceLineWriter::PrintFunction(IDiaSymbol* function, return false; } - if (!PrintLines(lines)) { + // Get top level lines first, which later may be split into multiple smaller + // lines if any inline exists in their ranges if we want to handle inline. + Lines line_list; + if (!GetLines(lines, &line_list)) { return false; } + if (handle_inline_) { + vector> inlines; + if (!GetInlines(block, &line_list, 0, &inlines)) { + return false; + } + PrintInlines(inlines); + } + PrintLines(line_list); return true; } @@ -392,6 +572,10 @@ bool PDBSourceLineWriter::PrintSourceFiles() { return false; } + // Print a dummy file with id equals 0 to represent unknown file, because + // inline records might have unknown call site. + fwprintf(output_, L"FILE %d unknown file\n", 0); + CComPtr compiland; ULONG count; while (SUCCEEDED(compilands->Next(1, &compiland, &count)) && count == 1) { @@ -555,6 +739,97 @@ bool PDBSourceLineWriter::PrintFunctions() { return true; } +void PDBSourceLineWriter::PrintInlineOrigins() const { + struct OriginCompare { + bool operator()(const InlineOrigin lhs, const InlineOrigin rhs) const { + return lhs.id < rhs.id; + } + }; + set origins; + // Sort by origin id. + for (auto const& origin : inline_origins_) + origins.insert(origin.second); + for (auto o : origins) { + fprintf(output_, "INLINE_ORIGIN %d %ls\n", o.id, o.name.c_str()); + } +} + +bool PDBSourceLineWriter::GetInlines(IDiaSymbol* block, + Lines* line_list, + int inline_nest_level, + vector>* inlines) { + CComPtr inline_callsites; + if (FAILED(block->findChildrenEx(SymTagInlineSite, nullptr, nsNone, + &inline_callsites))) { + return false; + } + ULONG count; + CComPtr callsite; + while (SUCCEEDED(inline_callsites->Next(1, &callsite, &count)) && + count == 1) { + unique_ptr new_inline(new Inline(inline_nest_level)); + CComPtr lines; + // All inlinee lines have the same file id. + DWORD file_id = 0; + DWORD call_site_line = 0; + if (FAILED(session_->findInlineeLines(callsite, &lines))) { + return false; + } + CComPtr dia_line; + while (SUCCEEDED(lines->Next(1, &dia_line, &count)) && count == 1) { + Line line; + if (!GetLine(dia_line, &line)) { + return false; + } + // Silently ignore zero-length lines. + if (line.length != 0) { + // Use the first line num and file id at rva as this inline's call site + // line number, because after adding lines it may be changed to inner + // line number and inner file id. + if (call_site_line == 0) + call_site_line = line_list->GetLineNum(line.rva); + if (file_id == 0) + file_id = line_list->GetFileId(line.rva); + line_list->AddLine(line); + new_inline->ExtendRanges(line); + } + dia_line.Release(); + } + BSTR name; + callsite->get_name(&name); + if (SysStringLen(name) == 0) { + name = SysAllocString(L""); + } + auto iter = inline_origins_.find(name); + if (iter == inline_origins_.end()) { + InlineOrigin origin; + origin.id = inline_origins_.size(); + origin.name = name; + inline_origins_[name] = origin; + } + new_inline->SetOriginId(inline_origins_[name].id); + new_inline->SetCallSiteLine(call_site_line); + new_inline->SetCallSiteFileId(file_id); + // Go to next level. + vector> child_inlines; + if (!GetInlines(callsite, line_list, inline_nest_level + 1, + &child_inlines)) { + return false; + } + new_inline->SetChildInlines(std::move(child_inlines)); + inlines->push_back(std::move(new_inline)); + callsite.Release(); + } + return true; +} + +void PDBSourceLineWriter::PrintInlines( + const vector>& inlines) const { + for (const unique_ptr& in : inlines) { + in->Print(output_); + } +} + #undef max bool PDBSourceLineWriter::PrintFrameDataUsingPDB() { @@ -1105,10 +1380,8 @@ bool PDBSourceLineWriter::WriteSymbols(FILE* symbol_file) { bool ret = PrintPDBInfo(); // This is not a critical piece of the symbol file. PrintPEInfo(); - ret = ret && - PrintSourceFiles() && - PrintFunctions() && - PrintFrameData(); + ret = ret && PrintSourceFiles() && PrintFunctions() && PrintFrameData(); + PrintInlineOrigins(); output_ = NULL; return ret; diff --git a/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.h b/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.h index 00f6e59294..42bd94d95a 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/windows/pdb_source_line_writer.h @@ -35,8 +35,11 @@ #include +#include +#include #include #include +#include #include "common/windows/module_info.h" #include "common/windows/omap.h" @@ -47,6 +50,8 @@ struct IDiaSymbol; namespace google_breakpad { +using std::map; +using std::vector; using std::wstring; using std::unordered_map; @@ -58,7 +63,7 @@ class PDBSourceLineWriter { ANY_FILE // try PDB_FILE and then EXE_FILE }; - explicit PDBSourceLineWriter(); + explicit PDBSourceLineWriter(bool handle_inline = false); ~PDBSourceLineWriter(); // Opens the given file. For executable files, the corresponding pdb @@ -99,9 +104,110 @@ class PDBSourceLineWriter { bool UsesGUID(bool *uses_guid); private: - // Outputs the line/address pairs for each line in the enumerator. + // InlineOrigin represents INLINE_ORIGIN record in a symbol file. It's an + // inlined function. + struct InlineOrigin { + // The unique id for an InlineOrigin. + int id; + // The name of the inlined function. + wstring name; + }; + + // Line represents LINE record in a symbol file. It represents a source code + // line. + struct Line { + // The relative address of a line. + DWORD rva; + // The number bytes this line has. + DWORD length; + // The source line number. + DWORD line_num; + // The source file id where the source line is located at. + DWORD file_id; + }; + + // Inline represents INLINE record in a symbol file. + class Inline { + public: + explicit Inline(int inline_nest_level); + + void SetOriginId(int origin_id); + + // Adding inlinee line's range into ranges. If line is adjacent with any + // existing lines, extend the range. Otherwise, add line as a new range. + void ExtendRanges(const Line& line); + + void SetCallSiteLine(DWORD call_site_line); + + void SetCallSiteFileId(DWORD call_site_file_id); + + void SetChildInlines(std::vector> child_inlines); + + void Print(FILE* output) const; + + private: + // The nest level of this inline record. + int inline_nest_level_; + // The source line number at where this inlined function is called. + DWORD call_site_line_ = 0; + // The call site file id at where this inlined function is called. + DWORD call_site_file_id_ = 0; + // The id used for referring to an InlineOrigin. + int origin_id_ = 0; + // A map from rva to length. This is the address ranges covered by this + // Inline. + map ranges_; + // The list of direct Inlines inlined inside this Inline. + vector> child_inlines_; + }; + + // Lines represents a map of lines inside a function with rva as the key. + // AddLine function adds a line into the map and ensures that there is no + // overlap between any two lines in the map. + class Lines { + public: + const map& GetLineMap() const { return line_map_; } + + // Finds the line from line_map_ that contains the given rva returns its + // line_num. If not found, return 0. + DWORD GetLineNum(DWORD rva) const; + + // Finds the line from line_map_ that contains the given rva returns its + // file_id. If not found, return 0. + DWORD GetFileId(DWORD rva) const; + + // Add the `line` into line_map_. If the `line` overlaps with existing + // lines, truncate the existing lines and add the given line. It ensures + // that all lines in line_map_ do not overlap with each other. For example, + // suppose there is a line A in the map and we call AddLine with Line B. + // Line A: rva: 100, length: 20, line_num: 10, file_id: 1 + // Line B: rva: 105, length: 10, line_num: 4, file_id: 2 + // After calling AddLine with Line B, we will have the following lines: + // Line 1: rva: 100, length: 5, line_num: 10, file_id: 1 + // Line 2: rva: 105, length: 10, line_num: 4, file_id: 2 + // Line 3: rva: 115, length: 5, line_num: 10, file_id: 1 + void AddLine(const Line& line); + + private: + // Finds the line from line_map_ that contains the given rva. If not found, + // return nullptr. + const Line* GetLine(DWORD rva) const; + // The key is rva. AddLine function ensures that any two lines in the map do + // not overlap. + map line_map_; + }; + + // Construct Line from IDiaLineNumber. The output Line is stored at line. + // Return true on success. + bool GetLine(IDiaLineNumber* dia_line, Line* line) const; + + // Construct Lines from IDiaEnumLineNumbers. The list of Lines are stored at + // line_list. // Returns true on success. - bool PrintLines(IDiaEnumLineNumbers *lines); + bool GetLines(IDiaEnumLineNumbers* lines, Lines* line_list) const; + + // Outputs the line/address pairs for each line in the enumerator. + void PrintLines(const Lines& lines) const; // Outputs a function address and name, followed by its source line list. // block can be the same object as function, or it can be a reference to a @@ -118,6 +224,25 @@ class PDBSourceLineWriter { // Returns true on success. bool PrintSourceFiles(); + // Output all inline origins. + void PrintInlineOrigins() const; + + // Retrieve inlines inside the given block. It also adds inlinee lines to + // `line_list` since inner lines are more precise source location. If the + // block has children wih SymTagInlineSite Tag, it will recursively (DFS) call + // itself with each child as first argument. Returns true on success. + // `block`: the IDiaSymbol that may have inline sites. + // `line_list`: the list of lines inside current function. + // `inline_nest_level`: the nest level of block's Inlines. + // `inlines`: the vector to store the list of inlines for the block. + bool GetInlines(IDiaSymbol* block, + Lines* line_list, + int inline_nest_level, + vector>* inlines); + + // Outputs all inlines. + void PrintInlines(const vector>& inlines) const; + // Outputs all of the frame information necessary to construct stack // backtraces in the absence of frame pointers. For x86 data stored in // .pdb files. Returns true on success. @@ -172,8 +297,8 @@ class PDBSourceLineWriter { // reference it. There may be multiple files with identical filenames // but different unique IDs. The cache attempts to coalesce these into // one ID per unique filename. - DWORD GetRealFileID(DWORD id) { - unordered_map::iterator iter = file_ids_.find(id); + DWORD GetRealFileID(DWORD id) const { + unordered_map::const_iterator iter = file_ids_.find(id); if (iter == file_ids_.end()) return id; return iter->second; @@ -213,9 +338,15 @@ class PDBSourceLineWriter { // This maps unique filenames to file IDs. unordered_map unique_files_; + // The INLINE_ORIGINS records. The key is the function name. + std::map inline_origins_; + // This is used for calculating post-transform symbol addresses and lengths. ImageMap image_map_; + // If we should output INLINE/INLINE_ORIGIN records + bool handle_inline_; + // Disallow copy ctor and operator= PDBSourceLineWriter(const PDBSourceLineWriter&); void operator=(const PDBSourceLineWriter&); diff --git a/thirdparty/sentry-native/external/breakpad/src/common/windows/pe_util.cc b/thirdparty/sentry-native/external/breakpad/src/common/windows/pe_util.cc index 7dcfa7c9ca..c4bf0c05b8 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/windows/pe_util.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/windows/pe_util.cc @@ -35,6 +35,7 @@ #include #include +#include #include "common/windows/string_utils-inl.h" #include "common/windows/guid_string.h" @@ -42,15 +43,19 @@ namespace { /* - * Not defined in WinNT.h for some reason. Definitions taken from: - * http://uninformed.org/index.cgi?v=4&a=1&p=13 + * Not defined in WinNT.h prior to SDK 10.0.20348.0 for some reason. + * Definitions taken from: http://uninformed.org/index.cgi?v=4&a=1&p=13 * */ typedef unsigned char UBYTE; -#if !defined(_WIN64) +#if !defined(UNW_FLAG_EHANDLER) #define UNW_FLAG_EHANDLER 0x01 +#endif +#if !defined(UNW_FLAG_UHANDLER) #define UNW_FLAG_UHANDLER 0x02 +#endif +#if !defined(UNW_FLAG_CHAININFO) #define UNW_FLAG_CHAININFO 0x04 #endif diff --git a/thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.cc b/thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.cc new file mode 100644 index 0000000000..b5f2a428a9 --- /dev/null +++ b/thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.cc @@ -0,0 +1,88 @@ +#include "common/windows/sym_upload_v2_protocol.h" + +#include + +#include "common/windows/http_upload.h" +#include "common/windows/symbol_collector_client.h" + +using google_breakpad::CompleteUploadResult; +using google_breakpad::HTTPUpload; +using google_breakpad::SymbolCollectorClient; +using google_breakpad::SymbolStatus; +using google_breakpad::UploadUrlResponse; +using std::wstring; + +namespace google_breakpad { + +static bool SymUploadV2ProtocolSend(const wchar_t* api_url, + const wchar_t* api_key, + int* timeout_ms, + const wstring& debug_file, + const wstring& debug_id, + const wstring& symbol_filename, + const wstring& symbol_type, + bool force) { + wstring url(api_url); + wstring key(api_key); + + if (!force) { + SymbolStatus symbolStatus = SymbolCollectorClient::CheckSymbolStatus( + url, key, timeout_ms, debug_file, debug_id); + if (symbolStatus == SymbolStatus::Found) { + wprintf( + L"Symbol file already exists, upload aborted." + L" Use \"-f\" to overwrite.\n"); + return true; + } else if (symbolStatus == SymbolStatus::Unknown) { + wprintf(L"Failed to get check for existing symbol.\n"); + return false; + } + } + + UploadUrlResponse uploadUrlResponse; + if (!SymbolCollectorClient::CreateUploadUrl(url, key, timeout_ms, + &uploadUrlResponse)) { + wprintf(L"Failed to create upload URL.\n"); + return false; + } + + wstring signed_url = uploadUrlResponse.upload_url; + wstring upload_key = uploadUrlResponse.upload_key; + wstring response; + int response_code; + bool success = HTTPUpload::SendPutRequest( + signed_url, symbol_filename, timeout_ms, &response, &response_code); + if (!success) { + wprintf(L"Failed to send symbol file.\n"); + wprintf(L"Response code: %ld\n", response_code); + wprintf(L"Response:\n"); + wprintf(L"%s\n", response.c_str()); + return false; + } else if (response_code == 0) { + wprintf(L"Failed to send symbol file: No response code\n"); + return false; + } else if (response_code != 200) { + wprintf(L"Failed to send symbol file: Response code %ld\n", response_code); + wprintf(L"Response:\n"); + wprintf(L"%s\n", response.c_str()); + return false; + } + + CompleteUploadResult completeUploadResult = + SymbolCollectorClient::CompleteUpload(url, key, timeout_ms, upload_key, + debug_file, debug_id, symbol_type); + if (completeUploadResult == CompleteUploadResult::Error) { + wprintf(L"Failed to complete upload.\n"); + return false; + } else if (completeUploadResult == CompleteUploadResult::DuplicateData) { + wprintf( + L"Uploaded file checksum matched existing file checksum," + L" no change necessary.\n"); + } else { + wprintf(L"Successfully sent the symbol file.\n"); + } + + return true; +} + +} // namespace google_breakpad \ No newline at end of file diff --git a/thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.h b/thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.h new file mode 100644 index 0000000000..065d05c82e --- /dev/null +++ b/thirdparty/sentry-native/external/breakpad/src/common/windows/sym_upload_v2_protocol.h @@ -0,0 +1,64 @@ +// Copyright (c) 2022, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef COMMON_WINDOWS_SYM_UPLOAD_V2_PROTOCOL_H_ +#define COMMON_WINDOWS_SYM_UPLOAD_V2_PROTOCOL_H_ + +#include + +namespace google_breakpad { + +// Sends file at |symbol_filename| using the sym-upload-v2 protocol to +// |api_url| using key |api_key|, and using identifiers |debug_file| and +// |debug_id|. |timeout_ms| is the number of milliseconds to wait before +// terminating the upload attempt. |symbol_type| is the type of the symbol +// file, which is one of: +// "BREAKPAD" +// "ELF" +// "PE" +// "MACHO" +// "DEBUG_ONLY" +// "DWP" +// "DSYM" +// "PDB" +// "SOURCE_MAP" +// If |force| is set then it will overwrite an existing file with the +// same |debug_file| and |debug_id| in the store. +bool SymUploadV2ProtocolSend(const wchar_t* api_url, + const wchar_t* api_key, + int* timeout_ms, + const std::wstring& debug_file, + const std::wstring& debug_id, + const std::wstring& symbol_filename, + const std::wstring& symbol_type, + bool force); + +} // namespace google_breakpad + +#endif // COMMON_WINDOWS_SYM_UPLOAD_V2_PROTOCOL_H_ \ No newline at end of file diff --git a/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.cc b/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.cc index 30c663ed37..0831b22cba 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.cc +++ b/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.cc @@ -12,6 +12,7 @@ namespace google_breakpad { bool SymbolCollectorClient::CreateUploadUrl( wstring& api_url, wstring& api_key, + int* timeout_ms, UploadUrlResponse *uploadUrlResponse) { wstring url = api_url + L"/v1/uploads:create" @@ -23,7 +24,7 @@ namespace google_breakpad { url, L"", L"", - NULL, + timeout_ms, &response, &response_code)) { wprintf(L"Failed to create upload url.\n"); @@ -66,17 +67,27 @@ namespace google_breakpad { CompleteUploadResult SymbolCollectorClient::CompleteUpload( wstring& api_url, wstring& api_key, + int* timeout_ms, const wstring& upload_key, const wstring& debug_file, - const wstring& debug_id) { + const wstring& debug_id, + const wstring& type) { wstring url = api_url + L"/v1/uploads/" + upload_key + L":complete" L"?key=" + api_key; wstring body = L"{ symbol_id: {" - L"debug_file: \"" + debug_file + L"\", " - L"debug_id: \"" + debug_id + L"\" " - L"} }"; + L"debug_file: \"" + + debug_file + + L"\", " + L"debug_id: \"" + + debug_id + + L"\" " + L"}, " + L"symbol_upload_type: \"" + + type + + L"\", " + L"use_async_processing: true }"; wstring response; int response_code; @@ -84,7 +95,7 @@ namespace google_breakpad { url, body, L"application/json", - NULL, + timeout_ms, &response, &response_code)) { wprintf(L"Failed to complete upload.\n"); @@ -116,6 +127,7 @@ namespace google_breakpad { SymbolStatus SymbolCollectorClient::CheckSymbolStatus( wstring& api_url, wstring& api_key, + int* timeout_ms, const wstring& debug_file, const wstring& debug_id) { wstring response; @@ -126,7 +138,7 @@ namespace google_breakpad { if (!HTTPUpload::SendGetRequest( url, - NULL, + timeout_ms, &response, &response_code)) { wprintf(L"Failed to check symbol status.\n"); diff --git a/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.h b/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.h index 30e0cb3230..bdf9f7cb29 100644 --- a/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.h +++ b/thirdparty/sentry-native/external/breakpad/src/common/windows/symbol_collector_client.h @@ -64,22 +64,25 @@ namespace google_breakpad { static bool CreateUploadUrl( wstring& api_url, wstring& api_key, + int* timeout_ms, UploadUrlResponse *uploadUrlResponse); // Notify the API that symbol file upload is finished and its contents // are ready to be read and/or used for further processing. - static CompleteUploadResult CompleteUpload( - wstring& api_url, - wstring& api_key, - const wstring& upload_key, - const wstring& debug_file, - const wstring& debug_id); + static CompleteUploadResult CompleteUpload(wstring& api_url, + wstring& api_key, + int* timeout_ms, + const wstring& upload_key, + const wstring& debug_file, + const wstring& debug_id, + const wstring& type); // Returns whether or not a symbol file corresponding to the debug_file/ // debug_id pair is already present in symbol storage. static SymbolStatus CheckSymbolStatus( wstring& api_url, wstring& api_key, + int* timeout_ms, const wstring& debug_file, const wstring& debug_id); }; diff --git a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/common/minidump_format.h b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/common/minidump_format.h index 7b36d1127d..e236663582 100644 --- a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/common/minidump_format.h +++ b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/common/minidump_format.h @@ -239,6 +239,15 @@ typedef struct { MDRVA rva; } MDLocationDescriptor; /* MINIDUMP_LOCATION_DESCRIPTOR */ +/* An MDRVA64 is an 64-bit offset into the minidump file. The beginning of the + * MDRawHeader is at offset 0. */ +typedef uint64_t MDRVA64; /* RVA64 */ + +typedef struct { + uint64_t data_size; + MDRVA64 rva; +} MDLocationDescriptor64; /* MINIDUMP_LOCATION_DESCRIPTOR64 */ + typedef struct { /* The base address of the memory range on the host that produced the @@ -332,6 +341,7 @@ typedef enum { MD_JAVASCRIPT_DATA_STREAM = 20, MD_SYSTEM_MEMORY_INFO_STREAM = 21, MD_PROCESS_VM_COUNTERS_STREAM = 22, + MD_THREAD_NAME_LIST_STREAM = 24, /* MDRawThreadNameList */ MD_LAST_RESERVED_STREAM = 0x0000ffff, /* Breakpad extension types. 0x4767 = "Gg" */ @@ -382,6 +392,20 @@ typedef struct { static const size_t MDRawThreadList_minsize = offsetof(MDRawThreadList, threads[0]); +#pragma pack(push, 4) +typedef struct { + uint32_t thread_id; + MDRVA64 thread_name_rva; /* MDString */ +} MDRawThreadName; /* MINIDUMP_THREAD_NAME */ + +typedef struct { + uint32_t number_of_thread_names; + MDRawThreadName thread_names[1]; +} MDRawThreadNameList; /* MINIDUMP_THREAD_NAME_LIST */ +#pragma pack(pop) + +static const size_t MDRawThreadNameList_minsize = + offsetof(MDRawThreadNameList, thread_names[0]); typedef struct { uint64_t base_of_image; diff --git a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/minidump.h b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/minidump.h index 1c40a821a9..200a7e82d1 100644 --- a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/minidump.h +++ b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/minidump.h @@ -370,6 +370,86 @@ class MinidumpThreadList : public MinidumpStream { DISALLOW_COPY_AND_ASSIGN(MinidumpThreadList); }; +// MinidumpThreadName contains the name of a thread. +class MinidumpThreadName : public MinidumpObject { + public: + virtual ~MinidumpThreadName(); + + const MDRawThreadName* thread_name() const { + return valid_ ? &thread_name_ : NULL; + } + + // Gets the thread ID. + virtual bool GetThreadID(uint32_t* thread_id) const; + + // Print a human-readable representation of the object to stdout. + void Print(); + + // Returns the name of the thread. + virtual std::string GetThreadName() const; + + protected: + explicit MinidumpThreadName(Minidump* minidump); + + private: + // These objects are managed by MinidumpThreadNameList. + friend class MinidumpThreadNameList; + + // This works like MinidumpStream::Read, but is driven by + // MinidumpThreadNameList. No size checking is done, because + // MinidumpThreadNameList handles that directly. + bool Read(); + + // Reads indirectly-referenced data, including the thread name. + bool ReadAuxiliaryData(); + + // True after a successful Read. This is different from valid_, which is not + // set true until ReadAuxiliaryData also completes successfully. + // thread_name_valid_ is only used by ReadAuxiliaryData and the functions it + // calls to determine whether the object is ready for auxiliary data to be + // read. + bool thread_name_valid_; + + MDRawThreadName thread_name_; + + // Cached thread name. + const string* name_; +}; + +// MinidumpThreadNameList contains all of the names of the threads (as +// MinidumpThreadNames) in a process. +class MinidumpThreadNameList : public MinidumpStream { + public: + virtual ~MinidumpThreadNameList(); + + virtual unsigned int thread_name_count() const { + return valid_ ? thread_name_count_ : 0; + } + + // Sequential access to thread names. + virtual MinidumpThreadName* GetThreadNameAtIndex(unsigned int index) const; + + // Print a human-readable representation of the object to stdout. + void Print(); + + protected: + explicit MinidumpThreadNameList(Minidump* aMinidump); + + private: + friend class Minidump; + + typedef vector MinidumpThreadNames; + + static const uint32_t kStreamType = MD_THREAD_NAME_LIST_STREAM; + + bool Read(uint32_t aExpectedSize) override; + + // The list of thread names. + MinidumpThreadNames* thread_names_; + uint32_t thread_name_count_; + + DISALLOW_COPY_AND_ASSIGN(MinidumpThreadNameList); +}; // MinidumpModule wraps MDRawModule, which contains information about loaded // code modules. Access is provided to various data referenced indirectly @@ -1188,6 +1268,7 @@ class Minidump { // to avoid exposing an ugly API (GetStream needs to accept a garbage // parameter). virtual MinidumpThreadList* GetThreadList(); + virtual MinidumpThreadNameList* GetThreadNameList(); virtual MinidumpModuleList* GetModuleList(); virtual MinidumpMemoryList* GetMemoryList(); virtual MinidumpException* GetException(); diff --git a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_result.h b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_result.h index 15c7213e9b..9317e98e15 100644 --- a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_result.h +++ b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_result.h @@ -56,9 +56,13 @@ enum ProcessResult { PROCESS_ERROR_DUPLICATE_REQUESTING_THREADS, // There was more than one // requesting thread. - PROCESS_SYMBOL_SUPPLIER_INTERRUPTED // The dump processing was + PROCESS_SYMBOL_SUPPLIER_INTERRUPTED, // The dump processing was // interrupted by the // SymbolSupplier(not fatal). + + PROCESS_ERROR_GETTING_THREAD_NAME, // There was an error getting one + // thread's name from the dump. + }; } // namespace google_breakpad diff --git a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_state.h b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_state.h index 9bc44c450c..c13246fda6 100644 --- a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_state.h +++ b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/process_state.h @@ -111,6 +111,7 @@ class ProcessState { const vector* thread_memory_regions() const { return &thread_memory_regions_; } + const vector* thread_names() const { return &thread_names_; } const SystemInfo* system_info() const { return &system_info_; } const CodeModules* modules() const { return modules_; } const CodeModules* unloaded_modules() const { return unloaded_modules_; } @@ -176,6 +177,12 @@ class ProcessState { vector threads_; vector thread_memory_regions_; + // Names of each thread at the time of the crash, one for each entry in + // threads_. Note that a thread's name might be empty if there was no + // corresponding ThreadNamesStream in the minidump, or if a particular thread + // ID was not present in the THREAD_NAME_LIST. + vector thread_names_; + // OS and CPU information. SystemInfo system_info_; diff --git a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame.h b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame.h index 5f3932b682..7d5682a7dc 100644 --- a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame.h +++ b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame.h @@ -50,9 +50,12 @@ struct StackFrame { FRAME_TRUST_CFI_SCAN, // Found while scanning stack using call frame info FRAME_TRUST_FP, // Derived from frame pointer FRAME_TRUST_CFI, // Derived from call frame info - FRAME_TRUST_PREWALKED, // Explicitly provided by some external stack walker. + // Explicitly provided by some external stack walker. + FRAME_TRUST_PREWALKED, FRAME_TRUST_CONTEXT, // Given as instruction pointer in a context - FRAME_TRUST_INLINE // Found by inline records in symbol files. + FRAME_TRUST_INLINE, // Found by inline records in symbol files. + // Derived from leaf function by simulating a return. + FRAME_TRUST_LEAF, }; StackFrame() @@ -63,7 +66,8 @@ struct StackFrame { source_file_name(), source_line(0), source_line_base(), - trust(FRAME_TRUST_NONE){} + trust(FRAME_TRUST_NONE), + is_multiple(false) {} virtual ~StackFrame() {} // Return a string describing how this stack frame was found @@ -84,7 +88,9 @@ struct StackFrame { return "stack scanning"; case StackFrame::FRAME_TRUST_INLINE: return "inline record"; - default: + case StackFrame::FRAME_TRUST_LEAF: + return "simulating a return from leaf function"; + default: return "unknown"; } } @@ -140,6 +146,12 @@ struct StackFrame { // Amount of trust the stack walker has in the instruction pointer // of this frame. FrameTrust trust; + + // True if the frame corresponds to multiple functions, for example as the + // result of identical code folding by the linker. In that case the function + // name, filename, etc. information above represents the state of an arbitrary + // one of these functions. + bool is_multiple; }; } // namespace google_breakpad diff --git a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame_cpu.h b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame_cpu.h index dc5d8ae673..24e28ca12c 100644 --- a/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame_cpu.h +++ b/thirdparty/sentry-native/external/breakpad/src/google_breakpad/processor/stack_frame_cpu.h @@ -251,7 +251,10 @@ struct StackFrameARM : public StackFrame { // Return the ContextValidity flag for register rN. static ContextValidity RegisterValidFlag(int n) { - return ContextValidity(1 << n); + if (0 <= n && n <= 15) { + return ContextValidity(1 << n); + } + return CONTEXT_VALID_NONE; } // Register state. This is only fully valid for the topmost frame in a diff --git a/thirdparty/sentry-native/external/crashpad/.gn b/thirdparty/sentry-native/external/crashpad/.gn index d447a5537c..e4dc49c31f 100644 --- a/thirdparty/sentry-native/external/crashpad/.gn +++ b/thirdparty/sentry-native/external/crashpad/.gn @@ -13,3 +13,4 @@ # limitations under the License. buildconfig = "//build/BUILDCONFIG.gn" +script_executable = "python3" diff --git a/thirdparty/sentry-native/external/crashpad/.vpython3 b/thirdparty/sentry-native/external/crashpad/.vpython3 new file mode 100644 index 0000000000..0d7baf9efc --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/.vpython3 @@ -0,0 +1,32 @@ +# Copyright 2022 The Crashpad Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is a vpython "spec" file. +# +# It describes patterns for python wheel dependencies of the python scripts. +# +# Read more about `vpython` and how to modify this file here: +# https://chromium.googlesource.com/infra/infra/+/master/doc/users/vpython.md + +# This is needed for snapshot/win/end_to_end_test.py. +wheel: < + name: "infra/python/wheels/pywin32/${vpython_platform}" + version: "version:300" + match_tag: < + platform: "win32" + > + match_tag: < + platform: "win_amd64" + > +> diff --git a/thirdparty/sentry-native/external/crashpad/BUILD.gn b/thirdparty/sentry-native/external/crashpad/BUILD.gn index c0f8bcbc0d..61546be124 100644 --- a/thirdparty/sentry-native/external/crashpad/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/BUILD.gn @@ -17,7 +17,10 @@ import("build/test.gni") import("util/net/tls.gni") config("crashpad_config") { - include_dirs = [ "." ] + include_dirs = [ + ".", + root_gen_dir, + ] } if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) { diff --git a/thirdparty/sentry-native/external/crashpad/CMakeLists.txt b/thirdparty/sentry-native/external/crashpad/CMakeLists.txt index e228933505..b6e2e6d5ac 100644 --- a/thirdparty/sentry-native/external/crashpad/CMakeLists.txt +++ b/thirdparty/sentry-native/external/crashpad/CMakeLists.txt @@ -52,7 +52,22 @@ endfunction() if(WIN32) enable_language(ASM_MASM) + if(MINGW) + find_program(JWASM_FOUND jwasm) + if (JWASM_FOUND) + set(CMAKE_ASM_MASM_COMPILER ${JWASM_FOUND}) + execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE COMPILER_VERSION_OUTPUT) + if (COMPILER_VERSION_OUTPUT) + if (COMPILER_VERSION_OUTPUT MATCHES "x86_64") + set(JWASM_FLAGS -win64) + else() + set(JWASM_FLAGS -coff) + endif() + endif() + set(CMAKE_ASM_MASM_FLAGS ${CMAKE_ASM_MASM_FLAGS} ${JWASM_FLAGS}) + endif(JWASM_FOUND) + if(NOT CMAKE_ASM_MASM_COMPILER OR CMAKE_ASM_MASM_COMPILER STREQUAL "ml" OR CMAKE_ASM_MASM_COMPILER STREQUAL "ml64") message(WARNING "No custom ASM_MASM compiler defined via 'CMAKE_ASM_MASM_COMPILER'. Trying to use UASM...") set(CMAKE_ASM_MASM_COMPILER "uasm") @@ -60,12 +75,12 @@ if(WIN32) if(NOT CMAKE_ASM_MASM_FLAGS) set(CMAKE_ASM_MASM_FLAGS "-win64 -10") #use default compatibility flags endif() - endif() + endif(MINGW) else() enable_language(ASM) endif() -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_library(crashpad_interface INTERFACE) diff --git a/thirdparty/sentry-native/external/crashpad/DEPS b/thirdparty/sentry-native/external/crashpad/DEPS index c1edb80c15..9829da3433 100644 --- a/thirdparty/sentry-native/external/crashpad/DEPS +++ b/thirdparty/sentry-native/external/crashpad/DEPS @@ -14,6 +14,7 @@ vars = { 'chromium_git': 'https://chromium.googlesource.com', + 'gn_version': 'git_revision:2ecd43a10266bd091c98e6dcde507c64f6a0dad3', 'pull_linux_clang': False, 'pull_win_toolchain': False, # Controls whether crashpad/build/ios/setup-ios-gn.py is run as part of @@ -25,21 +26,21 @@ vars = { deps = { 'buildtools': Var('chromium_git') + '/chromium/src/buildtools.git@' + - '9e121212d42be62a7cce38072f925f8398d11e49', + '8b16338d17cd71b04a6ba28da7322ab6739892c2', 'crashpad/third_party/edo/edo': { 'url': Var('chromium_git') + '/external/github.com/google/eDistantObject.git@' + - '6ffbf833173f53fcd06ecf08670a95cc01c01f72', + '727e556705278598fce683522beedbb9946bfda0', 'condition': 'checkout_ios', }, 'crashpad/third_party/googletest/googletest': Var('chromium_git') + '/external/github.com/google/googletest@' + - '11da093e0477185dbd78abaaa9f99db15be498d0', + 'af29db7ec28d6df1c7f0f745186884091e602e07', 'crashpad/third_party/lss/lss': Var('chromium_git') + '/linux-syscall-support.git@' + - '7bde79cc274d06451bf65ae82c012a5d3e476b5a', + 'e1e7b0ad8ee99a875b272c8e33e308472e897660', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - '0e22eed71eec97dacbe80822a14c5cd0b580d793', + '5654edb4225bcad13901155c819febb5748e502b', 'crashpad/third_party/libfuzzer/src': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' + 'fda403cf93ecb8792cb1d061564d89a6553ca020', @@ -47,7 +48,37 @@ deps = { Var('chromium_git') + '/chromium/src/third_party/zlib@' + '13dc246a58e4b72104d35f9b1809af95221ebda7', - # CIPD packages below. + # CIPD packages. + 'buildtools/linux64': { + 'packages': [ + { + 'package': 'gn/gn/linux-amd64', + 'version': Var('gn_version'), + } + ], + 'dep_type': 'cipd', + 'condition': 'host_os == "linux"', + }, + 'buildtools/mac': { + 'packages': [ + { + 'package': 'gn/gn/mac-${{arch}}', + 'version': Var('gn_version'), + } + ], + 'dep_type': 'cipd', + 'condition': 'host_os == "mac"', + }, + 'buildtools/win': { + 'packages': [ + { + 'package': 'gn/gn/windows-amd64', + 'version': Var('gn_version'), + } + ], + 'dep_type': 'cipd', + 'condition': 'host_os == "win"', + }, 'crashpad/third_party/linux/clang/linux-amd64': { 'packages': [ { @@ -106,7 +137,7 @@ deps = { 'packages': [ { 'package': 'chrome_internal/third_party/sdk/windows', - 'version': 'uploaded:2018-06-13' + 'version': 'uploaded:2021-04-28' }, ], 'condition': 'checkout_win and pull_win_toolchain', @@ -125,7 +156,9 @@ hooks = [ '--no_auth', '--bucket=chromium-clang-format', '--sha1_file', - 'buildtools/mac/clang-format.sha1', + 'buildtools/mac/clang-format.{host_cpu}.sha1', + '--output', + 'buildtools/mac/clang-format', ], }, { @@ -169,7 +202,7 @@ hooks = [ 'pattern': '.', 'condition': 'run_setup_ios_gn and checkout_ios', 'action': [ - 'python', + 'python3', 'crashpad/build/ios/setup_ios_gn.py' ], }, diff --git a/thirdparty/sentry-native/external/crashpad/build/ios/convert_gn_xcodeproj.py b/thirdparty/sentry-native/external/crashpad/build/ios/convert_gn_xcodeproj.py index d546279ce0..8c5c6d073f 100644 --- a/thirdparty/sentry-native/external/crashpad/build/ios/convert_gn_xcodeproj.py +++ b/thirdparty/sentry-native/external/crashpad/build/ios/convert_gn_xcodeproj.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2020 The Crashpad Authors. All rights reserved. # @@ -26,14 +26,146 @@ import argparse import collections import copy import filecmp -import json +import functools import hashlib +import json import os import re import shutil +import string import subprocess import sys import tempfile +import xml.etree.ElementTree + + +LLDBINIT_PATH = '$(PROJECT_DIR)/.lldbinit' + +PYTHON_RE = re.compile('[ /]python[23]?$') + +XCTEST_PRODUCT_TYPES = frozenset(( + 'com.apple.product-type.bundle.unit-test', + 'com.apple.product-type.bundle.ui-testing', +)) + +SCHEME_PRODUCT_TYPES = frozenset(( + 'com.apple.product-type.app-extension', + 'com.apple.product-type.application', + 'com.apple.product-type.framework' +)) + + +class Template(string.Template): + + """A subclass of string.Template that changes delimiter.""" + + delimiter = '@' + + +@functools.lru_cache +def LoadSchemeTemplate(root, name): + """Return a string.Template object for scheme file loaded relative to root.""" + path = os.path.join(root, 'build', 'ios', name) + with open(path) as file: + return Template(file.read()) + + +def CreateIdentifier(str_id): + """Return a 24 characters string that can be used as an identifier.""" + return hashlib.sha1(str_id.encode("utf-8")).hexdigest()[:24].upper() + + +def GenerateSchemeForTarget(root, project, old_project, name, path, tests): + """Generates the .xcsheme file for target named |name|. + + The file is generated in the new project schemes directory from a template. + If there is an existing previous project, then the old scheme file is copied + and the lldbinit setting is set. If lldbinit setting is already correct, the + file is not modified, just copied. + """ + project_name = os.path.basename(project) + relative_path = os.path.join('xcshareddata', 'xcschemes', name + '.xcscheme') + identifier = CreateIdentifier('%s %s' % (name, path)) + + scheme_path = os.path.join(project, relative_path) + if not os.path.isdir(os.path.dirname(scheme_path)): + os.makedirs(os.path.dirname(scheme_path)) + + old_scheme_path = os.path.join(old_project, relative_path) + if os.path.exists(old_scheme_path): + made_changes = False + + tree = xml.etree.ElementTree.parse(old_scheme_path) + tree_root = tree.getroot() + + for reference in tree_root.findall('.//BuildableReference'): + for (attr, value) in ( + ('BuildableName', path), + ('BlueprintName', name), + ('BlueprintIdentifier', identifier)): + if reference.get(attr) != value: + reference.set(attr, value) + made_changes = True + + for child in tree_root: + if child.tag not in ('TestAction', 'LaunchAction'): + continue + + if child.get('customLLDBInitFile') != LLDBINIT_PATH: + child.set('customLLDBInitFile', LLDBINIT_PATH) + made_changes = True + + # Override the list of testables. + if child.tag == 'TestAction': + for subchild in child: + if subchild.tag != 'Testables': + continue + + for elt in list(subchild): + subchild.remove(elt) + + if tests: + template = LoadSchemeTemplate(root, 'xcodescheme-testable.template') + for (key, test_path, test_name) in sorted(tests): + testable = ''.join(template.substitute( + BLUEPRINT_IDENTIFIER=key, + BUILDABLE_NAME=test_path, + BLUEPRINT_NAME=test_name, + PROJECT_NAME=project_name)) + + testable_elt = xml.etree.ElementTree.fromstring(testable) + subchild.append(testable_elt) + + if made_changes: + tree.write(scheme_path, xml_declaration=True, encoding='UTF-8') + + else: + shutil.copyfile(old_scheme_path, scheme_path) + + else: + + testables = '' + if tests: + template = LoadSchemeTemplate(root, 'xcodescheme-testable.template') + testables = '\n' + ''.join( + template.substitute( + BLUEPRINT_IDENTIFIER=key, + BUILDABLE_NAME=test_path, + BLUEPRINT_NAME=test_name, + PROJECT_NAME=project_name) + for (key, test_path, test_name) in sorted(tests)).rstrip() + + template = LoadSchemeTemplate(root, 'xcodescheme.template') + + with open(scheme_path, 'w') as scheme_file: + scheme_file.write( + template.substitute( + TESTABLES=testables, + LLDBINIT_PATH=LLDBINIT_PATH, + BLUEPRINT_IDENTIFIER=identifier, + BUILDABLE_NAME=path, + BLUEPRINT_NAME=name, + PROJECT_NAME=project_name)) class XcodeProject(object): @@ -46,7 +178,7 @@ class XcodeProject(object): while True: self.counter += 1 str_id = "%s %s %d" % (parent_name, obj['isa'], self.counter) - new_id = hashlib.sha1(str_id.encode("utf-8")).hexdigest()[:24].upper() + new_id = CreateIdentifier(str_id) # Make sure ID is unique. It's possible there could be an id conflict # since this is run after GN runs. @@ -54,6 +186,93 @@ class XcodeProject(object): self.objects[new_id] = obj return new_id + def IterObjectsByIsa(self, isa): + """Iterates overs objects of the |isa| type.""" + for key, obj in self.objects.items(): + if obj['isa'] == isa: + yield (key, obj) + + def IterNativeTargetByProductType(self, product_types): + """Iterates over PBXNativeTarget objects of any |product_types| types.""" + for key, obj in self.IterObjectsByIsa('PBXNativeTarget'): + if obj['productType'] in product_types: + yield (key, obj) + + def UpdateBuildScripts(self): + """Update build scripts to respect configuration and platforms.""" + for key, obj in self.IterObjectsByIsa('PBXShellScriptBuildPhase'): + + shell_path = obj['shellPath'] + shell_code = obj['shellScript'] + if shell_path.endswith('/sh'): + shell_code = shell_code.replace( + 'ninja -C .', + 'ninja -C "../${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}"') + elif PYTHON_RE.search(shell_path): + shell_code = shell_code.replace( + '''ninja_params = [ '-C', '.' ]''', + '''ninja_params = [ '-C', '../' + os.environ['CONFIGURATION']''' + ''' + os.environ['EFFECTIVE_PLATFORM_NAME'] ]''') + + # Replace the build script in the object. + obj['shellScript'] = shell_code + + + def UpdateBuildConfigurations(self, configurations): + """Add new configurations, using the first one as default.""" + + # Create a list with all the objects of interest. This is needed + # because objects will be added to/removed from the project upon + # iterating this list and python dictionaries cannot be mutated + # during iteration. + for key, obj in list(self.IterObjectsByIsa('XCConfigurationList')): + # Use the first build configuration as template for creating all the + # new build configurations. + build_config_template = self.objects[obj['buildConfigurations'][0]] + build_config_template['buildSettings']['CONFIGURATION_BUILD_DIR'] = \ + '$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)' + + + # Remove the existing build configurations from the project before + # creating the new ones. + for build_config_id in obj['buildConfigurations']: + del self.objects[build_config_id] + obj['buildConfigurations'] = [] + + for configuration in configurations: + build_config = copy.copy(build_config_template) + build_config['name'] = configuration + build_config_id = self.AddObject('products', build_config) + obj['buildConfigurations'].append(build_config_id) + + def GetHostMappingForXCTests(self): + """Returns a dict from targets to the list of their xctests modules.""" + mapping = collections.defaultdict(list) + for key, obj in self.IterNativeTargetByProductType(XCTEST_PRODUCT_TYPES): + build_config_lists_id = obj['buildConfigurationList'] + build_configs = self.objects[build_config_lists_id]['buildConfigurations'] + + # Use the first build configuration to get the name of the host target. + # This is arbitrary, but since the build configuration are all identical + # after UpdateBuildConfiguration, except for their 'name', it is fine. + build_config = self.objects[build_configs[0]] + if obj['productType'] == 'com.apple.product-type.bundle.unit-test': + # The test_host value will look like this: + # `$(BUILD_PRODUCTS_DIR)/host_app_name.app/host_app_name` + # + # Extract the `host_app_name.app` part as key for the output. + test_host_path = build_config['buildSettings']['TEST_HOST'] + test_host_name = os.path.basename(os.path.dirname(test_host_path)) + else: + test_host_name = build_config['buildSettings']['TEST_TARGET_NAME'] + + test_name = obj['name'] + test_path = self.objects[obj['productReference']]['path'] + + mapping[test_host_name].append((key, test_name, test_path)) + + return dict(mapping) + def check_output(command): """Wrapper around subprocess.check_output that decode output as utf-8.""" @@ -100,7 +319,7 @@ def WriteXcodeProject(output_path, json_string): os.path.join(output_path, 'project.pbxproj')) -def UpdateXcodeProject(project_dir, configurations, root_dir): +def UpdateXcodeProject(project_dir, old_project_dir, configurations, root_dir): """Update inplace Xcode project to support multiple configurations. Args: @@ -113,41 +332,25 @@ def UpdateXcodeProject(project_dir, configurations, root_dir): json_data = json.loads(LoadXcodeProjectAsJSON(project_dir)) project = XcodeProject(json_data['objects']) - objects_to_remove = [] - for value in list(project.objects.values()): - isa = value['isa'] + project.UpdateBuildScripts() + project.UpdateBuildConfigurations(configurations) - # Teach build shell script to look for the configuration and platform. - if isa == 'PBXShellScriptBuildPhase': - shell_path = value['shellPath'] - if shell_path.endswith('/sh'): - value['shellScript'] = value['shellScript'].replace( - 'ninja -C .', - 'ninja -C "../${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}"') - elif re.search('[ /]python[23]?$', shell_path): - value['shellScript'] = value['shellScript'].replace( - 'ninja_params = [ \'-C\', \'.\' ]', - 'ninja_params = [ \'-C\', \'../\' + os.environ[\'CONFIGURATION\']' - ' + os.environ[\'EFFECTIVE_PLATFORM_NAME\'] ]') + mapping = project.GetHostMappingForXCTests() - # Add new configuration, using the first one as default. - if isa == 'XCConfigurationList': - value['defaultConfigurationName'] = configurations[0] - objects_to_remove.extend(value['buildConfigurations']) + # Generate schemes for application, extensions and framework targets + for key, obj in project.IterNativeTargetByProductType(SCHEME_PRODUCT_TYPES): + product = project.objects[obj['productReference']] + product_path = product['path'] - build_config_template = project.objects[value['buildConfigurations'][0]] - build_config_template['buildSettings']['CONFIGURATION_BUILD_DIR'] = \ - '$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)' + # For XCTests, the key is the product path, while for XCUITests, the key + # is the target name. Use a sum of both possible keys (there should not + # be overlaps since different hosts are used for XCTests and XCUITests + # but this make the code simpler). + tests = mapping.get(product_path, []) + mapping.get(obj['name'], []) + GenerateSchemeForTarget( + root_dir, project_dir, old_project_dir, + obj['name'], product_path, tests) - value['buildConfigurations'] = [] - for configuration in configurations: - new_build_config = copy.copy(build_config_template) - new_build_config['name'] = configuration - value['buildConfigurations'].append( - project.AddObject('products', new_build_config)) - - for object_id in objects_to_remove: - del project.objects[object_id] source = GetOrCreateRootGroup(project, json_data['rootObject'], 'Source') AddMarkdownToProject(project, root_dir, source) @@ -274,7 +477,7 @@ def GetFolderForPath(project, group_object, path): return group_object -def ConvertGnXcodeProject(root_dir, input_dir, output_dir, configurations): +def ConvertGnXcodeProject(root_dir, proj_name, input_dir, output_dir, configs): '''Tweak the Xcode project generated by gn to support multiple configurations. The Xcode projects generated by "gn gen --ide" only supports a single @@ -284,34 +487,22 @@ def ConvertGnXcodeProject(root_dir, input_dir, output_dir, configurations): to select them in Xcode). Args: + root_dir: directory that is the root of the project + proj_name: name of the Xcode project "file" (usually `all.xcodeproj`) input_dir: directory containing the XCode projects created by "gn gen --ide" output_dir: directory where the tweaked Xcode projects will be saved - configurations: list of string corresponding to the configurations that - need to be supported by the tweaked Xcode projects, must contains at - least one value. + configs: list of string corresponding to the configurations that need to be + supported by the tweaked Xcode projects, must contains at least one + value. ''' - # Update the project (supports legacy name "products.xcodeproj" or the new - # project name "all.xcodeproj"). - for project_name in ('all.xcodeproj', 'products.xcodeproj'): - if os.path.exists(os.path.join(input_dir, project_name)): - UpdateXcodeProject( - os.path.join(input_dir, project_name), - configurations, root_dir) + UpdateXcodeProject( + os.path.join(input_dir, proj_name), + os.path.join(output_dir, proj_name), + configs, root_dir) - CopyTreeIfChanged(os.path.join(input_dir, project_name), - os.path.join(output_dir, project_name)) - - else: - shutil.rmtree(os.path.join(output_dir, project_name), ignore_errors=True) - - # Copy all.xcworkspace if it exists (will be removed in a future gn version). - workspace_name = 'all.xcworkspace' - if os.path.exists(os.path.join(input_dir, workspace_name)): - CopyTreeIfChanged(os.path.join(input_dir, workspace_name), - os.path.join(output_dir, workspace_name)) - else: - shutil.rmtree(os.path.join(output_dir, workspace_name), ignore_errors=True) + CopyTreeIfChanged(os.path.join(input_dir, proj_name), + os.path.join(output_dir, proj_name)) def Main(args): @@ -329,33 +520,30 @@ def Main(args): parser.add_argument( '--root', type=os.path.abspath, required=True, help='root directory of the project') + parser.add_argument( + '--project-name', default='all.xcodeproj', dest='proj_name', + help='name of the Xcode project (default: %(default)s)') args = parser.parse_args(args) if not os.path.isdir(args.input): sys.stderr.write('Input directory does not exists.\n') return 1 - # Depending on the version of "gn", there should be either one project file - # named "all.xcodeproj" or a project file named "products.xcodeproj" and a - # workspace named "all.xcworkspace". - required_files_sets = [ - set(("all.xcodeproj",)), - set(("products.xcodeproj", "all.xcworkspace")), - ] - - for required_files in required_files_sets: - if required_files.issubset(os.listdir(args.input)): - break - else: + if args.proj_name not in os.listdir(args.input): sys.stderr.write( - 'Input directory does not contain all necessary Xcode projects.\n') + 'Input directory does not contain the Xcode project.\n') return 1 if not args.configurations: sys.stderr.write('At least one configuration required, see --add-config.\n') return 1 - ConvertGnXcodeProject(args.root, args.input, args.output, args.configurations) + ConvertGnXcodeProject( + args.root, + args.proj_name, + args.input, + args.output, + args.configurations) if __name__ == '__main__': sys.exit(Main(sys.argv[1:])) diff --git a/thirdparty/sentry-native/external/crashpad/build/ios/setup_ios_gn.py b/thirdparty/sentry-native/external/crashpad/build/ios/setup_ios_gn.py index 9522ce6757..aacc8ec7bd 100644 --- a/thirdparty/sentry-native/external/crashpad/build/ios/setup_ios_gn.py +++ b/thirdparty/sentry-native/external/crashpad/build/ios/setup_ios_gn.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2020 The Crashpad Authors. All rights reserved. # @@ -15,334 +15,391 @@ # limitations under the License. import argparse +import configparser import convert_gn_xcodeproj import errno +import io import os +import platform import re import shutil import subprocess import sys import tempfile -try: - import configparser -except ImportError: - import ConfigParser as configparser -try: - import StringIO as io -except ImportError: - import io +SUPPORTED_TARGETS = ('iphoneos', 'iphonesimulator', 'maccatalyst') +SUPPORTED_CONFIGS = ('Debug', 'Release', 'Profile', 'Official') -SUPPORTED_TARGETS = ('iphoneos', 'iphonesimulator') -SUPPORTED_CONFIGS = ('Debug', 'Release', 'Profile', 'Official', 'Coverage') +# Pattern matching lines from ~/.lldbinit that must not be copied to the +# generated .lldbinit file. They match what the user were told to add to +# their global ~/.lldbinit file before setup-gn.py was updated to generate +# a project specific file and thus must not be copied as they would cause +# the settings to be overwritten. +LLDBINIT_SKIP_PATTERNS = ( + re.compile('^script sys.path\\[:0\\] = \\[\'.*/src/tools/lldb\'\\]$'), + re.compile('^script import lldbinit$'), + re.compile('^settings append target.source-map .* /google/src/.*$'), +) -class ConfigParserWithStringInterpolation(configparser.SafeConfigParser): - '''A .ini file parser that supports strings and environment variables.''' +def HostCpuArch(): + '''Returns the arch of the host cpu for GN.''' + HOST_CPU_ARCH = { + 'arm64': '"arm64"', + 'x86_64': '"x64"', + } + return HOST_CPU_ARCH[platform.machine()] - ENV_VAR_PATTERN = re.compile(r'\$([A-Za-z0-9_]+)') - def values(self, section): - return map(lambda kv: self._UnquoteString(self._ExpandEnvVar(kv[1])), - configparser.ConfigParser.items(self, section)) +class ConfigParserWithStringInterpolation(configparser.ConfigParser): - def getstring(self, section, option): - return self._UnquoteString(self._ExpandEnvVar(self.get(section, - option))) + '''A .ini file parser that supports strings and environment variables.''' - def _UnquoteString(self, string): - if not string or string[0] != '"' or string[-1] != '"': - return string - return string[1:-1] + ENV_VAR_PATTERN = re.compile(r'\$([A-Za-z0-9_]+)') - def _ExpandEnvVar(self, value): - match = self.ENV_VAR_PATTERN.search(value) - if not match: - return value - name, (begin, end) = match.group(1), match.span(0) - prefix, suffix = value[:begin], self._ExpandEnvVar(value[end:]) - return prefix + os.environ.get(name, '') + suffix + def values(self, section): + return filter( + lambda val: val != '', + map(lambda kv: self._UnquoteString(self._ExpandEnvVar(kv[1])), + configparser.ConfigParser.items(self, section))) + + def getstring(self, section, option, fallback=''): + try: + raw_value = self.get(section, option) + except configparser.NoOptionError: + return fallback + return self._UnquoteString(self._ExpandEnvVar(raw_value)) + + def _UnquoteString(self, string): + if not string or string[0] != '"' or string[-1] != '"': + return string + return string[1:-1] + + def _ExpandEnvVar(self, value): + match = self.ENV_VAR_PATTERN.search(value) + if not match: + return value + name, (begin, end) = match.group(1), match.span(0) + prefix, suffix = value[:begin], self._ExpandEnvVar(value[end:]) + return prefix + os.environ.get(name, '') + suffix class GnGenerator(object): - '''Holds configuration for a build and method to generate gn default - files.''' - FAT_BUILD_DEFAULT_ARCH = '64-bit' + '''Holds configuration for a build and method to generate gn default files.''' - TARGET_CPU_VALUES = { - 'iphoneos': { - '32-bit': '"arm"', - '64-bit': '"arm64"', - }, - 'iphonesimulator': { - '32-bit': '"x86"', - '64-bit': '"x64"', - } - } + FAT_BUILD_DEFAULT_ARCH = '64-bit' - def __init__(self, settings, config, target): - assert target in SUPPORTED_TARGETS - assert config in SUPPORTED_CONFIGS - self._settings = settings - self._config = config - self._target = target + TARGET_CPU_VALUES = { + 'iphoneos': '"arm64"', + 'iphonesimulator': HostCpuArch(), + 'maccatalyst': HostCpuArch(), + } - def _GetGnArgs(self): - """Build the list of arguments to pass to gn. + TARGET_ENVIRONMENT_VALUES = { + 'iphoneos': '"device"', + 'iphonesimulator': '"simulator"', + 'maccatalyst': '"catalyst"' + } - Returns: - A list of tuple containing gn variable names and variable values (it - is not a dictionary as the order needs to be preserved). - """ - args = [] + def __init__(self, settings, config, target): + assert target in SUPPORTED_TARGETS + assert config in SUPPORTED_CONFIGS + self._settings = settings + self._config = config + self._target = target - args.append(('is_debug', self._config in ('Debug', 'Coverage'))) + def _GetGnArgs(self, extra_args=None): + """Build the list of arguments to pass to gn. - if os.environ.get('FORCE_MAC_TOOLCHAIN', '0') == '1': - args.append(('use_system_xcode', False)) + Returns: + A list of tuple containing gn variable names and variable values (it + is not a dictionary as the order needs to be preserved). + """ + args = [] - cpu_values = self.TARGET_CPU_VALUES[self._target] - build_arch = self._settings.getstring('build', 'arch') - if build_arch == 'fat': - target_cpu = cpu_values[self.FAT_BUILD_DEFAULT_ARCH] - args.append(('target_cpu', target_cpu)) - args.append( - ('additional_target_cpus', - [cpu for cpu in cpu_values.itervalues() if cpu != target_cpu])) - else: - args.append(('target_cpu', cpu_values[build_arch])) + is_debug = self._config == 'Debug' + official = self._config == 'Official' + is_optim = self._config in ('Profile', 'Official') - # Add user overrides after the other configurations so that they can - # refer to them and override them. - args.extend(self._settings.items('gn_args')) - return args + args.append(('target_os', '"ios"')) + args.append(('is_debug', is_debug)) - def Generate(self, gn_path, root_path, out_path): - buf = io.StringIO() - self.WriteArgsGn(buf) - WriteToFileIfChanged(os.path.join(out_path, 'args.gn'), - buf.getvalue(), - overwrite=True) + if os.environ.get('FORCE_MAC_TOOLCHAIN', '0') == '1': + args.append(('use_system_xcode', False)) - subprocess.check_call( - self.GetGnCommand(gn_path, root_path, out_path, True)) + args.append(('target_cpu', self.TARGET_CPU_VALUES[self._target])) + args.append(( + 'target_environment', + self.TARGET_ENVIRONMENT_VALUES[self._target])) - def CreateGnRules(self, gn_path, root_path, out_path): - buf = io.StringIO() - self.WriteArgsGn(buf) - WriteToFileIfChanged(os.path.join(out_path, 'args.gn'), - buf.getvalue(), - overwrite=True) + # If extra arguments are passed to the function, pass them before the + # user overrides (if any). + if extra_args is not None: + args.extend(extra_args) - buf = io.StringIO() - gn_command = self.GetGnCommand(gn_path, root_path, out_path, False) - self.WriteBuildNinja(buf, gn_command) - WriteToFileIfChanged(os.path.join(out_path, 'build.ninja'), - buf.getvalue(), - overwrite=False) + # Add user overrides after the other configurations so that they can + # refer to them and override them. + args.extend(self._settings.items('gn_args')) + return args - buf = io.StringIO() - self.WriteBuildNinjaDeps(buf) - WriteToFileIfChanged(os.path.join(out_path, 'build.ninja.d'), - buf.getvalue(), - overwrite=False) - def WriteArgsGn(self, stream): - stream.write('# This file was generated by setup-gn.py. Do not edit\n') - stream.write('# but instead use ~/.setup-gn or $repo/.setup-gn files\n') - stream.write('# to configure settings.\n') - stream.write('\n') + def Generate(self, gn_path, proj_name, root_path, build_dir): + self.WriteArgsGn(build_dir, xcode_project_name=proj_name) + subprocess.check_call(self.GetGnCommand( + gn_path, root_path, build_dir, xcode_project_name=proj_name)) + def CreateGnRules(self, gn_path, root_path, build_dir): + gn_command = self.GetGnCommand(gn_path, root_path, build_dir) + self.WriteArgsGn(build_dir) + self.WriteBuildNinja(gn_command, build_dir) + self.WriteBuildNinjaDeps(build_dir) + + def WriteArgsGn(self, build_dir, xcode_project_name=None): + with open(os.path.join(build_dir, 'args.gn'), 'w') as stream: + stream.write('# This file was generated by setup-gn.py. Do not edit\n') + stream.write('# but instead use ~/.setup-gn or $repo/.setup-gn files\n') + stream.write('# to configure settings.\n') + stream.write('\n') + + if self._target != 'maccatalyst': if self._settings.has_section('$imports$'): - for import_rule in self._settings.values('$imports$'): - stream.write('import("%s")\n' % import_rule) - stream.write('\n') + for import_rule in self._settings.values('$imports$'): + stream.write('import("%s")\n' % import_rule) + stream.write('\n') - gn_args = self._GetGnArgs() - for name, value in gn_args: - if isinstance(value, bool): - stream.write('%s = %s\n' % (name, str(value).lower())) - elif isinstance(value, list): - stream.write('%s = [%s' % - (name, '\n' if len(value) > 1 else '')) - if len(value) == 1: - prefix = ' ' - suffix = ' ' - else: - prefix = ' ' - suffix = ',\n' - for item in value: - if isinstance(item, bool): - stream.write('%s%s%s' % - (prefix, str(item).lower(), suffix)) - else: - stream.write('%s%s%s' % (prefix, item, suffix)) - stream.write(']\n') + gn_args = self._GetGnArgs() + + for name, value in gn_args: + if isinstance(value, bool): + stream.write('%s = %s\n' % (name, str(value).lower())) + elif isinstance(value, list): + stream.write('%s = [%s' % (name, '\n' if len(value) > 1 else '')) + if len(value) == 1: + prefix = ' ' + suffix = ' ' + else: + prefix = ' ' + suffix = ',\n' + for item in value: + if isinstance(item, bool): + stream.write('%s%s%s' % (prefix, str(item).lower(), suffix)) else: - stream.write('%s = %s\n' % (name, value)) - - def WriteBuildNinja(self, stream, gn_command): - stream.write('rule gn\n') - stream.write(' command = %s\n' % NinjaEscapeCommand(gn_command)) - stream.write(' description = Regenerating ninja files\n') - stream.write('\n') - stream.write('build build.ninja: gn\n') - stream.write(' generator = 1\n') - stream.write(' depfile = build.ninja.d\n') - - def WriteBuildNinjaDeps(self, stream): - stream.write('build.ninja: nonexistant_file.gn\n') - - def GetGnCommand(self, gn_path, src_path, out_path, generate_xcode_project): - gn_command = [gn_path, '--root=%s' % os.path.realpath(src_path), '-q'] - if generate_xcode_project: - gn_command.append('--ide=xcode') - gn_command.append('--ninja-executable=autoninja') - if self._settings.has_section('filters'): - target_filters = self._settings.values('filters') - if target_filters: - gn_command.append('--filters=%s' % ';'.join(target_filters)) + stream.write('%s%s%s' % (prefix, item, suffix)) + stream.write(']\n') else: - gn_command.append('--check') - gn_command.append('gen') - gn_command.append('//%s' % os.path.relpath(os.path.abspath(out_path), - os.path.abspath(src_path))) - return gn_command + # ConfigParser removes quote around empty string which confuse + # `gn gen` so restore them. + if not value: + value = '""' + stream.write('%s = %s\n' % (name, value)) + def WriteBuildNinja(self, gn_command, build_dir): + with open(os.path.join(build_dir, 'build.ninja'), 'w') as stream: + stream.write('ninja_required_version = 1.7.2\n') + stream.write('\n') + stream.write('rule gn\n') + stream.write(' command = %s\n' % NinjaEscapeCommand(gn_command)) + stream.write(' description = Regenerating ninja files\n') + stream.write('\n') + stream.write('build build.ninja: gn\n') + stream.write(' generator = 1\n') + stream.write(' depfile = build.ninja.d\n') -def WriteToFileIfChanged(filename, content, overwrite): - '''Write |content| to |filename| if different. If |overwrite| is False - and the file already exists it is left untouched.''' - if os.path.exists(filename): - if not overwrite: - return - with open(filename) as file: - if file.read() == content: - return - if not os.path.isdir(os.path.dirname(filename)): - os.makedirs(os.path.dirname(filename)) - with open(filename, 'w') as file: - file.write(content) + def WriteBuildNinjaDeps(self, build_dir): + with open(os.path.join(build_dir, 'build.ninja.d'), 'w') as stream: + stream.write('build.ninja: nonexistant_file.gn\n') + + def GetGnCommand(self, gn_path, src_path, out_path, xcode_project_name=None): + gn_command = [ gn_path, '--root=%s' % os.path.realpath(src_path), '-q' ] + if xcode_project_name is not None: + gn_command.append('--ide=xcode') + gn_command.append('--ninja-executable=autoninja') + gn_command.append('--xcode-build-system=new') + gn_command.append('--xcode-project=%s' % xcode_project_name) + if self._settings.has_section('filters'): + target_filters = self._settings.values('filters') + if target_filters: + gn_command.append('--filters=%s' % ';'.join(target_filters)) + else: + gn_command.append('--check') + gn_command.append('gen') + gn_command.append('//%s' % + os.path.relpath(os.path.abspath(out_path), os.path.abspath(src_path))) + return gn_command def NinjaNeedEscape(arg): - '''Returns True if |arg| needs to be escaped when written to .ninja file.''' - return ':' in arg or '*' in arg or ';' in arg + '''Returns True if |arg| needs to be escaped when written to .ninja file.''' + return ':' in arg or '*' in arg or ';' in arg def NinjaEscapeCommand(command): - '''Escapes |command| in order to write it to .ninja file.''' - result = [] - for arg in command: - if NinjaNeedEscape(arg): - arg = arg.replace(':', '$:') - arg = arg.replace(';', '\\;') - arg = arg.replace('*', '\\*') - else: - result.append(arg) - return ' '.join(result) + '''Escapes |command| in order to write it to .ninja file.''' + result = [] + for arg in command: + if NinjaNeedEscape(arg): + arg = arg.replace(':', '$:') + arg = arg.replace(';', '\\;') + arg = arg.replace('*', '\\*') + else: + result.append(arg) + return ' '.join(result) def FindGn(): - '''Returns absolute path to gn binary looking at the PATH env variable.''' - for path in os.environ['PATH'].split(os.path.pathsep): - gn_path = os.path.join(path, 'gn') - if os.path.isfile(gn_path) and os.access(gn_path, os.X_OK): - return gn_path - return None + '''Returns absolute path to gn binary looking at the PATH env variable.''' + for path in os.environ['PATH'].split(os.path.pathsep): + gn_path = os.path.join(path, 'gn') + if os.path.isfile(gn_path) and os.access(gn_path, os.X_OK): + return gn_path + return None -def GenerateXcodeProject(gn_path, root_dir, out_dir, settings): - '''Convert GN generated Xcode project into multi-configuration Xcode - project.''' +def GenerateXcodeProject(gn_path, root_dir, proj_name, out_dir, settings): + '''Generate Xcode project with Xcode and convert to multi-configurations.''' + prefix = os.path.abspath(os.path.join(out_dir, '_temp')) + temp_path = tempfile.mkdtemp(prefix=prefix) + try: + generator = GnGenerator(settings, 'Debug', 'iphonesimulator') + generator.Generate(gn_path, proj_name, root_dir, temp_path) + convert_gn_xcodeproj.ConvertGnXcodeProject( + root_dir, + '%s.xcodeproj' % proj_name, + os.path.join(temp_path), + os.path.join(out_dir, 'build'), + SUPPORTED_CONFIGS) + finally: + if os.path.exists(temp_path): + shutil.rmtree(temp_path) - temp_path = tempfile.mkdtemp( - prefix=os.path.abspath(os.path.join(out_dir, '_temp'))) - try: - generator = GnGenerator(settings, 'Debug', 'iphonesimulator') - generator.Generate(gn_path, root_dir, temp_path) - convert_gn_xcodeproj.ConvertGnXcodeProject( - root_dir, os.path.join(temp_path), os.path.join(out_dir, 'build'), - SUPPORTED_CONFIGS) - finally: - if os.path.exists(temp_path): - shutil.rmtree(temp_path) +def CreateLLDBInitFile(root_dir, out_dir, settings): + ''' + Generate an .lldbinit file for the project that load the script that fixes + the mapping of source files (see docs/ios/build_instructions.md#debugging). + ''' + with open(os.path.join(out_dir, 'build', '.lldbinit'), 'w') as lldbinit: + lldb_script_dir = os.path.join(os.path.abspath(root_dir), 'tools', 'lldb') + lldbinit.write('script sys.path[:0] = [\'%s\']\n' % lldb_script_dir) + lldbinit.write('script import lldbinit\n') + + workspace_name = settings.getstring( + 'gn_args', + 'ios_internal_citc_workspace_name') + + if workspace_name != '': + username = os.environ['USER'] + for shortname in ('googlemac', 'third_party', 'blaze-out'): + lldbinit.write('settings append target.source-map %s %s\n' % ( + shortname, + '/google/src/cloud/%s/%s/google3/%s' % ( + username, workspace_name, shortname))) + + # Append the content of //ios/build/tools/lldbinit.defaults if it exists. + tools_dir = os.path.join(root_dir, 'ios', 'build', 'tools') + defaults_lldbinit_path = os.path.join(tools_dir, 'lldbinit.defaults') + if os.path.isfile(defaults_lldbinit_path): + with open(defaults_lldbinit_path) as defaults_lldbinit: + for line in defaults_lldbinit: + lldbinit.write(line) + + # Append the content of ~/.lldbinit if it exists. Line that look like they + # are trying to configure source mapping are skipped as they probably date + # back from when setup-gn.py was not generating an .lldbinit file. + global_lldbinit_path = os.path.join(os.environ['HOME'], '.lldbinit') + if os.path.isfile(global_lldbinit_path): + with open(global_lldbinit_path) as global_lldbinit: + for line in global_lldbinit: + if any(pattern.match(line) for pattern in LLDBINIT_SKIP_PATTERNS): + continue + lldbinit.write(line) def GenerateGnBuildRules(gn_path, root_dir, out_dir, settings): - '''Generates all template configurations for gn.''' - for config in SUPPORTED_CONFIGS: - for target in SUPPORTED_TARGETS: - build_dir = os.path.join(out_dir, '%s-%s' % (config, target)) - generator = GnGenerator(settings, config, target) - generator.CreateGnRules(gn_path, root_dir, build_dir) + '''Generates all template configurations for gn.''' + for config in SUPPORTED_CONFIGS: + for target in SUPPORTED_TARGETS: + build_dir = os.path.join(out_dir, '%s-%s' % (config, target)) + if not os.path.isdir(build_dir): + os.makedirs(build_dir) + + generator = GnGenerator(settings, config, target) + generator.CreateGnRules(gn_path, root_dir, build_dir) def Main(args): - default_root = os.path.normpath( - os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) + default_root = os.path.normpath(os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir)) - parser = argparse.ArgumentParser( - description='Generate build directories for use with gn.') - parser.add_argument( - 'root', - default=default_root, - nargs='?', - help='root directory where to generate multiple out configurations') - parser.add_argument('--import', - action='append', - dest='import_rules', - default=[], - help='path to file defining default gn variables') - parser.add_argument('--gn-path', - default=None, - help='path to gn binary (default: look up in $PATH)') - parser.add_argument( - '--build-dir', - default='out', - help='path where the build should be created (default: %(default)s)') - args = parser.parse_args(args) + parser = argparse.ArgumentParser( + description='Generate build directories for use with gn.') + parser.add_argument( + 'root', default=default_root, nargs='?', + help='root directory where to generate multiple out configurations') + parser.add_argument( + '--import', action='append', dest='import_rules', default=[], + help='path to file defining default gn variables') + parser.add_argument( + '--gn-path', default=None, + help='path to gn binary (default: look up in $PATH)') + parser.add_argument( + '--build-dir', default='out', + help='path where the build should be created (default: %(default)s)') + parser.add_argument( + '--config-path', default=os.path.expanduser('~/.setup-gn'), + help='path to the user config file (default: %(default)s)') + parser.add_argument( + '--system-config-path', default=os.path.splitext(__file__)[0] + '.config', + help='path to the default config file (default: %(default)s)') + parser.add_argument( + '--project-name', default='all', dest='proj_name', + help='name of the generated Xcode project (default: %(default)s)') + parser.add_argument( + '--no-xcode-project', action='store_true', default=False, + help='do not generate the build directory with XCode project') + args = parser.parse_args(args) - # Load configuration (first global and then any user overrides). - settings = ConfigParserWithStringInterpolation() - settings.read([ - os.path.splitext(__file__)[0] + '.config', - os.path.expanduser('~/.setup-gn'), - ]) + # Load configuration (first global and then any user overrides). + settings = ConfigParserWithStringInterpolation() + settings.read([ + args.system_config_path, + args.config_path, + ]) - # Add private sections corresponding to --import argument. - if args.import_rules: - settings.add_section('$imports$') - for i, import_rule in enumerate(args.import_rules): - if not import_rule.startswith('//'): - import_rule = '//%s' % os.path.relpath( - os.path.abspath(import_rule), os.path.abspath(args.root)) - settings.set('$imports$', '$rule%d$' % i, import_rule) + # Add private sections corresponding to --import argument. + if args.import_rules: + settings.add_section('$imports$') + for i, import_rule in enumerate(args.import_rules): + if not import_rule.startswith('//'): + import_rule = '//%s' % os.path.relpath( + os.path.abspath(import_rule), os.path.abspath(args.root)) + settings.set('$imports$', '$rule%d$' % i, import_rule) - # Validate settings. - if settings.getstring('build', 'arch') not in ('64-bit', '32-bit', 'fat'): - sys.stderr.write('ERROR: invalid value for build.arch: %s\n' % - settings.getstring('build', 'arch')) - sys.exit(1) + # Validate settings. + if settings.getstring('build', 'arch') not in ('64-bit', '32-bit', 'fat'): + sys.stderr.write('ERROR: invalid value for build.arch: %s\n' % + settings.getstring('build', 'arch')) + sys.exit(1) - # Find path to gn binary either from command-line or in PATH. - if args.gn_path: - gn_path = args.gn_path - else: - gn_path = FindGn() - if gn_path is None: - sys.stderr.write('ERROR: cannot find gn in PATH\n') - sys.exit(1) + # Find path to gn binary either from command-line or in PATH. + if args.gn_path: + gn_path = args.gn_path + else: + gn_path = FindGn() + if gn_path is None: + sys.stderr.write('ERROR: cannot find gn in PATH\n') + sys.exit(1) - out_dir = os.path.join(args.root, args.build_dir) - if not os.path.isdir(out_dir): - os.makedirs(out_dir) + out_dir = os.path.join(args.root, args.build_dir) + if not os.path.isdir(out_dir): + os.makedirs(out_dir) - GenerateXcodeProject(gn_path, args.root, out_dir, settings) - GenerateGnBuildRules(gn_path, args.root, out_dir, settings) + if not args.no_xcode_project: + GenerateXcodeProject(gn_path, args.root, args.proj_name, out_dir, settings) + CreateLLDBInitFile(args.root, out_dir, settings) + GenerateGnBuildRules(gn_path, args.root, out_dir, settings) if __name__ == '__main__': - sys.exit(Main(sys.argv[1:])) + sys.exit(Main(sys.argv[1:])) diff --git a/thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme-testable.template b/thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme-testable.template new file mode 100644 index 0000000000..61b6f471b7 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme-testable.template @@ -0,0 +1,10 @@ + + + + diff --git a/thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme.template b/thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme.template new file mode 100644 index 0000000000..514bea4ef0 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/build/ios/xcodescheme.template @@ -0,0 +1,80 @@ + + + + + + + + + + + + @{TESTABLES} + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/sentry-native/external/crashpad/build/run_tests.py b/thirdparty/sentry-native/external/crashpad/build/run_tests.py index f48652ff78..71d1d9c34d 100644 --- a/thirdparty/sentry-native/external/crashpad/build/run_tests.py +++ b/thirdparty/sentry-native/external/crashpad/build/run_tests.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python -# coding: utf-8 +#!/usr/bin/env python3 # Copyright 2014 The Crashpad Authors. All rights reserved. # @@ -15,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function - import argparse import os import pipes @@ -40,7 +37,7 @@ def _FindGNFromBinaryDir(binary_dir): build_ninja = os.path.join(binary_dir, 'build.ninja') if os.path.isfile(build_ninja): - with open(build_ninja, 'rb') as f: + with open(build_ninja, 'r') as f: # Look for the always-generated regeneration rule of the form: # # rule gn @@ -78,10 +75,11 @@ def _BinaryDirTargetOS(binary_dir): ], shell=IS_WINDOWS_HOST, stdout=subprocess.PIPE, - stderr=open(os.devnull)) + stderr=open(os.devnull), + text=True) value = popen.communicate()[0] if popen.returncode == 0: - match = re.match('target_os = "(.*)"$', value.decode('utf-8')) + match = re.match('target_os = "(.*)"$', value) if match: return match.group(1) @@ -196,13 +194,14 @@ def _RunOnAndroidTarget(binary_dir, test, android_device, extra_command_line): child = subprocess.Popen(adb_command, shell=IS_WINDOWS_HOST, stdin=open(os.devnull), - stdout=subprocess.PIPE) + stdout=subprocess.PIPE, + text=True) FINAL_LINE_RE = re.compile('status=(\d+)$') final_line = None while True: # Use readline so that the test output appears “live” when running. - data = child.stdout.readline().decode('utf-8') + data = child.stdout.readline() if data == '': break if final_line is not None: @@ -369,10 +368,11 @@ def _RunOnIOSTarget(binary_dir, test, is_xcuitest=False): xctestrun_path = f.name print(xctestrun_path) - if is_xcuitest: - plistlib.writePlist(xcuitest(binary_dir, test), xctestrun_path) - else: - plistlib.writePlist(xctest(binary_dir, test), xctestrun_path) + with open(xctestrun_path, 'wb') as fp: + if is_xcuitest: + plistlib.dump(xcuitest(binary_dir, test), fp) + else: + plistlib.dump(xctest(binary_dir, test), fp) subprocess.check_call([ 'xcodebuild', 'test-without-building', '-xctestrun', xctestrun_path, @@ -421,10 +421,11 @@ def main(args): android_device = os.environ.get('ANDROID_DEVICE') if not android_device: adb_devices = subprocess.check_output(['adb', 'devices'], - shell=IS_WINDOWS_HOST) + shell=IS_WINDOWS_HOST, + text=True) devices = [] for line in adb_devices.splitlines(): - line = line.decode('utf-8') + line = line if (line == 'List of devices attached' or re.match('^\* daemon .+ \*$', line) or line == ''): continue diff --git a/thirdparty/sentry-native/external/crashpad/client/annotation.h b/thirdparty/sentry-native/external/crashpad/client/annotation.h index 8e7a3cbdc1..9766fe7030 100644 --- a/thirdparty/sentry-native/external/crashpad/client/annotation.h +++ b/thirdparty/sentry-native/external/crashpad/client/annotation.h @@ -28,7 +28,7 @@ #include "build/build_config.h" namespace crashpad { -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) namespace internal { class InProcessIntermediateDumpHandler; } // namespace internal @@ -72,7 +72,8 @@ class AnnotationList; class Annotation { public: //! \brief The maximum length of an annotation’s name, in bytes. - static constexpr size_t kNameMaxLength = 64; + //! Matches the behavior of Breakpad's SimpleStringDictionary. + static constexpr size_t kNameMaxLength = 256; //! \brief The maximum size of an annotation’s value, in bytes. static constexpr size_t kValueMaxSize = 5 * 4096; @@ -106,7 +107,7 @@ class Annotation { // variables defined in a constexpr function, which is valid. Avoid them // and the also-problematic DCHECK until all the infrastructure is updated: // https://crbug.com/crashpad/201. -#if !defined(OS_WIN) || (defined(_MSC_VER) && _MSC_VER >= 1910) +#if !BUILDFLAG(IS_WIN) || (defined(_MSC_VER) && _MSC_VER >= 1910) const UnderlyingType start = static_cast(Type::kUserDefinedStart); const UnderlyingType user_type = start + value; @@ -173,7 +174,7 @@ class Annotation { protected: friend class AnnotationList; -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) friend class internal::InProcessIntermediateDumpHandler; #endif diff --git a/thirdparty/sentry-native/external/crashpad/client/annotation_list.h b/thirdparty/sentry-native/external/crashpad/client/annotation_list.h index 02389530c8..1c2141fe6a 100644 --- a/thirdparty/sentry-native/external/crashpad/client/annotation_list.h +++ b/thirdparty/sentry-native/external/crashpad/client/annotation_list.h @@ -19,7 +19,7 @@ #include "client/annotation.h" namespace crashpad { -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) namespace internal { class InProcessIntermediateDumpHandler; } // namespace internal @@ -87,7 +87,7 @@ class AnnotationList { Iterator end(); protected: -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) friend class internal::InProcessIntermediateDumpHandler; #endif diff --git a/thirdparty/sentry-native/external/crashpad/client/crash_report_database.cc b/thirdparty/sentry-native/external/crashpad/client/crash_report_database.cc index 5c8156e01e..f3e3d53f91 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crash_report_database.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crash_report_database.cc @@ -28,12 +28,13 @@ namespace { constexpr base::FilePath::CharType kAttachmentsDirectory[] = FILE_PATH_LITERAL("attachments"); -bool AttachmentNameIsOK(const std::string& name) { - for (const char c : name) { - if (c != '_' && c != '-' && c != '.' && !isalnum(c)) - return false; - } - return true; +std::string FixAttachmentName(std::string name) { + std::replace_if(name.begin(), name.end(), [&](char c) + { + return c != '_' && c != '-' && c != '.' && !isalnum(c); + }, '_'); + + return name; } } // namespace @@ -68,7 +69,7 @@ bool CrashReportDatabase::NewReport::Initialize( return false; } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) const std::wstring uuid_string = uuid_.ToWString(); #else const std::string uuid_string = uuid_.ToString(); @@ -94,19 +95,15 @@ FileReaderInterface* CrashReportDatabase::NewReport::Reader() { FileWriter* CrashReportDatabase::NewReport::AddAttachment( const std::string& name) { - if (!AttachmentNameIsOK(name)) { - LOG(ERROR) << "invalid name for attachment " << name; - return nullptr; - } base::FilePath report_attachments_dir = database_->AttachmentsPath(uuid_); if (!LoggingCreateDirectory( report_attachments_dir, FilePermissions::kOwnerOnly, true)) { return nullptr; } -#if defined(OS_WIN) - const std::wstring name_string = base::UTF8ToWide(name); +#if BUILDFLAG(IS_WIN) + const std::wstring name_string = base::UTF8ToWide(FixAttachmentName(name)); #else - const std::string name_string = name; + const std::string name_string = FixAttachmentName(name); #endif base::FilePath attachment_path = report_attachments_dir.Append(name_string); auto writer = std::make_unique(); @@ -137,7 +134,7 @@ void CrashReportDatabase::UploadReport::InitializeAttachments() { continue; } attachment_readers_.emplace_back(std::move(file_reader)); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) const std::string name_string = base::WideToUTF8(filename.value()); #else const std::string name_string = filename.value(); @@ -177,7 +174,7 @@ CrashReportDatabase::OperationStatus CrashReportDatabase::RecordUploadComplete( } base::FilePath CrashReportDatabase::AttachmentsPath(const UUID& uuid) { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) const std::wstring uuid_string = uuid.ToWString(); #else const std::string uuid_string = uuid.ToString(); diff --git a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_generic.cc b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_generic.cc index f5dfa891b0..c4e0401096 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_generic.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_generic.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/ignore_result.h" #include "base/logging.h" #include "build/build_config.h" #include "client/settings.h" @@ -257,8 +257,16 @@ class CrashReportDatabaseGeneric : public CrashReportDatabase { // Writes the metadata for report to the filesystem at path. static bool WriteMetadata(const base::FilePath& path, const Report& report); + Settings& SettingsInternal() { + if (!settings_init_) + settings_.Initialize(base_dir_.Append(kSettings)); + settings_init_ = true; + return settings_; + } + base::FilePath base_dir_; Settings settings_; + bool settings_init_ = false; InitializationStateDcheck initialized_; }; @@ -289,10 +297,6 @@ bool CrashReportDatabaseGeneric::Initialize(const base::FilePath& path, return false; } - if (!settings_.Initialize(base_dir_.Append(kSettings))) { - return false; - } - INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -317,7 +321,7 @@ base::FilePath CrashReportDatabaseGeneric::DatabasePath() { Settings* CrashReportDatabaseGeneric::GetSettings() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return &settings_; + return &SettingsInternal(); } OperationStatus CrashReportDatabaseGeneric::PrepareNewCrashReport( @@ -356,14 +360,14 @@ OperationStatus CrashReportDatabaseGeneric::FinishedWritingCrashReport( return kFileSystemError; } // We've moved the report to pending, so it no longer needs to be removed. - ignore_result(report->file_remover_.release()); + std::ignore = report->file_remover_.release(); // Close all the attachments and disarm their removers too. for (auto& writer : report->attachment_writers_) { writer->Close(); } for (auto& remover : report->attachment_removers_) { - ignore_result(remover.release()); + std::ignore = remover.release(); } *uuid = report->ReportID(); @@ -588,7 +592,7 @@ OperationStatus CrashReportDatabaseGeneric::RecordUploadAttempt( return kDatabaseError; } - if (!settings_.SetLastUploadAttemptTime(now)) { + if (!SettingsInternal().SetLastUploadAttemptTime(now)) { return kDatabaseError; } @@ -600,7 +604,7 @@ base::FilePath CrashReportDatabaseGeneric::ReportPath(const UUID& uuid, DCHECK_NE(state, kUninitialized); DCHECK_NE(state, kSearchable); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) const std::wstring uuid_string = uuid.ToWString(); #else const std::string uuid_string = uuid.ToString(); diff --git a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_mac.mm b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_mac.mm index d1c0a3ed2e..4c9e5e72e8 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_mac.mm +++ b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_mac.mm @@ -14,9 +14,9 @@ #include "client/crash_report_database.h" +#import #include #include -#import #include #include #include @@ -25,8 +25,10 @@ #include #include -#include "base/cxx17_backports.h" -#include "base/ignore_result.h" +#include +#include +#include + #include "base/logging.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "base/posix/eintr_wrapper.h" @@ -42,6 +44,10 @@ #include "util/misc/initialization_state_dcheck.h" #include "util/misc/metrics.h" +#if BUILDFLAG(IS_IOS) +#include "util/ios/scoped_background_task.h" +#endif // BUILDFLAG(IS_IOS) + namespace crashpad { namespace { @@ -52,7 +58,7 @@ constexpr char kCompletedDirectory[] = "completed"; constexpr char kSettings[] = "settings.dat"; -constexpr const char* kReportDirectories[] = { +constexpr std::array kReportDirectories = { kWriteDirectory, kUploadPendingDirectory, kCompletedDirectory, @@ -178,6 +184,11 @@ class CrashReportDatabaseMac : public CrashReportDatabase { //! \brief A private extension of the Report class that maintains bookkeeping //! information of the database. struct UploadReportMac : public UploadReport { +#if BUILDFLAG(IS_IOS) + //! \brief Obtain a background task assertion while a flock is in use. + //! Ensure this is defined first so it is destroyed last. + internal::ScopedBackgroundTask ios_background_task{"UploadReportMac"}; +#endif // BUILDFLAG(IS_IOS) //! \brief Stores the flock of the file for the duration of //! GetReportForUploading() and RecordUploadAttempt(). base::ScopedFD lock_fd; @@ -251,20 +262,27 @@ class CrashReportDatabaseMac : public CrashReportDatabase { // Cleans any attachments that have no associated report in any state. void CleanOrphanedAttachments(); + Settings& SettingsInternal() { + if (!settings_init_) + settings_.Initialize(base_dir_.Append(kSettings)); + settings_init_ = true; + return settings_; + } + base::FilePath base_dir_; Settings settings_; + bool settings_init_; bool xattr_new_names_; InitializationStateDcheck initialized_; }; - CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path) : CrashReportDatabase(), base_dir_(path), settings_(), + settings_init_(false), xattr_new_names_(false), - initialized_() { -} + initialized_() {} CrashReportDatabaseMac::~CrashReportDatabaseMac() {} @@ -281,8 +299,8 @@ bool CrashReportDatabaseMac::Initialize(bool may_create) { } // Create the three processing directories for the database. - for (size_t i = 0; i < base::size(kReportDirectories); ++i) { - if (!CreateOrEnsureDirectoryExists(base_dir_.Append(kReportDirectories[i]))) + for (const auto& dir : kReportDirectories) { + if (!CreateOrEnsureDirectoryExists(base_dir_.Append(dir))) return false; } @@ -290,9 +308,6 @@ bool CrashReportDatabaseMac::Initialize(bool may_create) { return false; } - if (!settings_.Initialize(base_dir_.Append(kSettings))) - return false; - // Do an xattr operation as the last step, to ensure the filesystem has // support for them. This xattr also serves as a marker for whether the // database uses old or new xattr names. @@ -323,7 +338,7 @@ base::FilePath CrashReportDatabaseMac::DatabasePath() { Settings* CrashReportDatabaseMac::GetSettings() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return &settings_; + return &SettingsInternal(); } CrashReportDatabase::OperationStatus @@ -385,14 +400,14 @@ CrashReportDatabaseMac::FinishedWritingCrashReport( PLOG(ERROR) << "rename " << path.value() << " to " << new_path.value(); return kFileSystemError; } - ignore_result(report->file_remover_.release()); + std::ignore = report->file_remover_.release(); // Close all the attachments and disarm their removers too. for (auto& writer : report->attachment_writers_) { writer->Close(); } for (auto& remover : report->attachment_removers_) { - ignore_result(remover.release()); + std::ignore = remover.release(); } Metrics::CrashReportPending(Metrics::PendingReportReason::kNewlyCreated); @@ -516,7 +531,7 @@ CrashReportDatabaseMac::RecordUploadAttempt(UploadReport* report, return kDatabaseError; } - if (!settings_.SetLastUploadAttemptTime(now)) { + if (!SettingsInternal().SetLastUploadAttemptTime(now)) { return kDatabaseError; } diff --git a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_test.cc b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_test.cc index 357702b069..bdb6dc242c 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_test.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_test.cc @@ -185,6 +185,41 @@ TEST_F(CrashReportDatabaseTest, Initialize) { EXPECT_FALSE(db); } +TEST_F(CrashReportDatabaseTest, Settings) { + // Initialize three databases and ensure settings.dat isn't created yet. + ASSERT_TRUE(db()); + + base::FilePath settings_path = + path().Append(FILE_PATH_LITERAL("settings.dat")); + EXPECT_FALSE(FileExists(settings_path)); + + std::unique_ptr db2 = + CrashReportDatabase::Initialize(path()); + ASSERT_TRUE(db2); + EXPECT_FALSE(FileExists(settings_path)); + + std::unique_ptr db3 = + CrashReportDatabase::Initialize(path()); + ASSERT_TRUE(db3); + EXPECT_FALSE(FileExists(settings_path)); + + // Ensure settings.dat exists after getter. + Settings* settings = db3->GetSettings(); + ASSERT_TRUE(settings); + EXPECT_TRUE(FileExists(settings_path)); + + time_t last_upload_attempt_time = 42; + ASSERT_TRUE(settings->SetLastUploadAttemptTime(last_upload_attempt_time)); + + // Ensure the first two databases read the same value. + ASSERT_TRUE( + db2->GetSettings()->GetLastUploadAttemptTime(&last_upload_attempt_time)); + EXPECT_EQ(last_upload_attempt_time, 42); + ASSERT_TRUE( + db()->GetSettings()->GetLastUploadAttemptTime(&last_upload_attempt_time)); + EXPECT_EQ(last_upload_attempt_time, 42); +} + TEST_F(CrashReportDatabaseTest, NewCrashReport) { std::unique_ptr new_report; EXPECT_EQ(db()->PrepareNewCrashReport(&new_report), @@ -737,7 +772,7 @@ TEST_F(CrashReportDatabaseTest, OrphanedAttachments) { ASSERT_TRUE(LoggingRemoveFile(report.file_path)); -#if !defined(OS_APPLE) && !defined(OS_WIN) +#if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_WIN) // CrashReportDatabaseMac stores metadata in xattrs and does not have .meta // files. // CrashReportDatabaseWin stores metadata in a global metadata file and not @@ -749,7 +784,7 @@ TEST_F(CrashReportDatabaseTest, OrphanedAttachments) { ASSERT_EQ(db()->LookUpCrashReport(uuid, &report), CrashReportDatabase::kReportNotFound); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) const std::wstring uuid_string = uuid.ToWString(); #else const std::string uuid_string = uuid.ToString(); @@ -763,7 +798,7 @@ TEST_F(CrashReportDatabaseTest, OrphanedAttachments) { EXPECT_TRUE(FileExists(file_path1)); EXPECT_TRUE(FileExists(file_path1)); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // On Windows, reports removed from metadata are counted, even if the file // is not on the disk. EXPECT_EQ(db()->CleanDatabase(0), 1); @@ -778,7 +813,7 @@ TEST_F(CrashReportDatabaseTest, OrphanedAttachments) { // This test uses knowledge of the database format to break it, so it only // applies to the unfified database implementation. -#if !defined(OS_APPLE) && !defined(OS_WIN) +#if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_WIN) TEST_F(CrashReportDatabaseTest, CleanBrokenDatabase) { // Remove report files if metadata goes missing. CrashReportDatabase::Report report; @@ -843,7 +878,7 @@ TEST_F(CrashReportDatabaseTest, CleanBrokenDatabase) { EXPECT_FALSE(PathExists(report.file_path)); EXPECT_FALSE(PathExists(metadata3)); } -#endif // !OS_APPLE && !OS_WIN +#endif // !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_WIN) TEST_F(CrashReportDatabaseTest, TotalSize_MainReportOnly) { std::unique_ptr new_report; diff --git a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_win.cc b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_win.cc index 65feaa4cf4..e16aa104fb 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crash_report_database_win.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crash_report_database_win.cc @@ -21,9 +21,9 @@ #include #include +#include #include -#include "base/ignore_result.h" #include "base/logging.h" #include "base/numerics/safe_math.h" #include "base/strings/utf_string_conversions.h" @@ -662,13 +662,25 @@ class CrashReportDatabaseWin : public CrashReportDatabase { std::unique_ptr AcquireMetadata(); + Settings& SettingsInternal() { + if (!settings_init_) + settings_.Initialize(base_dir_.Append(kSettings)); + settings_init_ = true; + return settings_; + } + base::FilePath base_dir_; Settings settings_; + bool settings_init_; InitializationStateDcheck initialized_; }; CrashReportDatabaseWin::CrashReportDatabaseWin(const base::FilePath& path) - : CrashReportDatabase(), base_dir_(path), settings_(), initialized_() {} + : CrashReportDatabase(), + base_dir_(path), + settings_(), + settings_init_(false), + initialized_() {} CrashReportDatabaseWin::~CrashReportDatabaseWin() { } @@ -691,9 +703,6 @@ bool CrashReportDatabaseWin::Initialize(bool may_create) { if (!CreateDirectoryIfNecessary(AttachmentsRootPath())) return false; - if (!settings_.Initialize(base_dir_.Append(kSettings))) - return false; - INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -704,7 +713,7 @@ base::FilePath CrashReportDatabaseWin::DatabasePath() { Settings* CrashReportDatabaseWin::GetSettings() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return &settings_; + return &SettingsInternal(); } OperationStatus CrashReportDatabaseWin::PrepareNewCrashReport( @@ -735,14 +744,14 @@ OperationStatus CrashReportDatabaseWin::FinishedWritingCrashReport( time(nullptr), ReportState::kPending)); - ignore_result(report->file_remover_.release()); + std::ignore = report->file_remover_.release(); // Close all the attachments and disarm their removers too. for (auto& writer : report->attachment_writers_) { writer->Close(); } for (auto& remover : report->attachment_removers_) { - ignore_result(remover.release()); + std::ignore = remover.release(); } *uuid = report->ReportID(); @@ -848,7 +857,7 @@ OperationStatus CrashReportDatabaseWin::RecordUploadAttempt( report->upload_explicitly_requested; } - if (!settings_.SetLastUploadAttemptTime(now)) + if (!SettingsInternal().SetLastUploadAttemptTime(now)) return kDatabaseError; return kNoError; diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_client.h b/thirdparty/sentry-native/external/crashpad/client/crashpad_client.h index 588802ce8b..e8d6b06e1f 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_client.h +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_client.h @@ -28,12 +28,12 @@ #include "util/file/file_io.h" #include "util/misc/capture_context.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include "base/mac/scoped_mach_port.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include "util/win/scoped_handle.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include #include #endif @@ -125,7 +125,8 @@ class CrashpadClient { bool asynchronous_start, const std::vector& attachments = {}); -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) || DOXYGEN +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + DOXYGEN //! \brief Retrieve the socket and process ID for the handler. //! //! `StartHandler()` must have successfully been called before calling this @@ -170,9 +171,10 @@ class CrashpadClient { //! //! \return `true` on success. Otherwise `false` with a message logged. static bool InitializeSignalStackForThread(); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS || DOXYGEN +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) || DOXYGEN -#if defined(OS_ANDROID) || DOXYGEN +#if BUILDFLAG(IS_ANDROID) || DOXYGEN //! \brief Installs a signal handler to execute `/system/bin/app_process` and //! load a Java class in response to a crash. //! @@ -339,9 +341,10 @@ class CrashpadClient { const std::map& annotations, const std::vector& arguments, int socket); -#endif // OS_ANDROID || DOXYGEN +#endif // BUILDFLAG(IS_ANDROID) || DOXYGEN -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) || DOXYGEN +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) || \ + DOXYGEN //! \brief Installs a signal handler to launch a handler process in reponse to //! a crash. //! @@ -418,7 +421,7 @@ class CrashpadClient { //! CaptureContext() or similar. static void DumpWithoutCrash(NativeCPUContext* context); - //! \brief Disables any installed crash handler, including any + //! \brief Disables any installed crash handler, not including any //! FirstChanceHandler and crashes the current process. //! //! \param[in] message A message to be logged before crashing. @@ -454,9 +457,10 @@ class CrashpadClient { //! //! \param[in] unhandled_signals The set of unhandled signals void SetUnhandledSignals(const std::set& unhandled_signals); -#endif // OS_LINUX || OS_ANDROID || OS_CHROMEOS || DOXYGEN +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_CHROMEOS) || DOXYGEN -#if defined(OS_IOS) || DOXYGEN +#if BUILDFLAG(IS_IOS) || DOXYGEN //! \brief Configures the process to direct its crashes to the iOS in-process //! Crashpad handler. //! @@ -554,9 +558,21 @@ class CrashpadClient { static void DumpWithoutCrashAndDeferProcessingAtPath( NativeCPUContext* context, const base::FilePath path); + + //! \brief Unregister the Crashpad client. Intended to be used by tests so + //! multiple Crashpad clients can be started and stopped. Not expected to + //! be used in a shipping application. + static void ResetForTesting(); + + //! \brief Inject a callback into Mach handling. Intended to be used by + //! tests to trigger a reentrant exception. + static void SetMachExceptionCallbackForTesting(void (*callback)()); + + //! \brief Returns the thread id of the Mach exception thread, used by tests. + static uint64_t GetThreadIdForTesting(); #endif -#if defined(OS_APPLE) || DOXYGEN +#if BUILDFLAG(IS_APPLE) || DOXYGEN //! \brief Sets the process’ crash handler to a Mach service registered with //! the bootstrap server. //! @@ -606,7 +622,7 @@ class CrashpadClient { base::mac::ScopedMachSendRight GetHandlerMachPort() const; #endif -#if defined(OS_WIN) || DOXYGEN +#if BUILDFLAG(IS_WIN) || DOXYGEN //! \brief The type for custom handlers installed by clients. using FirstChanceHandlerWin = bool (*)(EXCEPTION_POINTERS*); @@ -714,20 +730,9 @@ class CrashpadClient { static bool DumpAndCrashTargetProcess(HANDLE process, HANDLE blame_thread, DWORD exception_code); - - enum : uint32_t { - //! \brief The exception code (roughly "Client called") used when - //! DumpAndCrashTargetProcess() triggers an exception in a target - //! process. - //! - //! \note This value does not have any bits of the top nibble set, to avoid - //! confusion with real exception codes which tend to have those bits - //! set. - kTriggeredExceptionCode = 0xcca11ed, - }; #endif -#if defined(OS_APPLE) || DOXYGEN +#if BUILDFLAG(IS_APPLE) || DOXYGEN //! \brief Configures the process to direct its crashes to the default handler //! for the operating system. //! @@ -761,14 +766,14 @@ class CrashpadClient { #endif private: -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) base::mac::ScopedMachSendRight exception_port_; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) std::wstring ipc_pipe_; ScopedKernelHANDLE handler_start_thread_; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) std::set unhandled_signals_; -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) }; } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios.cc b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios.cc index 01d3484579..f40a8c76f1 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios.cc @@ -14,17 +14,19 @@ #include "client/crashpad_client.h" +#include #include +#include #include +#include -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/mac/mach_logging.h" #include "base/mac/scoped_mach_port.h" #include "client/ios_handler/exception_processor.h" #include "client/ios_handler/in_process_handler.h" -#include "util/ios/ios_system_data_collector.h" +#include "util/ios/raw_logging.h" #include "util/mach/exc_server_variants.h" #include "util/mach/exception_ports.h" #include "util/mach/mach_extensions.h" @@ -40,7 +42,7 @@ bool IsBeingDebugged() { kinfo_proc kern_proc_info; int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; size_t len = sizeof(kern_proc_info); - if (sysctl(mib, base::size(mib), &kern_proc_info, &len, nullptr, 0) == 0) + if (sysctl(mib, std::size(mib), &kern_proc_info, &len, nullptr, 0) == 0) return kern_proc_info.kp_proc.p_flag & P_TRACED; return false; } @@ -60,21 +62,54 @@ class CrashHandler : public Thread, CrashHandler& operator=(const CrashHandler&) = delete; static CrashHandler* Get() { - static CrashHandler* instance = new CrashHandler(); - return instance; + if (!instance_) + instance_ = new CrashHandler(); + return instance_; + } + + static void ResetForTesting() { + delete instance_; + instance_ = nullptr; } bool Initialize(const base::FilePath& database, const std::string& url, const std::map& annotations) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); - if (!in_process_handler_.Initialize( - database, url, annotations, system_data_) || + if (!in_process_handler_.Initialize(database, url, annotations) || !InstallMachExceptionHandler() || - !Signals::InstallHandler(SIGABRT, CatchSignal, 0, &old_action_)) { + // xnu turns hardware faults into Mach exceptions, so the only signal + // left to register is SIGABRT, which never starts off as a hardware + // fault. Installing a handler for other signals would lead to + // recording exceptions twice. As a consequence, Crashpad will not + // generate intermediate dumps for anything manually calling + // raise(SIG*). In practice, this doesn’t actually happen for crash + // signals that originate as hardware faults. + !Signals::InstallHandler( + SIGABRT, CatchAndReraiseSignal, 0, &old_action_)) { LOG(ERROR) << "Unable to initialize Crashpad."; return false; } + + // For applications that haven't ignored or set a handler for SIGPIPE: + // It’s OK for an application to set its own SIGPIPE handler (including + // SIG_IGN) before initializing Crashpad, because Crashpad will discover the + // existing handler and not install its own. + // It’s OK for Crashpad to install its own SIGPIPE handler and for the + // application to subsequently install its own (including SIG_IGN) + // afterwards, because its handler will replace Crashpad’s. + // This is useful to cover the default situation where nobody installs a + // SIGPIPE handler and the disposition is at SIG_DFL, because SIGPIPE is a + // “kill” signal (bsd/sys/signalvar.h sigprop). In that case, without + // Crashpad, SIGPIPE results in a silent and unreported kill (and not even + // ReportCrash will record it), but developers probably want to be alerted + // to the conditon. + struct sigaction sa; + if (sigaction(SIGPIPE, nullptr, &sa) == 0 && sa.sa_handler == SIG_DFL) { + Signals::InstallHandler( + SIGPIPE, CatchAndReraiseSignalDefaultAction, 0, nullptr); + } + InstallObjcExceptionPreprocessor(this); INITIALIZATION_STATE_SET_VALID(initialized_); return true; @@ -91,37 +126,23 @@ class CrashHandler : public Thread, in_process_handler_.ProcessIntermediateDump(file, annotations); } - void DumpWithContext(NativeCPUContext* context) { - const mach_exception_data_type_t code[2] = {}; - static constexpr int kSimulatedException = -1; - HandleMachException(MACH_EXCEPTION_CODES, - mach_thread_self(), - kSimulatedException, - code, - base::size(code), - MACHINE_THREAD_STATE, - reinterpret_cast(context), - MACHINE_THREAD_STATE_COUNT); - } - void DumpWithoutCrash(NativeCPUContext* context, bool process_dump) { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - internal::InProcessHandler::ScopedAlternateWriter scoper( - &in_process_handler_); - if (scoper.Open()) { - DumpWithContext(context); - if (process_dump) { - in_process_handler_.ProcessIntermediateDump(scoper.path()); - } + base::FilePath path; + if (!in_process_handler_.DumpExceptionFromSimulatedMachException( + context, kMachExceptionSimulated, &path)) { + return; + } + + if (process_dump) { + in_process_handler_.ProcessIntermediateDump(path); } } void DumpWithoutCrashAtPath(NativeCPUContext* context, const base::FilePath& path) { - internal::InProcessHandler::ScopedAlternateWriter scoper( - &in_process_handler_); - if (scoper.OpenAtPath(path)) - DumpWithContext(context); + in_process_handler_.DumpExceptionFromSimulatedMachExceptionAtPath( + context, kMachExceptionSimulated, path); } void StartProcessingPendingReports() { @@ -129,9 +150,21 @@ class CrashHandler : public Thread, in_process_handler_.StartProcessingPendingReports(); } + void SetMachExceptionCallbackForTesting(void (*callback)()) { + in_process_handler_.SetMachExceptionCallbackForTesting(callback); + } + + uint64_t GetThreadIdForTesting() { return Thread::GetThreadIdForTesting(); } + private: CrashHandler() = default; + ~CrashHandler() { + UninstallObjcExceptionPreprocessor(); + Signals::InstallDefaultHandler(SIGABRT); + UninstallMachExceptionHandler(); + } + bool InstallMachExceptionHandler() { exception_port_.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE)); if (!exception_port_.is_valid()) { @@ -164,15 +197,22 @@ class CrashHandler : public Thread, return false; } + mach_handler_running_ = true; Start(); return true; } + void UninstallMachExceptionHandler() { + mach_handler_running_ = false; + exception_port_.reset(); + Join(); + } + // Thread: void ThreadMain() override { UniversalMachExcServer universal_mach_exc_server(this); - while (true) { + while (mach_handler_running_) { mach_msg_return_t mr = MachMessageServer::Run(&universal_mach_exc_server, exception_port_.get(), @@ -180,7 +220,20 @@ class CrashHandler : public Thread, MachMessageServer::kPersistent, MachMessageServer::kReceiveLargeIgnore, kMachMessageTimeoutWaitIndefinitely); - MACH_CHECK(mr == MACH_SEND_INVALID_DEST, mr) << "MachMessageServer::Run"; + MACH_CHECK( + mach_handler_running_ + ? mr == MACH_SEND_INVALID_DEST // This shouldn't happen for + // exception messages that come + // from the kernel itself, but if + // something else in-process sends + // exception messages and breaks, + // handle that case. + : (mr == MACH_RCV_PORT_CHANGED || // Port was closed while the + // thread was listening. + mr == MACH_RCV_INVALID_NAME), // Port was closed before the + // thread started listening. + mr) + << "MachMessageServer::Run"; } } @@ -209,8 +262,7 @@ class CrashHandler : public Thread, // inherit the task exception ports, and this process isn’t prepared to // handle them if (task != mach_task_self()) { - LOG(WARNING) << "task 0x" << std::hex << task << " != 0x" - << mach_task_self(); + CRASHPAD_RAW_LOG("MachException task != mach_task_self()"); return KERN_FAILURE; } @@ -224,7 +276,31 @@ class CrashHandler : public Thread, old_state_count); // Respond with KERN_FAILURE so the system will continue to handle this - // exception as a crash. + // exception. xnu will turn this Mach exception into a signal and take the + // default action to terminate the process. However, if sigprocmask is + // called before this Mach exception returns (such as by another thread + // calling abort, see: Libc-1506.40.4/stdlib/FreeBSD/abort.c), the Mach + // exception will be converted into a signal but delivery will be blocked. + // Since concurrent exceptions lead to the losing thread sleeping + // indefinitely, if the abort thread never returns, the thread that + // triggered this Mach exception will repeatedly trap and the process will + // never terminate. If the abort thread didn’t have a user-space signal + // handler that slept forever, the abort would terminate the process even if + // all other signals had been blocked. Instead, unblock all signals + // corresponding to all Mach exceptions Crashpad is registered for before + // returning KERN_FAILURE. There is still racy behavior possible with this + // call to sigprocmask, but the repeated calls to CatchMachException here + // will eventually lead to termination. + sigset_t unblock_set; + sigemptyset(&unblock_set); + sigaddset(&unblock_set, SIGILL); // EXC_BAD_INSTRUCTION + sigaddset(&unblock_set, SIGTRAP); // EXC_BREAKPOINT + sigaddset(&unblock_set, SIGFPE); // EXC_ARITHMETIC + sigaddset(&unblock_set, SIGBUS); // EXC_BAD_ACCESS + sigaddset(&unblock_set, SIGSEGV); // EXC_BAD_ACCESS + if (sigprocmask(SIG_UNBLOCK, &unblock_set, nullptr) != 0) { + CRASHPAD_RAW_LOG("sigprocmask"); + } return KERN_FAILURE; } @@ -236,8 +312,7 @@ class CrashHandler : public Thread, thread_state_flavor_t flavor, ConstThreadState old_state, mach_msg_type_number_t old_state_count) { - in_process_handler_.DumpExceptionFromMachException(system_data_, - behavior, + in_process_handler_.DumpExceptionFromMachException(behavior, thread, exception, code, @@ -249,8 +324,8 @@ class CrashHandler : public Thread, void HandleUncaughtNSException(const uint64_t* frames, const size_t num_frames) override { - in_process_handler_.DumpExceptionFromNSExceptionFrames( - system_data_, frames, num_frames); + in_process_handler_.DumpExceptionFromNSExceptionWithFrames(frames, + num_frames); // After uncaught exceptions are reported, the system immediately triggers a // call to std::terminate()/abort(). Remove the abort handler so a second // dump isn't generated. @@ -259,17 +334,9 @@ class CrashHandler : public Thread, void HandleUncaughtNSExceptionWithContext( NativeCPUContext* context) override { - const mach_exception_data_type_t code[2] = {0, 0}; - in_process_handler_.DumpExceptionFromMachException( - system_data_, - MACH_EXCEPTION_CODES, - mach_thread_self(), - kMachExceptionFromNSException, - code, - base::size(code), - MACHINE_THREAD_STATE, - reinterpret_cast(context), - MACHINE_THREAD_STATE_COUNT); + base::FilePath path; + in_process_handler_.DumpExceptionFromSimulatedMachException( + context, kMachExceptionFromNSException, &path); // After uncaught exceptions are reported, the system immediately triggers a // call to std::terminate()/abort(). Remove the abort handler so a second @@ -277,29 +344,63 @@ class CrashHandler : public Thread, CHECK(Signals::InstallDefaultHandler(SIGABRT)); } + void HandleUncaughtNSExceptionWithContextAtPath( + NativeCPUContext* context, + const base::FilePath& path) override { + in_process_handler_.DumpExceptionFromSimulatedMachExceptionAtPath( + context, kMachExceptionFromNSException, path); + } + + bool MoveIntermediateDumpAtPathToPending( + const base::FilePath& path) override { + if (in_process_handler_.MoveIntermediateDumpAtPathToPending(path)) { + // After uncaught exceptions are reported, the system immediately triggers + // a call to std::terminate()/abort(). Remove the abort handler so a + // second dump isn't generated. + CHECK(Signals::InstallDefaultHandler(SIGABRT)); + return true; + } + return false; + } + // The signal handler installed at OS-level. - static void CatchSignal(int signo, siginfo_t* siginfo, void* context) { + static void CatchAndReraiseSignal(int signo, + siginfo_t* siginfo, + void* context) { + Get()->HandleAndReraiseSignal(signo, + siginfo, + reinterpret_cast(context), + &(Get()->old_action_)); + } + + static void CatchAndReraiseSignalDefaultAction(int signo, + siginfo_t* siginfo, + void* context) { Get()->HandleAndReraiseSignal( - signo, siginfo, reinterpret_cast(context)); + signo, siginfo, reinterpret_cast(context), nullptr); } void HandleAndReraiseSignal(int signo, siginfo_t* siginfo, - ucontext_t* context) { - in_process_handler_.DumpExceptionFromSignal(system_data_, siginfo, context); + ucontext_t* context, + struct sigaction* old_action) { + in_process_handler_.DumpExceptionFromSignal(siginfo, context); // Always call system handler. - Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, &old_action_); + Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, old_action); } base::mac::ScopedMachReceiveRight exception_port_; ExceptionPorts::ExceptionHandlerVector original_handlers_; struct sigaction old_action_ = {}; internal::InProcessHandler in_process_handler_; - internal::IOSSystemDataCollector system_data_; + static CrashHandler* instance_; + std::atomic mach_handler_running_ = false; InitializationStateDcheck initialized_; }; +CrashHandler* CrashHandler::instance_ = nullptr; + } // namespace CrashpadClient::CrashpadClient() {} @@ -364,4 +465,22 @@ void CrashpadClient::DumpWithoutCrashAndDeferProcessingAtPath( crash_handler->DumpWithoutCrashAtPath(context, path); } +void CrashpadClient::ResetForTesting() { + CrashHandler* crash_handler = CrashHandler::Get(); + DCHECK(crash_handler); + crash_handler->ResetForTesting(); +} + +void CrashpadClient::SetMachExceptionCallbackForTesting(void (*callback)()) { + CrashHandler* crash_handler = CrashHandler::Get(); + DCHECK(crash_handler); + crash_handler->SetMachExceptionCallbackForTesting(callback); +} + +uint64_t CrashpadClient::GetThreadIdForTesting() { + CrashHandler* crash_handler = CrashHandler::Get(); + DCHECK(crash_handler); + return crash_handler->GetThreadIdForTesting(); +} + } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios_test.mm b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios_test.mm index 3c350e9fd5..596f4b8481 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios_test.mm +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_ios_test.mm @@ -25,50 +25,67 @@ #include "gtest/gtest.h" #include "test/scoped_temp_dir.h" #include "testing/platform_test.h" +#include "util/thread/thread.h" namespace crashpad { namespace test { namespace { -using CrashpadIOSClient = PlatformTest; +class CrashpadIOSClient : public PlatformTest { + protected: + // testing::Test: + + void SetUp() override { + ASSERT_TRUE(client_.StartCrashpadInProcessHandler( + base::FilePath(database_dir.path()), "", {})); + database_ = CrashReportDatabase::Initialize(database_dir.path()); + } + + void TearDown() override { client_.ResetForTesting(); } + + auto& Client() { return client_; } + auto& Database() { return database_; } + + private: + std::unique_ptr database_; + CrashpadClient client_; + ScopedTempDir database_dir; +}; TEST_F(CrashpadIOSClient, DumpWithoutCrash) { - CrashpadClient client; - ScopedTempDir database_dir; - ASSERT_TRUE(client.StartCrashpadInProcessHandler( - base::FilePath(database_dir.path()), "", {})); - std::unique_ptr database = - CrashReportDatabase::Initialize(database_dir.path()); std::vector reports; - EXPECT_EQ(database->GetPendingReports(&reports), + EXPECT_EQ(Database()->GetPendingReports(&reports), CrashReportDatabase::kNoError); ASSERT_EQ(reports.size(), 0u); CRASHPAD_SIMULATE_CRASH(); - reports.clear(); - EXPECT_EQ(database->GetPendingReports(&reports), + + EXPECT_EQ(Database()->GetPendingReports(&reports), CrashReportDatabase::kNoError); ASSERT_EQ(reports.size(), 1u); +} +TEST_F(CrashpadIOSClient, DumpWithoutCrashAndDefer) { + std::vector reports; CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING(); - reports.clear(); - EXPECT_EQ(database->GetPendingReports(&reports), + EXPECT_EQ(Database()->GetPendingReports(&reports), + CrashReportDatabase::kNoError); + ASSERT_EQ(reports.size(), 0u); + Client().ProcessIntermediateDumps(); + EXPECT_EQ(Database()->GetPendingReports(&reports), CrashReportDatabase::kNoError); ASSERT_EQ(reports.size(), 1u); - client.ProcessIntermediateDumps(); - reports.clear(); - EXPECT_EQ(database->GetPendingReports(&reports), - CrashReportDatabase::kNoError); - ASSERT_EQ(reports.size(), 2u); +} +TEST_F(CrashpadIOSClient, DumpWithoutCrashAndDeferAtPath) { + std::vector reports; ScopedTempDir crash_dir; UUID uuid; uuid.InitializeWithNew(); CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING_AT_PATH( crash_dir.path().Append(uuid.ToString())); - reports.clear(); - EXPECT_EQ(database->GetPendingReports(&reports), + EXPECT_EQ(Database()->GetPendingReports(&reports), CrashReportDatabase::kNoError); - ASSERT_EQ(reports.size(), 2u); + ASSERT_EQ(reports.size(), 0u); NSError* error = nil; NSArray* paths = [[NSFileManager defaultManager] @@ -76,12 +93,43 @@ TEST_F(CrashpadIOSClient, DumpWithoutCrash) { crash_dir.path().value()) error:&error]; ASSERT_EQ([paths count], 1u); - client.ProcessIntermediateDump( + Client().ProcessIntermediateDump( crash_dir.path().Append([paths[0] fileSystemRepresentation])); reports.clear(); - EXPECT_EQ(database->GetPendingReports(&reports), + EXPECT_EQ(Database()->GetPendingReports(&reports), CrashReportDatabase::kNoError); - ASSERT_EQ(reports.size(), 3u); + ASSERT_EQ(reports.size(), 1u); +} + +class RaceThread : public Thread { + public: + explicit RaceThread() : Thread() {} + + private: + void ThreadMain() override { + for (int i = 0; i < 10; ++i) { + CRASHPAD_SIMULATE_CRASH(); + } + } +}; + +TEST_F(CrashpadIOSClient, MultipleThreadsSimulateCrash) { + RaceThread race_threads[2]; + for (RaceThread& race_thread : race_threads) { + race_thread.Start(); + } + + for (int i = 0; i < 10; ++i) { + CRASHPAD_SIMULATE_CRASH(); + } + for (RaceThread& race_thread : race_threads) { + race_thread.Join(); + } + + std::vector reports; + ASSERT_EQ(Database()->GetPendingReports(&reports), + CrashReportDatabase::kNoError); + EXPECT_EQ(reports.size(), 30u); } // This test is covered by a similar XCUITest, but for development purposes it's @@ -89,10 +137,6 @@ TEST_F(CrashpadIOSClient, DumpWithoutCrash) { // to correctly run this in Google Test. Leave the test here, disabled, for use // during development only. TEST_F(CrashpadIOSClient, DISABLED_ThrowNSException) { - CrashpadClient client; - ScopedTempDir database_dir; - ASSERT_TRUE(client.StartCrashpadInProcessHandler( - base::FilePath(database_dir.path()), "", {})); [NSException raise:@"GoogleTestNSException" format:@"ThrowException"]; } @@ -101,10 +145,6 @@ TEST_F(CrashpadIOSClient, DISABLED_ThrowNSException) { // to correctly run this in Google Test. Leave the test here, disabled, for use // during development only. TEST_F(CrashpadIOSClient, DISABLED_ThrowException) { - CrashpadClient client; - ScopedTempDir database_dir; - ASSERT_TRUE(client.StartCrashpadInProcessHandler( - base::FilePath(database_dir.path()), "", {})); std::vector empty_vector; empty_vector.at(42); } diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux.cc b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux.cc index 641cf21742..00e1214326 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux.cc @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include #include @@ -26,8 +28,11 @@ #include #include +#include + #include "base/logging.h" #include "base/strings/stringprintf.h" +#include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "client/client_argv_handling.h" #include "third_party/lss/lss.h" @@ -56,7 +61,7 @@ std::string FormatArgumentAddress(const std::string& name, const void* addr) { return base::StringPrintf("--%s=%p", name.c_str(), addr); } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) std::vector BuildAppProcessArgs( const std::string& class_name, @@ -124,7 +129,7 @@ std::vector BuildArgsToLaunchWithLinker( return argv; } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) // A base class for Crashpad signal handler implementations. class SignalHandler { @@ -136,10 +141,14 @@ class SignalHandler { // handler has been installed. static SignalHandler* Get() { return handler_; } - // Disables any installed Crashpad signal handler for the calling thread. If a - // crash signal is received, any previously installed (non-Crashpad) signal - // handler will be restored and the signal reraised. - static void DisableForThread() { disabled_for_thread_ = true; } + // Disables any installed Crashpad signal handler. If a crash signal is + // received, any previously installed (non-Crashpad) signal handler will be + // restored and the signal reraised. + static void Disable() { + if (!handler_->disabled_.test_and_set()) { + handler_->WakeThreads(); + } + } void SetFirstChanceHandler(CrashpadClient::FirstChanceHandlerLinux handler) { first_chance_handler_ = handler; @@ -147,17 +156,7 @@ class SignalHandler { // The base implementation for all signal handlers, suitable for calling // directly to simulate signal delivery. - bool HandleCrash(int signo, siginfo_t* siginfo, void* context) { - if (disabled_for_thread_) { - return false; - } - - if (first_chance_handler_ && - first_chance_handler_( - signo, siginfo, static_cast(context))) { - return true; - } - + void HandleCrash(int signo, siginfo_t* siginfo, void* context) { exception_information_.siginfo_address = FromPointerCast( siginfo); @@ -168,7 +167,6 @@ class SignalHandler { ScopedPrSetDumpable set_dumpable(false); HandleCrashImpl(); - return false; } protected: @@ -193,27 +191,78 @@ class SignalHandler { virtual void HandleCrashImpl() = 0; private: + static constexpr int32_t kDumpNotDone = 0; + static constexpr int32_t kDumpDone = 1; + // The signal handler installed at OS-level. static void HandleOrReraiseSignal(int signo, siginfo_t* siginfo, void* context) { - if (handler_->HandleCrash(signo, siginfo, context)) { + if (handler_->first_chance_handler_ && + handler_->first_chance_handler_( + signo, siginfo, static_cast(context))) { return; } + + // Only handle the first fatal signal observed. If another thread receives a + // crash signal, it waits for the first dump to complete instead of + // requesting another. + if (!handler_->disabled_.test_and_set()) { + handler_->HandleCrash(signo, siginfo, context); + handler_->WakeThreads(); + } else { + // Processes on Android normally have several chained signal handlers that + // co-operate to report crashes. e.g. WebView will have this signal + // handler installed, the app embedding WebView may have a signal handler + // installed, and Bionic will have a signal handler. Each signal handler + // runs in succession, possibly managed by libsigchain. This wait is + // intended to avoid ill-effects from multiple signal handlers from + // different layers (possibly all trying to use ptrace()) from running + // simultaneously. It does not block forever so that in most conditions, + // those signal handlers will still have a chance to run and ensures + // process termination in case the first crashing thread crashes again in + // its signal handler. Though less typical, this situation also occurs on + // other Linuxes, e.g. to produce in-process stack traces for debug + // builds. + handler_->WaitForDumpDone(); + } + Signals::RestoreHandlerAndReraiseSignalOnReturn( siginfo, handler_->old_actions_.ActionForSignal(signo)); } + void WaitForDumpDone() { + kernel_timespec timeout; + timeout.tv_sec = 5; + timeout.tv_nsec = 0; + sys_futex(&dump_done_futex_, + FUTEX_WAIT_PRIVATE, + kDumpNotDone, + &timeout, + nullptr, + 0); + } + + void WakeThreads() { + dump_done_futex_ = kDumpDone; + sys_futex( + &dump_done_futex_, FUTEX_WAKE_PRIVATE, INT_MAX, nullptr, nullptr, 0); + } + Signals::OldActions old_actions_ = {}; ExceptionInformation exception_information_ = {}; CrashpadClient::FirstChanceHandlerLinux first_chance_handler_ = nullptr; + int32_t dump_done_futex_ = kDumpNotDone; +#if !defined(__cpp_lib_atomic_value_initialization) || \ + __cpp_lib_atomic_value_initialization < 201911L + std::atomic_flag disabled_ = ATOMIC_FLAG_INIT; +#else + std::atomic_flag disabled_; +#endif static SignalHandler* handler_; - - static thread_local bool disabled_for_thread_; }; SignalHandler* SignalHandler::handler_ = nullptr; -thread_local bool SignalHandler::disabled_for_thread_ = false; // Launches a single use handler to snapshot this process. class LaunchAtCrashHandler : public SignalHandler { @@ -307,17 +356,11 @@ class RequestCrashDumpHandler : public SignalHandler { } pid = creds.pid; } - if (pid > 0 && prctl(PR_SET_PTRACER, pid, 0, 0, 0) != 0) { - PLOG(WARNING) << "prctl"; - // TODO(jperaza): If this call to set the ptracer failed, it might be - // possible to try again just before a dump request, in case the - // environment has changed. Revisit ExceptionHandlerClient::SetPtracer() - // and consider saving the result of this call in ExceptionHandlerClient - // or as a member in this signal handler. ExceptionHandlerClient hasn't - // been responsible for maintaining state and a new ExceptionHandlerClient - // has been constructed as a local whenever a client needs to communicate - // with the handler. ExceptionHandlerClient lifetimes and ownership will - // need to be reconsidered if it becomes responsible for state. + if (pid > 0) { + pthread_atfork(nullptr, nullptr, SetPtracerAtFork); + if (prctl(PR_SET_PTRACER, pid, 0, 0, 0) != 0) { + PLOG(WARNING) << "prctl"; + } } sock_to_handler_.reset(sock.release()); handler_pid_ = pid; @@ -338,6 +381,13 @@ class RequestCrashDumpHandler : public SignalHandler { } void HandleCrashImpl() override { + // Attempt to set the ptracer again, in case a crash occurs after a fork, + // before SetPtracerAtFork() has been called. Ignore errors because the + // system call may be disallowed if the sandbox is engaged. + if (handler_pid_ > 0) { + sys_prctl(PR_SET_PTRACER, handler_pid_, 0, 0, 0); + } + ExceptionHandlerProtocol::ClientInformation info = {}; info.exception_information_address = FromPointerCast(&GetExceptionInfo()); @@ -360,6 +410,14 @@ class RequestCrashDumpHandler : public SignalHandler { ~RequestCrashDumpHandler() = delete; + static void SetPtracerAtFork() { + auto handler = RequestCrashDumpHandler::Get(); + if (handler->handler_pid_ > 0 && + prctl(PR_SET_PTRACER, handler->handler_pid_, 0, 0, 0) != 0) { + PLOG(WARNING) << "prctl"; + } + } + ScopedFileHandle sock_to_handler_; pid_t handler_pid_ = -1; @@ -415,7 +473,7 @@ bool CrashpadClient::StartHandler( std::move(client_sock), handler_pid, &unhandled_signals_); } -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // static bool CrashpadClient::GetHandlerSocket(int* sock, pid_t* pid) { auto signal_handler = RequestCrashDumpHandler::Get(); @@ -519,9 +577,10 @@ bool CrashpadClient::InitializeSignalStackForThread() { } return true; } -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) bool CrashpadClient::StartJavaHandlerAtCrash( const std::string& class_name, @@ -666,7 +725,7 @@ void CrashpadClient::DumpWithoutCrash(NativeCPUContext* context) { // static void CrashpadClient::CrashWithoutDump(const std::string& message) { - SignalHandler::DisableForThread(); + SignalHandler::Disable(); LOG(FATAL) << message; } diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux_test.cc b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux_test.cc index a3ddc31c8a..4a2bb4189a 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux_test.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_linux_test.cc @@ -15,6 +15,7 @@ #include "client/crashpad_client.h" #include +#include #include #include #include @@ -23,9 +24,11 @@ #include "base/check_op.h" #include "base/notreached.h" +#include "build/build_config.h" #include "client/annotation.h" #include "client/annotation_list.h" #include "client/crash_report_database.h" +#include "client/crashpad_info.h" #include "client/simulate_crash.h" #include "gtest/gtest.h" #include "snapshot/annotation_snapshot.h" @@ -49,7 +52,7 @@ #include "util/posix/signals.h" #include "util/thread/thread.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #include "dlfcn_internal.h" @@ -73,12 +76,13 @@ struct StartHandlerForSelfTestOptions { bool set_first_chance_handler; bool crash_non_main_thread; bool client_uses_signals; + bool gather_indirectly_referenced_memory; CrashType crash_type; }; class StartHandlerForSelfTest : public testing::TestWithParam< - std::tuple> { + std::tuple> { public: StartHandlerForSelfTest() = default; @@ -88,10 +92,14 @@ class StartHandlerForSelfTest ~StartHandlerForSelfTest() = default; void SetUp() override { + // MSAN requires that padding bytes have been initialized for structs that + // are written to files. + memset(&options_, 0, sizeof(options_)); std::tie(options_.start_handler_at_crash, options_.set_first_chance_handler, options_.crash_non_main_thread, options_.client_uses_signals, + options_.gather_indirectly_referenced_memory, options_.crash_type) = GetParam(); } @@ -101,10 +109,6 @@ class StartHandlerForSelfTest StartHandlerForSelfTestOptions options_; }; -bool HandleCrashSuccessfully(int, siginfo_t*, ucontext_t*) { - return true; -} - bool InstallHandler(CrashpadClient* client, bool start_at_crash, const base::FilePath& handler_path, @@ -134,7 +138,7 @@ constexpr char kTestAnnotationValue[] = "value_of_annotation"; constexpr char kTestAttachmentName[] = "test_attachment"; constexpr char kTestAttachmentContent[] = "attachment_content"; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) constexpr char kTestAbortMessage[] = "test abort message"; #endif @@ -147,7 +151,8 @@ void ValidateAttachment(const CrashReportDatabase::UploadReport* report) { 0); } -void ValidateExtraMemory(const ProcessSnapshotMinidump& minidump) { +void ValidateExtraMemory(const StartHandlerForSelfTestOptions& options, + const ProcessSnapshotMinidump& minidump) { // Verify that if we have an exception, then the code around the instruction // pointer is included in the extra memory. const ExceptionSnapshot* exception = minidump.Exception(); @@ -164,14 +169,15 @@ void ValidateExtraMemory(const ProcessSnapshotMinidump& minidump) { break; } } - EXPECT_TRUE(pc_found); + EXPECT_EQ(pc_found, options.gather_indirectly_referenced_memory); } -void ValidateDump(const CrashReportDatabase::UploadReport* report) { +void ValidateDump(const StartHandlerForSelfTestOptions& options, + const CrashReportDatabase::UploadReport* report) { ProcessSnapshotMinidump minidump_snapshot; ASSERT_TRUE(minidump_snapshot.Initialize(report->Reader())); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // This part of the test requires Q. The API level on Q devices will be 28 // until the API is finalized, so we can't check API level yet. For now, test // for the presence of a libc symbol which was introduced in Q. @@ -184,7 +190,7 @@ void ValidateDump(const CrashReportDatabase::UploadReport* report) { #endif ValidateAttachment(report); - ValidateExtraMemory(minidump_snapshot); + ValidateExtraMemory(options, minidump_snapshot); for (const ModuleSnapshot* module : minidump_snapshot.Modules()) { for (const AnnotationSnapshot& annotation : module->AnnotationObjects()) { @@ -213,13 +219,24 @@ int RecurseInfinitely(int* ptr) { } #pragma clang diagnostic pop +sigjmp_buf do_crash_sigjmp_env; + +bool HandleCrashSuccessfully(int, siginfo_t*, ucontext_t*) { + siglongjmp(do_crash_sigjmp_env, 1); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code-return" + return true; +#pragma clang diagnostic pop +} + void DoCrash(const StartHandlerForSelfTestOptions& options, CrashpadClient* client) { + if (sigsetjmp(do_crash_sigjmp_env, 1) != 0) { + return; + } + switch (options.crash_type) { case CrashType::kSimulated: - if (options.set_first_chance_handler) { - client->SetFirstChanceExceptionHandler(HandleCrashSuccessfully); - } CRASHPAD_SIMULATE_CRASH(); break; @@ -330,6 +347,11 @@ CRASHPAD_CHILD_TEST_MAIN(StartHandlerForSelfTestChild) { client_handler, SA_ONSTACK, &old_actions)); } + if (options.gather_indirectly_referenced_memory) { + CrashpadInfo::GetCrashpadInfo()->set_gather_indirectly_referenced_memory( + TriState::kEnabled, 1024 * 1024 * 4); + } + base::FilePath handler_path = TestPaths::Executable().DirName().Append( FILE_PATH_LITERAL("crashpad_handler")); @@ -350,7 +372,11 @@ CRASHPAD_CHILD_TEST_MAIN(StartHandlerForSelfTestChild) { return EXIT_FAILURE; } -#if defined(OS_ANDROID) + if (options.set_first_chance_handler) { + client.SetFirstChanceExceptionHandler(HandleCrashSuccessfully); + } + +#if BUILDFLAG(IS_ANDROID) if (android_set_abort_message) { android_set_abort_message(kTestAbortMessage); } @@ -372,17 +398,19 @@ class StartHandlerForSelfInChildTest : public MultiprocessExec { StartHandlerForSelfInChildTest(const StartHandlerForSelfTestOptions& options) : MultiprocessExec(), options_(options) { SetChildTestMainFunction("StartHandlerForSelfTestChild"); - switch (options.crash_type) { - case CrashType::kSimulated: - // kTerminationNormal, EXIT_SUCCESS - break; - case CrashType::kBuiltinTrap: - SetExpectedChildTerminationBuiltinTrap(); - break; - case CrashType::kInfiniteRecursion: - SetExpectedChildTermination(TerminationReason::kTerminationSignal, - SIGSEGV); - break; + if (!options.set_first_chance_handler) { + switch (options.crash_type) { + case CrashType::kSimulated: + // kTerminationNormal, EXIT_SUCCESS + break; + case CrashType::kBuiltinTrap: + SetExpectedChildTerminationBuiltinTrap(); + break; + case CrashType::kInfiniteRecursion: + SetExpectedChildTermination(TerminationReason::kTerminationSignal, + SIGSEGV); + break; + } } } @@ -433,27 +461,25 @@ class StartHandlerForSelfInChildTest : public MultiprocessExec { reports.clear(); ASSERT_EQ(database->GetPendingReports(&reports), CrashReportDatabase::kNoError); - ASSERT_EQ(reports.size(), options_.set_first_chance_handler ? 0u : 1u); - if (options_.set_first_chance_handler) { + bool report_expected = !options_.set_first_chance_handler || + options_.crash_type == CrashType::kSimulated; + ASSERT_EQ(reports.size(), report_expected ? 1u : 0u); + + if (!report_expected) { return; } std::unique_ptr report; ASSERT_EQ(database->GetReportForUploading(reports[0].uuid, &report), CrashReportDatabase::kNoError); - ValidateDump(report.get()); + ValidateDump(options_, report.get()); } StartHandlerForSelfTestOptions options_; }; TEST_P(StartHandlerForSelfTest, StartHandlerInChild) { - if (Options().set_first_chance_handler && - Options().crash_type != CrashType::kSimulated) { - // TODO(jperaza): test first chance handlers with real crashes. - return; - } #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ defined(UNDEFINED_SANITIZER) if (Options().crash_type == CrashType::kInfiniteRecursion) { @@ -471,6 +497,7 @@ INSTANTIATE_TEST_SUITE_P( testing::Bool(), testing::Bool(), testing::Bool(), + testing::Bool(), testing::Values(CrashType::kSimulated, CrashType::kBuiltinTrap, CrashType::kInfiniteRecursion))); diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_mac.cc b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_mac.cc index 44e3be559e..0d174f5d2a 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_mac.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_mac.cc @@ -21,9 +21,9 @@ #include #include +#include #include -#include "base/ignore_result.h" #include "base/logging.h" #include "base/mac/mach_logging.h" #include "base/strings/stringprintf.h" @@ -180,7 +180,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { handler_restarter->StartRestartThread( handler, database, metrics_dir, url, annotations, arguments, attachments)) { // The thread owns the object now. - ignore_result(handler_restarter.release()); + std::ignore = handler_restarter.release(); } // If StartRestartThread() failed, proceed without the ability to restart. @@ -372,7 +372,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { return false; } - ignore_result(receive_right.release()); + std::ignore = receive_right.release(); return true; } diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_win.cc b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_win.cc index 57696054de..bdf15797c3 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_client_win.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_client_win.cc @@ -36,6 +36,7 @@ #include "util/win/command_line.h" #include "util/win/context_wrappers.h" #include "util/win/critical_section_with_debug_info.h" +#include "util/win/exception_codes.h" #include "util/win/get_function.h" #include "util/win/handle.h" #include "util/win/initial_client_data.h" @@ -69,7 +70,18 @@ HANDLE g_non_crash_dump_done = INVALID_HANDLE_VALUE; CrashpadClient::FirstChanceHandlerWin first_chance_handler_ = nullptr; // Guards multiple simultaneous calls to DumpWithoutCrash(). This is leaked. -base::Lock* g_non_crash_dump_lock; +base::Lock* g_non_crash_dump_lock = nullptr; + +class CrashDumpAutoReleaser { + public: + ~CrashDumpAutoReleaser() { + if (g_non_crash_dump_lock) { + delete g_non_crash_dump_lock; + g_non_crash_dump_lock = nullptr; + } + } +}; +static CrashDumpAutoReleaser gAutoReleaser; // Where we store a pointer to the context information when taking a non-crash // dump. @@ -394,8 +406,7 @@ bool StartHandlerProcess( } for (const base::FilePath& attachment : data->attachments) { AppendCommandLineArgument( - FormatArgumentString("attachment", attachment.value()), - &command_line); + FormatArgumentString("attachment", attachment.value()), &command_line); } ScopedKernelHANDLE this_process( @@ -932,7 +943,7 @@ bool CrashpadClient::DumpAndCrashTargetProcess(HANDLE process, // ecx = kTriggeredExceptionCode for dwExceptionCode. data_to_write.push_back(0xb9); - AddUint32(&data_to_write, kTriggeredExceptionCode); + AddUint32(&data_to_write, ExceptionCodes::kTriggeredExceptionCode); // jmp to RaiseException() via rax. data_to_write.push_back(0x48); // mov rax, imm. diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_info.cc b/thirdparty/sentry-native/external/crashpad/client/crashpad_info.cc index 929c0df11f..8f13276fd8 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_info.cc +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_info.cc @@ -16,10 +16,11 @@ #include +#include "build/build_config.h" #include "util/misc/address_sanitizer.h" #include "util/misc/from_pointer_cast.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include #endif @@ -52,10 +53,10 @@ static_assert(std::is_standard_layout::value, // because it’s POD, no code should need to run to initialize this under // release-mode optimization. -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) __attribute__(( -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) // Put the structure in a well-known section name where it can be easily // found without having to consult the symbol table. section(SEG_DATA ",crashpad_info"), @@ -77,16 +78,16 @@ __attribute__(( // The “used” attribute prevents the structure from being dead-stripped. used)) -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) // Put the struct in a section name CPADinfo where it can be found without the // symbol table. #pragma section("CPADinfo", read, write) __declspec(allocate("CPADinfo")) -#else // !defined(OS_POSIX) && !defined(OS_WIN) +#else // !BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_WIN) #error Port -#endif // !defined(OS_POSIX) && !defined(OS_WIN) +#endif // !BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_WIN) CrashpadInfo g_crashpad_info; @@ -94,8 +95,8 @@ extern "C" int* CRASHPAD_NOTE_REFERENCE; // static CrashpadInfo* CrashpadInfo::GetCrashpadInfo() { -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ - defined(OS_FUCHSIA) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_FUCHSIA) // This otherwise-unused reference is used so that any module that // references GetCrashpadInfo() will also include the note in the // .note.crashpad.info section. That note in turn contains the address of diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_info.h b/thirdparty/sentry-native/external/crashpad/client/crashpad_info.h index cc05398e3f..6c7ce3277e 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_info.h +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_info.h @@ -23,15 +23,15 @@ #include "client/simple_string_dictionary.h" #include "util/misc/tri_state.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) namespace crashpad { namespace internal { -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) class InProcessIntermediateDumpHandler; #endif @@ -230,7 +230,7 @@ struct CrashpadInfo { }; protected: -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) friend class internal::InProcessIntermediateDumpHandler; #endif diff --git a/thirdparty/sentry-native/external/crashpad/client/crashpad_info_note.S b/thirdparty/sentry-native/external/crashpad/client/crashpad_info_note.S index ef3d68ccb4..80de22d606 100644 --- a/thirdparty/sentry-native/external/crashpad/client/crashpad_info_note.S +++ b/thirdparty/sentry-native/external/crashpad/client/crashpad_info_note.S @@ -17,7 +17,7 @@ // that symbol to be in the dynamic symbol table. #include "util/misc/elf_note_types.h" -#include "util/misc/arm64_bti_note.S" +#include "util/misc/arm64_pac_bti.S" // namespace crashpad { // CrashpadInfo g_crashpad_info; diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.h b/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.h index 7318e21446..233f7e45af 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.h +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.h @@ -15,8 +15,7 @@ #ifndef CRASHPAD_UTIL_IOS_EXCEPTION_PROCESSOR_H_ #define CRASHPAD_UTIL_IOS_EXCEPTION_PROCESSOR_H_ -#include - +#include "base/files/file_path.h" #include "util/misc/capture_context.h" namespace crashpad { @@ -40,6 +39,28 @@ class ObjcExceptionDelegate { virtual void HandleUncaughtNSException(const uint64_t* frames, const size_t num_frames) = 0; + //! \brief Generate an intermediate dump from an NSException caught with its + //! associated CPU context. Because the method for intercepting + //! exceptions is imperfect, write the the intermediate dump to a + //! temporary location specified by \a path. If the NSException matches + //! the one used in the UncaughtExceptionHandler, call + //! MoveIntermediateDumpAtPathToPending to move to the proper Crashpad + //! database pending location. + //! + //! \param[in] context The cpu context of the thread throwing an exception. + //! \param[in] path Path to write the intermediate dump. + virtual void HandleUncaughtNSExceptionWithContextAtPath( + NativeCPUContext* context, + const base::FilePath& path) = 0; + + //! \brief Moves an intermediate dump to the pending directory. This is meant + //! to be used by the UncaughtExceptionHandler, when the NSException + //! caught by the preprocessor matches the UncaughtExceptionHandler. + //! + //! \param[in] path Path to the specific intermediate dump. + virtual bool MoveIntermediateDumpAtPathToPending( + const base::FilePath& path) = 0; + protected: ~ObjcExceptionDelegate() {} }; @@ -59,6 +80,10 @@ class ObjcExceptionDelegate { //! signal handler. It should only be installed once. void InstallObjcExceptionPreprocessor(ObjcExceptionDelegate* delegate); +//! \brief Uninstalls the Objective-C exception preprocessor. Expected to be +//! used by tests only. +void UninstallObjcExceptionPreprocessor(); + } // namespace crashpad #endif // CRASHPAD_UTIL_IOS_EXCEPTION_PROCESSOR_H_ diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.mm b/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.mm index 33981326f1..e276554499 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.mm +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/exception_processor.mm @@ -53,6 +53,8 @@ #include "client/annotation.h" #include "client/simulate_crash_ios.h" +namespace crashpad { + namespace { // From 10.15.0 objc4-779.1/runtime/objc-exception.mm. @@ -132,16 +134,12 @@ std::string GetTraceString() { return FormatStackTrace(addresses, 1024); } -crashpad::ObjcExceptionDelegate* g_exception_delegate; -objc_exception_preprocessor g_next_preprocessor; -NSUncaughtExceptionHandler* g_next_uncaught_exception_handler; - static void SetNSExceptionAnnotations(NSException* exception, std::string& name, std::string& reason) { @try { name = base::SysNSStringToUTF8(exception.name); - static crashpad::StringAnnotation<256> nameKey("exceptionName"); + static StringAnnotation<256> nameKey("exceptionName"); nameKey.Set(name); } @catch (id name_exception) { LOG(ERROR) << "Unable to read uncaught Objective-C exception name."; @@ -149,7 +147,7 @@ static void SetNSExceptionAnnotations(NSException* exception, @try { reason = base::SysNSStringToUTF8(exception.reason); - static crashpad::StringAnnotation<512> reasonKey("exceptionReason"); + static StringAnnotation<1024> reasonKey("exceptionReason"); reasonKey.Set(reason); } @catch (id reason_exception) { LOG(ERROR) << "Unable to read uncaught Objective-C exception reason."; @@ -157,7 +155,7 @@ static void SetNSExceptionAnnotations(NSException* exception, @try { if (exception.userInfo) { - static crashpad::StringAnnotation<512> userInfoKey("exceptionUserInfo"); + static StringAnnotation<1024> userInfoKey("exceptionUserInfo"); userInfoKey.Set(base::SysNSStringToUTF8( [NSString stringWithFormat:@"%@", exception.userInfo])); } @@ -166,26 +164,125 @@ static void SetNSExceptionAnnotations(NSException* exception, } } -static void ObjcUncaughtExceptionHandler(NSException* exception) { - std::string name, reason; - SetNSExceptionAnnotations(exception, name, reason); - NSArray* addressArray = [exception callStackReturnAddresses]; - if ([addressArray count] > 0) { - static crashpad::StringAnnotation<256> nameKey("UncaughtNSException"); - nameKey.Set("true"); - std::vector addresses; - for (NSNumber* address in addressArray) - addresses.push_back([address unsignedLongLongValue]); - g_exception_delegate->HandleUncaughtNSException(&addresses[0], - addresses.size()); - } else { - LOG(WARNING) << "Uncaught Objective-C exception name: " << name - << " reason: " << reason << " with no " - << " -callStackReturnAddresses."; - crashpad::NativeCPUContext cpu_context; - crashpad::CaptureContext(&cpu_context); - g_exception_delegate->HandleUncaughtNSExceptionWithContext(&cpu_context); +//! \brief Helper class to own the complex types used by the Objective-C +//! exception preprocessor. +class ExceptionPreprocessorState { + public: + ExceptionPreprocessorState(const ExceptionPreprocessorState&) = delete; + ExceptionPreprocessorState& operator=(const ExceptionPreprocessorState&) = + delete; + + static ExceptionPreprocessorState* Get() { + static ExceptionPreprocessorState* instance = []() { + return new ExceptionPreprocessorState(); + }(); + return instance; } + + // Writes an intermediate dumps to a temporary location to be used by the + // final UncaughtExceptionHandler and notifies the preprocessor chain. + id HandleUncaughtException(NativeCPUContext* cpu_context, id exception) { + // If this isn't the first time the preprocessor has detected an uncaught + // NSException, note this in the second intermediate dump. + objc_exception_preprocessor next_preprocessor = next_preprocessor_; + static bool handled_first_exception; + if (handled_first_exception) { + static StringAnnotation<5> name_key("MultipleHandledUncaughtNSException"); + name_key.Set("true"); + + // Unregister so we stop getting in the way of the exception processor if + // we aren't correctly identifying sinkholes. The final uncaught exception + // handler is still active. + objc_setExceptionPreprocessor(next_preprocessor_); + next_preprocessor_ = nullptr; + } + handled_first_exception = true; + + // Use tmp/ for this intermediate dump path. Normally these dumps are + // written to the "pending-serialized-ios-dump" folder and are eligable for + // the next pass to convert pending intermediate dumps to minidump files. + // Since this intermediate dump isn't eligable until the uncaught handler, + // use tmp/. + base::FilePath path(base::SysNSStringToUTF8([NSTemporaryDirectory() + stringByAppendingPathComponent:[[NSUUID UUID] UUIDString]])); + exception_delegate_->HandleUncaughtNSExceptionWithContextAtPath(cpu_context, + path); + last_handled_intermediate_dump_ = path; + + return next_preprocessor ? next_preprocessor(exception) : exception; + } + + // If the PreprocessException already captured this exception via + // HANDLE_UNCAUGHT_NSEXCEPTION. Move last_handled_intermediate_dump_ to + // the pending intermediate dump directory and return true. Otherwise the + // preprocessor didn't catch anything, so pass the frames or just the context + // to the exception_delegate. + void FinalizeUncaughtNSException(id exception) { + if ([last_exception_ isEqual:exception] && + !last_handled_intermediate_dump_.empty() && + exception_delegate_->MoveIntermediateDumpAtPathToPending( + last_handled_intermediate_dump_)) { + last_handled_intermediate_dump_ = base::FilePath(); + return; + } + + std::string name, reason; + SetNSExceptionAnnotations(exception, name, reason); + NSArray* address_array = [exception callStackReturnAddresses]; + + if ([address_array count] > 0) { + static StringAnnotation<256> name_key("UncaughtNSException"); + name_key.Set("true"); + std::vector addresses; + for (NSNumber* address in address_array) + addresses.push_back([address unsignedLongLongValue]); + exception_delegate_->HandleUncaughtNSException(&addresses[0], + addresses.size()); + } else { + LOG(WARNING) << "Uncaught Objective-C exception name: " << name + << " reason: " << reason << " with no " + << " -callStackReturnAddresses."; + NativeCPUContext cpu_context; + CaptureContext(&cpu_context); + exception_delegate_->HandleUncaughtNSExceptionWithContext(&cpu_context); + } + } + + id MaybeCallNextPreprocessor(id exception) { + return next_preprocessor_ ? next_preprocessor_(exception) : exception; + } + + // Register the objc_setExceptionPreprocessor and NSUncaughtExceptionHandler. + void Install(ObjcExceptionDelegate* delegate); + + // Restore the objc_setExceptionPreprocessor and NSUncaughtExceptionHandler. + void Uninstall(); + + NSException* last_exception() { return last_exception_; } + void set_last_exception(NSException* exception) { + [last_exception_ release]; + last_exception_ = [exception retain]; + } + + private: + ExceptionPreprocessorState() = default; + ~ExceptionPreprocessorState() = default; + + // Location of the intermediate dump generated after an exception triggered + // HANDLE_UNCAUGHT_NSEXCEPTION. + base::FilePath last_handled_intermediate_dump_; + + // Recorded last NSException in case the exception is caught and thrown again + // (without using objc_exception_rethrow.) + NSException* last_exception_ = nil; + + ObjcExceptionDelegate* exception_delegate_ = nullptr; + objc_exception_preprocessor next_preprocessor_ = nullptr; + NSUncaughtExceptionHandler* next_uncaught_exception_handler_ = nullptr; +}; + +static void ObjcUncaughtExceptionHandler(NSException* exception) { + ExceptionPreprocessorState::Get()->FinalizeUncaughtNSException(exception); } // This function is used to make it clear to the crash processor that an @@ -197,15 +294,12 @@ static __attribute__((noinline)) id HANDLE_UNCAUGHT_NSEXCEPTION( SetNSExceptionAnnotations(exception, name, reason); LOG(WARNING) << "Handling Objective-C exception name: " << name << " reason: " << reason << " with sinkhole: " << sinkhole; - crashpad::NativeCPUContext cpu_context; - crashpad::CaptureContext(&cpu_context); - g_exception_delegate->HandleUncaughtNSExceptionWithContext(&cpu_context); + NativeCPUContext cpu_context{}; + CaptureContext(&cpu_context); - // Remove the uncaught exception handler so we don't record this twice. - NSSetUncaughtExceptionHandler(g_next_uncaught_exception_handler); - g_next_uncaught_exception_handler = nullptr; - - return g_next_preprocessor ? g_next_preprocessor(exception) : exception; + ExceptionPreprocessorState* preprocessor_state = + ExceptionPreprocessorState::Get(); + return preprocessor_state->HandleUncaughtException(&cpu_context, exception); } // Returns true if |path| equals |sinkhole| on device. Simulator paths prepend @@ -226,13 +320,23 @@ bool ModulePathMatchesSinkhole(const char* path, const char* sinkhole) { } id ObjcExceptionPreprocessor(id exception) { + // Some sinkholes don't use objc_exception_rethrow when they should, which + // would otherwise prevent the exception_preprocessor from getting called + // again. Because of this, track the most recently seen exception and + // ignore it. + ExceptionPreprocessorState* preprocessor_state = + ExceptionPreprocessorState::Get(); + if ([preprocessor_state->last_exception() isEqual:exception]) { + return preprocessor_state->MaybeCallNextPreprocessor(exception); + } + preprocessor_state->set_last_exception(exception); + static bool seen_first_exception; - static crashpad::StringAnnotation<256> firstexception("firstexception"); - static crashpad::StringAnnotation<256> lastexception("lastexception"); - static crashpad::StringAnnotation<1024> firstexception_bt( - "firstexception_bt"); - static crashpad::StringAnnotation<1024> lastexception_bt("lastexception_bt"); + static StringAnnotation<256> firstexception("firstexception"); + static StringAnnotation<256> lastexception("lastexception"); + static StringAnnotation<1024> firstexception_bt("firstexception_bt"); + static StringAnnotation<1024> lastexception_bt("lastexception_bt"); auto* key = seen_first_exception ? &lastexception : &firstexception; auto* bt_key = seen_first_exception ? &lastexception_bt : &firstexception_bt; NSString* value = [NSString @@ -470,36 +574,41 @@ id ObjcExceptionPreprocessor(id exception) { } // Forward to the next preprocessor. - return g_next_preprocessor ? g_next_preprocessor(exception) : exception; + return preprocessor_state->MaybeCallNextPreprocessor(exception); +} + +void ExceptionPreprocessorState::Install(ObjcExceptionDelegate* delegate) { + DCHECK(!next_preprocessor_); + exception_delegate_ = delegate; + + // Preprocessor. + next_preprocessor_ = + objc_setExceptionPreprocessor(&ObjcExceptionPreprocessor); + + // Uncaught processor. + next_uncaught_exception_handler_ = NSGetUncaughtExceptionHandler(); + NSSetUncaughtExceptionHandler(&ObjcUncaughtExceptionHandler); +} + +void ExceptionPreprocessorState::Uninstall() { + DCHECK(next_preprocessor_); + objc_setExceptionPreprocessor(next_preprocessor_); + next_preprocessor_ = nullptr; + + NSSetUncaughtExceptionHandler(next_uncaught_exception_handler_); + next_uncaught_exception_handler_ = nullptr; + + exception_delegate_ = nullptr; } } // namespace -namespace crashpad { - void InstallObjcExceptionPreprocessor(ObjcExceptionDelegate* delegate) { - DCHECK(!g_next_preprocessor); - - // Preprocessor. - g_next_preprocessor = - objc_setExceptionPreprocessor(&ObjcExceptionPreprocessor); - - // Uncaught processor. - g_exception_delegate = delegate; - g_next_uncaught_exception_handler = NSGetUncaughtExceptionHandler(); - NSSetUncaughtExceptionHandler(&ObjcUncaughtExceptionHandler); + ExceptionPreprocessorState::Get()->Install(delegate); } void UninstallObjcExceptionPreprocessor() { - DCHECK(g_next_preprocessor); - - objc_setExceptionPreprocessor(g_next_preprocessor); - g_exception_delegate = nullptr; - - NSSetUncaughtExceptionHandler(g_next_uncaught_exception_handler); - g_next_uncaught_exception_handler = nullptr; - - g_next_preprocessor = nullptr; + ExceptionPreprocessorState::Get()->Uninstall(); } } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.cc b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.cc index 6058e3b3f1..92bb72e15b 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.cc +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.cc @@ -17,6 +17,9 @@ #include #include +#include + +#include "base/cxx17_backports.h" #include "base/logging.h" #include "client/ios_handler/in_process_intermediate_dump_handler.h" #include "client/prune_crash_reports.h" @@ -24,6 +27,7 @@ #include "minidump/minidump_file_writer.h" #include "util/file/directory_reader.h" #include "util/file/filesystem.h" +#include "util/ios/raw_logging.h" namespace { @@ -46,6 +50,10 @@ constexpr char kLockedExtension[] = ".locked"; // uuid in the intermediate dump file name. constexpr char kBundleSeperator[] = "@"; +// Zero-ed codes used by kMachExceptionFromNSException and +// kMachExceptionSimulated. +constexpr mach_exception_data_type_t kEmulatedMachExceptionCodes[2] = {}; + } // namespace namespace crashpad { @@ -54,17 +62,16 @@ namespace internal { InProcessHandler::InProcessHandler() = default; InProcessHandler::~InProcessHandler() { - if (upload_thread_started_ && upload_thread_) { - upload_thread_->Stop(); + if (cached_writer_) { + cached_writer_->Close(); } - prune_thread_->Stop(); + UpdatePruneAndUploadThreads(false); } bool InProcessHandler::Initialize( const base::FilePath& database, const std::string& url, - const std::map& annotations, - const IOSSystemDataCollector& system_data) { + const std::map& annotations) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); annotations_ = annotations; database_ = CrashReportDatabase::Initialize(database); @@ -72,7 +79,7 @@ bool InProcessHandler::Initialize( return false; } bundle_identifier_and_seperator_ = - system_data.BundleIdentifier() + kBundleSeperator; + system_data_.BundleIdentifier() + kBundleSeperator; if (!url.empty()) { // TODO(scottmg): options.rate_limit should be removed when we have a @@ -96,36 +103,55 @@ bool InProcessHandler::Initialize( if (!CreateDirectory(base_dir_)) return false; + bool is_app_extension = system_data_.IsExtension(); prune_thread_.reset(new PruneIntermediateDumpsAndCrashReportsThread( database_.get(), PruneCondition::GetDefault(), base_dir_, bundle_identifier_and_seperator_, - system_data.IsExtension())); - prune_thread_->Start(); + is_app_extension)); + if (is_app_extension || system_data_.IsApplicationActive()) + prune_thread_->Start(); - if (!OpenNewFile()) + if (!is_app_extension) { + system_data_.SetActiveApplicationCallback([this](bool active) { + dispatch_async( + dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + UpdatePruneAndUploadThreads(active); + }); + }); + } + + base::FilePath cached_writer_path = NewLockedFilePath(); + cached_writer_ = CreateWriterWithPath(cached_writer_path); + if (!cached_writer_.get()) return false; + // Cache the locked and unlocked path here so no allocations are needed during + // any exceptions. + cached_writer_path_ = cached_writer_path.value(); + cached_writer_unlocked_path_ = + cached_writer_path.RemoveFinalExtension().value(); INITIALIZATION_STATE_SET_VALID(initialized_); return true; } -void InProcessHandler::DumpExceptionFromSignal( - const IOSSystemDataCollector& system_data, - siginfo_t* siginfo, - ucontext_t* context) { +void InProcessHandler::DumpExceptionFromSignal(siginfo_t* siginfo, + ucontext_t* context) { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - { - ScopedReport report(writer_.get(), system_data, annotations_); - InProcessIntermediateDumpHandler::WriteExceptionFromSignal( - writer_.get(), system_data, siginfo, context); + ScopedLockedWriter writer(GetCachedWriter(), + cached_writer_path_.c_str(), + cached_writer_unlocked_path_.c_str()); + if (!writer.GetWriter()) { + CRASHPAD_RAW_LOG("Cannot DumpExceptionFromSignal without writer"); + return; } - PostReportCleanup(); + ScopedReport report(writer.GetWriter(), system_data_, annotations_); + InProcessIntermediateDumpHandler::WriteExceptionFromSignal( + writer.GetWriter(), system_data_, siginfo, context); } void InProcessHandler::DumpExceptionFromMachException( - const IOSSystemDataCollector& system_data, exception_behavior_t behavior, thread_t thread, exception_type_t exception, @@ -135,35 +161,97 @@ void InProcessHandler::DumpExceptionFromMachException( ConstThreadState old_state, mach_msg_type_number_t old_state_count) { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - { - ScopedReport report(writer_.get(), system_data, annotations_); - InProcessIntermediateDumpHandler::WriteExceptionFromMachException( - writer_.get(), - behavior, - thread, - exception, - code, - code_count, - flavor, - old_state, - old_state_count); + ScopedLockedWriter writer(GetCachedWriter(), + cached_writer_path_.c_str(), + cached_writer_unlocked_path_.c_str()); + if (!writer.GetWriter()) { + CRASHPAD_RAW_LOG("Cannot DumpExceptionFromMachException without writer"); + return; } - PostReportCleanup(); + + if (mach_exception_callback_for_testing_) { + mach_exception_callback_for_testing_(); + } + + ScopedReport report(writer.GetWriter(), system_data_, annotations_); + InProcessIntermediateDumpHandler::WriteExceptionFromMachException( + writer.GetWriter(), + behavior, + thread, + exception, + code, + code_count, + flavor, + old_state, + old_state_count); } -void InProcessHandler::DumpExceptionFromNSExceptionFrames( - const IOSSystemDataCollector& system_data, +void InProcessHandler::DumpExceptionFromNSExceptionWithFrames( const uint64_t* frames, const size_t num_frames) { - { - ScopedReport report( - writer_.get(), system_data, annotations_, frames, num_frames); - InProcessIntermediateDumpHandler::WriteExceptionFromNSException( - writer_.get()); + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + ScopedLockedWriter writer(GetCachedWriter(), + cached_writer_path_.c_str(), + cached_writer_unlocked_path_.c_str()); + if (!writer.GetWriter()) { + CRASHPAD_RAW_LOG( + "Cannot DumpExceptionFromNSExceptionWithFrames without writer"); + return; } - PostReportCleanup(); + ScopedReport report( + writer.GetWriter(), system_data_, annotations_, frames, num_frames); + InProcessIntermediateDumpHandler::WriteExceptionFromNSException( + writer.GetWriter()); } +bool InProcessHandler::DumpExceptionFromSimulatedMachException( + const NativeCPUContext* context, + exception_type_t exception, + base::FilePath* path) { + base::FilePath locked_path = NewLockedFilePath(); + *path = locked_path.RemoveFinalExtension(); + return DumpExceptionFromSimulatedMachExceptionAtPath( + context, exception, locked_path); +} + +bool InProcessHandler::DumpExceptionFromSimulatedMachExceptionAtPath( + const NativeCPUContext* context, + exception_type_t exception, + const base::FilePath& path) { + // This does not use the cached writer. It's expected that simulated + // exceptions can be called multiple times and there is no expectation that + // the application is in an unsafe state, or will be terminated after this + // call. + std::unique_ptr unsafe_writer = + CreateWriterWithPath(path); + base::FilePath writer_path_unlocked = path.RemoveFinalExtension(); + ScopedLockedWriter writer(unsafe_writer.get(), + path.value().c_str(), + writer_path_unlocked.value().c_str()); + if (!writer.GetWriter()) { + CRASHPAD_RAW_LOG( + "Cannot DumpExceptionFromSimulatedMachExceptionAtPath without writer"); + return false; + } + ScopedReport report(writer.GetWriter(), system_data_, annotations_); + InProcessIntermediateDumpHandler::WriteExceptionFromMachException( + writer.GetWriter(), + MACH_EXCEPTION_CODES, + mach_thread_self(), + exception, + kEmulatedMachExceptionCodes, + std::size(kEmulatedMachExceptionCodes), + MACHINE_THREAD_STATE, + reinterpret_cast(context), + MACHINE_THREAD_STATE_COUNT); + return true; +} + +bool InProcessHandler::MoveIntermediateDumpAtPathToPending( + const base::FilePath& path) { + base::FilePath new_path_unlocked = NewLockedFilePath().RemoveFinalExtension(); + return MoveFileOrDirectory(path, new_path_unlocked); +} void InProcessHandler::ProcessIntermediateDumps( const std::map& annotations) { INITIALIZATION_STATE_DCHECK_VALID(initialized_); @@ -184,9 +272,36 @@ void InProcessHandler::ProcessIntermediateDump( } void InProcessHandler::StartProcessingPendingReports() { - if (!upload_thread_started_ && upload_thread_) { - upload_thread_->Start(); - upload_thread_started_ = true; + if (!upload_thread_) + return; + + upload_thread_enabled_ = true; + + // This may be a no-op if IsApplicationActive is false, as it is not safe to + // start the upload thread when in the background (due to the potential for + // flocked files in shared containers). + // TODO(crbug.com/crashpad/400): Consider moving prune and upload thread to + // BackgroundTasks and/or NSURLSession. This might allow uploads to continue + // in the background. + UpdatePruneAndUploadThreads(system_data_.IsApplicationActive()); +} + +void InProcessHandler::UpdatePruneAndUploadThreads(bool active) { + base::AutoLock lock_owner(prune_and_upload_lock_); + // TODO(crbug.com/crashpad/400): Consider moving prune and upload thread to + // BackgroundTasks and/or NSURLSession. This might allow uploads to continue + // in the background. + if (active) { + if (!prune_thread_->is_running()) + prune_thread_->Start(); + if (upload_thread_enabled_ && !upload_thread_->is_running()) { + upload_thread_->Start(); + } + } else { + if (prune_thread_->is_running()) + prune_thread_->Stop(); + if (upload_thread_enabled_ && upload_thread_->is_running()) + upload_thread_->Stop(); } } @@ -198,6 +313,7 @@ void InProcessHandler::SaveSnapshot( if (database_status != CrashReportDatabase::kNoError) { Metrics::ExceptionCaptureResult( Metrics::CaptureResult::kPrepareNewCrashReportFailed); + return; } process_snapshot.SetReportID(new_report->ReportID()); @@ -212,6 +328,7 @@ void InProcessHandler::SaveSnapshot( if (!minidump.WriteEverything(new_report->Writer())) { Metrics::ExceptionCaptureResult( Metrics::CaptureResult::kMinidumpWriteFailed); + return; } UUID uuid; database_status = @@ -219,6 +336,7 @@ void InProcessHandler::SaveSnapshot( if (database_status != CrashReportDatabase::kNoError) { Metrics::ExceptionCaptureResult( Metrics::CaptureResult::kFinishedWritingCrashReportFailed); + return; } if (upload_thread_) { @@ -243,6 +361,7 @@ std::vector InProcessHandler::PendingFiles() { // intermediate dumps into never getting processed. std::vector other_files; + base::FilePath cached_writer_path(cached_writer_path_); while ((result = reader.NextFile(&file)) == DirectoryReader::Result::kSuccess) { // Don't try to process files marked as 'locked' from a different bundle id. @@ -254,9 +373,9 @@ std::vector InProcessHandler::PendingFiles() { continue; } - // Never process the current file. + // Never process the current cached writer path. file = base_dir_.Append(file); - if (file == current_file_) + if (file == cached_writer_path) continue; // Otherwise, include any other unlocked, or locked files matching @@ -277,35 +396,51 @@ std::vector InProcessHandler::PendingFiles() { return files; } -InProcessHandler::ScopedAlternateWriter::ScopedAlternateWriter( - InProcessHandler* handler) - : handler_(handler) {} +IOSIntermediateDumpWriter* InProcessHandler::GetCachedWriter() { + static_assert( + std::atomic::is_always_lock_free, + "std::atomic_compare_exchange_strong uint64_t may not be signal-safe"); + uint64_t thread_self; + // This is only safe when passing pthread_self(), otherwise this can lock. + pthread_threadid_np(pthread_self(), &thread_self); + uint64_t expected = 0; + if (!std::atomic_compare_exchange_strong( + &exception_thread_id_, &expected, thread_self)) { + if (expected == thread_self) { + // Another exception came in from this thread, which means it's likely + // that our own handler crashed. We could open up a new intermediate dump + // and try to save this dump, but we could end up endlessly writing dumps. + // Instead, give up. + } else { + // Another thread is handling a crash. Sleep forever. + while (1) { + sleep(std::numeric_limits::max()); + } + } + return nullptr; + } -bool InProcessHandler::ScopedAlternateWriter::Open() { + return cached_writer_.get(); +} + +std::unique_ptr +InProcessHandler::CreateWriterWithPath(const base::FilePath& writer_path) { + std::unique_ptr writer = + std::make_unique(); + if (!writer->Open(writer_path)) { + DLOG(ERROR) << "Unable to open intermediate dump file: " + << writer_path.value(); + return nullptr; + } + return writer; +} + +const base::FilePath InProcessHandler::NewLockedFilePath() { UUID uuid; uuid.InitializeWithNew(); - const std::string uuid_string = uuid.ToString(); - return OpenAtPath(handler_->base_dir_.Append(uuid_string)); -} - -bool InProcessHandler::ScopedAlternateWriter::OpenAtPath( - const base::FilePath& path) { - path_ = path; - handler_->SetOpenNewFileAfterReport(false); - original_writer_ = handler_->GetWriter(); - auto writer = std::make_unique(); - if (!writer->Open(path_)) { - DLOG(ERROR) << "Unable to open alternate intermediate dump file: " - << path_.value(); - return false; - } - handler_->SetWriter(std::move(writer)); - return true; -} - -InProcessHandler::ScopedAlternateWriter::~ScopedAlternateWriter() { - handler_->SetWriter(std::move(original_writer_)); - handler_->SetOpenNewFileAfterReport(true); + const std::string file_string = + bundle_identifier_and_seperator_ + uuid.ToString() + kLockedExtension; + return base_dir_.Append(file_string); } InProcessHandler::ScopedReport::ScopedReport( @@ -318,6 +453,7 @@ InProcessHandler::ScopedReport::ScopedReport( frames_(frames), num_frames_(num_frames), rootMap_(writer) { + DCHECK(writer); InProcessIntermediateDumpHandler::WriteHeader(writer); InProcessIntermediateDumpHandler::WriteProcessInfo(writer, annotations); InProcessIntermediateDumpHandler::WriteSystemInfo(writer, system_data); @@ -331,34 +467,24 @@ InProcessHandler::ScopedReport::~ScopedReport() { InProcessIntermediateDumpHandler::WriteModuleInfo(writer_); } -bool InProcessHandler::OpenNewFile() { - if (!current_file_.empty()) { - // Remove .lock extension so this dump can be processed on next run by this - // client, or a client with a different bundle id that can access this dump. - base::FilePath new_path = current_file_.RemoveFinalExtension(); - MoveFileOrDirectory(current_file_, new_path); - } - UUID uuid; - uuid.InitializeWithNew(); - const std::string file_string = - bundle_identifier_and_seperator_ + uuid.ToString() + kLockedExtension; - current_file_ = base_dir_.Append(file_string); - writer_ = std::make_unique(); - if (!writer_->Open(current_file_)) { - DLOG(ERROR) << "Unable to open intermediate dump file: " - << current_file_.value(); - return false; - } - return true; -} +InProcessHandler::ScopedLockedWriter::ScopedLockedWriter( + IOSIntermediateDumpWriter* writer, + const char* writer_path, + const char* writer_unlocked_path) + : writer_path_(writer_path), + writer_unlocked_path_(writer_unlocked_path), + writer_(writer) {} -void InProcessHandler::PostReportCleanup() { - if (writer_) { - writer_->Close(); - writer_.reset(); +InProcessHandler::ScopedLockedWriter::~ScopedLockedWriter() { + if (!writer_) + return; + + writer_->Close(); + if (rename(writer_path_, writer_unlocked_path_) != 0) { + CRASHPAD_RAW_LOG("Could not remove locked extension."); + CRASHPAD_RAW_LOG(writer_path_); + CRASHPAD_RAW_LOG(writer_unlocked_path_); } - if (open_new_file_after_report_) - OpenNewFile(); } } // namespace internal diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.h b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.h index d94f19e7e6..0e6b70b3c1 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.h +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler.h @@ -12,18 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include #include +#include #include #include #include #include "base/files/file_path.h" +#include "base/synchronization/lock.h" #include "client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.h" #include "handler/crash_report_upload_thread.h" #include "snapshot/ios/process_snapshot_ios_intermediate_dump.h" #include "util/ios/ios_intermediate_dump_writer.h" #include "util/ios/ios_system_data_collector.h" +#include "util/misc/capture_context.h" #include "util/misc/initialization_state_dcheck.h" namespace crashpad { @@ -46,28 +50,28 @@ class InProcessHandler { //! \param[in] database The path to a Crashpad database. //! \param[in] url The URL of an upload server. //! \param[in] annotations Process annotations to set in each crash report. - //! \param[in] system_data An object containing various system data points. //! \return `true` if a handler to a pending intermediate dump could be //! opened. bool Initialize(const base::FilePath& database, const std::string& url, - const std::map& annotations, - const IOSSystemDataCollector& system_data); + const std::map& annotations); //! \brief Generate an intermediate dump from a signal handler exception. + //! Writes the dump with the cached writer does not allow concurrent + //! exceptions to be written. It is expected the system will terminate + //! the application after this call. //! - //! \param[in] system_data An object containing various system data points. //! \param[in] siginfo A pointer to a `siginfo_t` object received by a signal //! handler. //! \param[in] context A pointer to a `ucontext_t` object received by a //! signal. - void DumpExceptionFromSignal(const IOSSystemDataCollector& system_data, - siginfo_t* siginfo, - ucontext_t* context); + void DumpExceptionFromSignal(siginfo_t* siginfo, ucontext_t* context); - //! \brief Generate an intermediate dump from a mach exception. + //! \brief Generate an intermediate dump from a mach exception. Writes the + //! dump with the cached writer does not allow concurrent exceptions to be + //! written. It is expected the system will terminate the application + //! after this call. //! - //! \param[in] system_data An object containing various system data points. //! \param[in] behavior //! \param[in] thread //! \param[in] exception @@ -76,8 +80,7 @@ class InProcessHandler { //! \param[in,out] flavor //! \param[in] old_state //! \param[in] old_state_count - void DumpExceptionFromMachException(const IOSSystemDataCollector& system_data, - exception_behavior_t behavior, + void DumpExceptionFromMachException(exception_behavior_t behavior, thread_t thread, exception_type_t exception, const mach_exception_data_type_t* code, @@ -91,15 +94,48 @@ class InProcessHandler { //! When the ObjcExceptionPreprocessor does not detect an NSException as it is //! thrown, the last-chance uncaught exception handler passes a list of call //! stack frame addresses. Record them in the intermediate dump so a minidump - //! with a 'fake' call stack is generated. + //! with a 'fake' call stack is generated. Writes the dump with the cached + //! writer does not allow concurrent exceptions to be written. It is expected + //! the system will terminate the application after this call. + //! - //! \param[in] system_data An object containing various system data points. //! \param[in] frames An array of call stack frame addresses. //! \param[in] num_frames The number of frames in |frames|. - void DumpExceptionFromNSExceptionFrames( - const IOSSystemDataCollector& system_data, - const uint64_t* frames, - const size_t num_frames); + void DumpExceptionFromNSExceptionWithFrames(const uint64_t* frames, + const size_t num_frames); + + //! \brief Generate a simulated intermediate dump similar to a Mach exception + //! in the same base directory as other exceptions. Does not use the + //! cached writer. + //! + //! \param[in] context A pointer to a NativeCPUContext object for this + //! simulated exception. + //! \param[in] exception + //! \param[out] path The path of the intermediate dump generated. + //! \return `true` if the pending intermediate dump could be written. + bool DumpExceptionFromSimulatedMachException(const NativeCPUContext* context, + exception_type_t exception, + base::FilePath* path); + + //! \brief Generate a simulated intermediate dump similar to a Mach exception + //! at a specific path. Does not use the cached writer. + //! + //! \param[in] context A pointer to a NativeCPUContext object for this + //! simulated exception. + //! \param[in] exception + //! \param[in] path Path to where the intermediate dump should be written. + //! \return `true` if the pending intermediate dump could be written. + bool DumpExceptionFromSimulatedMachExceptionAtPath( + const NativeCPUContext* context, + exception_type_t exception, + const base::FilePath& path); + + //! \brief Moves an intermediate dump to the pending directory. This is meant + //! to be used by the UncaughtExceptionHandler, when NSException caught + //! by the preprocessor matches the UncaughtExceptionHandler. + //! + //! \param[in] path Path to the specific intermediate dump. + bool MoveIntermediateDumpAtPathToPending(const base::FilePath& path); //! \brief Requests that the handler convert all intermediate dumps into //! minidumps and trigger an upload if possible. @@ -121,34 +157,11 @@ class InProcessHandler { //! pending reports. void StartProcessingPendingReports(); - //! \brief Helper that swaps out the InProcessHandler's |writer_| with an - //! alternate writer so DumpWithContext does not interfere with the - //! |writer_| created on startup. This is useful for -DumpWithoutCrash, - //! which may write to an alternate location. - class ScopedAlternateWriter { - public: - ScopedAlternateWriter(InProcessHandler* handler); - ~ScopedAlternateWriter(); - ScopedAlternateWriter(const ScopedAlternateWriter&) = delete; - ScopedAlternateWriter& operator=(const ScopedAlternateWriter&) = delete; - //! \brief Open's an alternate dump writer in the same directory as the - //! default InProcessHandler's dump writer, so the file will be - //! processed with -ProcessIntermediateDumps() - bool Open(); - - //! \brief Open's an alternate dump writer in the client provided |path|. - //! The file will only be processed by calling - //! ProcessIntermediateDump(path) - bool OpenAtPath(const base::FilePath& path); - - //! \brief The path of the alternate dump writer. - const base::FilePath& path() { return path_; } - - private: - InProcessHandler* handler_; - std::unique_ptr original_writer_; - base::FilePath path_; - }; + //! \brief Inject a callback into Mach handling. Intended to be used by + //! tests to trigger a reentrant exception. + void SetMachExceptionCallbackForTesting(void (*callback)()) { + mach_exception_callback_for_testing_ = callback; + } private: //! \brief Helper to start and end intermediate reports. @@ -170,38 +183,74 @@ class InProcessHandler { IOSIntermediateDumpWriter::ScopedRootMap rootMap_; }; - std::unique_ptr GetWriter() { - return std::move(writer_); - } + //! \brief Helper to manage closing the intermediate dump writer and unlocking + //! the dump file (renaming the file) after the report is written. + class ScopedLockedWriter { + public: + ScopedLockedWriter(IOSIntermediateDumpWriter* writer, + const char* writer_path, + const char* writer_unlocked_path); - void SetWriter(std::unique_ptr writer) { - writer_ = std::move(writer); - } + //! \brief Close the writer_ and rename to the file with path without the + //! .locked extension. + ~ScopedLockedWriter(); - void SetOpenNewFileAfterReport(bool open_new_file_after_report) { - open_new_file_after_report_ = open_new_file_after_report; - } + ScopedLockedWriter(const ScopedLockedWriter&) = delete; + ScopedLockedWriter& operator=(const ScopedLockedWriter&) = delete; + IOSIntermediateDumpWriter* GetWriter() { return writer_; } + + private: + const char* writer_path_; + const char* writer_unlocked_path_; + IOSIntermediateDumpWriter* writer_; + }; + + //! \brief Manage the prune and upload thread when the active state changes. + void UpdatePruneAndUploadThreads(bool active); + + //! \brief Writes a minidump to the Crashpad database from the + //! \a process_snapshot, and triggers the upload_thread_ if started. void SaveSnapshot(ProcessSnapshotIOSIntermediateDump& process_snapshot); - // Process a maximum of 20 pending intermediate dumps. Dumps named with our - // bundle id get first priority to prevent spamming. + //! \brief Process a maximum of 20 pending intermediate dumps. Dumps named + //! with our bundle id get first priority to prevent spamming. std::vector PendingFiles(); - bool OpenNewFile(); - void PostReportCleanup(); + //! \brief Lock access to the cached intermediate dump writer from + //! concurrent signal, Mach exception and uncaught NSExceptions so that + //! the first exception wins. If the same thread triggers another + //! reentrant exception, ignore it. If a different thread triggers a + //! concurrent exception, sleep indefinitely. + IOSIntermediateDumpWriter* GetCachedWriter(); - bool upload_thread_started_ = false; - bool open_new_file_after_report_ = true; + //! \brief Open a new intermediate dump writer from \a writer_path. + std::unique_ptr CreateWriterWithPath( + const base::FilePath& writer_path); + + //! \brief Generates a new file path to be used by an intermediate dump + //! writer built from base_dir_,, bundle_identifier_and_seperator_, a new + //! UUID, with a .locked extension. + const base::FilePath NewLockedFilePath(); + + // Intended to be used by tests triggering a reentrant exception. Called + // in DumpExceptionFromMachException after aquiring the cached_writer_. + void (*mach_exception_callback_for_testing_)() = nullptr; + + // Used to synchronize access to UpdatePruneAndUploadThreads(). + base::Lock prune_and_upload_lock_; + std::atomic_bool upload_thread_enabled_ = false; std::map annotations_; base::FilePath base_dir_; - base::FilePath current_file_; - std::unique_ptr writer_; - std::unique_ptr alternate_mach_writer_; + std::string cached_writer_path_; + std::string cached_writer_unlocked_path_; + std::unique_ptr cached_writer_; + std::atomic exception_thread_id_ = 0; std::unique_ptr upload_thread_; std::unique_ptr prune_thread_; std::unique_ptr database_; std::string bundle_identifier_and_seperator_; + IOSSystemDataCollector system_data_; InitializationStateDcheck initialized_; }; diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler_test.cc b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler_test.cc index d7dfc05304..110d86c759 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler_test.cc +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_handler_test.cc @@ -36,8 +36,7 @@ class InProcessHandlerTest : public testing::Test { // testing::Test: void SetUp() override { - ASSERT_TRUE( - in_process_handler_.Initialize(temp_dir_.path(), "", {}, system_data_)); + ASSERT_TRUE(in_process_handler_.Initialize(temp_dir_.path(), "", {})); pending_dir_ = temp_dir_.path().Append("pending-serialized-ios-dump"); bundle_identifier_and_seperator_ = system_data_.BundleIdentifier() + "@"; } diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc index 12dcf2b49f..e7e9003e3b 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler.cc @@ -21,7 +21,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "build/build_config.h" #include "snapshot/snapshot_constants.h" #include "util/ios/ios_intermediate_dump_writer.h" @@ -428,7 +429,7 @@ void CaptureMemoryPointedToByThreadState(IOSIntermediateDumpWriter* writer, MaybeCaptureMemoryAround(writer, thread_state.__rip); #elif defined(ARCH_CPU_ARM_FAMILY) MaybeCaptureMemoryAround(writer, thread_state.__pc); - for (size_t i = 0; i < base::size(thread_state.__x); ++i) { + for (size_t i = 0; i < std::size(thread_state.__x); ++i) { MaybeCaptureMemoryAround(writer, thread_state.__x[i]); } #endif @@ -598,7 +599,7 @@ void InProcessIntermediateDumpHandler::WriteProcessInfo( kinfo_proc kern_proc_info; int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; size_t len = sizeof(kern_proc_info); - if (sysctl(mib, base::size(mib), &kern_proc_info, &len, nullptr, 0) == 0) { + if (sysctl(mib, std::size(mib), &kern_proc_info, &len, nullptr, 0) == 0) { WriteProperty( writer, IntermediateDumpKey::kPID, &kern_proc_info.kp_proc.p_pid); WriteProperty(writer, @@ -646,7 +647,7 @@ void InProcessIntermediateDumpHandler::WriteProcessInfo( IntermediateDumpKey::kSystemTime, &task_thread_times.system_time); } else { - CRASHPAD_RAW_LOG("task_info task_basic_info"); + CRASHPAD_RAW_LOG("task_info thread_times_info"); } if (!annotations.empty()) { @@ -810,6 +811,22 @@ void InProcessIntermediateDumpHandler::WriteThreadInfo( CRASHPAD_RAW_LOG_ERROR(kr, "thread_info::THREAD_BASIC_INFO"); } + thread_extended_info extended_info; + count = THREAD_EXTENDED_INFO_COUNT; + kr = thread_info(thread, + THREAD_EXTENDED_INFO, + reinterpret_cast(&extended_info), + &count); + if (kr == KERN_SUCCESS) { + WritePropertyBytes( + writer, + IntermediateDumpKey::kThreadName, + reinterpret_cast(extended_info.pth_name), + strnlen(extended_info.pth_name, sizeof(extended_info.pth_name))); + } else { + CRASHPAD_RAW_LOG_ERROR(kr, "thread_info::THREAD_EXTENDED_INFO"); + } + thread_precedence_policy precedence; count = THREAD_PRECEDENCE_POLICY_COUNT; boolean_t get_default = FALSE; @@ -962,10 +979,12 @@ void InProcessIntermediateDumpHandler::WriteModuleInfo( return; } - WriteProperty(writer, - IntermediateDumpKey::kName, - image->imageFilePath, - strlen(image->imageFilePath)); + if (image->imageFilePath) { + WriteProperty(writer, + IntermediateDumpKey::kName, + image->imageFilePath, + strlen(image->imageFilePath)); + } uint64_t address = FromPointerCast(image->imageLoadAddress); WriteProperty(writer, IntermediateDumpKey::kAddress, &address); WriteProperty( @@ -975,7 +994,12 @@ void InProcessIntermediateDumpHandler::WriteModuleInfo( { IOSIntermediateDumpWriter::ScopedArrayMap modules(writer); - WriteProperty(writer, IntermediateDumpKey::kName, image_infos->dyldPath); + if (image_infos->dyldPath) { + WriteProperty(writer, + IntermediateDumpKey::kName, + image_infos->dyldPath, + strlen(image_infos->dyldPath)); + } uint64_t address = FromPointerCast(image_infos->dyldImageLoadAddress); WriteProperty(writer, IntermediateDumpKey::kAddress, &address); diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler_test.cc b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler_test.cc index b79f93f67b..f1d8a546a5 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler_test.cc +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/in_process_intermediate_dump_handler_test.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/files/file_path.h" #include "build/build_config.h" #include "client/annotation.h" @@ -25,6 +26,7 @@ #include "client/simple_string_dictionary.h" #include "gtest/gtest.h" #include "snapshot/ios/process_snapshot_ios_intermediate_dump.h" +#include "test/scoped_set_thread_name.h" #include "test/scoped_temp_dir.h" #include "test/test_paths.h" #include "util/file/filesystem.h" @@ -48,6 +50,7 @@ class InProcessIntermediateDumpHandlerTest : public testing::Test { } void TearDown() override { + EXPECT_TRUE(writer_->Close()); writer_.reset(); EXPECT_FALSE(IsRegularFile(path_)); } @@ -74,7 +77,7 @@ class InProcessIntermediateDumpHandlerTest : public testing::Test { mach_thread_self(), kSimulatedException, code, - base::size(code), + std::size(code), MACHINE_THREAD_STATE, reinterpret_cast(&cpu_context), MACHINE_THREAD_STATE_COUNT); @@ -103,12 +106,18 @@ TEST_F(InProcessIntermediateDumpHandlerTest, TestSystem) { EXPECT_STREQ(system->CPUVendor().c_str(), "GenuineIntel"); #elif defined(ARCH_CPU_ARM64) EXPECT_EQ(system->GetCPUArchitecture(), kCPUArchitectureARM64); - utsname uts; - ASSERT_EQ(uname(&uts), 0); - EXPECT_STREQ(system->MachineDescription().c_str(), uts.machine); #else #error Port to your CPU architecture #endif +#if TARGET_OS_SIMULATOR + EXPECT_EQ(system->MachineDescription().substr(0, 13), + std::string("iOS Simulator")); +#elif TARGET_OS_IPHONE + utsname uts; + ASSERT_EQ(uname(&uts), 0); + EXPECT_STREQ(system->MachineDescription().c_str(), uts.machine); +#endif + EXPECT_EQ(system->GetOperatingSystem(), SystemSnapshot::kOperatingSystemIOS); } @@ -198,6 +207,8 @@ TEST_F(InProcessIntermediateDumpHandlerTest, TestAnnotations) { } TEST_F(InProcessIntermediateDumpHandlerTest, TestThreads) { + const ScopedSetThreadName scoped_set_thread_name("TestThreads"); + WriteReport(); internal::ProcessSnapshotIOSIntermediateDump process_snapshot; ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), {})); @@ -213,6 +224,7 @@ TEST_F(InProcessIntermediateDumpHandlerTest, TestThreads) { &count), 0); EXPECT_EQ(threads[0]->ThreadID(), identifier_info.thread_id); + EXPECT_EQ(threads[0]->ThreadName(), "TestThreads"); } TEST_F(InProcessIntermediateDumpHandlerTest, TestProcess) { diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.cc b/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.cc index d6cfe885d2..651b390775 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.cc +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.cc @@ -19,6 +19,7 @@ #include "client/prune_crash_reports.h" #include "util/file/directory_reader.h" #include "util/file/filesystem.h" +#include "util/ios/scoped_background_task.h" namespace crashpad { @@ -27,6 +28,9 @@ namespace { // The file extension used to indicate a file is locked. constexpr char kLockedExtension[] = ".locked"; +// Prune onces a day. +constexpr time_t prune_interval = 60 * 60 * 24; + // If the client finds a locked file matching it's own bundle id, unlock it // after 24 hours. constexpr time_t matching_bundle_locked_ttl = 60 * 60 * 24; @@ -95,11 +99,12 @@ PruneIntermediateDumpsAndCrashReportsThread:: base::FilePath pending_path, std::string bundle_identifier_and_seperator, bool is_extension) - : thread_(60 * 60 * 24, this), + : thread_(prune_interval, this), condition_(std::move(condition)), pending_path_(pending_path), bundle_identifier_and_seperator_(bundle_identifier_and_seperator), initial_work_delay_(is_extension ? extension_delay : app_delay), + last_start_time_(0), database_(database) {} PruneIntermediateDumpsAndCrashReportsThread:: @@ -115,8 +120,25 @@ void PruneIntermediateDumpsAndCrashReportsThread::Stop() { void PruneIntermediateDumpsAndCrashReportsThread::DoWork( const WorkerThread* thread) { + // This thread may be stopped and started a number of times throughout the + // lifetime of the process to prevent 0xdead10cc kills (see + // crbug.com/crashpad/400), but it should only run once per prune_interval + // after initial_work_delay_. + time_t now = time(nullptr); + if (now - last_start_time_ < prune_interval) + return; + last_start_time_ = now; + + internal::ScopedBackgroundTask scoper("PruneThread"); database_->CleanDatabase(60 * 60 * 24 * 3); + + // Here and below, respect Stop() being called after each task. + if (!thread_.is_running()) + return; PruneCrashReportDatabase(database_, condition_.get()); + + if (!thread_.is_running()) + return; if (!clean_old_intermediate_dumps_) { clean_old_intermediate_dumps_ = true; UnlockOldIntermediateDumps(pending_path_, bundle_identifier_and_seperator_); diff --git a/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.h b/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.h index b2764234c3..cc40980d50 100644 --- a/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.h +++ b/thirdparty/sentry-native/external/crashpad/client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.h @@ -84,6 +84,9 @@ class PruneIntermediateDumpsAndCrashReportsThread //! It is expected to only be called from the same thread that called Start(). void Stop() override; + //! \return `true` if the thread is running, `false` if it is not. + bool is_running() const { return thread_.is_running(); } + private: // WorkerThread::Delegate: void DoWork(const WorkerThread* thread) override; @@ -94,6 +97,7 @@ class PruneIntermediateDumpsAndCrashReportsThread std::string bundle_identifier_and_seperator_; bool clean_old_intermediate_dumps_; double initial_work_delay_; + time_t last_start_time_; CrashReportDatabase* database_; // weak }; diff --git a/thirdparty/sentry-native/external/crashpad/client/settings.cc b/thirdparty/sentry-native/external/crashpad/client/settings.cc index 3855b9b6a4..eef24f7149 100644 --- a/thirdparty/sentry-native/external/crashpad/client/settings.cc +++ b/thirdparty/sentry-native/external/crashpad/client/settings.cc @@ -20,12 +20,13 @@ #include "base/logging.h" #include "base/posix/eintr_wrapper.h" +#include "build/build_config.h" #include "util/file/filesystem.h" #include "util/numeric/in_range_cast.h" namespace crashpad { -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) Settings::ScopedLockedFileHandle::ScopedLockedFileHandle() : handle_(kInvalidFileHandle), lockfile_path_() { @@ -68,7 +69,36 @@ void Settings::ScopedLockedFileHandle::Destroy() { } } -#else // OS_FUCHSIA +#else // BUILDFLAG(IS_FUCHSIA) + +#if BUILDFLAG(IS_IOS) + +Settings::ScopedLockedFileHandle::ScopedLockedFileHandle( + const FileHandle& value) + : ScopedGeneric(value) { + ios_background_task_ = std::make_unique( + "ScopedLockedFileHandle"); +} + +Settings::ScopedLockedFileHandle::ScopedLockedFileHandle( + Settings::ScopedLockedFileHandle&& rvalue) { + ios_background_task_.reset(rvalue.ios_background_task_.release()); + reset(rvalue.release()); +} + +Settings::ScopedLockedFileHandle& Settings::ScopedLockedFileHandle::operator=( + Settings::ScopedLockedFileHandle&& rvalue) { + ios_background_task_.reset(rvalue.ios_background_task_.release()); + reset(rvalue.release()); + return *this; +} + +Settings::ScopedLockedFileHandle::~ScopedLockedFileHandle() { + // Call reset() to ensure the lock is released before the ios_background_task. + reset(); +} + +#endif // BUILDFLAG(IS_IOS) namespace internal { @@ -82,7 +112,7 @@ void ScopedLockedFileHandleTraits::Free(FileHandle handle) { } // namespace internal -#endif // OS_FUCHSIA +#endif // BUILDFLAG(IS_FUCHSIA) struct Settings::Data { static constexpr uint32_t kSettingsMagic = 'CPds'; @@ -193,7 +223,7 @@ Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle( FileLocking locking, const base::FilePath& file_path) { ScopedFileHandle scoped(file); -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) base::FilePath lockfile_path(file_path.value() + ".__lock__"); if (scoped.is_valid()) { ScopedFileHandle lockfile_scoped( @@ -206,6 +236,10 @@ Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle( } return ScopedLockedFileHandle(scoped.release(), base::FilePath()); #else + // It's important to create the ScopedLockedFileHandle before calling + // LoggingLockFile on iOS, so a ScopedBackgroundTask is created *before* + // the LoggingLockFile call below. + ScopedLockedFileHandle handle(kInvalidFileHandle); if (scoped.is_valid()) { if (LoggingLockFile( scoped.get(), locking, FileLockingBlocking::kBlocking) != @@ -213,7 +247,8 @@ Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle( scoped.reset(); } } - return ScopedLockedFileHandle(scoped.release()); + handle.reset(scoped.release()); + return handle; #endif } diff --git a/thirdparty/sentry-native/external/crashpad/client/settings.h b/thirdparty/sentry-native/external/crashpad/client/settings.h index d17f357ed4..8ad8a2b16f 100644 --- a/thirdparty/sentry-native/external/crashpad/client/settings.h +++ b/thirdparty/sentry-native/external/crashpad/client/settings.h @@ -17,8 +17,6 @@ #include -#include - #include "base/files/file_path.h" #include "base/scoped_generic.h" #include "build/build_config.h" @@ -26,6 +24,10 @@ #include "util/misc/initialization_state.h" #include "util/misc/uuid.h" +#if BUILDFLAG(IS_IOS) +#include "util/ios/scoped_background_task.h" +#endif // BUILDFLAG(IS_IOS) + namespace crashpad { namespace internal { @@ -125,7 +127,7 @@ class Settings { // and closes the file on destruction. Note that on Fuchsia, this handle DOES // NOT offer correct operation, only an attempt to DCHECK if racy behavior is // detected. -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) struct ScopedLockedFileHandle { public: ScopedLockedFileHandle(); @@ -155,10 +157,29 @@ class Settings { FileHandle handle_; base::FilePath lockfile_path_; }; -#else // OS_FUCHSIA +#elif BUILDFLAG(IS_IOS) + // iOS needs to use ScopedBackgroundTask anytime a file lock is used. + class ScopedLockedFileHandle + : public base::ScopedGeneric { + public: + using base::ScopedGeneric< + FileHandle, + internal::ScopedLockedFileHandleTraits>::ScopedGeneric; + + ScopedLockedFileHandle(const FileHandle& value); + ScopedLockedFileHandle(ScopedLockedFileHandle&& rvalue); + ScopedLockedFileHandle& operator=(ScopedLockedFileHandle&& rvalue); + + ~ScopedLockedFileHandle(); + + private: + std::unique_ptr ios_background_task_; + }; +#else using ScopedLockedFileHandle = base::ScopedGeneric; -#endif // OS_FUCHSIA +#endif // BUILDFLAG(IS_FUCHSIA) static ScopedLockedFileHandle MakeScopedLockedFileHandle( FileHandle file, FileLocking locking, diff --git a/thirdparty/sentry-native/external/crashpad/client/settings_test.cc b/thirdparty/sentry-native/external/crashpad/client/settings_test.cc index 5f13cfcca8..74a2014718 100644 --- a/thirdparty/sentry-native/external/crashpad/client/settings_test.cc +++ b/thirdparty/sentry-native/external/crashpad/client/settings_test.cc @@ -154,7 +154,7 @@ TEST_F(SettingsTest, UnlinkFile) { EXPECT_TRUE(settings()->SetUploadsEnabled(true)); EXPECT_TRUE(settings()->SetLastUploadAttemptTime(time(nullptr))); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) EXPECT_EQ(_wunlink(settings_path().value().c_str()), 0) << ErrnoMessage("_wunlink"); #else diff --git a/thirdparty/sentry-native/external/crashpad/client/simple_string_dictionary_test.cc b/thirdparty/sentry-native/external/crashpad/client/simple_string_dictionary_test.cc index cc025a1741..1b4f8d2b5a 100644 --- a/thirdparty/sentry-native/external/crashpad/client/simple_string_dictionary_test.cc +++ b/thirdparty/sentry-native/external/crashpad/client/simple_string_dictionary_test.cc @@ -132,8 +132,10 @@ TEST(SimpleStringDictionary, Iterator) { // Set a bunch of key/value pairs like key0/value0, key1/value1, ... for (int i = 0; i < kPartitionIndex; ++i) { - sprintf(key, "key%d", i); - sprintf(value, "value%d", i); + ASSERT_LT(snprintf(key, sizeof(key), "key%d", i), + static_cast(sizeof(key))); + ASSERT_LT(snprintf(value, sizeof(value), "value%d", i), + static_cast(sizeof(value))); dict.SetKeyValue(key, value); } expected_dictionary_size = kPartitionIndex; @@ -152,8 +154,10 @@ TEST(SimpleStringDictionary, Iterator) { // Set some more key/value pairs like key59/value59, key60/value60, ... for (int i = kPartitionIndex; i < kDictionaryCapacity; ++i) { - sprintf(key, "key%d", i); - sprintf(value, "value%d", i); + ASSERT_LT(snprintf(key, sizeof(key), "key%d", i), + static_cast(sizeof(key))); + ASSERT_LT(snprintf(value, sizeof(value), "value%d", i), + static_cast(sizeof(value))); dict.SetKeyValue(key, value); } expected_dictionary_size += kDictionaryCapacity - kPartitionIndex; diff --git a/thirdparty/sentry-native/external/crashpad/client/simulate_crash.h b/thirdparty/sentry-native/external/crashpad/client/simulate_crash.h index d01e1682d7..62a2ff9384 100644 --- a/thirdparty/sentry-native/external/crashpad/client/simulate_crash.h +++ b/thirdparty/sentry-native/external/crashpad/client/simulate_crash.h @@ -17,13 +17,13 @@ #include "build/build_config.h" -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) #include "client/simulate_crash_mac.h" -#elif defined(OS_IOS) +#elif BUILDFLAG(IS_IOS) #include "client/simulate_crash_ios.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include "client/simulate_crash_win.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "client/simulate_crash_linux.h" #endif diff --git a/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac.cc b/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac.cc index 48d81a0d9c..86f4043d6e 100644 --- a/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac.cc +++ b/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac.cc @@ -17,8 +17,9 @@ #include #include +#include + #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/mac/mach_logging.h" #include "base/mac/scoped_mach_port.h" @@ -207,7 +208,7 @@ void SimulateCrash(const NativeCPUContext& cpu_context) { base::mac::ScopedMachSendRight thread(mach_thread_self()); exception_type_t exception = kMachExceptionSimulated; mach_exception_data_type_t codes[] = {0, 0}; - mach_msg_type_number_t code_count = base::size(codes); + mach_msg_type_number_t code_count = std::size(codes); // Look up the handler for EXC_CRASH exceptions in the same way that the // kernel would: try a thread handler, then a task handler, and finally a host @@ -229,7 +230,7 @@ void SimulateCrash(const NativeCPUContext& cpu_context) { bool success = false; for (size_t target_type_index = 0; - !success && target_type_index < base::size(kTargetTypes); + !success && target_type_index < std::size(kTargetTypes); ++target_type_index) { ExceptionPorts::ExceptionHandlerVector handlers; ExceptionPorts exception_ports(kTargetTypes[target_type_index], diff --git a/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac_test.cc b/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac_test.cc index f22b2a69de..ccd0267c31 100644 --- a/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac_test.cc +++ b/thirdparty/sentry-native/external/crashpad/client/simulate_crash_mac_test.cc @@ -18,7 +18,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gtest/gtest.h" @@ -370,13 +371,13 @@ TEST(SimulateCrash, SimulateCrash) { #endif }; - for (size_t target_index = 0; target_index < base::size(kTargets); + for (size_t target_index = 0; target_index < std::size(kTargets); ++target_index) { TestSimulateCrashMac::ExceptionPortsTarget target = kTargets[target_index]; SCOPED_TRACE(base::StringPrintf( "target_index %zu, target %d", target_index, target)); - for (size_t behavior_index = 0; behavior_index < base::size(kBehaviors); + for (size_t behavior_index = 0; behavior_index < std::size(kBehaviors); ++behavior_index) { exception_behavior_t behavior = kBehaviors[behavior_index]; SCOPED_TRACE(base::StringPrintf( @@ -390,7 +391,7 @@ TEST(SimulateCrash, SimulateCrash) { target, behavior, THREAD_STATE_NONE); test_simulate_crash_mac.Run(); } else { - for (size_t flavor_index = 0; flavor_index < base::size(kFlavors); + for (size_t flavor_index = 0; flavor_index < std::size(kFlavors); ++flavor_index) { thread_state_flavor_t flavor = kFlavors[flavor_index]; SCOPED_TRACE(base::StringPrintf( diff --git a/thirdparty/sentry-native/external/crashpad/compat/non_elf/elf.h b/thirdparty/sentry-native/external/crashpad/compat/non_elf/elf.h deleted file mode 100644 index 1245f16dd8..0000000000 --- a/thirdparty/sentry-native/external/crashpad/compat/non_elf/elf.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2019 The Crashpad Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef CRASHPAD_COMPAT_NON_ELF_ELF_H_ -#define CRASHPAD_COMPAT_NON_ELF_ELF_H_ - -#include "third_party/glibc/elf/elf.h" - -#endif // CRASHPAD_COMPAT_NON_ELF_ELF_H_ diff --git a/thirdparty/sentry-native/external/crashpad/compat/non_win/dbghelp.h b/thirdparty/sentry-native/external/crashpad/compat/non_win/dbghelp.h index 0d9852bb69..55fd47b98c 100644 --- a/thirdparty/sentry-native/external/crashpad/compat/non_win/dbghelp.h +++ b/thirdparty/sentry-native/external/crashpad/compat/non_win/dbghelp.h @@ -42,6 +42,15 @@ //! \sa MINIDUMP_LOCATION_DESCRIPTOR typedef uint32_t RVA; +//! \brief A 64-bit offset within a minidump file, relative to the start of its +//! MINIDUMP_HEADER. +//! +//! RVA stands for “relative virtual address”. Within a minidump file, RVAs are +//! used as pointers to link structures together. +//! +//! \sa MINIDUMP_LOCATION_DESCRIPTOR64 +typedef uint64_t RVA64; + //! \brief A pointer to a structure or union within a minidump file. struct __attribute__((packed, aligned(4))) MINIDUMP_LOCATION_DESCRIPTOR { //! \brief The size of the referenced structure or union, in bytes. @@ -52,6 +61,16 @@ struct __attribute__((packed, aligned(4))) MINIDUMP_LOCATION_DESCRIPTOR { RVA Rva; }; +//! \brief A 64-bit pointer to a structure or union within a minidump file. +struct __attribute__((packed, aligned(4))) MINIDUMP_LOCATION_DESCRIPTOR64 { + //! \brief The size of the referenced structure or union, in bytes. + uint64_t DataSize; + + //! \brief The 64-bit relative virtual address of the structure or union + //! within the minidump file. + RVA64 Rva; +}; + //! \brief A pointer to a snapshot of a region of memory contained within a //! minidump file. //! @@ -176,6 +195,9 @@ enum MINIDUMP_STREAM_TYPE { //! \brief The stream type for MINIDUMP_MEMORY_INFO_LIST. MemoryInfoListStream = 16, + //! \brief The stream type for MINIDUMP_THREAD_NAME_LIST. + ThreadNamesStream = 24, + //! \brief Values greater than this value will not be used by the system //! and can be used for custom user data streams. LastReservedStream = 0xffff, @@ -1080,6 +1102,27 @@ struct __attribute__((packed, aligned(4))) MINIDUMP_MEMORY_INFO_LIST { uint64_t NumberOfEntries; }; +//! \brief Contains the name of the thread with the given thread ID. +struct __attribute__((packed, aligned(4))) MINIDUMP_THREAD_NAME { + //! \brief The identifier of the thread. + uint32_t ThreadId; + + //! \brief RVA64 of a MINIDUMP_STRING containing the name of the thread. + RVA64 RvaOfThreadName; +}; + +//! \brief Variable-sized struct which contains a list of MINIDUMP_THREAD_NAME +//! structs. +struct __attribute__((packed, aligned(4))) MINIDUMP_THREAD_NAME_LIST { + //! \brief The number of MINIDUMP_THREAD_NAME structs following this field. + uint32_t NumberOfThreadNames; + + //! \brief A variably-sized array containing zero or more + //! MINIDUMP_THREAD_NAME structs. The length of the array is indicated by + //! the NumberOfThreadNames field in this struct. + struct MINIDUMP_THREAD_NAME ThreadNames[0]; +}; + //! \brief Minidump file type values for MINIDUMP_HEADER::Flags. These bits //! describe the types of data carried within a minidump file. enum MINIDUMP_TYPE { @@ -1100,6 +1143,11 @@ enum MINIDUMP_TYPE { //! MINIDUMP_MEMORY_DESCRIPTOR containing the 256 bytes centered around //! the exception address or the instruction pointer. MiniDumpNormal = 0x00000000, + + //! \brief A minidump with extended contexts. + //! + //! Contains Normal plus a MISC_INFO_5 structure describing the contexts. + MiniDumpWithAvxXStateContext = 0x00200000, }; #endif // CRASHPAD_COMPAT_NON_WIN_DBGHELP_H_ diff --git a/thirdparty/sentry-native/external/crashpad/compat/non_win/winnt.h b/thirdparty/sentry-native/external/crashpad/compat/non_win/winnt.h index f2ed6ace07..376e27cd7a 100644 --- a/thirdparty/sentry-native/external/crashpad/compat/non_win/winnt.h +++ b/thirdparty/sentry-native/external/crashpad/compat/non_win/winnt.h @@ -155,6 +155,17 @@ //! Architecture (253665-060), 13.4.2 “XSAVE Header”. #define MAXIMUM_XSTATE_FEATURES (64) +//! \anchor XSTATE_x +//! \name XSTATE_* +//! +//! \brief Offsets and constants for extended state. +//! \{ +#define XSTATE_COMPACTION_ENABLE (63) +#define XSTATE_COMPACTION_ENABLE_MASK (1ull << XSTATE_COMPACTION_ENABLE) +#define XSTATE_CET_U (11) +#define XSTATE_MASK_CET_U (1ull << XSTATE_CET_U) +//! \} + //! \brief The location of a single state component within an XSAVE area. struct XSTATE_FEATURE { //! \brief The location of a state component within a CPU-specific context diff --git a/thirdparty/sentry-native/external/crashpad/doc/developing.md b/thirdparty/sentry-native/external/crashpad/doc/developing.md index 60c4155360..a4017fb787 100644 --- a/thirdparty/sentry-native/external/crashpad/doc/developing.md +++ b/thirdparty/sentry-native/external/crashpad/doc/developing.md @@ -46,8 +46,9 @@ the `$PATH` environment variable: Windows](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/). * On Linux, obtain appropriate tools for C++ development through any appropriate means including the system’s package manager. On Debian and - Debian-based distributions, the `build-essential` and `zlib1g-dev` - packages should suffice. + Debian-based distributions, the `build-essential`, `zlib1g-dev`, and any + one of the `libcurl4-*-dev` packages such as `libcurl4-openssl-dev` should + suffice. * Chromium’s [depot_tools](https://www.chromium.org/developers/how-tos/depottools). * [Git](https://git-scm.com/). This is provided by Xcode on macOS, by diff --git a/thirdparty/sentry-native/external/crashpad/doc/support/generate_doxygen.py b/thirdparty/sentry-native/external/crashpad/doc/support/generate_doxygen.py index 577b51e596..7b28aa93d9 100644 --- a/thirdparty/sentry-native/external/crashpad/doc/support/generate_doxygen.py +++ b/thirdparty/sentry-native/external/crashpad/doc/support/generate_doxygen.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2017 The Crashpad Authors. All rights reserved. # diff --git a/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.cc b/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.cc index 3872e1142f..138cf80026 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.cc @@ -40,9 +40,13 @@ #include "util/net/url.h" #include "util/stdlib/map_insert.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include "handler/mac/file_limit_annotation.h" -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) + +#if BUILDFLAG(IS_IOS) +#include "util/ios/scoped_background_task.h" +#endif // BUILDFLAG(IS_IOS) namespace crashpad { @@ -51,7 +55,7 @@ namespace { // The number of seconds to wait between checking for pending reports. const int kRetryWorkIntervalSeconds = 15 * 60; -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) // The number of times to attempt to upload a pending report, repeated on // failure. Attempts will happen once per launch, once per call to // ReportPending(), and, if Options.watch_pending_reports is true, once every @@ -97,6 +101,10 @@ void CrashReportUploadThread::Stop() { } void CrashReportUploadThread::ProcessPendingReports() { +#if BUILDFLAG(IS_IOS) + internal::ScopedBackgroundTask scoper("CrashReportUploadThread"); +#endif // BUILDFLAG(IS_IOS) + std::vector known_report_uuids = known_pending_report_uuids_.Drain(); for (const UUID& report_uuid : known_report_uuids) { CrashReportDatabase::Report report; @@ -152,9 +160,9 @@ void CrashReportUploadThread::ProcessPendingReports() { void CrashReportUploadThread::ProcessPendingReport( const CrashReportDatabase::Report& report) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) RecordFileLimitAnnotation(); -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) Settings* const settings = database_->GetSettings(); @@ -172,10 +180,10 @@ void CrashReportUploadThread::ProcessPendingReport( if (ShouldRateLimitUpload(report)) return; -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) if (ShouldRateLimitRetry(report)) return; -#endif +#endif // BUILDFLAG(IS_IOS) std::unique_ptr upload_report; CrashReportDatabase::OperationStatus status = @@ -217,7 +225,7 @@ void CrashReportUploadThread::ProcessPendingReport( report.uuid, Metrics::CrashSkippedReason::kPrepareForUploadFailed); break; case UploadResult::kRetry: -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) if (upload_report->upload_attempts > kRetryAttempts) { upload_report.reset(); database_->SkipReportUpload(report.uuid, @@ -303,7 +311,13 @@ CrashReportUploadThread::UploadResult CrashReportUploadThread::UploadReport( } http_transport->SetBodyStream(http_multipart_builder.GetBodyStream()); // TODO(mark): The timeout should be configurable by the client. - http_transport->SetTimeout(60.0); // 1 minute. +#if BUILDFLAG(IS_IOS) + // iOS background assertions only last 30 seconds, keep the timeout shorter. + double timeout_seconds = 20; +#else + double timeout_seconds = 60; +#endif + http_transport->SetTimeout(timeout_seconds); std::string url = url_; if (options_.identify_client_via_url) { @@ -377,7 +391,7 @@ bool CrashReportUploadThread::ShouldRateLimitUpload( return false; } -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) bool CrashReportUploadThread::ShouldRateLimitRetry( const CrashReportDatabase::Report& report) { if (retry_uuid_time_map_.find(report.uuid) != retry_uuid_time_map_.end()) { diff --git a/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.h b/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.h index 7649ae0db4..2af958d7da 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.h +++ b/thirdparty/sentry-native/external/crashpad/handler/crash_report_upload_thread.h @@ -19,6 +19,7 @@ #include #include +#include "build/build_config.h" #include "client/crash_report_database.h" #include "util/misc/uuid.h" #include "util/stdlib/thread_safe_vector.h" @@ -107,6 +108,9 @@ class CrashReportUploadThread : public WorkerThread::Delegate, //! It is expected to only be called from the same thread that called Start(). void Stop() override; + //! \return `true` if the thread is running, `false` if it is not. + bool is_running() const { return thread_.is_running(); } + private: //! \brief The result code from UploadReport(). enum class UploadResult { @@ -186,7 +190,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate, //! upload attempts to be retried. bool ShouldRateLimitUpload(const CrashReportDatabase::Report& report); -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) //! \brief Rate-limit report retries. //! //! \param[in] report The crash report to process. @@ -206,7 +210,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate, const std::string url_; WorkerThread thread_; ThreadSafeVector known_pending_report_uuids_; -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) // This is not thread-safe, and only used by the worker thread. std::map retry_uuid_time_map_; #endif diff --git a/thirdparty/sentry-native/external/crashpad/handler/crashpad_handler_test_extended_handler.cc b/thirdparty/sentry-native/external/crashpad/handler/crashpad_handler_test_extended_handler.cc index 4abcacd50f..9901aba2af 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/crashpad_handler_test_extended_handler.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/crashpad_handler_test_extended_handler.cc @@ -19,7 +19,7 @@ #include "minidump/test/minidump_user_extension_stream_util.h" #include "tools/tool_support.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include #endif @@ -55,16 +55,16 @@ int ExtendedHandlerMain(int argc, char* argv[]) { } // namespace -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int main(int argc, char* argv[]) { return ExtendedHandlerMain(argc, argv); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) int wmain(int argc, wchar_t* argv[]) { return crashpad::ToolSupport::Wmain(argc, argv, &ExtendedHandlerMain); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) diff --git a/thirdparty/sentry-native/external/crashpad/handler/handler_main.cc b/thirdparty/sentry-native/external/crashpad/handler/handler_main.cc index f094e66c23..7c7cea8083 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/handler_main.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/handler_main.cc @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -28,7 +29,6 @@ #include #include "base/auto_reset.h" -#include "base/compiler_specific.h" #include "base/files/file_path.h" #include "base/files/scoped_file.h" #include "base/logging.h" @@ -61,13 +61,13 @@ #include "handler/linux/cros_crash_report_exception_handler.h" #endif -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include #include "handler/linux/crash_report_exception_handler.h" #include "handler/linux/exception_handler_server.h" #include "util/posix/signals.h" -#elif defined(OS_APPLE) +#elif BUILDFLAG(IS_APPLE) #include #include @@ -79,7 +79,7 @@ #include "util/mach/child_port_handshake.h" #include "util/posix/close_stdio.h" #include "util/posix/signals.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include "handler/win/crash_report_exception_handler.h" @@ -87,32 +87,42 @@ #include "util/win/handle.h" #include "util/win/initial_client_data.h" #include "util/win/session_end_watcher.h" -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) namespace crashpad { namespace { -#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ - defined(OS_ANDROID) || defined(OS_APPLE) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) #define ATTACHMENTS_SUPPORTED 1 -#endif // OS_WIN || OS_LINUX || OS_CHROMEOS || OS_ANDROID || OS_APPLE +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE) void Usage(const base::FilePath& me) { + // clang-format off fprintf(stderr, "Usage: %" PRFilePath " [OPTION]...\n" "Crashpad's exception handler server.\n" "\n" " --annotation=KEY=VALUE set a process annotation in each crash report\n" + // clang-format on #if defined(ATTACHMENTS_SUPPORTED) + // clang-format off " --attachment=FILE_PATH attach specified file to each crash report\n" " at the time of the crash\n" + // clang-format on #endif // ATTACHMENTS_SUPPORTED + // clang-format off " --database=PATH store the crash report database at PATH\n" -#if defined(OS_APPLE) + // clang-format on +#if BUILDFLAG(IS_APPLE) + // clang-format off " --handshake-fd=FD establish communication with the client over FD\n" -#endif // OS_APPLE -#if defined(OS_WIN) + // clang-format on +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_WIN) + // clang-format off " --initial-client-data=HANDLE_request_crash_dump,\n" " HANDLE_request_non_crash_dump,\n" " HANDLE_non_crash_dump_completed,\n" @@ -122,13 +132,20 @@ void Usage(const base::FilePath& me) { " Address_non_crash_exception_information,\n" " Address_debug_critical_section\n" " use precreated data to register initial client\n" -#endif // OS_WIN -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) + // clang-format on +#endif // BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + // clang-format off " --initial-client-fd=FD a socket connected to a client.\n" -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS -#if defined(OS_APPLE) + // clang-format on +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_APPLE) + // clang-format off " --mach-service=SERVICE register SERVICE with the bootstrap server\n" -#endif // OS_APPLE + // clang-format on +#endif // BUILDFLAG(IS_APPLE) + // clang-format off " --metrics-dir=DIR store metrics files in DIR (only in Chromium)\n" " --monitor-self run a second handler to catch crashes in the first\n" " --monitor-self-annotation=KEY=VALUE\n" @@ -141,18 +158,26 @@ void Usage(const base::FilePath& me) { " --no-periodic-tasks don't scan for new reports or prune the database\n" " --no-rate-limit don't rate limit crash uploads\n" " --no-upload-gzip don't use gzip compression when uploading\n" -#if defined(OS_ANDROID) + // clang-format on +#if BUILDFLAG(IS_ANDROID) + // clang-format off " --no-write-minidump-to-database\n" " don't write minidump to database\n" -#endif // OS_ANDROID -#if defined(OS_WIN) + // clang-format on +#endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_WIN) + // clang-format off " --pipe-name=PIPE communicate with the client over PIPE\n" -#endif // OS_WIN -#if defined(OS_APPLE) + // clang-format on +#endif // BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_APPLE) + // clang-format off " --reset-own-crash-exception-port-to-system-default\n" " reset the server's exception handler to default\n" -#endif // OS_APPLE -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) + // clang-format on +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) + // clang-format off " --sanitization-information=SANITIZATION_INFORMATION_ADDRESS\n" " the address of a SanitizationInformation struct.\n" " --shared-client-connection the file descriptor provided by\n" @@ -160,10 +185,15 @@ void Usage(const base::FilePath& me) { " clients\n" " --trace-parent-with-exception=EXCEPTION_INFORMATION_ADDRESS\n" " request a dump for the handler's parent process\n" -#endif // OS_LINUX || OS_CHROMEOS || OS_ANDROID + // clang-format on +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) + // clang-format off " --url=URL send crash reports to this Breakpad server URL,\n" " only if uploads are enabled for the database\n" + // clang-format on #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) + // clang-format off " --use-cros-crash-reporter\n" " pass crash reports to /sbin/crash_reporter\n" " instead of storing them in the database\n" @@ -174,13 +204,18 @@ void Usage(const base::FilePath& me) { " pass the --always_allow_feedback flag to\n" " crash_reporter, thus skipping metrics consent\n" " checks\n" + // clang-format on #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) + // clang-format off " --write-minidump-to-log write minidump to log\n" -#endif // OS_ANDROID + // clang-format on +#endif // BUILDFLAG(IS_ANDROID) + // clang-format off " --help display this help and exit\n" " --version output version information and exit\n", me.value().c_str()); + // clang-format on ToolSupport::UsageTail(me); } @@ -191,23 +226,23 @@ struct Options { base::FilePath database; base::FilePath metrics_dir; std::vector monitor_self_arguments; -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) std::string mach_service; int handshake_fd; bool reset_own_crash_exception_port_to_system_default; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) VMAddress exception_information_address; VMAddress sanitization_information_address; int initial_client_fd; bool shared_client_connection; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) bool write_minidump_to_log; bool write_minidump_to_database; -#endif // OS_ANDROID -#elif defined(OS_WIN) +#endif // BUILDFLAG(IS_ANDROID) +#elif BUILDFLAG(IS_WIN) std::string pipe_name; InitialClientData initial_client_data; -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) bool identify_client_via_url; bool monitor_self; bool periodic_tasks; @@ -252,11 +287,15 @@ bool AddKeyValueToMap(std::map* map, // a normal exit, or if a CallMetricsRecordNormalExit object is destroyed after // something else logs an exit event. void MetricsRecordExit(Metrics::LifetimeMilestone milestone) { - static bool once = [](Metrics::LifetimeMilestone milestone) { +#if !defined(__cpp_lib_atomic_value_initialization) || \ + __cpp_lib_atomic_value_initialization < 201911L + static std::atomic_flag metrics_exit_recorded = ATOMIC_FLAG_INIT; +#else + static std::atomic_flag metrics_exit_recorded; +#endif + if (!metrics_exit_recorded.test_and_set()) { Metrics::HandlerLifetimeMilestone(milestone); - return true; - }(milestone); - ALLOW_UNUSED_LOCAL(once); + } } // Calls MetricsRecordExit() to record a failure, and returns EXIT_FAILURE for @@ -280,8 +319,8 @@ class CallMetricsRecordNormalExit { } }; -#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ - defined(OS_ANDROID) +#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_ANDROID) void HandleCrashSignal(int sig, siginfo_t* siginfo, void* context) { MetricsRecordExit(Metrics::LifetimeMilestone::kCrashed); @@ -341,7 +380,7 @@ void InstallCrashHandler() { Signals::InstallTerminateHandlers(HandleTerminateSignal, 0, nullptr); } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) struct ResetSIGTERMTraits { static struct sigaction* InvalidValue() { @@ -367,9 +406,9 @@ void HandleSIGTERM(int sig, siginfo_t* siginfo, void* context) { g_exception_handler_server->Stop(); } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) LONG(WINAPI* g_original_exception_filter)(EXCEPTION_POINTERS*) = nullptr; @@ -422,11 +461,11 @@ void InstallCrashHandler() { // enough. Note that destroying the TerminateHandler would wait for its thread // to exit, which isn’t necessary or desirable. SetConsoleCtrlHandler(ConsoleHandler, true); - static TerminateHandler* terminate_handler = new TerminateHandler(); - ALLOW_UNUSED_LOCAL(terminate_handler); + [[maybe_unused]] static TerminateHandler* terminate_handler = + new TerminateHandler(); } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) void MonitorSelf(const Options& options) { base::FilePath executable_path; @@ -462,7 +501,7 @@ void MonitorSelf(const Options& options) { // instance of crashpad_handler to be writing metrics at a time, and it should // be the primary instance. CrashpadClient crashpad_client; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) if (!crashpad_client.StartHandlerAtCrash(executable_path, options.database, base::FilePath(), @@ -515,7 +554,7 @@ void InitCrashpadLogging() { #if BUILDFLAG(IS_CHROMEOS_ASH) settings.logging_dest = logging::LOG_TO_FILE; settings.log_file_path = "/var/log/chrome/chrome"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; #else settings.logging_dest = @@ -546,18 +585,19 @@ int HandlerMain(int argc, kOptionAttachment, #endif // ATTACHMENTS_SUPPORTED kOptionDatabase, -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) kOptionHandshakeFD, -#endif // OS_APPLE -#if defined(OS_WIN) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_WIN) kOptionInitialClientData, -#endif // OS_WIN -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) kOptionInitialClientFD, -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS -#if defined(OS_APPLE) +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_APPLE) kOptionMachService, -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) kOptionMetrics, kOptionMonitorSelf, kOptionMonitorSelfAnnotation, @@ -566,16 +606,16 @@ int HandlerMain(int argc, kOptionNoPeriodicTasks, kOptionNoRateLimit, kOptionNoUploadGzip, -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) kOptionNoWriteMinidumpToDatabase, -#endif // OS_ANDROID -#if defined(OS_WIN) +#endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_WIN) kOptionPipeName, -#endif // OS_WIN -#if defined(OS_APPLE) +#endif // BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_APPLE) kOptionResetOwnCrashExceptionPortToSystemDefault, -#endif // OS_APPLE -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) kOptionSanitizationInformation, kOptionSharedClientConnection, kOptionTraceParentWithException, @@ -586,9 +626,9 @@ int HandlerMain(int argc, kOptionMinidumpDirForTests, kOptionAlwaysAllowFeedback, #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) kOptionWriteMinidumpToLog, -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) // Standard options. kOptionHelp = -2, @@ -601,21 +641,22 @@ int HandlerMain(int argc, {"attachment", required_argument, nullptr, kOptionAttachment}, #endif // ATTACHMENTS_SUPPORTED {"database", required_argument, nullptr, kOptionDatabase}, -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD}, -#endif // OS_APPLE -#if defined(OS_WIN) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_WIN) {"initial-client-data", required_argument, nullptr, kOptionInitialClientData}, -#endif // OS_APPLE -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) {"initial-client-fd", required_argument, nullptr, kOptionInitialClientFD}, -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS -#if defined(OS_APPLE) +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_APPLE) {"mach-service", required_argument, nullptr, kOptionMachService}, -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) {"metrics-dir", required_argument, nullptr, kOptionMetrics}, {"monitor-self", no_argument, nullptr, kOptionMonitorSelf}, {"monitor-self-annotation", @@ -633,22 +674,22 @@ int HandlerMain(int argc, {"no-periodic-tasks", no_argument, nullptr, kOptionNoPeriodicTasks}, {"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit}, {"no-upload-gzip", no_argument, nullptr, kOptionNoUploadGzip}, -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) {"no-write-minidump-to-database", no_argument, nullptr, kOptionNoWriteMinidumpToDatabase}, -#endif // OS_ANDROID -#if defined(OS_WIN) +#endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_WIN) {"pipe-name", required_argument, nullptr, kOptionPipeName}, -#endif // OS_WIN -#if defined(OS_APPLE) +#endif // BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_APPLE) {"reset-own-crash-exception-port-to-system-default", no_argument, nullptr, kOptionResetOwnCrashExceptionPortToSystemDefault}, -#endif // OS_APPLE -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) {"sanitization-information", required_argument, nullptr, @@ -661,42 +702,40 @@ int HandlerMain(int argc, required_argument, nullptr, kOptionTraceParentWithException}, -#endif // OS_LINUX || OS_CHROMEOS || OS_ANDROID +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) {"url", required_argument, nullptr, kOptionURL}, #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) {"use-cros-crash-reporter", - no_argument, - nullptr, - kOptionUseCrosCrashReporter}, + no_argument, + nullptr, + kOptionUseCrosCrashReporter}, {"minidump-dir-for-tests", - required_argument, - nullptr, - kOptionMinidumpDirForTests}, - {"always-allow-feedback", - no_argument, - nullptr, - kOptionAlwaysAllowFeedback}, + required_argument, + nullptr, + kOptionMinidumpDirForTests}, + {"always-allow-feedback", no_argument, nullptr, kOptionAlwaysAllowFeedback}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) {"write-minidump-to-log", no_argument, nullptr, kOptionWriteMinidumpToLog}, -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) {"help", no_argument, nullptr, kOptionHelp}, {"version", no_argument, nullptr, kOptionVersion}, {nullptr, 0, nullptr, 0}, }; Options options = {}; -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) options.handshake_fd = -1; #endif options.identify_client_via_url = true; -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) options.initial_client_fd = kInvalidFileHandle; #endif options.periodic_tasks = true; options.rate_limit = true; options.upload_gzip = true; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) options.write_minidump_to_database = true; #endif @@ -721,7 +760,7 @@ int HandlerMain(int argc, ToolSupport::CommandLineArgumentToFilePathStringType(optarg)); break; } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) case kOptionHandshakeFD: { if (!StringToNumber(optarg, &options.handshake_fd) || options.handshake_fd < 0) { @@ -735,8 +774,8 @@ int HandlerMain(int argc, options.mach_service = optarg; break; } -#endif // OS_APPLE -#if defined(OS_WIN) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_WIN) case kOptionInitialClientData: { if (!options.initial_client_data.InitializeFromString(optarg)) { ToolSupport::UsageHint( @@ -745,8 +784,8 @@ int HandlerMain(int argc, } break; } -#endif // OS_WIN -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) case kOptionInitialClientFD: { if (!base::StringToInt(optarg, &options.initial_client_fd)) { ToolSupport::UsageHint(me, "failed to parse --initial-client-fd"); @@ -754,7 +793,8 @@ int HandlerMain(int argc, } break; } -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) case kOptionMetrics: { options.metrics_dir = base::FilePath( ToolSupport::CommandLineArgumentToFilePathStringType(optarg)); @@ -792,25 +832,25 @@ int HandlerMain(int argc, options.upload_gzip = false; break; } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) case kOptionNoWriteMinidumpToDatabase: { options.write_minidump_to_database = false; break; } -#endif // OS_ANDROID -#if defined(OS_WIN) +#endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_WIN) case kOptionPipeName: { options.pipe_name = optarg; break; } -#endif // OS_WIN -#if defined(OS_APPLE) +#endif // BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_APPLE) case kOptionResetOwnCrashExceptionPortToSystemDefault: { options.reset_own_crash_exception_port_to_system_default = true; break; } -#endif // OS_APPLE -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) case kOptionSanitizationInformation: { if (!StringToNumber(optarg, &options.sanitization_information_address)) { @@ -832,7 +872,8 @@ int HandlerMain(int argc, } break; } -#endif // OS_LINUX || OS_CHROMEOS || OS_ANDROID +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) case kOptionURL: { options.url = optarg; break; @@ -852,12 +893,12 @@ int HandlerMain(int argc, break; } #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) case kOptionWriteMinidumpToLog: { options.write_minidump_to_log = true; break; } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) case kOptionHelp: { Usage(me); MetricsRecordExit(Metrics::LifetimeMilestone::kExitedEarly); @@ -877,7 +918,7 @@ int HandlerMain(int argc, argc -= optind; argv += optind; -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) if (options.handshake_fd < 0 && options.mach_service.empty()) { ToolSupport::UsageHint(me, "--handshake-fd or --mach-service is required"); return ExitFailure(); @@ -887,7 +928,7 @@ int HandlerMain(int argc, me, "--handshake-fd and --mach-service are incompatible"); return ExitFailure(); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) if (!options.initial_client_data.IsValid() && options.pipe_name.empty()) { ToolSupport::UsageHint(me, "--initial-client-data or --pipe-name is required"); @@ -898,7 +939,7 @@ int HandlerMain(int argc, me, "--initial-client-data and --pipe-name are incompatible"); return ExitFailure(); } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) if (!options.exception_information_address && options.initial_client_fd == kInvalidFileHandle) { ToolSupport::UsageHint( @@ -918,15 +959,15 @@ int HandlerMain(int argc, me, "--shared-client-connection requires --initial-client-fd"); return ExitFailure(); } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) if (!options.write_minidump_to_log && !options.write_minidump_to_database) { ToolSupport::UsageHint(me, "--no_write_minidump_to_database is required to use " "with --write_minidump_to_log."); ExitFailure(); } -#endif // OS_ANDROID -#endif // OS_APPLE +#endif // BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(IS_APPLE) if (options.database.empty()) { ToolSupport::UsageHint(me, "--database is required"); @@ -938,11 +979,11 @@ int HandlerMain(int argc, return ExitFailure(); } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) if (options.reset_own_crash_exception_port_to_system_default) { CrashpadClient::UseSystemDefaultHandler(); } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) if (options.monitor_self) { MonitorSelf(options); @@ -991,7 +1032,7 @@ int HandlerMain(int argc, upload_thread.Get()->Start(); } -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) std::unique_ptr exception_handler; #else std::unique_ptr exception_handler; @@ -1031,18 +1072,18 @@ int HandlerMain(int argc, #if defined(ATTACHMENTS_SUPPORTED) &options.attachments, #endif // ATTACHMENTS_SUPPORTED -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) options.write_minidump_to_database, options.write_minidump_to_log, -#endif // OS_ANDROID -#if defined(OS_LINUX) +#endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_LINUX) true, false, -#endif // OS_LINUX +#endif // BUILDFLAG(IS_LINUX) user_stream_sources); #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) if (options.exception_information_address) { ExceptionHandlerProtocol::ClientInformation info; info.exception_information_address = options.exception_information_address; @@ -1052,7 +1093,8 @@ int HandlerMain(int argc, ? EXIT_SUCCESS : ExitFailure(); } -#endif // OS_LINUX || OS_CHROMEOS || OS_ANDROID +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) ScopedStoppable prune_thread; if (options.periodic_tasks) { @@ -1061,7 +1103,7 @@ int HandlerMain(int argc, prune_thread.Get()->Start(); } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) if (options.mach_service.empty()) { // Don’t do this when being run by launchd. See launchd.plist(5). CloseStdinAndStdout(); @@ -1104,7 +1146,7 @@ int HandlerMain(int argc, } RecordFileLimitAnnotation(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) // Shut down as late as possible relative to programs we're watching. if (!SetProcessShutdownParameters(0x100, SHUTDOWN_NORETRY)) PLOG(ERROR) << "SetProcessShutdownParameters"; @@ -1114,9 +1156,9 @@ int HandlerMain(int argc, if (!options.pipe_name.empty()) { exception_handler_server.SetPipeName(base::UTF8ToWide(options.pipe_name)); } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) ExceptionHandlerServer exception_handler_server; -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) base::GlobalHistogramAllocator* histogram_allocator = nullptr; if (!options.metrics_dir.empty()) { @@ -1131,19 +1173,19 @@ int HandlerMain(int argc, Metrics::HandlerLifetimeMilestone(Metrics::LifetimeMilestone::kStarted); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) if (options.initial_client_data.IsValid()) { exception_handler_server.InitializeWithInheritedDataForInitialClient( options.initial_client_data, exception_handler.get()); } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) if (options.initial_client_fd == kInvalidFileHandle || !exception_handler_server.InitializeWithClient( ScopedFileHandle(options.initial_client_fd), options.shared_client_connection)) { return ExitFailure(); } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) exception_handler_server.Run(exception_handler.get()); diff --git a/thirdparty/sentry-native/external/crashpad/handler/handler_main.h b/thirdparty/sentry-native/external/crashpad/handler/handler_main.h index 252654118a..b6cc467cdd 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/handler_main.h +++ b/thirdparty/sentry-native/external/crashpad/handler/handler_main.h @@ -35,7 +35,7 @@ int HandlerMain(int argc, char* argv[], const UserStreamDataSources* user_stream_sources); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) //! \brief The `main()` entry point for Android libraries. //! //! This symbol is the entry point for crashpad when it is dynamically loaded diff --git a/thirdparty/sentry-native/external/crashpad/handler/linux/crash_report_exception_handler.cc b/thirdparty/sentry-native/external/crashpad/handler/linux/crash_report_exception_handler.cc index 84f9534fed..88378a9fa4 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/linux/crash_report_exception_handler.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/linux/crash_report_exception_handler.cc @@ -36,7 +36,7 @@ #include "util/stream/log_output_stream.h" #include "util/stream/zlib_output_stream.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif @@ -52,7 +52,7 @@ class Logger final : public LogOutputStream::Delegate { ~Logger() override = default; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) int Log(const char* buf) override { return __android_log_buf_write( LOG_ID_CRASH, ANDROID_LOG_FATAL, "crashpad", buf); diff --git a/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server.cc b/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server.cc index c9fbb0add0..aef252fa4d 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server.cc @@ -198,7 +198,7 @@ class PtraceStrategyDeciderImpl : public PtraceStrategyDecider { if (HaveCapSysPtrace()) { return Strategy::kDirectPtrace; } - FALLTHROUGH; + [[fallthrough]]; case PtraceScope::kNoAttach: LOG(WARNING) << "no ptrace"; return Strategy::kNoPtrace; diff --git a/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server_test.cc b/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server_test.cc index 786bab1baa..c7fa90d894 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server_test.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/linux/exception_handler_server_test.cc @@ -30,7 +30,7 @@ #include "util/synchronization/semaphore.h" #include "util/thread/thread.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif diff --git a/thirdparty/sentry-native/external/crashpad/handler/mac/file_limit_annotation.cc b/thirdparty/sentry-native/external/crashpad/handler/mac/file_limit_annotation.cc index 0813b9502c..063345343d 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/mac/file_limit_annotation.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/mac/file_limit_annotation.cc @@ -21,9 +21,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "client/crashpad_info.h" @@ -108,7 +108,7 @@ void RecordFileLimitAnnotation() { int mib[] = {CTL_KERN, KERN_MAXFILES}; size = sizeof(value); std::string max_files = FormatFromSysctl( - sysctl(mib, base::size(mib), &value, &size, nullptr, 0), &value, &size); + sysctl(mib, std::size(mib), &value, &size, nullptr, 0), &value, &size); std::string open_files = CountOpenFileDescriptors(); diff --git a/thirdparty/sentry-native/external/crashpad/handler/main.cc b/thirdparty/sentry-native/external/crashpad/handler/main.cc index 3ae73ecddf..855a5a7dee 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/main.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/main.cc @@ -17,17 +17,17 @@ #include "build/build_config.h" #include "tools/tool_support.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include #endif -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int main(int argc, char* argv[]) { return crashpad::HandlerMain(argc, argv, nullptr); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) namespace { @@ -50,4 +50,4 @@ int wmain(int argc, wchar_t* argv[]) { return crashpad::ToolSupport::Wmain(argc, argv, HandlerMainAdaptor); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) diff --git a/thirdparty/sentry-native/external/crashpad/handler/win/crash_other_program.cc b/thirdparty/sentry-native/external/crashpad/handler/win/crash_other_program.cc index bbd25af5df..3020f6621f 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/win/crash_other_program.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/win/crash_other_program.cc @@ -24,6 +24,7 @@ #include "test/test_paths.h" #include "test/win/child_launcher.h" #include "util/file/file_io.h" +#include "util/win/exception_codes.h" #include "util/win/scoped_handle.h" #include "util/win/xp_compat.h" @@ -108,7 +109,7 @@ int CrashOtherProgram(int argc, wchar_t* argv[]) { DWORD expect_exit_code; if (argc == 3 && wcscmp(argv[2], L"noexception") == 0) { - expect_exit_code = CrashpadClient::kTriggeredExceptionCode; + expect_exit_code = ExceptionCodes::kTriggeredExceptionCode; if (!CrashpadClient::DumpAndCrashTargetProcess( child.process_handle(), 0, 0)) return EXIT_FAILURE; diff --git a/thirdparty/sentry-native/external/crashpad/handler/win/crashy_test_program.cc b/thirdparty/sentry-native/external/crashpad/handler/win/crashy_test_program.cc index 4fb2554774..f5cf04877b 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/win/crashy_test_program.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/win/crashy_test_program.cc @@ -19,12 +19,12 @@ #include #include +#include #include #include #include #include -#include "base/cxx17_backports.h" #include "base/files/file_path.h" #include "base/logging.h" #include "build/build_config.h" @@ -83,11 +83,11 @@ void AllocateMemoryOfVariousProtections() { // All of these allocations are leaked, we want to view them in windbg via // !vprot. void* reserve = VirtualAlloc( - nullptr, base::size(kPageTypes) * kPageSize, MEM_RESERVE, PAGE_READWRITE); + nullptr, std::size(kPageTypes) * kPageSize, MEM_RESERVE, PAGE_READWRITE); PCHECK(reserve) << "VirtualAlloc MEM_RESERVE"; uintptr_t reserve_as_int = reinterpret_cast(reserve); - for (size_t i = 0; i < base::size(kPageTypes); ++i) { + for (size_t i = 0; i < std::size(kPageTypes); ++i) { void* result = VirtualAlloc(reinterpret_cast(reserve_as_int + (kPageSize * i)), kPageSize, diff --git a/thirdparty/sentry-native/external/crashpad/handler/win/hanging_program.cc b/thirdparty/sentry-native/external/crashpad/handler/win/hanging_program.cc index b65d46db82..aff3ae28e6 100644 --- a/thirdparty/sentry-native/external/crashpad/handler/win/hanging_program.cc +++ b/thirdparty/sentry-native/external/crashpad/handler/win/hanging_program.cc @@ -15,7 +15,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/debug/alias.h" #include "base/logging.h" #include "base/notreached.h" @@ -125,7 +126,7 @@ int wmain(int argc, wchar_t* argv[]) { // This is not expected to return. DWORD count = WaitForMultipleObjects( - static_cast(base::size(threads)), threads, true, INFINITE); + static_cast(std::size(threads)), threads, true, INFINITE); if (count == WAIT_FAILED) { PLOG(ERROR) << "WaitForMultipleObjects"; } else { diff --git a/thirdparty/sentry-native/external/crashpad/infra/config/generated/cr-buildbucket.cfg b/thirdparty/sentry-native/external/crashpad/infra/config/generated/cr-buildbucket.cfg index d34621cdf0..a79e5cfa44 100644 --- a/thirdparty/sentry-native/external/crashpad/infra/config/generated/cr-buildbucket.cfg +++ b/thirdparty/sentry-native/external/crashpad/infra/config/generated/cr-buildbucket.cfg @@ -23,7 +23,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.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-16.04" + dimensions: "os:Ubuntu-18.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-16.04" + dimensions: "os:Ubuntu-18.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-16.04" + dimensions: "os:Ubuntu-18.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-10.15" + dimensions: "os:Mac-11" 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-10.15" + dimensions: "os:Mac-11" 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-10.15" + dimensions: "os:Mac-11" 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-10.15" + dimensions: "os:Mac-11" 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-16.04" + dimensions: "os:Ubuntu-18.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-16.04" + dimensions: "os:Ubuntu-18.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-10.15" + dimensions: "os:Mac-11" 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-10.15" + dimensions: "os:Mac-11" dimensions: "pool:luci.flex.ci" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -450,6 +450,9 @@ buckets { } properties: '{' + ' "$depot_tools/windows_sdk": {' + ' "version": "uploaded:2021-04-28"' + ' },' ' "$gatekeeper": {' ' "group": "client.crashpad"' ' },' @@ -483,6 +486,9 @@ buckets { } properties: '{' + ' "$depot_tools/windows_sdk": {' + ' "version": "uploaded:2021-04-28"' + ' },' ' "$gatekeeper": {' ' "group": "client.crashpad"' ' },' @@ -531,7 +537,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -562,7 +568,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -593,7 +599,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -623,7 +629,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -652,7 +658,7 @@ buckets { name: "crashpad_ios_arm64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" + dimensions: "os:Mac-11" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -686,7 +692,7 @@ buckets { name: "crashpad_ios_arm64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" + dimensions: "os:Mac-11" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -720,7 +726,7 @@ buckets { name: "crashpad_ios_x64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" + dimensions: "os:Mac-11" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -753,7 +759,7 @@ buckets { name: "crashpad_ios_x64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" + dimensions: "os:Mac-11" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -787,7 +793,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -817,7 +823,7 @@ buckets { swarming_host: "chromium-swarm.appspot.com" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" + dimensions: "os:Ubuntu-18.04" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -846,7 +852,7 @@ buckets { name: "crashpad_mac_x64_dbg" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" + dimensions: "os:Mac-11" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -879,7 +885,7 @@ buckets { name: "crashpad_mac_x64_rel" swarming_host: "chromium-swarm.appspot.com" dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" + dimensions: "os:Mac-11" dimensions: "pool:luci.flex.try" exe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" @@ -922,6 +928,9 @@ buckets { } properties: '{' + ' "$depot_tools/windows_sdk": {' + ' "version": "uploaded:2021-04-28"' + ' },' ' "$kitchen": {' ' "devshell": true,' ' "git_auth": true' @@ -952,6 +961,9 @@ buckets { } properties: '{' + ' "$depot_tools/windows_sdk": {' + ' "version": "uploaded:2021-04-28"' + ' },' ' "$kitchen": {' ' "devshell": true,' ' "git_auth": true' diff --git a/thirdparty/sentry-native/external/crashpad/infra/config/generated/luci-scheduler.cfg b/thirdparty/sentry-native/external/crashpad/infra/config/generated/luci-scheduler.cfg index 6b3d04d1b3..a2251eb899 100644 --- a/thirdparty/sentry-native/external/crashpad/infra/config/generated/luci-scheduler.cfg +++ b/thirdparty/sentry-native/external/crashpad/infra/config/generated/luci-scheduler.cfg @@ -10,7 +10,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_fuchsia_arm64_dbg" } } @@ -20,7 +20,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_fuchsia_arm64_rel" } } @@ -30,7 +30,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_fuchsia_x64_dbg" } } @@ -40,7 +40,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_fuchsia_x64_rel" } } @@ -50,7 +50,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_ios_arm64_dbg" } } @@ -60,7 +60,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_ios_arm64_rel" } } @@ -70,7 +70,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_ios_x64_dbg" } } @@ -80,7 +80,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_ios_x64_rel" } } @@ -90,7 +90,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_linux_x64_dbg" } } @@ -100,7 +100,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_linux_x64_rel" } } @@ -110,7 +110,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_mac_x64_dbg" } } @@ -120,7 +120,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_mac_x64_rel" } } @@ -130,7 +130,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_win_x64_dbg" } } @@ -140,7 +140,7 @@ job { acl_sets: "ci" buildbucket { server: "cr-buildbucket.appspot.com" - bucket: "luci.crashpad.ci" + bucket: "ci" builder: "crashpad_win_x64_rel" } } diff --git a/thirdparty/sentry-native/external/crashpad/infra/config/generated/project.cfg b/thirdparty/sentry-native/external/crashpad/infra/config/generated/project.cfg index 9dcccbfab2..28e9f2e62e 100644 --- a/thirdparty/sentry-native/external/crashpad/infra/config/generated/project.cfg +++ b/thirdparty/sentry-native/external/crashpad/infra/config/generated/project.cfg @@ -7,8 +7,9 @@ name: "crashpad" access: "group:all" lucicfg { - version: "1.30.1" + version: "1.30.9" package_dir: ".." config_dir: "generated" entry_point: "main.star" + experiments: "crbug.com/1182002" } diff --git a/thirdparty/sentry-native/external/crashpad/infra/config/main.star b/thirdparty/sentry-native/external/crashpad/infra/config/main.star index f51ef23e1e..fade252303 100644 --- a/thirdparty/sentry-native/external/crashpad/infra/config/main.star +++ b/thirdparty/sentry-native/external/crashpad/infra/config/main.star @@ -13,15 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -lucicfg.check_version("1.28.0", "Please update depot_tools") - -# Enable LUCI Realms support and Launch 100% of Swarming tasks for builds in -# "realms-aware mode". -lucicfg.enable_experiment("crbug.com/1085650") +lucicfg.check_version("1.30.9", "Please update depot_tools") REPO_URL = "https://chromium.googlesource.com/crashpad/crashpad" REVIEW_URL = "https://chromium-review.googlesource.com/crashpad/crashpad" +# Use LUCI Scheduler BBv2 names and add Scheduler realms configs. +lucicfg.enable_experiment("crbug.com/1182002") + luci.project( name = "crashpad", buildbucket = "cr-buildbucket.appspot.com", @@ -157,13 +156,13 @@ def crashpad_dimensions(platform, bucket): dimensions["pool"] = "luci.flex." + bucket if platform == "fuchsia": - dimensions["os"] = "Ubuntu-16.04" + dimensions["os"] = "Ubuntu-18.04" elif platform == "ios": - dimensions["os"] = "Mac-10.15" + dimensions["os"] = "Mac-11" elif platform == "linux": - dimensions["os"] = "Ubuntu-16.04" + dimensions["os"] = "Ubuntu-18.04" elif platform == "mac": - dimensions["os"] = "Mac-10.15" + dimensions["os"] = "Mac-11" elif platform == "win": dimensions["os"] = "Windows-10" @@ -183,6 +182,11 @@ def crashpad_properties(platform, cpu, config, bucket): if cpu != "x64": properties["target_cpu"] = cpu + if platform == "win": + properties["$depot_tools/windows_sdk"] = { + "version": "uploaded:2021-04-28", + } + if bucket == "ci": properties["$gatekeeper"] = { "group": "client.crashpad", diff --git a/thirdparty/sentry-native/external/crashpad/minidump/BUILD.gn b/thirdparty/sentry-native/external/crashpad/minidump/BUILD.gn index 515ec0f377..a300897f80 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/minidump/BUILD.gn @@ -52,6 +52,8 @@ crashpad_static_library("minidump") { "minidump_system_info_writer.h", "minidump_thread_id_map.cc", "minidump_thread_id_map.h", + "minidump_thread_name_list_writer.cc", + "minidump_thread_name_list_writer.h", "minidump_thread_writer.cc", "minidump_thread_writer.h", "minidump_unloaded_module_writer.cc", @@ -166,6 +168,7 @@ source_set("minidump_test") { "minidump_string_writer_test.cc", "minidump_system_info_writer_test.cc", "minidump_thread_id_map_test.cc", + "minidump_thread_name_list_writer_test.cc", "minidump_thread_writer_test.cc", "minidump_unloaded_module_writer_test.cc", "minidump_user_stream_writer_test.cc", diff --git a/thirdparty/sentry-native/external/crashpad/minidump/CMakeLists.txt b/thirdparty/sentry-native/external/crashpad/minidump/CMakeLists.txt index b964add2a7..cec2e91830 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/CMakeLists.txt +++ b/thirdparty/sentry-native/external/crashpad/minidump/CMakeLists.txt @@ -38,6 +38,8 @@ add_library(crashpad_minidump STATIC minidump_system_info_writer.h minidump_thread_id_map.cc minidump_thread_id_map.h + minidump_thread_name_list_writer.cc + minidump_thread_name_list_writer.h minidump_thread_writer.cc minidump_thread_writer.h minidump_unloaded_module_writer.cc diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer.cc index 54a3ecba16..8a62eccb81 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer.cc @@ -147,9 +147,10 @@ bool MinidumpAnnotationListWriter::WriteObject( FileWriterInterface* file_writer) { DCHECK_EQ(state(), kStateWritable); - std::vector iov(1 + objects_.size()); - iov[0].iov_base = minidump_list_.get(); - iov[0].iov_len = sizeof(*minidump_list_); + std::vector iov; + iov.reserve(1 + objects_.size()); + iov.emplace_back( + WritableIoVec{minidump_list_.get(), sizeof(*minidump_list_)}); for (const auto& object : objects_) { iov.emplace_back(WritableIoVec{object->minidump_annotation(), diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer_test.cc index c862f023e5..ff3c2a8e3c 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_annotation_writer_test.cc @@ -14,9 +14,9 @@ #include "minidump/minidump_annotation_writer.h" +#include #include -#include "base/cxx17_backports.h" #include "gtest/gtest.h" #include "minidump/minidump_extensions.h" #include "minidump/test/minidump_byte_array_writer_test_util.h" @@ -107,7 +107,7 @@ TEST(MinidumpAnnotationWriter, ThreeItems) { MinidumpAnnotationListWriter list_writer; - for (size_t i = 0; i < base::size(kNames); ++i) { + for (size_t i = 0; i < std::size(kNames); ++i) { auto annotation = std::make_unique(); annotation->InitializeWithData(kNames[i], kTypes[i], kValues[i]); list_writer.AddObject(std::move(annotation)); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_byte_array_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_byte_array_writer_test.cc index 526e38badf..8742ea4481 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_byte_array_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_byte_array_writer_test.cc @@ -14,9 +14,9 @@ #include "minidump/minidump_byte_array_writer.h" +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -35,7 +35,7 @@ TEST(MinidumpByteArrayWriter, Write) { {}, }; - for (size_t i = 0; i < base::size(kTests); ++i) { + for (size_t i = 0; i < std::size(kTests); ++i) { SCOPED_TRACE(base::StringPrintf("index %" PRIuS, i)); StringFile string_file; @@ -67,7 +67,7 @@ TEST(MinidumpByteArrayWriter, SetData) { {}, }; - for (size_t i = 0; i < base::size(kTests); ++i) { + for (size_t i = 0; i < std::size(kTests); ++i) { SCOPED_TRACE(base::StringPrintf("index %" PRIuS, i)); crashpad::MinidumpByteArrayWriter writer; diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context.h b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context.h index 3a3e603cb0..c10743d848 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context.h +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context.h @@ -225,7 +225,7 @@ enum MinidumpContextAMD64Flags : uint32_t { //! \brief Indicates the validity of `xsave` data (`CONTEXT_XSTATE`). //! //! The context contains `xsave` data. This is used with an extended context - //! structure not currently defined here. + //! structure which is partly implemented for CET state only. kMinidumpContextAMD64Xstate = kMinidumpContextAMD64 | 0x00000040, //! \brief Indicates the validity of control, integer, and floating-point @@ -386,6 +386,51 @@ struct MinidumpContextARM { uint32_t extra[8]; }; +//! \brief CONTEXT_CHUNK +struct MinidumpContextChunk { + int32_t offset; + uint32_t size; +}; + +//! \brief CONTEXT_EX +struct MinidumpContextExHeader { + MinidumpContextChunk all; + MinidumpContextChunk legacy; + MinidumpContextChunk xstate; +}; + +//! \brief XSAVE_AREA_HEADER +struct MinidumpXSaveAreaHeader { + uint64_t mask; + uint64_t compaction_mask; + uint64_t xsave_header_reserved[6]; +}; + +//! \brief Offset of first xsave feature in the full extended context. +//! +//! This is used to calculate the final size of the extended context, and +//! can be validated by calling InitializeContext2 with one XSTATE feature, +//! and LocateXStateFeature to determine the first offset. +//! Also see "MANAGING STATE USING THE XSAVE FEATURE SET", Ch. 13, Intel SDM. +constexpr uint32_t kMinidumpAMD64XSaveOffset = 0x550; + +//! \brief Offset of first xsave feature within the extended context area. +//! +//! 0x240 is the size of the legacy area (512) + the xsave header(64 bytes) +//! Intel SDM 13.4.1. This is not where the item is in the extended compacted +//! context, but is the offset recorded in the minidump. It needs to be correct +//! there. See https://windows-internals.com/cet-on-windows/ for some discussion +//! "CONTEXT_XSTATE: Extended processor state chunk. The state is stored in the +//! same format the XSAVE operation stores it with exception of the first 512 +//! bytes, i.e. starting from XSAVE_AREA_HEADER." This may vary by cpuid. +constexpr uint32_t kXSaveAreaFirstOffset = 0x240; + +//! \brief XSAVE_CET_U_FORMAT +struct MinidumpAMD64XSaveFormatCetU { + uint64_t cetmsr; + uint64_t ssp; +}; + //! \brief 64-bit ARM-specifc flags for MinidumpContextARM64::context_flags. enum MinidumpContextARM64Flags : uint32_t { //! \brief Identifies the context structure as 64-bit ARM. diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.cc index d7e53a4932..bf02c1bd28 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.cc @@ -21,6 +21,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" +#include "build/build_config.h" #include "snapshot/cpu_context.h" #include "util/file/file_writer.h" #include "util/stdlib/aligned_allocator.h" @@ -35,7 +36,7 @@ static_assert(sizeof(MinidumpContextAMD64) == 1232, "MinidumpContextAMD64 size"); // These structures can also be checked against definitions in the Windows SDK. -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #if defined(ARCH_CPU_X86_FAMILY) static_assert(sizeof(MinidumpContextX86) == sizeof(WOW64_CONTEXT), "WOW64_CONTEXT size"); @@ -45,7 +46,7 @@ static_assert(sizeof(MinidumpContextX86) == sizeof(CONTEXT), "CONTEXT size"); static_assert(sizeof(MinidumpContextAMD64) == sizeof(CONTEXT), "CONTEXT size"); #endif #endif // ARCH_CPU_X86_FAMILY -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } // namespace @@ -117,6 +118,11 @@ size_t MinidumpContextWriter::SizeOfObject() { return ContextSize(); } +size_t MinidumpContextWriter::FreezeAndGetSizeOfObject() { + Freeze(); + return SizeOfObject(); +} + MinidumpContextX86Writer::MinidumpContextX86Writer() : MinidumpContextWriter(), context_() { context_.context_flags = kMinidumpContextX86; @@ -125,7 +131,6 @@ MinidumpContextX86Writer::MinidumpContextX86Writer() MinidumpContextX86Writer::~MinidumpContextX86Writer() { } - void MinidumpContextX86Writer::InitializeFromSnapshot( const CPUContextX86* context_snapshot) { DCHECK_EQ(state(), kStateMutable); @@ -212,7 +217,14 @@ void MinidumpContextAMD64Writer::InitializeFromSnapshot( DCHECK_EQ(state(), kStateMutable); DCHECK_EQ(context_.context_flags, kMinidumpContextAMD64); - context_.context_flags = kMinidumpContextAMD64All; + if (context_snapshot->xstate.enabled_features != 0) { + // Extended context. + context_.context_flags = + kMinidumpContextAMD64All | kMinidumpContextAMD64Xstate; + } else { + // Fixed size context - no xsave components. + context_.context_flags = kMinidumpContextAMD64All; + } context_.mx_csr = context_snapshot->fxsave.mxcsr; context_.cs = context_snapshot->cs; @@ -246,6 +258,15 @@ void MinidumpContextAMD64Writer::InitializeFromSnapshot( // This is effectively a memcpy() of a big structure. context_.fxsave = context_snapshot->fxsave; + + // If XSave features are being recorded store in xsave_entries in xcomp_bv + // order. We will not see features we do not support as we provide flags + // to the OS when first obtaining a snapshot. + if (context_snapshot->xstate.enabled_features & XSTATE_MASK_CET_U) { + auto cet_u = std::make_unique(); + cet_u->InitializeFromSnapshot(context_snapshot); + xsave_entries_.push_back(std::move(cet_u)); + } } size_t MinidumpContextAMD64Writer::Alignment() { @@ -257,14 +278,96 @@ size_t MinidumpContextAMD64Writer::Alignment() { bool MinidumpContextAMD64Writer::WriteObject(FileWriterInterface* file_writer) { DCHECK_EQ(state(), kStateWritable); + // Note: all sizes here come from our constants, not from untrustworthy data. + std::vector data(ContextSize()); + unsigned char* const buf = data.data(); - return file_writer->Write(&context_, sizeof(context_)); + // CONTEXT always comes first. + DCHECK_LE(sizeof(context_), data.size()); + memcpy(buf, &context_, sizeof(context_)); + + if (xsave_entries_.size() > 0) { + MinidumpContextExHeader context_ex = {{0, 0}, {0, 0}, {0, 0}}; + MinidumpXSaveAreaHeader xsave_header = {0, 0, {}}; + + // CONTEXT_EX goes directly after the CONTEXT. |offset| is relative to + // &CONTEXT_EX. + context_ex.all.offset = -static_cast(sizeof(context_)); + context_ex.all.size = static_cast(ContextSize()); + context_ex.legacy.offset = context_ex.all.offset; + context_ex.legacy.size = sizeof(context_); + // Then... there is a gap. + // + // In the compacted format the XSave area header goes just before + // the first xsave entry. It has a total size given by the header + // + (padded) sizes of all the entries. + context_ex.xstate.offset = static_cast( + kMinidumpAMD64XSaveOffset - sizeof(MinidumpXSaveAreaHeader) - + sizeof(context_)); + context_ex.xstate.size = + static_cast(sizeof(MinidumpXSaveAreaHeader) + ContextSize() - + kMinidumpAMD64XSaveOffset); + + // Store CONTEXT_EX now it is complete. + DCHECK_LE(sizeof(context_) + sizeof(context_ex), data.size()); + memcpy(&buf[sizeof(context_)], &context_ex, sizeof(context_ex)); + + // Calculate flags for xsave header & write entries (they will be + // *after* the xsave header). + size_t cursor = kMinidumpAMD64XSaveOffset; + for (auto const& entry : xsave_entries_) { + xsave_header.mask |= 1ull << entry->XCompBVBit(); + DCHECK_LE(cursor + entry->Size(), data.size()); + entry->Copy(&buf[cursor]); + cursor += entry->Size(); + } + + xsave_header.compaction_mask = + xsave_header.mask | XSTATE_COMPACTION_ENABLE_MASK; + + // Store xsave header at its calculated offset. It is before the entries + // above, but we need to add the |mask| bits before writing it. + DCHECK_LE( + context_ex.xstate.offset + sizeof(context_) + sizeof(xsave_header), + data.size()); + memcpy(&buf[context_ex.xstate.offset + sizeof(context_)], + &xsave_header, + sizeof(xsave_header)); + } + + if (!file_writer->Write(data.data(), data.size())) + return false; + + return true; } size_t MinidumpContextAMD64Writer::ContextSize() const { DCHECK_GE(state(), kStateFrozen); + if (xsave_entries_.size() == 0) { + return sizeof(context_); + } else { + DCHECK_EQ(context_.context_flags, + kMinidumpContextAMD64All | kMinidumpContextAMD64Xstate); + DCHECK(xsave_entries_.size() != 0); + size_t size = kMinidumpAMD64XSaveOffset; + for (auto& entry : xsave_entries_) { + size += entry->Size(); + } + return size; + } +} - return sizeof(context_); +bool MinidumpXSaveAMD64CetU::InitializeFromSnapshot( + const CPUContextX86_64* context_snapshot) { + DCHECK_EQ(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; +} + +bool MinidumpXSaveAMD64CetU::Copy(void* dst) const { + memcpy(dst, &cet_u_, sizeof(cet_u_)); + return true; } MinidumpContextARMWriter::MinidumpContextARMWriter() diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.h b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.h index 80b312b23c..9acc7fa012 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.h +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer.h @@ -27,6 +27,7 @@ namespace crashpad { struct CPUContext; struct CPUContextX86; struct CPUContextX86_64; +class MinidumpMiscInfoWriter; //! \brief The base class for writers of CPU context structures in minidump //! files. @@ -49,6 +50,12 @@ class MinidumpContextWriter : public internal::MinidumpWritable { static std::unique_ptr CreateFromSnapshot( const CPUContext* context_snapshot); + //! \brief Returns the size of the context structure that this object will + //! write. + //! + //! \note This method will force this to #kStateFrozen, if it is not already. + size_t FreezeAndGetSizeOfObject(); + protected: MinidumpContextWriter() : MinidumpWritable() {} @@ -105,6 +112,36 @@ class MinidumpContextX86Writer final : public MinidumpContextWriter { MinidumpContextX86 context_; }; +//! \brief Wraps an xsave feature that knows where and how big it is. +class MinidumpXSaveFeatureAMD64 { + public: + virtual ~MinidumpXSaveFeatureAMD64() = default; + // Number of bytes that will be written. May need to vary by CPUID (see + // Intel 13.5). + virtual size_t Size() const = 0; + // Intel 13.4.2 XCOMP_BV. + virtual uint8_t XCompBVBit() const = 0; + // Write data to dst. Does not write padding. + virtual bool Copy(void* dst) const = 0; +}; + +//! \brief XSAVE_CET_U_FORMAT +class MinidumpXSaveAMD64CetU final : public MinidumpXSaveFeatureAMD64 { + public: + MinidumpXSaveAMD64CetU() {} + ~MinidumpXSaveAMD64CetU() {} + MinidumpXSaveAMD64CetU(const MinidumpXSaveAMD64CetU&) = delete; + MinidumpXSaveAMD64CetU& operator=(const MinidumpXSaveAMD64CetU&) = delete; + + size_t Size() const override { return sizeof(cet_u_); } + uint8_t XCompBVBit() const override { return XSTATE_CET_U; } + bool Copy(void* dst) const override; + bool InitializeFromSnapshot(const CPUContextX86_64* context_snapshot); + + private: + MinidumpAMD64XSaveFormatCetU cet_u_; +}; + //! \brief The writer for a MinidumpContextAMD64 structure in a minidump file. class MinidumpContextAMD64Writer final : public MinidumpContextWriter { public: @@ -157,6 +194,8 @@ class MinidumpContextAMD64Writer final : public MinidumpContextWriter { private: MinidumpContextAMD64 context_; + // These should be in order of XCompBVBit(). + std::vector> xsave_entries_; }; //! \brief The writer for a MinidumpContextARM structure in a minidump file. diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer_test.cc index 3216a906ba..f52d9baeb6 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_context_writer_test.cc @@ -16,6 +16,10 @@ #include +#include +#include + +#include "base/notreached.h" #include "gtest/gtest.h" #include "minidump/minidump_context.h" #include "minidump/test/minidump_context_test_util.h" @@ -28,7 +32,7 @@ namespace crashpad { namespace test { namespace { -template +template void EmptyContextTest(void (*expect_context)(uint32_t, const Context*, bool)) { Writer context_writer; StringFile string_file; @@ -36,13 +40,34 @@ void EmptyContextTest(void (*expect_context)(uint32_t, const Context*, bool)) { ASSERT_EQ(string_file.string().size(), sizeof(Context)); const Context* observed = - MinidumpWritableAtRVA(string_file.string(), 0); + MinidumpWritableAtRVA(string_file.string(), RVAType(0)); ASSERT_TRUE(observed); expect_context(0, observed, false); } -TEST(MinidumpContextWriter, MinidumpContextX86Writer) { +class TestTypeNames { + public: + template + static std::string GetName(int) { + if (std::is_same()) { + return "RVA"; + } + if (std::is_same()) { + return "RVA64"; + } + NOTREACHED(); + return ""; + } +}; + +template +class MinidumpContextWriter : public ::testing::Test {}; + +using RVATypes = ::testing::Types; +TYPED_TEST_SUITE(MinidumpContextWriter, RVATypes, TestTypeNames); + +TYPED_TEST(MinidumpContextWriter, MinidumpContextX86Writer) { StringFile string_file; { @@ -50,7 +75,7 @@ TEST(MinidumpContextWriter, MinidumpContextX86Writer) { // context. SCOPED_TRACE("zero"); - EmptyContextTest( + EmptyContextTest( ExpectMinidumpContextX86); } @@ -67,14 +92,15 @@ TEST(MinidumpContextWriter, MinidumpContextX86Writer) { ASSERT_EQ(string_file.string().size(), sizeof(MinidumpContextX86)); const MinidumpContextX86* observed = - MinidumpWritableAtRVA(string_file.string(), 0); + MinidumpWritableAtRVA(string_file.string(), + TypeParam(0)); ASSERT_TRUE(observed); ExpectMinidumpContextX86(kSeed, observed, false); } } -TEST(MinidumpContextWriter, MinidumpContextAMD64Writer) { +TYPED_TEST(MinidumpContextWriter, MinidumpContextAMD64Writer) { { // Make sure that a heap-allocated context writer has the proper alignment, // because it may be nonstandard. @@ -91,8 +117,9 @@ TEST(MinidumpContextWriter, MinidumpContextAMD64Writer) { // context. SCOPED_TRACE("zero"); - EmptyContextTest( - ExpectMinidumpContextAMD64); + EmptyContextTest(ExpectMinidumpContextAMD64); } { @@ -108,109 +135,137 @@ TEST(MinidumpContextWriter, MinidumpContextAMD64Writer) { ASSERT_EQ(string_file.string().size(), sizeof(MinidumpContextAMD64)); const MinidumpContextAMD64* observed = - MinidumpWritableAtRVA(string_file.string(), 0); + MinidumpWritableAtRVA(string_file.string(), + TypeParam(0)); ASSERT_TRUE(observed); ExpectMinidumpContextAMD64(kSeed, observed, false); } } -template +template void FromSnapshotTest(const CPUContext& snapshot_context, void (*expect_context)(uint32_t, const Context*, bool), uint32_t seed) { - std::unique_ptr context_writer = - MinidumpContextWriter::CreateFromSnapshot(&snapshot_context); + std::unique_ptr<::crashpad::MinidumpContextWriter> context_writer = + ::crashpad::MinidumpContextWriter::CreateFromSnapshot(&snapshot_context); ASSERT_TRUE(context_writer); StringFile string_file; ASSERT_TRUE(context_writer->WriteEverything(&string_file)); const Context* observed = - MinidumpWritableAtRVA(string_file.string(), 0); + MinidumpWritableAtRVA(string_file.string(), RVAType(0)); ASSERT_TRUE(observed); expect_context(seed, observed, true); } -TEST(MinidumpContextWriter, X86_FromSnapshot) { +TYPED_TEST(MinidumpContextWriter, X86_FromSnapshot) { constexpr uint32_t kSeed = 32; CPUContextX86 context_x86; CPUContext context; context.x86 = &context_x86; InitializeCPUContextX86(&context, kSeed); - FromSnapshotTest( + FromSnapshotTest( context, ExpectMinidumpContextX86, kSeed); } -TEST(MinidumpContextWriter, AMD64_FromSnapshot) { +TYPED_TEST(MinidumpContextWriter, AMD64_FromSnapshot) { constexpr uint32_t kSeed = 64; CPUContextX86_64 context_x86_64; CPUContext context; context.x86_64 = &context_x86_64; InitializeCPUContextX86_64(&context, kSeed); - FromSnapshotTest( + FromSnapshotTest( context, ExpectMinidumpContextAMD64, kSeed); } -TEST(MinidumpContextWriter, ARM_Zeros) { - EmptyContextTest( +TYPED_TEST(MinidumpContextWriter, AMD64_CetFromSnapshot) { + constexpr uint32_t kSeed = 77; + CPUContextX86_64 context_x86_64; + CPUContext context; + context.x86_64 = &context_x86_64; + InitializeCPUContextX86_64(&context, kSeed); + context_x86_64.xstate.enabled_features |= XSTATE_MASK_CET_U; + context_x86_64.xstate.cet_u.cetmsr = 1; + context_x86_64.xstate.cet_u.ssp = kSeed * kSeed; + // We cannot use FromSnapshotTest as we write more than the fixed context. + std::unique_ptr<::crashpad::MinidumpContextWriter> context_writer = + ::crashpad::MinidumpContextWriter::CreateFromSnapshot(&context); + ASSERT_TRUE(context_writer); + + StringFile string_file; + ASSERT_TRUE(context_writer->WriteEverything(&string_file)); + + const MinidumpContextAMD64* observed = + MinidumpWritableAtRVA(string_file.string(), + TypeParam(0)); + ASSERT_TRUE(observed); + + ExpectMinidumpContextAMD64(kSeed, observed, true); +} + +TYPED_TEST(MinidumpContextWriter, ARM_Zeros) { + EmptyContextTest( ExpectMinidumpContextARM); } -TEST(MinidumpContextWRiter, ARM64_Zeros) { - EmptyContextTest( +TYPED_TEST(MinidumpContextWriter, ARM64_Zeros) { + EmptyContextTest( ExpectMinidumpContextARM64); } -TEST(MinidumpContextWriter, ARM_FromSnapshot) { +TYPED_TEST(MinidumpContextWriter, ARM_FromSnapshot) { constexpr uint32_t kSeed = 32; CPUContextARM context_arm; CPUContext context; context.arm = &context_arm; InitializeCPUContextARM(&context, kSeed); - FromSnapshotTest( + FromSnapshotTest( context, ExpectMinidumpContextARM, kSeed); } -TEST(MinidumpContextWriter, ARM64_FromSnapshot) { +TYPED_TEST(MinidumpContextWriter, ARM64_FromSnapshot) { constexpr uint32_t kSeed = 64; CPUContextARM64 context_arm64; CPUContext context; context.arm64 = &context_arm64; InitializeCPUContextARM64(&context, kSeed); - FromSnapshotTest( + FromSnapshotTest( context, ExpectMinidumpContextARM64, kSeed); } -TEST(MinidumpContextWriter, MIPS_Zeros) { - EmptyContextTest( +TYPED_TEST(MinidumpContextWriter, MIPS_Zeros) { + EmptyContextTest( ExpectMinidumpContextMIPS); } -TEST(MinidumpContextWriter, MIPS64_Zeros) { - EmptyContextTest( - ExpectMinidumpContextMIPS64); +TYPED_TEST(MinidumpContextWriter, MIPS64_Zeros) { + EmptyContextTest(ExpectMinidumpContextMIPS64); } -TEST(MinidumpContextWriter, MIPS_FromSnapshot) { +TYPED_TEST(MinidumpContextWriter, MIPS_FromSnapshot) { constexpr uint32_t kSeed = 32; CPUContextMIPS context_mips; CPUContext context; context.mipsel = &context_mips; InitializeCPUContextMIPS(&context, kSeed); - FromSnapshotTest( + FromSnapshotTest( context, ExpectMinidumpContextMIPS, kSeed); } -TEST(MinidumpContextWriter, MIPS64_FromSnapshot) { +TYPED_TEST(MinidumpContextWriter, MIPS64_FromSnapshot) { constexpr uint32_t kSeed = 64; CPUContextMIPS64 context_mips; CPUContext context; context.mips64 = &context_mips; InitializeCPUContextMIPS64(&context, kSeed); - FromSnapshotTest( - context, ExpectMinidumpContextMIPS64, kSeed); + FromSnapshotTest(context, ExpectMinidumpContextMIPS64, kSeed); } } // namespace diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_exception_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_exception_writer_test.cc index 0243c175df..e09232fe7c 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_exception_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_exception_writer_test.cc @@ -14,10 +14,10 @@ #include "minidump/minidump_exception_writer.h" +#include #include #include -#include "base/cxx17_backports.h" #include "gtest/gtest.h" #include "minidump/minidump_context.h" #include "minidump/minidump_context_writer.h" @@ -86,7 +86,7 @@ void ExpectExceptionStream(const MINIDUMP_EXCEPTION_STREAM* expected, expected_exception.NumberParameters); EXPECT_EQ(observed->ExceptionRecord.__unusedAlignment, 0u); for (size_t index = 0; - index < base::size(observed_exception.ExceptionInformation); + index < std::size(observed_exception.ExceptionInformation); ++index) { EXPECT_EQ(observed_exception.ExceptionInformation[index], expected_exception.ExceptionInformation[index]); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_extensions.h b/thirdparty/sentry-native/external/crashpad/minidump/minidump_extensions.h index db0c33ec5e..959b8e423d 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_extensions.h +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_extensions.h @@ -93,6 +93,11 @@ enum MinidumpStreamType : uint32_t { //! \sa MemoryInfoListStream kMinidumpStreamTypeMemoryInfoList = MemoryInfoListStream, + //! \brief The stream type for MINIDUMP_THREAD_NAME_LIST. + //! + //! \sa ThreadNamesStream + kMinidumpStreamTypeThreadNameList = ThreadNamesStream, + //! \brief The last reserved minidump stream. //! //! \sa MemoryInfoListStream diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer.cc index 99ee2da06e..2c30abe169 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer.cc @@ -29,6 +29,7 @@ #endif #include "minidump/minidump_system_info_writer.h" #include "minidump/minidump_thread_id_map.h" +#include "minidump/minidump_thread_name_list_writer.h" #include "minidump/minidump_thread_writer.h" #include "minidump/minidump_unloaded_module_writer.h" #include "minidump/minidump_user_extension_stream_data_source.h" @@ -37,6 +38,7 @@ #include "snapshot/exception_snapshot.h" #include "snapshot/module_snapshot.h" #include "snapshot/process_snapshot.h" +#include "snapshot/thread_snapshot.h" #include "util/file/file_writer.h" #include "util/numeric/safe_assignment.h" @@ -81,6 +83,9 @@ void MinidumpFileWriter::InitializeFromSnapshot( auto misc_info = std::make_unique(); misc_info->InitializeFromSnapshot(process_snapshot); + if (misc_info->HasXStateData()) + header_.Flags = header_.Flags | MiniDumpWithAvxXStateContext; + add_stream_result = AddStream(std::move(misc_info)); DCHECK(add_stream_result); @@ -93,6 +98,21 @@ void MinidumpFileWriter::InitializeFromSnapshot( add_stream_result = AddStream(std::move(thread_list)); DCHECK(add_stream_result); + bool has_thread_name = false; + for (const ThreadSnapshot* thread_snapshot : process_snapshot->Threads()) { + if (!thread_snapshot->ThreadName().empty()) { + has_thread_name = true; + break; + } + } + if (has_thread_name) { + auto thread_name_list = std::make_unique(); + thread_name_list->InitializeFromSnapshot(process_snapshot->Threads(), + thread_id_map); + add_stream_result = AddStream(std::move(thread_name_list)); + DCHECK(add_stream_result); + } + const ExceptionSnapshot* exception_snapshot = process_snapshot->Exception(); if (exception_snapshot) { auto exception = std::make_unique(); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer_test.cc index efeaeab4cb..75c8525c82 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_file_writer_test.cc @@ -17,10 +17,10 @@ #include #include +#include #include #include -#include "base/cxx17_backports.h" #include "build/build_config.h" #include "gtest/gtest.h" #include "minidump/minidump_stream_writer.h" @@ -156,7 +156,7 @@ TEST(MinidumpFileWriter, AddUserExtensionStream) { minidump_file.SetTimestamp(kTimestamp); static constexpr uint8_t kStreamData[] = "Hello World!"; - constexpr size_t kStreamSize = base::size(kStreamData); + constexpr size_t kStreamSize = std::size(kStreamData); constexpr MinidumpStreamType kStreamType = static_cast(0x4d); @@ -418,12 +418,13 @@ TEST(MinidumpFileWriter, InitializeFromSnapshot_Exception) { // but the test should complete without failure. constexpr uint32_t kSnapshotTime = 0xfd469ab8; constexpr timeval kSnapshotTimeval = { -#ifdef OS_WIN - static_cast(kSnapshotTime), +#if BUILDFLAG(IS_WIN) + static_cast(kSnapshotTime), #else - static_cast(kSnapshotTime), + static_cast(kSnapshotTime), #endif - 0}; + 0 + }; TestProcessSnapshot process_snapshot; process_snapshot.SetSnapshotTime(kSnapshotTimeval); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_memory_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_memory_writer_test.cc index 02a352fcea..0ca0652d08 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_memory_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_memory_writer_test.cc @@ -14,9 +14,9 @@ #include "minidump/minidump_memory_writer.h" +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -342,7 +342,7 @@ TEST(MinidumpMemoryWriter, ExtraMemory) { TEST(MinidumpMemoryWriter, AddFromSnapshot) { MINIDUMP_MEMORY_DESCRIPTOR expect_memory_descriptors[3] = {}; - uint8_t values[base::size(expect_memory_descriptors)] = {}; + uint8_t values[std::size(expect_memory_descriptors)] = {}; expect_memory_descriptors[0].StartOfMemoryRange = 0; expect_memory_descriptors[0].Memory.DataSize = 0x1000; @@ -358,7 +358,7 @@ TEST(MinidumpMemoryWriter, AddFromSnapshot) { std::vector> memory_snapshots_owner; std::vector memory_snapshots; - for (size_t index = 0; index < base::size(expect_memory_descriptors); + for (size_t index = 0; index < std::size(expect_memory_descriptors); ++index) { memory_snapshots_owner.push_back(std::make_unique()); TestMemorySnapshot* memory_snapshot = memory_snapshots_owner.back().get(); @@ -397,7 +397,7 @@ TEST(MinidumpMemoryWriter, AddFromSnapshot) { TEST(MinidumpMemoryWriter, CoalesceExplicitMultiple) { MINIDUMP_MEMORY_DESCRIPTOR expect_memory_descriptors[4] = {}; - uint8_t values[base::size(expect_memory_descriptors)] = {}; + uint8_t values[std::size(expect_memory_descriptors)] = {}; expect_memory_descriptors[0].StartOfMemoryRange = 0; expect_memory_descriptors[0].Memory.DataSize = 1000; diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.cc index 64c3c2371b..51c91c4c90 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.cc @@ -14,26 +14,29 @@ #include "minidump/minidump_misc_info_writer.h" +#include #include #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "minidump/minidump_context_writer.h" #include "minidump/minidump_writer_util.h" #include "package.h" +#include "snapshot/cpu_context.h" #include "snapshot/process_snapshot.h" #include "snapshot/system_snapshot.h" +#include "snapshot/thread_snapshot.h" #include "util/file/file_writer.h" #include "util/numeric/in_range_cast.h" #include "util/numeric/safe_assignment.h" -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) #include -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) #include #endif @@ -67,7 +70,7 @@ std::string BuildString(const SystemSnapshot* system_snapshot) { return machine_description; } -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) // Converts the value of the __MAC_OS_X_VERSION_MIN_REQUIRED or // __MAC_OS_X_VERSION_MAX_ALLOWED macro from to a number // identifying the macOS version that it represents, in the same format used by @@ -93,7 +96,44 @@ int AvailabilityVersionToMacOSVersionNumber(int availability) { return availability; } -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) + +bool MaybeSetXStateData(const ProcessSnapshot* process_snapshot, + XSTATE_CONFIG_FEATURE_MSC_INFO* xstate) { + // Cannot set xstate data if there are no threads. + auto threads = process_snapshot->Threads(); + if (threads.size() == 0) + return false; + + // All threads should be the same as we request contexts in the same way. + auto context = threads.at(0)->Context(); + + // Only support AMD64. + if (context->architecture != kCPUArchitectureX86_64) + return false; + + // If no extended features, then we will just write the standard context. + if (context->x86_64->xstate.enabled_features == 0) + return false; + + xstate->SizeOfInfo = sizeof(*xstate); + // Needs to match the size of the context we'll write or the dump is invalid, + // so ask the first thread how large it will be. + auto context_writer = MinidumpContextWriter::CreateFromSnapshot(context); + xstate->ContextSize = + static_cast(context_writer->FreezeAndGetSizeOfObject()); + // Note: This isn't the same as xstateenabledfeatures! + xstate->EnabledFeatures = + context->x86_64->xstate.enabled_features | XSTATE_COMPACTION_ENABLE_MASK; + + // Note: if other XSAVE entries are to be supported they will be in order, + // and may have different offsets depending on what is saved. + if (context->x86_64->xstate.enabled_features & XSTATE_MASK_CET_U) { + xstate->Features[XSTATE_CET_U].Offset = kXSaveAreaFirstOffset; + xstate->Features[XSTATE_CET_U].Size = sizeof(MinidumpAMD64XSaveFormatCetU); + } + return true; +} } // namespace @@ -107,17 +147,17 @@ std::string MinidumpMiscInfoDebugBuildString() { // Caution: the minidump file format only has room for 39 UTF-16 code units // plus a UTF-16 NUL terminator. Don’t let strings get longer than this, or // they will be truncated and a message will be logged. -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) static constexpr char kOS[] = "mac"; -#elif defined(OS_IOS) +#elif BUILDFLAG(IS_IOS) static constexpr char kOS[] = "ios"; -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) static constexpr char kOS[] = "android"; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) static constexpr char kOS[] = "linux"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) static constexpr char kOS[] = "win"; -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) static constexpr char kOS[] = "fuchsia"; #else #error define kOS for this operating system @@ -145,12 +185,12 @@ std::string MinidumpMiscInfoDebugBuildString() { PACKAGE_VERSION, kOS); -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) debug_build_string += base::StringPrintf( ",%d,%d", AvailabilityVersionToMacOSVersionNumber(__MAC_OS_X_VERSION_MIN_REQUIRED), AvailabilityVersionToMacOSVersionNumber(__MAC_OS_X_VERSION_MAX_ALLOWED)); -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) debug_build_string += base::StringPrintf(",%d", __ANDROID_API__); #endif @@ -235,6 +275,11 @@ void MinidumpMiscInfoWriter::InitializeFromSnapshot( SetBuildString(BuildString(system_snapshot), internal::MinidumpMiscInfoDebugBuildString()); + + XSTATE_CONFIG_FEATURE_MSC_INFO xstate{}; + if (MaybeSetXStateData(process_snapshot, &xstate)) { + SetXStateData(xstate); + } } void MinidumpMiscInfoWriter::SetProcessID(uint32_t process_id) { @@ -311,7 +356,7 @@ void MinidumpMiscInfoWriter::SetTimeZone(uint32_t time_zone_id, internal::MinidumpWriterUtil::AssignUTF8ToUTF16( AsU16CStr(misc_info_.TimeZone.StandardName), - base::size(misc_info_.TimeZone.StandardName), + std::size(misc_info_.TimeZone.StandardName), standard_name); misc_info_.TimeZone.StandardDate = standard_date; @@ -319,7 +364,7 @@ void MinidumpMiscInfoWriter::SetTimeZone(uint32_t time_zone_id, internal::MinidumpWriterUtil::AssignUTF8ToUTF16( AsU16CStr(misc_info_.TimeZone.DaylightName), - base::size(misc_info_.TimeZone.DaylightName), + std::size(misc_info_.TimeZone.DaylightName), daylight_name); misc_info_.TimeZone.DaylightDate = daylight_date; @@ -337,11 +382,11 @@ void MinidumpMiscInfoWriter::SetBuildString( internal::MinidumpWriterUtil::AssignUTF8ToUTF16( AsU16CStr(misc_info_.BuildString), - base::size(misc_info_.BuildString), + std::size(misc_info_.BuildString), build_string); internal::MinidumpWriterUtil::AssignUTF8ToUTF16( AsU16CStr(misc_info_.DbgBldStr), - base::size(misc_info_.DbgBldStr), + std::size(misc_info_.DbgBldStr), debug_build_string); } @@ -353,6 +398,10 @@ void MinidumpMiscInfoWriter::SetXStateData( has_xstate_data_ = true; } +bool MinidumpMiscInfoWriter::HasXStateData() const { + return has_xstate_data_; +} + void MinidumpMiscInfoWriter::SetProcessCookie(uint32_t process_cookie) { DCHECK_EQ(state(), kStateMutable); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.h b/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.h index 9d89fe6480..cdaa0e4937 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.h +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer.h @@ -118,6 +118,9 @@ class MinidumpMiscInfoWriter final : public internal::MinidumpStreamWriter { //! \brief Sets MINIDUMP_MISC_INFO_5::XStateData. void SetXStateData(const XSTATE_CONFIG_FEATURE_MSC_INFO& xstate_data); + //! \brief Will this write extended context information? + bool HasXStateData() const; + //! \brief Sets the field referenced by #MINIDUMP_MISC5_PROCESS_COOKIE. void SetProcessCookie(uint32_t process_cookie); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer_test.cc index 18ac2966bb..c983414187 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_misc_info_writer_test.cc @@ -16,11 +16,10 @@ #include +#include #include #include -#include "base/compiler_specific.h" -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -126,7 +125,7 @@ void ExpectMiscInfoEqual( SCOPED_TRACE("Standard"); ExpectNULPaddedString16Equal(AsU16CStr(expected->TimeZone.StandardName), AsU16CStr(observed->TimeZone.StandardName), - base::size(expected->TimeZone.StandardName)); + std::size(expected->TimeZone.StandardName)); ExpectSystemTimeEqual(&expected->TimeZone.StandardDate, &observed->TimeZone.StandardDate); EXPECT_EQ(observed->TimeZone.StandardBias, expected->TimeZone.StandardBias); @@ -135,7 +134,7 @@ void ExpectMiscInfoEqual( SCOPED_TRACE("Daylight"); ExpectNULPaddedString16Equal(AsU16CStr(expected->TimeZone.DaylightName), AsU16CStr(observed->TimeZone.DaylightName), - base::size(expected->TimeZone.DaylightName)); + std::size(expected->TimeZone.DaylightName)); ExpectSystemTimeEqual(&expected->TimeZone.DaylightDate, &observed->TimeZone.DaylightDate); EXPECT_EQ(observed->TimeZone.DaylightBias, expected->TimeZone.DaylightBias); @@ -153,13 +152,13 @@ void ExpectMiscInfoEqual( SCOPED_TRACE("BuildString"); ExpectNULPaddedString16Equal(AsU16CStr(expected->BuildString), AsU16CStr(observed->BuildString), - base::size(expected->BuildString)); + std::size(expected->BuildString)); } { SCOPED_TRACE("DbgBldStr"); ExpectNULPaddedString16Equal(AsU16CStr(expected->DbgBldStr), AsU16CStr(observed->DbgBldStr), - base::size(expected->DbgBldStr)); + std::size(expected->DbgBldStr)); } } @@ -182,7 +181,7 @@ void ExpectMiscInfoEqual( EXPECT_EQ(observed_misc_info.XStateData.EnabledFeatures, expected_misc_info.XStateData.EnabledFeatures); for (size_t feature_index = 0; - feature_index < base::size(observed_misc_info.XStateData.Features); + feature_index < std::size(observed_misc_info.XStateData.Features); ++feature_index) { SCOPED_TRACE(base::StringPrintf("feature_index %" PRIuS, feature_index)); EXPECT_EQ(observed_misc_info.XStateData.Features[feature_index].Offset, @@ -409,7 +408,7 @@ TEST(MinidumpMiscInfoWriter, TimeZone) { base::UTF8ToUTF16(Crbug1189439Cast(kStandardName)); c16lcpy(AsU16CStr(expected.TimeZone.StandardName), standard_name_utf16.c_str(), - base::size(expected.TimeZone.StandardName)); + std::size(expected.TimeZone.StandardName)); memcpy(&expected.TimeZone.StandardDate, &kStandardDate, sizeof(expected.TimeZone.StandardDate)); @@ -418,7 +417,7 @@ TEST(MinidumpMiscInfoWriter, TimeZone) { base::UTF8ToUTF16(Crbug1189439Cast(kDaylightName)); c16lcpy(AsU16CStr(expected.TimeZone.DaylightName), daylight_name_utf16.c_str(), - base::size(expected.TimeZone.DaylightName)); + std::size(expected.TimeZone.DaylightName)); memcpy(&expected.TimeZone.DaylightDate, &kDaylightDate, sizeof(expected.TimeZone.DaylightDate)); @@ -436,11 +435,10 @@ TEST(MinidumpMiscInfoWriter, TimeZoneStringsOverflow) { constexpr uint32_t kTimeZoneId = 2; constexpr int32_t kBias = 300; - MINIDUMP_MISC_INFO_N tmp; - ALLOW_UNUSED_LOCAL(tmp); - std::string standard_name(base::size(tmp.TimeZone.StandardName) + 1, 's'); + [[maybe_unused]] MINIDUMP_MISC_INFO_N tmp; + std::string standard_name(std::size(tmp.TimeZone.StandardName) + 1, 's'); constexpr int32_t kStandardBias = 0; - std::string daylight_name(base::size(tmp.TimeZone.DaylightName), 'd'); + std::string daylight_name(std::size(tmp.TimeZone.DaylightName), 'd'); constexpr int32_t kDaylightBias = -60; // Test using kSystemTimeZero, because not all platforms will be able to @@ -471,7 +469,7 @@ TEST(MinidumpMiscInfoWriter, TimeZoneStringsOverflow) { std::u16string standard_name_utf16 = base::UTF8ToUTF16(standard_name); c16lcpy(AsU16CStr(expected.TimeZone.StandardName), standard_name_utf16.c_str(), - base::size(expected.TimeZone.StandardName)); + std::size(expected.TimeZone.StandardName)); memcpy(&expected.TimeZone.StandardDate, &kSystemTimeZero, sizeof(expected.TimeZone.StandardDate)); @@ -479,7 +477,7 @@ TEST(MinidumpMiscInfoWriter, TimeZoneStringsOverflow) { std::u16string daylight_name_utf16 = base::UTF8ToUTF16(daylight_name); c16lcpy(AsU16CStr(expected.TimeZone.DaylightName), daylight_name_utf16.c_str(), - base::size(expected.TimeZone.DaylightName)); + std::size(expected.TimeZone.DaylightName)); memcpy(&expected.TimeZone.DaylightDate, &kSystemTimeZero, sizeof(expected.TimeZone.DaylightDate)); @@ -511,12 +509,12 @@ TEST(MinidumpMiscInfoWriter, BuildStrings) { base::UTF8ToUTF16(Crbug1189439Cast(kBuildString)); c16lcpy(AsU16CStr(expected.BuildString), build_string_utf16.c_str(), - base::size(expected.BuildString)); + std::size(expected.BuildString)); std::u16string debug_build_string_utf16 = base::UTF8ToUTF16(Crbug1189439Cast(kDebugBuildString)); c16lcpy(AsU16CStr(expected.DbgBldStr), debug_build_string_utf16.c_str(), - base::size(expected.DbgBldStr)); + std::size(expected.DbgBldStr)); ExpectMiscInfoEqual(&expected, observed); } @@ -528,10 +526,9 @@ TEST(MinidumpMiscInfoWriter, BuildStringsOverflow) { MinidumpFileWriter minidump_file_writer; auto misc_info_writer = std::make_unique(); - MINIDUMP_MISC_INFO_N tmp; - ALLOW_UNUSED_LOCAL(tmp); - std::string build_string(base::size(tmp.BuildString) + 1, 'B'); - std::string debug_build_string(base::size(tmp.DbgBldStr), 'D'); + [[maybe_unused]] MINIDUMP_MISC_INFO_N tmp; + std::string build_string(std::size(tmp.BuildString) + 1, 'B'); + std::string debug_build_string(std::size(tmp.DbgBldStr), 'D'); misc_info_writer->SetBuildString(build_string, debug_build_string); @@ -548,12 +545,12 @@ TEST(MinidumpMiscInfoWriter, BuildStringsOverflow) { std::u16string build_string_utf16 = base::UTF8ToUTF16(build_string); c16lcpy(AsU16CStr(expected.BuildString), build_string_utf16.c_str(), - base::size(expected.BuildString)); + std::size(expected.BuildString)); std::u16string debug_build_string_utf16 = base::UTF8ToUTF16(debug_build_string); c16lcpy(AsU16CStr(expected.DbgBldStr), debug_build_string_utf16.c_str(), - base::size(expected.DbgBldStr)); + std::size(expected.DbgBldStr)); ExpectMiscInfoEqual(&expected, observed); } @@ -694,7 +691,7 @@ TEST(MinidumpMiscInfoWriter, Everything) { base::UTF8ToUTF16(Crbug1189439Cast(kStandardName)); c16lcpy(AsU16CStr(expected.TimeZone.StandardName), standard_name_utf16.c_str(), - base::size(expected.TimeZone.StandardName)); + std::size(expected.TimeZone.StandardName)); memcpy(&expected.TimeZone.StandardDate, &kSystemTimeZero, sizeof(expected.TimeZone.StandardDate)); @@ -703,7 +700,7 @@ TEST(MinidumpMiscInfoWriter, Everything) { base::UTF8ToUTF16(Crbug1189439Cast(kDaylightName)); c16lcpy(AsU16CStr(expected.TimeZone.DaylightName), daylight_name_utf16.c_str(), - base::size(expected.TimeZone.DaylightName)); + std::size(expected.TimeZone.DaylightName)); memcpy(&expected.TimeZone.DaylightDate, &kSystemTimeZero, sizeof(expected.TimeZone.DaylightDate)); @@ -712,12 +709,12 @@ TEST(MinidumpMiscInfoWriter, Everything) { base::UTF8ToUTF16(Crbug1189439Cast(kBuildString)); c16lcpy(AsU16CStr(expected.BuildString), build_string_utf16.c_str(), - base::size(expected.BuildString)); + std::size(expected.BuildString)); std::u16string debug_build_string_utf16 = base::UTF8ToUTF16(Crbug1189439Cast(kDebugBuildString)); c16lcpy(AsU16CStr(expected.DbgBldStr), debug_build_string_utf16.c_str(), - base::size(expected.DbgBldStr)); + std::size(expected.DbgBldStr)); ExpectMiscInfoEqual(&expected, observed); } @@ -761,18 +758,18 @@ TEST(MinidumpMiscInfoWriter, InitializeFromSnapshot) { expect_misc_info.TimeZone.Bias = 300; c16lcpy(AsU16CStr(expect_misc_info.TimeZone.StandardName), standard_time_name_utf16.c_str(), - base::size(expect_misc_info.TimeZone.StandardName)); + std::size(expect_misc_info.TimeZone.StandardName)); expect_misc_info.TimeZone.StandardBias = 0; c16lcpy(AsU16CStr(expect_misc_info.TimeZone.DaylightName), daylight_time_name_utf16.c_str(), - base::size(expect_misc_info.TimeZone.DaylightName)); + std::size(expect_misc_info.TimeZone.DaylightName)); expect_misc_info.TimeZone.DaylightBias = -60; c16lcpy(AsU16CStr(expect_misc_info.BuildString), build_string_utf16.c_str(), - base::size(expect_misc_info.BuildString)); + std::size(expect_misc_info.BuildString)); c16lcpy(AsU16CStr(expect_misc_info.DbgBldStr), debug_build_string_utf16.c_str(), - base::size(expect_misc_info.DbgBldStr)); + std::size(expect_misc_info.DbgBldStr)); const timeval kStartTime = { static_cast(expect_misc_info.ProcessCreateTime), 0}; diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc index 613314b3f4..ba5c5f223d 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc @@ -17,9 +17,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "gtest/gtest.h" #include "minidump/minidump_annotation_writer.h" #include "minidump/minidump_simple_string_dictionary_writer.h" @@ -155,9 +155,9 @@ TEST(MinidumpModuleCrashpadInfoWriter, FullModule) { sizeof(MinidumpSimpleStringDictionaryEntry) + sizeof(MinidumpAnnotationList) + 2 + // padding sizeof(MinidumpAnnotation) + sizeof(MinidumpUTF8String) + - base::size(kEntry) + 2 + // padding - sizeof(MinidumpUTF8String) + base::size(kKey) + - sizeof(MinidumpUTF8String) + base::size(kValue) + + std::size(kEntry) + 2 + // padding + sizeof(MinidumpUTF8String) + std::size(kKey) + + sizeof(MinidumpUTF8String) + std::size(kValue) + sizeof(MinidumpUTF8String) + annotation.name.size() + 1 + sizeof(MinidumpByteArray) + annotation.value.size()); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_writer_test.cc index 131575fabc..e189d77e8e 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_module_writer_test.cc @@ -17,9 +17,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -793,10 +793,10 @@ void InitializeTestModuleSnapshotFromMinidumpModule( TEST(MinidumpModuleWriter, InitializeFromSnapshot) { MINIDUMP_MODULE expect_modules[3] = {}; - const char* module_paths[base::size(expect_modules)] = {}; - const char* module_pdbs[base::size(expect_modules)] = {}; - UUID uuids[base::size(expect_modules)] = {}; - uint32_t ages[base::size(expect_modules)] = {}; + const char* module_paths[std::size(expect_modules)] = {}; + const char* module_pdbs[std::size(expect_modules)] = {}; + UUID uuids[std::size(expect_modules)] = {}; + uint32_t ages[std::size(expect_modules)] = {}; expect_modules[0].BaseOfImage = 0x100101000; expect_modules[0].SizeOfImage = 0xf000; @@ -887,7 +887,7 @@ TEST(MinidumpModuleWriter, InitializeFromSnapshot) { std::vector> module_snapshots_owner; std::vector module_snapshots; - for (size_t index = 0; index < base::size(expect_modules); ++index) { + for (size_t index = 0; index < std::size(expect_modules); ++index) { module_snapshots_owner.push_back(std::make_unique()); TestModuleSnapshot* module_snapshot = module_snapshots_owner.back().get(); InitializeTestModuleSnapshotFromMinidumpModule(module_snapshot, diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_rva_list_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_rva_list_writer_test.cc index f99d9435c2..adfed11287 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_rva_list_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_rva_list_writer_test.cc @@ -14,9 +14,9 @@ #include "minidump/minidump_rva_list_writer.h" +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -89,10 +89,10 @@ TEST(MinidumpRVAListWriter, ThreeChildren) { ASSERT_TRUE(list_writer.WriteEverything(&string_file)); const MinidumpRVAList* list = - MinidumpRVAListAtStart(string_file.string(), base::size(kValues)); + MinidumpRVAListAtStart(string_file.string(), std::size(kValues)); ASSERT_TRUE(list); - for (size_t index = 0; index < base::size(kValues); ++index) { + for (size_t index = 0; index < std::size(kValues); ++index) { SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index)); const uint32_t* child = MinidumpWritableAtRVA( diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_string_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_string_writer_test.cc index bfaf3a9aef..00b87653d9 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_string_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_string_writer_test.cc @@ -14,11 +14,12 @@ #include "minidump/minidump_string_writer.h" +#include #include +#include -#include "base/compiler_specific.h" -#include "base/cxx17_backports.h" #include "base/format_macros.h" +#include "base/notreached.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "gtest/gtest.h" @@ -31,7 +32,28 @@ namespace crashpad { namespace test { namespace { -TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) { +class TestTypeNames { + public: + template + static std::string GetName(int) { + if (std::is_same()) { + return "RVA"; + } + if (std::is_same()) { + return "RVA64"; + } + NOTREACHED(); + return ""; + } +}; + +template +class MinidumpStringWriter : public ::testing::Test {}; + +using RVATypes = ::testing::Types; +TYPED_TEST_SUITE(MinidumpStringWriter, RVATypes, TestTypeNames); + +TYPED_TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) { StringFile string_file; { @@ -42,9 +64,9 @@ TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) { ASSERT_EQ(string_file.string().size(), 6u); const MINIDUMP_STRING* minidump_string = - MinidumpStringAtRVA(string_file.string(), 0); + MinidumpStringAtRVA(string_file.string(), TypeParam(0)); EXPECT_TRUE(minidump_string); - EXPECT_EQ(MinidumpStringAtRVAAsString(string_file.string(), 0), + EXPECT_EQ(MinidumpStringAtRVAAsString(string_file.string(), TypeParam(0)), std::u16string()); } @@ -67,16 +89,15 @@ TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) { {4, "\360\220\204\202", 2, {0xd800, 0xdd02}}, // 𐄂 (non-BMP) }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { SCOPED_TRACE(base::StringPrintf( "index %" PRIuS ", input %s", index, kTestData[index].input_string)); // Make sure that the expected output string with its NUL terminator fits in // the space provided. - ASSERT_EQ( - kTestData[index] - .output_string[base::size(kTestData[index].output_string) - 1], - 0); + ASSERT_EQ(kTestData[index] + .output_string[std::size(kTestData[index].output_string) - 1], + 0); string_file.Reset(); crashpad::internal::MinidumpUTF16StringWriter string_writer; @@ -86,23 +107,22 @@ TEST(MinidumpStringWriter, MinidumpUTF16StringWriter) { const size_t expected_utf16_units_with_nul = kTestData[index].output_length + 1; - MINIDUMP_STRING* tmp; - ALLOW_UNUSED_LOCAL(tmp); + [[maybe_unused]] MINIDUMP_STRING* tmp; const size_t expected_utf16_bytes = expected_utf16_units_with_nul * sizeof(tmp->Buffer[0]); ASSERT_EQ(string_file.string().size(), sizeof(*tmp) + expected_utf16_bytes); const MINIDUMP_STRING* minidump_string = - MinidumpStringAtRVA(string_file.string(), 0); + MinidumpStringAtRVA(string_file.string(), TypeParam(0)); EXPECT_TRUE(minidump_string); std::u16string expect_string = std::u16string( kTestData[index].output_string, kTestData[index].output_length); - EXPECT_EQ(MinidumpStringAtRVAAsString(string_file.string(), 0), + EXPECT_EQ(MinidumpStringAtRVAAsString(string_file.string(), TypeParam(0)), expect_string); } } -TEST(MinidumpStringWriter, ConvertInvalidUTF8ToUTF16) { +TYPED_TEST(MinidumpStringWriter, ConvertInvalidUTF8ToUTF16) { StringFile string_file; static constexpr const char* kTestData[] = { @@ -114,7 +134,7 @@ TEST(MinidumpStringWriter, ConvertInvalidUTF8ToUTF16) { "\303\0\251", // NUL in middle of valid sequence }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { SCOPED_TRACE(base::StringPrintf( "index %" PRIuS ", input %s", index, kTestData[index])); string_file.Reset(); @@ -128,21 +148,20 @@ TEST(MinidumpStringWriter, ConvertInvalidUTF8ToUTF16) { // data written, and make sure that at least one U+FFFD replacement // character was written. const MINIDUMP_STRING* minidump_string = - MinidumpStringAtRVA(string_file.string(), 0); + MinidumpStringAtRVA(string_file.string(), TypeParam(0)); EXPECT_TRUE(minidump_string); - MINIDUMP_STRING* tmp; - ALLOW_UNUSED_LOCAL(tmp); + [[maybe_unused]] MINIDUMP_STRING* tmp; EXPECT_EQ( minidump_string->Length, string_file.string().size() - sizeof(*tmp) - sizeof(tmp->Buffer[0])); std::u16string output_string = - MinidumpStringAtRVAAsString(string_file.string(), 0); + MinidumpStringAtRVAAsString(string_file.string(), TypeParam(0)); EXPECT_FALSE(output_string.empty()); EXPECT_NE(output_string.find(0xfffd), std::u16string::npos); } } -TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) { +TYPED_TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) { StringFile string_file; { @@ -153,10 +172,11 @@ TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) { ASSERT_EQ(string_file.string().size(), 5u); const MinidumpUTF8String* minidump_string = - MinidumpUTF8StringAtRVA(string_file.string(), 0); + MinidumpUTF8StringAtRVA(string_file.string(), TypeParam(0)); EXPECT_TRUE(minidump_string); - EXPECT_EQ(MinidumpUTF8StringAtRVAAsString(string_file.string(), 0), - std::string()); + EXPECT_EQ( + MinidumpUTF8StringAtRVAAsString(string_file.string(), TypeParam(0)), + std::string()); } static constexpr struct { @@ -176,7 +196,7 @@ TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) { {4, "\360\220\204\202"}, // 𐄂 (non-BMP) }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { SCOPED_TRACE(base::StringPrintf( "index %" PRIuS ", input %s", index, kTestData[index].string)); @@ -192,10 +212,11 @@ TEST(MinidumpStringWriter, MinidumpUTF8StringWriter) { sizeof(MinidumpUTF8String) + expected_utf8_bytes_with_nul); const MinidumpUTF8String* minidump_string = - MinidumpUTF8StringAtRVA(string_file.string(), 0); + MinidumpUTF8StringAtRVA(string_file.string(), TypeParam(0)); EXPECT_TRUE(minidump_string); - EXPECT_EQ(MinidumpUTF8StringAtRVAAsString(string_file.string(), 0), - test_string); + EXPECT_EQ( + MinidumpUTF8StringAtRVAAsString(string_file.string(), TypeParam(0)), + test_string); } } @@ -249,11 +270,11 @@ void MinidumpStringListTest() { } } -TEST(MinidumpStringWriter, MinidumpUTF16StringList) { +TYPED_TEST(MinidumpStringWriter, MinidumpUTF16StringList) { MinidumpStringListTest(); } -TEST(MinidumpStringWriter, MinidumpUTF8StringList) { +TYPED_TEST(MinidumpStringWriter, MinidumpUTF8StringList) { MinidumpStringListTest(); } diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer.cc index 135010103b..bc9a5d65d3 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer.cc @@ -16,8 +16,9 @@ #include +#include + #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/notreached.h" #include "minidump/minidump_string_writer.h" #include "snapshot/system_snapshot.h" @@ -235,7 +236,7 @@ void MinidumpSystemInfoWriter::SetCPUX86VendorString( sizeof(registers) == sizeof(system_info_.Cpu.X86CpuInfo.VendorId), "VendorId sizes must be equal"); - for (size_t index = 0; index < base::size(registers); ++index) { + for (size_t index = 0; index < std::size(registers); ++index) { memcpy(®isters[index], &vendor[index * sizeof(*registers)], sizeof(*registers)); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer_test.cc index 206a8e41cc..81de730bd0 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_system_info_writer_test.cc @@ -20,7 +20,6 @@ #include #include -#include "base/compiler_specific.h" #include "gtest/gtest.h" #include "minidump/minidump_file_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" @@ -39,8 +38,7 @@ void GetSystemInfoStream(const std::string& file_contents, const MINIDUMP_SYSTEM_INFO** system_info, const MINIDUMP_STRING** csd_version) { // The expected number of bytes for the CSD version’s MINIDUMP_STRING::Buffer. - MINIDUMP_STRING* tmp; - ALLOW_UNUSED_LOCAL(tmp); + [[maybe_unused]] MINIDUMP_STRING* tmp; const size_t kCSDVersionBytes = csd_version_length * sizeof(tmp->Buffer[0]); const size_t kCSDVersionBytesWithNUL = kCSDVersionBytes + sizeof(tmp->Buffer[0]); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_id_map_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_id_map_test.cc index e972aebc9f..0883d9a554 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_id_map_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_id_map_test.cc @@ -16,9 +16,9 @@ #include +#include #include -#include "base/cxx17_backports.h" #include "gtest/gtest.h" #include "snapshot/test/test_thread_snapshot.h" @@ -41,8 +41,7 @@ class MinidumpThreadIDMapTest : public testing::Test { // testing::Test: void SetUp() override { - for (size_t index = 0; index < base::size(test_thread_snapshots_); - ++index) { + for (size_t index = 0; index < std::size(test_thread_snapshots_); ++index) { thread_snapshots_.push_back(&test_thread_snapshots_[index]); } } @@ -63,7 +62,7 @@ class MinidumpThreadIDMapTest : public testing::Test { } void SetThreadID(size_t index, uint64_t thread_id) { - ASSERT_LT(index, base::size(test_thread_snapshots_)); + ASSERT_LT(index, std::size(test_thread_snapshots_)); test_thread_snapshots_[index].SetThreadID(thread_id); } diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.cc new file mode 100644 index 0000000000..6f49f0cc99 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.cc @@ -0,0 +1,191 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "minidump/minidump_thread_name_list_writer.h" + +#include + +#include "base/logging.h" +#include "minidump/minidump_thread_id_map.h" +#include "snapshot/thread_snapshot.h" +#include "util/file/file_writer.h" +#include "util/numeric/safe_assignment.h" + +namespace crashpad { + +MinidumpThreadNameWriter::MinidumpThreadNameWriter() + : MinidumpWritable(), rva_of_thread_name_(), thread_id_(), name_() {} + +MinidumpThreadNameWriter::~MinidumpThreadNameWriter() {} + +void MinidumpThreadNameWriter::InitializeFromSnapshot( + const ThreadSnapshot* thread_snapshot, + const MinidumpThreadIDMap& thread_id_map) { + DCHECK_EQ(state(), kStateMutable); + + const auto it = thread_id_map.find(thread_snapshot->ThreadID()); + DCHECK(it != thread_id_map.end()); + SetThreadId(it->second); + SetThreadName(thread_snapshot->ThreadName()); +} + +RVA64 MinidumpThreadNameWriter::RvaOfThreadName() const { + DCHECK_EQ(state(), kStateWritable); + + return rva_of_thread_name_; +} + +uint32_t MinidumpThreadNameWriter::ThreadId() const { + DCHECK_EQ(state(), kStateWritable); + + return thread_id_; +} + +bool MinidumpThreadNameWriter::Freeze() { + DCHECK_EQ(state(), kStateMutable); + + name_->RegisterRVA(&rva_of_thread_name_); + + return MinidumpWritable::Freeze(); +} + +void MinidumpThreadNameWriter::SetThreadName(const std::string& name) { + DCHECK_EQ(state(), kStateMutable); + + if (!name_) { + name_.reset(new internal::MinidumpUTF16StringWriter()); + } + name_->SetUTF8(name); +} + +size_t MinidumpThreadNameWriter::SizeOfObject() { + DCHECK_GE(state(), kStateFrozen); + + // This object doesn’t directly write anything itself. Its parent writes the + // MINIDUMP_THREAD_NAME objects as part of a MINIDUMP_THREAD_NAME_LIST, and + // its children are responsible for writing themselves. + return 0; +} + +std::vector MinidumpThreadNameWriter::Children() { + DCHECK_GE(state(), kStateFrozen); + DCHECK(name_); + + std::vector children; + children.emplace_back(name_.get()); + + return children; +} + +bool MinidumpThreadNameWriter::WriteObject(FileWriterInterface* file_writer) { + DCHECK_EQ(state(), kStateWritable); + + // This object doesn’t directly write anything itself. Its + // MINIDUMP_THREAD_NAME is written by its parent as part of a + // MINIDUMP_THREAD_NAME_LIST, and its children are responsible for writing + // themselves. + return true; +} + +MinidumpThreadNameListWriter::MinidumpThreadNameListWriter() + : MinidumpStreamWriter(), thread_names_() {} + +MinidumpThreadNameListWriter::~MinidumpThreadNameListWriter() {} + +void MinidumpThreadNameListWriter::InitializeFromSnapshot( + const std::vector& thread_snapshots, + const MinidumpThreadIDMap& thread_id_map) { + DCHECK_EQ(state(), kStateMutable); + DCHECK(thread_names_.empty()); + + for (const ThreadSnapshot* thread_snapshot : thread_snapshots) { + auto thread = std::make_unique(); + thread->InitializeFromSnapshot(thread_snapshot, thread_id_map); + AddThreadName(std::move(thread)); + } +} + +void MinidumpThreadNameListWriter::AddThreadName( + std::unique_ptr thread_name) { + DCHECK_EQ(state(), kStateMutable); + + thread_names_.emplace_back(std::move(thread_name)); +} + +bool MinidumpThreadNameListWriter::Freeze() { + DCHECK_EQ(state(), kStateMutable); + + if (!MinidumpStreamWriter::Freeze()) { + return false; + } + + size_t thread_name_count = thread_names_.size(); + if (!AssignIfInRange(&thread_name_list_.NumberOfThreadNames, + thread_name_count)) { + LOG(ERROR) << "thread_name_count " << thread_name_count << " out of range"; + return false; + } + + return true; +} + +size_t MinidumpThreadNameListWriter::SizeOfObject() { + DCHECK_GE(state(), kStateFrozen); + + return sizeof(thread_name_list_) + + thread_names_.size() * sizeof(MINIDUMP_THREAD_NAME); +} + +std::vector +MinidumpThreadNameListWriter::Children() { + DCHECK_GE(state(), kStateFrozen); + + std::vector children; + children.reserve(thread_names_.size()); + for (const auto& thread_name : thread_names_) { + children.emplace_back(thread_name.get()); + } + + return children; +} + +bool MinidumpThreadNameListWriter::WriteObject( + FileWriterInterface* file_writer) { + DCHECK_EQ(state(), kStateWritable); + + WritableIoVec iov; + iov.iov_base = &thread_name_list_; + iov.iov_len = sizeof(thread_name_list_); + std::vector iovecs(1, iov); + iovecs.reserve(thread_names_.size() + 1); + + std::vector minidump_thread_names; + minidump_thread_names.reserve(thread_names_.size()); + for (const auto& thread_name : thread_names_) { + auto& minidump_thread_name = minidump_thread_names.emplace_back(); + minidump_thread_name.ThreadId = thread_name->ThreadId(); + minidump_thread_name.RvaOfThreadName = thread_name->RvaOfThreadName(); + iov.iov_base = &minidump_thread_name; + iov.iov_len = sizeof(minidump_thread_name); + iovecs.push_back(iov); + } + + return file_writer->WriteIoVec(&iovecs); +} + +MinidumpStreamType MinidumpThreadNameListWriter::StreamType() const { + return kMinidumpStreamTypeThreadNameList; +} + +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.h b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.h new file mode 100644 index 0000000000..f573111c49 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer.h @@ -0,0 +1,152 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_MINIDUMP_MINIDUMP_THREAD_NAME_LIST_WRITER_H_ +#define CRASHPAD_MINIDUMP_MINIDUMP_THREAD_NAME_LIST_WRITER_H_ + +#include +#include +#include +#include + +#include +#include + +#include "minidump/minidump_stream_writer.h" +#include "minidump/minidump_string_writer.h" +#include "minidump/minidump_thread_id_map.h" +#include "minidump/minidump_writable.h" + +namespace crashpad { + +//! \brief The writer for a MINIDUMP_THREAD_NAME object in a minidump file. +//! +//! Because MINIDUMP_THREAD_NAME objects only appear as elements of +//! MINIDUMP_THREAD_NAME_LIST objects, this class does not write any data on its +//! own. It makes its MINIDUMP_THREAD_NAME data available to its +//! MinidumpThreadNameListWriter parent, which writes it as part of a +//! MINIDUMP_THREAD_NAME_LIST. +class MinidumpThreadNameWriter final : public internal::MinidumpWritable { + public: + MinidumpThreadNameWriter(); + + MinidumpThreadNameWriter(const MinidumpThreadNameWriter&) = delete; + MinidumpThreadNameWriter& operator=(const MinidumpThreadNameWriter&) = delete; + + ~MinidumpThreadNameWriter() override; + + //! \brief Initializes the MINIDUMP_THREAD_NAME based on \a thread_snapshot. + //! + //! \param[in] thread_snapshot The thread snapshot to use as source data. + //! \param[in] thread_id_map A MinidumpThreadIDMap to be consulted to + //! determine the 32-bit minidump thread ID to use for \a thread_snapshot. + //! + //! \note Valid in #kStateMutable. + void InitializeFromSnapshot(const ThreadSnapshot* thread_snapshot, + const MinidumpThreadIDMap& thread_id_map); + + //! \brief Sets the ThreadId for MINIDUMP_THREAD_NAME::ThreadId. + void SetThreadId(uint32_t thread_id) { thread_id_ = thread_id; } + + //! \brief Gets the ThreadId for MINIDUMP_THREAD_NAME::ThreadId. + //! + //! \note Valid in #kStateWritable. + uint32_t ThreadId() const; + + //! \brief Sets MINIDUMP_THREAD_NAME::RvaOfThreadName. + void SetThreadName(const std::string& thread_name); + + //! \brief Returns an RVA64 which has been updated with the relative address + //! of the thread name. + //! + //! This method is expected to be called by a MinidumpThreadNameListWriter in + //! order to obtain the RVA64 of the thread name. + //! + //! \note Valid in #kStateWritable. + RVA64 RvaOfThreadName() const; + + private: + // MinidumpWritable: + bool Freeze() override; + size_t SizeOfObject() override; + std::vector Children() override; + bool WriteObject(FileWriterInterface* file_writer) override; + + // This exists as a separate field so MinidumpWritable::RegisterRVA() can be + // used on a guaranteed-aligned pointer (MINIDUMP_THREAD_NAME::RvaOfThreadName + // is not 64-bit aligned, causing issues on ARM). + RVA64 rva_of_thread_name_; + + // Although this class manages the data for a MINIDUMP_THREAD_NAME, it does + // not directly hold a MINIDUMP_THREAD_NAME, as that struct contains a + // non-aligned RVA64 field which prevents it use with + // MinidumpWritable::RegisterRVA(). + // + // Instead, this class individually holds the fields of the + // MINIDUMP_THREAD_NAME which are fetched by MinidumpThreadNameListWriter. + uint32_t thread_id_; + + std::unique_ptr name_; +}; + +//! \brief The writer for a MINIDUMP_THREAD_NAME_LIST stream in a minidump file, +//! containing a list of MINIDUMP_THREAD_NAME objects. +class MinidumpThreadNameListWriter final + : public internal::MinidumpStreamWriter { + public: + MinidumpThreadNameListWriter(); + + MinidumpThreadNameListWriter(const MinidumpThreadNameListWriter&) = delete; + MinidumpThreadNameListWriter& operator=(const MinidumpThreadNameListWriter&) = + delete; + + ~MinidumpThreadNameListWriter() override; + + //! \brief Adds an initialized MINIDUMP_THREAD_NAME for each thread in \a + //! thread_snapshots to the MINIDUMP_THREAD_NAME_LIST. + //! + //! \param[in] thread_snapshots The thread snapshots to use as source data. + //! \param[in] thread_id_map A MinidumpThreadIDMap previously built by + //! MinidumpThreadListWriter::InitializeFromSnapshot(). + //! + //! \note Valid in #kStateMutable. + void InitializeFromSnapshot( + const std::vector& thread_snapshots, + const MinidumpThreadIDMap& thread_id_map); + + //! \brief Adds a MinidumpThreadNameWriter to the MINIDUMP_THREAD_LIST. + //! + //! This object takes ownership of \a thread_name and becomes its parent in + //! the overall tree of internal::MinidumpWritable objects. + //! + //! \note Valid in #kStateMutable. + void AddThreadName(std::unique_ptr thread_name); + + private: + // MinidumpWritable: + bool Freeze() override; + size_t SizeOfObject() override; + std::vector Children() override; + bool WriteObject(FileWriterInterface* file_writer) override; + + // MinidumpStreamWriter: + MinidumpStreamType StreamType() const override; + + std::vector> thread_names_; + MINIDUMP_THREAD_NAME_LIST thread_name_list_; +}; + +} // namespace crashpad + +#endif // CRASHPAD_MINIDUMP_MINIDUMP_THREAD_NAME_LIST_WRITER_H_ diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer_test.cc new file mode 100644 index 0000000000..265c12e684 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_name_list_writer_test.cc @@ -0,0 +1,310 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "minidump/minidump_thread_name_list_writer.h" + +#include +#include +#include + +#include "base/compiler_specific.h" +#include "base/format_macros.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "gtest/gtest.h" +#include "minidump/minidump_file_writer.h" +#include "minidump/minidump_system_info_writer.h" +#include "minidump/test/minidump_file_writer_test_util.h" +#include "minidump/test/minidump_string_writer_test_util.h" +#include "minidump/test/minidump_writable_test_util.h" +#include "test/gtest_death.h" +#include "util/file/string_file.h" + +namespace crashpad { +namespace test { +namespace { + +// This returns the MINIDUMP_THREAD_NAME_LIST stream in |thread_name_list|. +void GetThreadNameListStream( + const std::string& file_contents, + const MINIDUMP_THREAD_NAME_LIST** thread_name_list) { + constexpr size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER); + const uint32_t kExpectedStreams = 1; + const size_t kThreadNameListStreamOffset = + kDirectoryOffset + kExpectedStreams * sizeof(MINIDUMP_DIRECTORY); + const size_t kThreadNameListOffset = + kThreadNameListStreamOffset + sizeof(MINIDUMP_THREAD_NAME_LIST); + + ASSERT_GE(file_contents.size(), kThreadNameListOffset); + + const MINIDUMP_DIRECTORY* directory; + const MINIDUMP_HEADER* header = + MinidumpHeaderAtStart(file_contents, &directory); + ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, kExpectedStreams, 0)); + ASSERT_TRUE(directory); + + ASSERT_EQ(directory[0].StreamType, kMinidumpStreamTypeThreadNameList); + EXPECT_EQ(directory[0].Location.Rva, kThreadNameListStreamOffset); + + *thread_name_list = + MinidumpWritableAtLocationDescriptor( + file_contents, directory[0].Location); + ASSERT_TRUE(thread_name_list); +} + +TEST(MinidumpThreadNameListWriter, EmptyThreadNameList) { + MinidumpFileWriter minidump_file_writer; + auto thread_name_list_writer = + std::make_unique(); + + ASSERT_TRUE( + minidump_file_writer.AddStream(std::move(thread_name_list_writer))); + + StringFile string_file; + ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); + + ASSERT_EQ(string_file.string().size(), + sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) + + sizeof(MINIDUMP_THREAD_NAME_LIST)); + + const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr; + ASSERT_NO_FATAL_FAILURE( + GetThreadNameListStream(string_file.string(), &thread_name_list)); + + EXPECT_EQ(thread_name_list->NumberOfThreadNames, 0u); +} + +// The MINIDUMP_THREAD_NAMEs |expected| and |observed| are compared against +// each other using Google Test assertions. +void ExpectThreadName(const MINIDUMP_THREAD_NAME* expected, + const MINIDUMP_THREAD_NAME* observed, + const std::string& file_contents, + const std::string& expected_thread_name) { + EXPECT_EQ(observed->ThreadId, expected->ThreadId); + EXPECT_NE(observed->RvaOfThreadName, 0u); + const std::string observed_thread_name = base::UTF16ToUTF8( + MinidumpStringAtRVAAsString(file_contents, observed->RvaOfThreadName)); + EXPECT_EQ(observed_thread_name, expected_thread_name); +} + +TEST(MinidumpThreadNameListWriter, OneThread) { + MinidumpFileWriter minidump_file_writer; + auto thread_list_writer = std::make_unique(); + + constexpr uint32_t kThreadID = 0x11111111; + const std::string kThreadName = "ariadne"; + + auto thread_name_list_writer = + std::make_unique(); + auto thread_name_writer = std::make_unique(); + thread_name_writer->SetThreadId(kThreadID); + thread_name_writer->SetThreadName(kThreadName); + thread_name_list_writer->AddThreadName(std::move(thread_name_writer)); + + ASSERT_TRUE( + minidump_file_writer.AddStream(std::move(thread_name_list_writer))); + + StringFile string_file; + ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); + + ASSERT_GT(string_file.string().size(), + sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) + + sizeof(MINIDUMP_THREAD_NAME_LIST) + + 1 * sizeof(MINIDUMP_THREAD_NAME)); + + const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr; + ASSERT_NO_FATAL_FAILURE( + GetThreadNameListStream(string_file.string(), &thread_name_list)); + + EXPECT_EQ(thread_name_list->NumberOfThreadNames, 1u); + + MINIDUMP_THREAD_NAME expected = {}; + expected.ThreadId = kThreadID; + + ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected, + &thread_name_list->ThreadNames[0], + string_file.string(), + kThreadName)); +} + +TEST(MinidumpThreadNameListWriter, OneThreadWithLeadingPadding) { + MinidumpFileWriter minidump_file_writer; + + // Add a stream before the MINIDUMP_THREAD_NAME_LIST to ensure the thread name + // MINIDUMP_STRING requires leading padding to align to a 4-byte boundary. + auto system_info_writer = std::make_unique(); + system_info_writer->SetCSDVersion(""); + ASSERT_TRUE(minidump_file_writer.AddStream(std::move(system_info_writer))); + + auto thread_list_writer = std::make_unique(); + + constexpr uint32_t kThreadID = 0x11111111; + const std::string kThreadName = "ariadne"; + + auto thread_name_list_writer = + std::make_unique(); + auto thread_name_writer = std::make_unique(); + thread_name_writer->SetThreadId(kThreadID); + thread_name_writer->SetThreadName(kThreadName); + thread_name_list_writer->AddThreadName(std::move(thread_name_writer)); + + ASSERT_TRUE( + minidump_file_writer.AddStream(std::move(thread_name_list_writer))); + + StringFile string_file; + ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); + + ASSERT_GT(string_file.string().size(), + sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) + + sizeof(MINIDUMP_THREAD_NAME_LIST) + + 1 * sizeof(MINIDUMP_THREAD_NAME)); + + const uint32_t kExpectedStreams = 2; + const MINIDUMP_DIRECTORY* directory; + const MINIDUMP_HEADER* header = + MinidumpHeaderAtStart(string_file.string(), &directory); + ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, kExpectedStreams, 0)); + ASSERT_TRUE(directory); + + ASSERT_EQ(directory[0].StreamType, kMinidumpStreamTypeSystemInfo); + ASSERT_EQ(directory[1].StreamType, kMinidumpStreamTypeThreadNameList); + + const MINIDUMP_THREAD_NAME_LIST* thread_name_list = + MinidumpWritableAtLocationDescriptor( + string_file.string(), directory[1].Location); + ASSERT_TRUE(thread_name_list); + + EXPECT_EQ(thread_name_list->NumberOfThreadNames, 1u); + + MINIDUMP_THREAD_NAME expected = {}; + expected.ThreadId = kThreadID; + + ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected, + &thread_name_list->ThreadNames[0], + string_file.string(), + kThreadName)); +} + +TEST(MinidumpThreadNameListWriter, TwoThreads_DifferentNames) { + MinidumpFileWriter minidump_file_writer; + auto thread_list_writer = std::make_unique(); + + constexpr uint32_t kFirstThreadID = 0x11111111; + const std::string kFirstThreadName = "ariadne"; + + constexpr uint32_t kSecondThreadID = 0x22222222; + const std::string kSecondThreadName = "theseus"; + + auto thread_name_list_writer = + std::make_unique(); + auto first_thread_name_writer = std::make_unique(); + first_thread_name_writer->SetThreadId(kFirstThreadID); + first_thread_name_writer->SetThreadName(kFirstThreadName); + thread_name_list_writer->AddThreadName(std::move(first_thread_name_writer)); + + auto second_thread_name_writer = std::make_unique(); + second_thread_name_writer->SetThreadId(kSecondThreadID); + second_thread_name_writer->SetThreadName(kSecondThreadName); + thread_name_list_writer->AddThreadName(std::move(second_thread_name_writer)); + + ASSERT_TRUE( + minidump_file_writer.AddStream(std::move(thread_name_list_writer))); + + StringFile string_file; + ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); + + ASSERT_GT(string_file.string().size(), + sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) + + sizeof(MINIDUMP_THREAD_NAME_LIST) + + 2 * sizeof(MINIDUMP_THREAD_NAME)); + + const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr; + ASSERT_NO_FATAL_FAILURE( + GetThreadNameListStream(string_file.string(), &thread_name_list)); + + EXPECT_EQ(thread_name_list->NumberOfThreadNames, 2u); + + MINIDUMP_THREAD_NAME expected = {}; + expected.ThreadId = kFirstThreadID; + + ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected, + &thread_name_list->ThreadNames[0], + string_file.string(), + kFirstThreadName)); + + expected.ThreadId = kSecondThreadID; + + ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected, + &thread_name_list->ThreadNames[1], + string_file.string(), + kSecondThreadName)); +} + +TEST(MinidumpThreadNameListWriter, TwoThreads_SameNames) { + MinidumpFileWriter minidump_file_writer; + auto thread_list_writer = std::make_unique(); + + constexpr uint32_t kFirstThreadID = 0x11111111; + const std::string kThreadName = "ariadne"; + + constexpr uint32_t kSecondThreadID = 0x22222222; + + auto thread_name_list_writer = + std::make_unique(); + auto first_thread_name_writer = std::make_unique(); + first_thread_name_writer->SetThreadId(kFirstThreadID); + first_thread_name_writer->SetThreadName(kThreadName); + thread_name_list_writer->AddThreadName(std::move(first_thread_name_writer)); + + auto second_thread_name_writer = std::make_unique(); + second_thread_name_writer->SetThreadId(kSecondThreadID); + second_thread_name_writer->SetThreadName(kThreadName); + thread_name_list_writer->AddThreadName(std::move(second_thread_name_writer)); + + ASSERT_TRUE( + minidump_file_writer.AddStream(std::move(thread_name_list_writer))); + + StringFile string_file; + ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file)); + + ASSERT_GT(string_file.string().size(), + sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) + + sizeof(MINIDUMP_THREAD_NAME_LIST) + + 2 * sizeof(MINIDUMP_THREAD_NAME)); + + const MINIDUMP_THREAD_NAME_LIST* thread_name_list = nullptr; + ASSERT_NO_FATAL_FAILURE( + GetThreadNameListStream(string_file.string(), &thread_name_list)); + + EXPECT_EQ(thread_name_list->NumberOfThreadNames, 2u); + + MINIDUMP_THREAD_NAME expected = {}; + expected.ThreadId = kFirstThreadID; + + ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected, + &thread_name_list->ThreadNames[0], + string_file.string(), + kThreadName)); + + expected.ThreadId = kSecondThreadID; + + ASSERT_NO_FATAL_FAILURE(ExpectThreadName(&expected, + &thread_name_list->ThreadNames[1], + string_file.string(), + kThreadName)); +} + +} // namespace +} // namespace test +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_writer_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_writer_test.cc index 924c5c11ea..9b0e064ca6 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_thread_writer_test.cc @@ -14,11 +14,11 @@ #include "minidump/minidump_thread_writer.h" +#include #include #include #include "base/compiler_specific.h" -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -531,10 +531,10 @@ template void RunInitializeFromSnapshotTest(bool thread_id_collision) { using MinidumpContextType = typename Traits::MinidumpContextType; MINIDUMP_THREAD expect_threads[3] = {}; - uint64_t thread_ids[base::size(expect_threads)] = {}; - uint8_t memory_values[base::size(expect_threads)] = {}; - uint32_t context_seeds[base::size(expect_threads)] = {}; - MINIDUMP_MEMORY_DESCRIPTOR tebs[base::size(expect_threads)] = {}; + uint64_t thread_ids[std::size(expect_threads)] = {}; + uint8_t memory_values[std::size(expect_threads)] = {}; + uint32_t context_seeds[std::size(expect_threads)] = {}; + MINIDUMP_MEMORY_DESCRIPTOR tebs[std::size(expect_threads)] = {}; constexpr size_t kTebSize = 1024; @@ -590,7 +590,7 @@ void RunInitializeFromSnapshotTest(bool thread_id_collision) { std::vector> thread_snapshots_owner; std::vector thread_snapshots; - for (size_t index = 0; index < base::size(expect_threads); ++index) { + for (size_t index = 0; index < std::size(expect_threads); ++index) { thread_snapshots_owner.push_back(std::make_unique()); TestThreadSnapshot* thread_snapshot = thread_snapshots_owner.back().get(); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.cc index 8f69c9c16b..e1d23bd7a3 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "util/file/file_writer.h" #include "util/numeric/safe_assignment.h" @@ -74,6 +75,12 @@ void MinidumpWritable::RegisterRVA(RVA* rva) { registered_rvas_.push_back(rva); } +void MinidumpWritable::RegisterRVA(RVA64* rva64) { + DCHECK_LE(state_, kStateFrozen); + + registered_rva64s_.push_back(rva64); +} + void MinidumpWritable::RegisterLocationDescriptor( MINIDUMP_LOCATION_DESCRIPTOR* location_descriptor) { DCHECK_LE(state_, kStateFrozen); @@ -81,12 +88,20 @@ void MinidumpWritable::RegisterLocationDescriptor( registered_location_descriptors_.push_back(location_descriptor); } +void MinidumpWritable::RegisterLocationDescriptor( + MINIDUMP_LOCATION_DESCRIPTOR64* location_descriptor64) { + DCHECK_LE(state_, kStateFrozen); + + registered_location_descriptor64s_.push_back(location_descriptor64); +} + MinidumpWritable::MinidumpWritable() : registered_rvas_(), + registered_rva64s_(), registered_location_descriptors_(), + registered_location_descriptor64s_(), leading_pad_bytes_(0), - state_(kStateMutable) { -} + state_(kStateMutable) {} bool MinidumpWritable::Freeze() { DCHECK_EQ(state_, kStateMutable); @@ -159,10 +174,10 @@ size_t MinidumpWritable::WillWriteAtOffset( return kInvalidSize; } - // Populate the RVA fields in other objects that have registered to point to - // this one. Typically, a parent object will have registered to point to its - // children, but this can also occur where no parent-child relationship - // exists. + // Populate the 32-bit RVA fields in other objects that have registered to + // point to this one. Typically, a parent object will have registered to + // point to its children, but this can also occur where no parent-child + // relationship exists. if (!registered_rvas_.empty() || !registered_location_descriptors_.empty()) { RVA local_rva; @@ -190,12 +205,45 @@ size_t MinidumpWritable::WillWriteAtOffset( } } - // This object is now considered writable. However, if it contains RVA or - // MINIDUMP_LOCATION_DESCRIPTOR fields, they may not be fully updated yet, - // because it’s the repsonsibility of these fields’ pointees to update them. - // Once WillWriteAtOffset has completed running for both phases on an entire - // tree, and the entire tree has moved into kStateFrozen, all RVA and - // MINIDUMP_LOCATION_DESCRIPTOR fields within that tree will be populated. + // Populate the 64-bit RVA fields in other objects that have registered to + // point to this one. Typically, a parent object will have registered to + // point to its children, but this can also occur where no parent-child + // relationship exists. + if (!registered_rva64s_.empty() || + !registered_location_descriptor64s_.empty()) { + RVA64 local_rva64; + if (!AssignIfInRange(&local_rva64, local_offset)) { + LOG(ERROR) << "offset " << local_offset << " out of range"; + return kInvalidSize; + } + + for (RVA64* rva64 : registered_rva64s_) { + *rva64 = local_rva64; + } + + if (!registered_location_descriptor64s_.empty()) { + decltype(registered_location_descriptor64s_[0]->DataSize) local_size; + if (!AssignIfInRange(&local_size, size)) { + LOG(ERROR) << "size " << size << " out of range"; + return kInvalidSize; + } + + for (MINIDUMP_LOCATION_DESCRIPTOR64* location_descriptor : + registered_location_descriptor64s_) { + location_descriptor->DataSize = local_size; + location_descriptor->Rva = local_rva64; + } + } + } + + // This object is now considered writable. However, if it contains RVA/RVA64 + // or MINIDUMP_LOCATION_DESCRIPTOR/MINIDUMP_LOCATION_DESCRIPTOR64 fields, + // they may not be fully updated yet, because it’s the repsonsibility of + // these fields’ pointees to update them. Once WillWriteAtOffset has + // completed running for both phases on an entire tree, and the entire tree + // has moved into kStateFrozen, all RVA/RVA64 and + // MINIDUMP_LOCATION_DESCRIPTOR/MINIDUMP_LOCATION_DESCRIPTOR64 fields within + // that tree will be populated. state_ = kStateWritable; } else { if (phase == kPhaseEarly) { @@ -245,7 +293,7 @@ bool MinidumpWritable::WritePaddingAndObject(FileWriterInterface* file_writer) { // The number of elements in kZeroes must be at least one less than the // maximum Alignment() ever encountered. static constexpr uint8_t kZeroes[kMaximumAlignment - 1] = {}; - DCHECK_LE(leading_pad_bytes_, base::size(kZeroes)); + DCHECK_LE(leading_pad_bytes_, std::size(kZeroes)); if (leading_pad_bytes_) { if (!file_writer->Write(&kZeroes, leading_pad_bytes_)) { diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.h b/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.h index bc36cb5c05..15d9241e08 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.h +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable.h @@ -70,6 +70,7 @@ class MinidumpWritable { // This is public instead of protected because objects of derived classes need // to be able to register their own pointers with distinct objects. void RegisterRVA(RVA* rva); + void RegisterRVA(RVA64* rva); //! \brief Registers a location descriptor as one that should point to the //! object on which this method is called. @@ -88,6 +89,8 @@ class MinidumpWritable { // to be able to register their own pointers with distinct objects. void RegisterLocationDescriptor( MINIDUMP_LOCATION_DESCRIPTOR* location_descriptor); + void RegisterLocationDescriptor( + MINIDUMP_LOCATION_DESCRIPTOR64* location_descriptor64); protected: //! \brief Identifies the state of an object. @@ -267,9 +270,15 @@ class MinidumpWritable { private: std::vector registered_rvas_; // weak + std::vector registered_rva64s_; // weak + // weak std::vector registered_location_descriptors_; + // weak + std::vector + registered_location_descriptor64s_; + size_t leading_pad_bytes_; State state_; }; diff --git a/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable_test.cc b/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable_test.cc index ef34e54225..2032b06363 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable_test.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/minidump_writable_test.cc @@ -485,14 +485,15 @@ TEST(MinidumpWritable, MinidumpWritable) { } } -class TestRVAMinidumpWritable final : public BaseTestMinidumpWritable { +template +class TTestRVAMinidumpWritable final : public BaseTestMinidumpWritable { public: - TestRVAMinidumpWritable() : BaseTestMinidumpWritable(), rva_() {} + TTestRVAMinidumpWritable() : BaseTestMinidumpWritable(), rva_() {} - TestRVAMinidumpWritable(const TestRVAMinidumpWritable&) = delete; - TestRVAMinidumpWritable& operator=(const TestRVAMinidumpWritable&) = delete; + TTestRVAMinidumpWritable(const TTestRVAMinidumpWritable&) = delete; + TTestRVAMinidumpWritable& operator=(const TTestRVAMinidumpWritable&) = delete; - ~TestRVAMinidumpWritable() {} + ~TTestRVAMinidumpWritable() {} void SetRVA(MinidumpWritable* other) { other->RegisterRVA(&rva_); } @@ -509,15 +510,46 @@ class TestRVAMinidumpWritable final : public BaseTestMinidumpWritable { } private: - RVA rva_; + RVAType rva_; }; -RVA RVAAtIndex(const std::string& string, size_t index) { - return *reinterpret_cast(&string[index * sizeof(RVA)]); +template +RVAType TRVAAtIndex(const std::string& string, size_t index) { + return *reinterpret_cast(&string[index * sizeof(RVAType)]); } -TEST(MinidumpWritable, RVA) { +template +struct TestNames {}; + +template <> +struct TestNames { + static constexpr char kName[] = "RVA"; +}; + +template <> +struct TestNames { + static constexpr char kName[] = "RVA64"; +}; + +class TestTypeNames { + public: + template + static std::string GetName(int) { + return std::string(TestNames::kName); + } +}; + +template +class MinidumpWritable : public ::testing::Test {}; + +using RVATypes = ::testing::Types; +TYPED_TEST_SUITE(MinidumpWritable, RVATypes, TestTypeNames); + +TYPED_TEST(MinidumpWritable, RVA) { StringFile string_file; + using TestRVAMinidumpWritable = TTestRVAMinidumpWritable; + const auto RVAAtIndex = TRVAAtIndex; + constexpr size_t kRVASize = sizeof(TypeParam); { SCOPED_TRACE("unset"); @@ -525,8 +557,8 @@ TEST(MinidumpWritable, RVA) { TestRVAMinidumpWritable rva_writable; EXPECT_TRUE(rva_writable.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 0 * sizeof(RVA)); + ASSERT_EQ(string_file.string().size(), kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 0 * kRVASize); rva_writable.Verify(); } @@ -537,8 +569,8 @@ TEST(MinidumpWritable, RVA) { rva_writable.SetRVA(&rva_writable); EXPECT_TRUE(rva_writable.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 0 * sizeof(RVA)); + ASSERT_EQ(string_file.string().size(), kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 0 * kRVASize); rva_writable.Verify(); } @@ -552,9 +584,9 @@ TEST(MinidumpWritable, RVA) { parent.AddChild(&child); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 2 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 0 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 1 * sizeof(RVA)); + ASSERT_EQ(string_file.string().size(), 2 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 0 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 1 * kRVASize); parent.Verify(); } @@ -567,9 +599,9 @@ TEST(MinidumpWritable, RVA) { parent.AddChild(&child); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 2 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 1 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 0 * sizeof(RVA)); + ASSERT_EQ(string_file.string().size(), 2 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 1 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 0 * kRVASize); parent.Verify(); } @@ -583,9 +615,9 @@ TEST(MinidumpWritable, RVA) { parent.AddChild(&child); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 2 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 1 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 0 * sizeof(RVA)); + ASSERT_EQ(string_file.string().size(), 2 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 1 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 0 * kRVASize); parent.Verify(); } @@ -607,28 +639,29 @@ TEST(MinidumpWritable, RVA) { child.AddChild(&grandchild_2); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 5 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 1 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 0 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 2), 1 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 3), 1 * sizeof(RVA)); - EXPECT_EQ(RVAAtIndex(string_file.string(), 4), 1 * sizeof(RVA)); + ASSERT_EQ(string_file.string().size(), 5 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 0), 1 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 1), 0 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 2), 1 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 3), 1 * kRVASize); + EXPECT_EQ(RVAAtIndex(string_file.string(), 4), 1 * kRVASize); parent.Verify(); } } -class TestLocationDescriptorMinidumpWritable final +template +class TTestLocationDescriptorMinidumpWritable final : public BaseTestMinidumpWritable { public: - TestLocationDescriptorMinidumpWritable() + TTestLocationDescriptorMinidumpWritable() : BaseTestMinidumpWritable(), location_descriptor_(), string_() {} - TestLocationDescriptorMinidumpWritable( - const TestLocationDescriptorMinidumpWritable&) = delete; - TestLocationDescriptorMinidumpWritable& operator=( - const TestLocationDescriptorMinidumpWritable&) = delete; + TTestLocationDescriptorMinidumpWritable( + const TTestLocationDescriptorMinidumpWritable&) = delete; + TTestLocationDescriptorMinidumpWritable& operator=( + const TTestLocationDescriptorMinidumpWritable&) = delete; - ~TestLocationDescriptorMinidumpWritable() {} + ~TTestLocationDescriptorMinidumpWritable() {} void SetLocationDescriptor(MinidumpWritable* other) { other->RegisterLocationDescriptor(&location_descriptor_); @@ -658,30 +691,61 @@ class TestLocationDescriptorMinidumpWritable final } private: - MINIDUMP_LOCATION_DESCRIPTOR location_descriptor_; + MinidumpLocationDescriptorType location_descriptor_; std::string string_; }; -struct LocationDescriptorAndData { - MINIDUMP_LOCATION_DESCRIPTOR location_descriptor; +template +struct TLocationDescriptorAndData { + MinidumpLocationDescriptorType location_descriptor; char string[1]; }; -const LocationDescriptorAndData* LDDAtIndex(const std::string& string, - size_t index) { - return reinterpret_cast(&string[index]); +template +const TLocationDescriptorAndData* TLDDAtIndex( + const std::string& string, + size_t index) { + return reinterpret_cast< + const TLocationDescriptorAndData*>( + &string[index]); } -TEST(MinidumpWritable, LocationDescriptor) { +template +class MinidumpWritableLocationDescriptor : public ::testing::Test {}; + +template <> +struct TestNames { + static constexpr char kName[] = "MINIDUMP_LOCATION_DESCRIPTOR"; +}; + +template <> +struct TestNames { + static constexpr char kName[] = "MINIDUMP_LOCATION_DESCRIPTOR64"; +}; + +using MinidumpLocationDescriptorTypes = + ::testing::Types; +TYPED_TEST_SUITE(MinidumpWritableLocationDescriptor, + MinidumpLocationDescriptorTypes, + TestTypeNames); + +TYPED_TEST(MinidumpWritableLocationDescriptor, LocationDescriptor) { StringFile string_file; + using LocationDescriptorAndData = TLocationDescriptorAndData; + const auto LDDAtIndex = TLDDAtIndex; + using TestLocationDescriptorMinidumpWritable = + TTestLocationDescriptorMinidumpWritable; + constexpr size_t kMinidumpLocationDescriptorSize = sizeof(TypeParam); + { SCOPED_TRACE("unset"); string_file.Reset(); TestLocationDescriptorMinidumpWritable location_descriptor_writable; EXPECT_TRUE(location_descriptor_writable.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 9u); + ASSERT_EQ(string_file.string().size(), kMinidumpLocationDescriptorSize + 1); const LocationDescriptorAndData* ldd = LDDAtIndex(string_file.string(), 0); EXPECT_EQ(ldd->location_descriptor.DataSize, 0u); EXPECT_EQ(ldd->location_descriptor.Rva, 0u); @@ -696,9 +760,10 @@ TEST(MinidumpWritable, LocationDescriptor) { &location_descriptor_writable); EXPECT_TRUE(location_descriptor_writable.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 9u); + ASSERT_EQ(string_file.string().size(), kMinidumpLocationDescriptorSize + 1); const LocationDescriptorAndData* ldd = LDDAtIndex(string_file.string(), 0); - EXPECT_EQ(ldd->location_descriptor.DataSize, 9u); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 1); EXPECT_EQ(ldd->location_descriptor.Rva, 0u); location_descriptor_writable.Verify(); } @@ -712,9 +777,10 @@ TEST(MinidumpWritable, LocationDescriptor) { location_descriptor_writable.SetString("zz"); EXPECT_TRUE(location_descriptor_writable.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 11u); + ASSERT_EQ(string_file.string().size(), kMinidumpLocationDescriptorSize + 3); const LocationDescriptorAndData* ldd = LDDAtIndex(string_file.string(), 0); - EXPECT_EQ(ldd->location_descriptor.DataSize, 11u); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 3); EXPECT_EQ(ldd->location_descriptor.Rva, 0u); EXPECT_STREQ("zz", ldd->string); location_descriptor_writable.Verify(); @@ -732,14 +798,18 @@ TEST(MinidumpWritable, LocationDescriptor) { parent.AddChild(&child); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 22u); + ASSERT_EQ(string_file.string().size(), + kMinidumpLocationDescriptorSize * 2 + 6); const LocationDescriptorAndData* ldd = LDDAtIndex(string_file.string(), 0); - EXPECT_EQ(ldd->location_descriptor.DataSize, 11u); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 3); EXPECT_EQ(ldd->location_descriptor.Rva, 0u); EXPECT_STREQ("yy", ldd->string); - ldd = LDDAtIndex(string_file.string(), 12); - EXPECT_EQ(ldd->location_descriptor.DataSize, 10u); - EXPECT_EQ(ldd->location_descriptor.Rva, 12u); + ldd = LDDAtIndex(string_file.string(), kMinidumpLocationDescriptorSize + 4); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 2); + EXPECT_EQ(ldd->location_descriptor.Rva, + kMinidumpLocationDescriptorSize + 4); EXPECT_STREQ("x", ldd->string); parent.Verify(); } @@ -755,12 +825,15 @@ TEST(MinidumpWritable, LocationDescriptor) { parent.AddChild(&child); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 23u); + ASSERT_EQ(string_file.string().size(), + kMinidumpLocationDescriptorSize * 2 + 7); const LocationDescriptorAndData* ldd = LDDAtIndex(string_file.string(), 0); - EXPECT_EQ(ldd->location_descriptor.DataSize, 11u); - EXPECT_EQ(ldd->location_descriptor.Rva, 12u); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 3); + EXPECT_EQ(ldd->location_descriptor.Rva, + kMinidumpLocationDescriptorSize + 4); EXPECT_STREQ("www", ldd->string); - ldd = LDDAtIndex(string_file.string(), 12); + ldd = LDDAtIndex(string_file.string(), kMinidumpLocationDescriptorSize + 4); EXPECT_EQ(ldd->location_descriptor.DataSize, 0u); EXPECT_EQ(ldd->location_descriptor.Rva, 0u); EXPECT_STREQ("vv", ldd->string); @@ -779,13 +852,17 @@ TEST(MinidumpWritable, LocationDescriptor) { parent.AddChild(&child); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 29u); + ASSERT_EQ(string_file.string().size(), + kMinidumpLocationDescriptorSize * 2 + 13); const LocationDescriptorAndData* ldd = LDDAtIndex(string_file.string(), 0); - EXPECT_EQ(ldd->location_descriptor.DataSize, 13u); - EXPECT_EQ(ldd->location_descriptor.Rva, 16u); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 5); + EXPECT_EQ(ldd->location_descriptor.Rva, + kMinidumpLocationDescriptorSize + 8); EXPECT_STREQ("uuuu", ldd->string); - ldd = LDDAtIndex(string_file.string(), 16); - EXPECT_EQ(ldd->location_descriptor.DataSize, 13u); + ldd = LDDAtIndex(string_file.string(), kMinidumpLocationDescriptorSize + 8); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 5); EXPECT_EQ(ldd->location_descriptor.Rva, 0u); EXPECT_STREQ("tttt", ldd->string); parent.Verify(); @@ -814,26 +891,38 @@ TEST(MinidumpWritable, LocationDescriptor) { child.AddChild(&grandchild_2); EXPECT_TRUE(parent.WriteEverything(&string_file)); - ASSERT_EQ(string_file.string().size(), 58u); + ASSERT_EQ(string_file.string().size(), + kMinidumpLocationDescriptorSize * 5 + 18); const LocationDescriptorAndData* ldd = LDDAtIndex(string_file.string(), 0); - EXPECT_EQ(ldd->location_descriptor.DataSize, 10u); - EXPECT_EQ(ldd->location_descriptor.Rva, 12u); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 2); + EXPECT_EQ(ldd->location_descriptor.Rva, + kMinidumpLocationDescriptorSize + 4); EXPECT_STREQ("s", ldd->string); - ldd = LDDAtIndex(string_file.string(), 12); + ldd = LDDAtIndex(string_file.string(), kMinidumpLocationDescriptorSize + 4); EXPECT_EQ(ldd->location_descriptor.DataSize, 0u); EXPECT_EQ(ldd->location_descriptor.Rva, 0u); EXPECT_STREQ("r", ldd->string); - ldd = LDDAtIndex(string_file.string(), 24); - EXPECT_EQ(ldd->location_descriptor.DataSize, 10u); - EXPECT_EQ(ldd->location_descriptor.Rva, 12u); + ldd = LDDAtIndex(string_file.string(), + kMinidumpLocationDescriptorSize * 2 + 8); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 2); + EXPECT_EQ(ldd->location_descriptor.Rva, + kMinidumpLocationDescriptorSize + 4); EXPECT_STREQ("q", ldd->string); - ldd = LDDAtIndex(string_file.string(), 36); - EXPECT_EQ(ldd->location_descriptor.DataSize, 10u); - EXPECT_EQ(ldd->location_descriptor.Rva, 12u); + ldd = LDDAtIndex(string_file.string(), + kMinidumpLocationDescriptorSize * 3 + 12); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 2); + EXPECT_EQ(ldd->location_descriptor.Rva, + kMinidumpLocationDescriptorSize + 4); EXPECT_STREQ("p", ldd->string); - ldd = LDDAtIndex(string_file.string(), 48); - EXPECT_EQ(ldd->location_descriptor.DataSize, 10u); - EXPECT_EQ(ldd->location_descriptor.Rva, 12u); + ldd = LDDAtIndex(string_file.string(), + kMinidumpLocationDescriptorSize * 4 + 16); + EXPECT_EQ(ldd->location_descriptor.DataSize, + kMinidumpLocationDescriptorSize + 2); + EXPECT_EQ(ldd->location_descriptor.Rva, + kMinidumpLocationDescriptorSize + 4); EXPECT_STREQ("o", ldd->string); parent.Verify(); } diff --git a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_context_test_util.cc b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_context_test_util.cc index 446e5a1526..06afacf460 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_context_test_util.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_context_test_util.cc @@ -17,7 +17,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -128,8 +129,7 @@ void InitializeMinidumpContextAMD64(MinidumpContextAMD64* context, context->ds = static_cast(value++); context->es = static_cast(value++); context->ss = static_cast(value++); - for (size_t index = 0; index < base::size(context->vector_register); - ++index) { + for (size_t index = 0; index < std::size(context->vector_register); ++index) { context->vector_register[index].lo = value++; context->vector_register[index].hi = value++; } @@ -152,7 +152,7 @@ void InitializeMinidumpContextARM(MinidumpContextARM* context, uint32_t seed) { uint32_t value = seed; - for (size_t index = 0; index < base::size(context->regs); ++index) { + for (size_t index = 0; index < std::size(context->regs); ++index) { context->regs[index] = value++; } context->fp = value++; @@ -163,7 +163,7 @@ void InitializeMinidumpContextARM(MinidumpContextARM* context, uint32_t seed) { context->pc = value++; context->cpsr = value++; - for (size_t index = 0; index < base::size(context->vfp); ++index) { + for (size_t index = 0; index < std::size(context->vfp); ++index) { context->vfp[index] = value++; } context->fpscr = value++; @@ -181,7 +181,7 @@ void InitializeMinidumpContextARM64(MinidumpContextARM64* context, uint32_t value = seed; - for (size_t index = 0; index < base::size(context->regs); ++index) { + for (size_t index = 0; index < std::size(context->regs); ++index) { context->regs[index] = value++; } context->fp = value++; @@ -190,7 +190,7 @@ void InitializeMinidumpContextARM64(MinidumpContextARM64* context, context->pc = value++; context->cpsr = value++; - for (size_t index = 0; index < base::size(context->fpsimd); ++index) { + for (size_t index = 0; index < std::size(context->fpsimd); ++index) { context->fpsimd[index].lo = value++; context->fpsimd[index].hi = value++; } @@ -210,7 +210,7 @@ void InitializeMinidumpContextMIPS(MinidumpContextMIPS* context, uint32_t value = seed; - for (size_t index = 0; index < base::size(context->regs); ++index) { + for (size_t index = 0; index < std::size(context->regs); ++index) { context->regs[index] = value++; } @@ -221,7 +221,7 @@ void InitializeMinidumpContextMIPS(MinidumpContextMIPS* context, context->status = value++; context->cause = value++; - for (size_t index = 0; index < base::size(context->fpregs.fregs); ++index) { + for (size_t index = 0; index < std::size(context->fpregs.fregs); ++index) { context->fpregs.fregs[index]._fp_fregs = static_cast(value++); } @@ -248,7 +248,7 @@ void InitializeMinidumpContextMIPS64(MinidumpContextMIPS64* context, uint64_t value = seed; - for (size_t index = 0; index < base::size(context->regs); ++index) { + for (size_t index = 0; index < std::size(context->regs); ++index) { context->regs[index] = value++; } @@ -259,7 +259,7 @@ void InitializeMinidumpContextMIPS64(MinidumpContextMIPS64* context, context->status = value++; context->cause = value++; - for (size_t index = 0; index < base::size(context->fpregs.dregs); ++index) { + for (size_t index = 0; index < std::size(context->fpregs.dregs); ++index) { context->fpregs.dregs[index] = static_cast(value++); } context->fpcsr = value++; @@ -294,33 +294,33 @@ void ExpectMinidumpContextFxsave(const FxsaveType* expected, EXPECT_EQ(observed->reserved_3, expected->reserved_3); EXPECT_EQ(observed->mxcsr, expected->mxcsr); EXPECT_EQ(observed->mxcsr_mask, expected->mxcsr_mask); - for (size_t st_mm_index = 0; st_mm_index < base::size(expected->st_mm); + for (size_t st_mm_index = 0; st_mm_index < std::size(expected->st_mm); ++st_mm_index) { SCOPED_TRACE(base::StringPrintf("st_mm_index %" PRIuS, st_mm_index)); EXPECT_EQ(BytesToHexString(observed->st_mm[st_mm_index].st, - base::size(observed->st_mm[st_mm_index].st)), + std::size(observed->st_mm[st_mm_index].st)), BytesToHexString(expected->st_mm[st_mm_index].st, - base::size(expected->st_mm[st_mm_index].st))); + std::size(expected->st_mm[st_mm_index].st))); EXPECT_EQ( BytesToHexString(observed->st_mm[st_mm_index].st_reserved, - base::size(observed->st_mm[st_mm_index].st_reserved)), + std::size(observed->st_mm[st_mm_index].st_reserved)), BytesToHexString(expected->st_mm[st_mm_index].st_reserved, - base::size(expected->st_mm[st_mm_index].st_reserved))); + std::size(expected->st_mm[st_mm_index].st_reserved))); } - for (size_t xmm_index = 0; xmm_index < base::size(expected->xmm); + for (size_t xmm_index = 0; xmm_index < std::size(expected->xmm); ++xmm_index) { EXPECT_EQ(BytesToHexString(observed->xmm[xmm_index], - base::size(observed->xmm[xmm_index])), + std::size(observed->xmm[xmm_index])), BytesToHexString(expected->xmm[xmm_index], - base::size(expected->xmm[xmm_index]))) + std::size(expected->xmm[xmm_index]))) << "xmm_index " << xmm_index; } EXPECT_EQ( - BytesToHexString(observed->reserved_4, base::size(observed->reserved_4)), - BytesToHexString(expected->reserved_4, base::size(expected->reserved_4))); + BytesToHexString(observed->reserved_4, std::size(observed->reserved_4)), + BytesToHexString(expected->reserved_4, std::size(expected->reserved_4))); EXPECT_EQ( - BytesToHexString(observed->available, base::size(observed->available)), - BytesToHexString(expected->available, base::size(expected->available))); + BytesToHexString(observed->available, std::size(observed->available)), + BytesToHexString(expected->available, std::size(expected->available))); } } // namespace @@ -345,11 +345,11 @@ void ExpectMinidumpContextX86( EXPECT_EQ(observed->fsave.fpu_cs, expected.fsave.fpu_cs); EXPECT_EQ(observed->fsave.fpu_dp, expected.fsave.fpu_dp); EXPECT_EQ(observed->fsave.fpu_ds, expected.fsave.fpu_ds); - for (size_t index = 0; index < base::size(expected.fsave.st); ++index) { + for (size_t index = 0; index < std::size(expected.fsave.st); ++index) { EXPECT_EQ(BytesToHexString(observed->fsave.st[index], - base::size(observed->fsave.st[index])), + std::size(observed->fsave.st[index])), BytesToHexString(expected.fsave.st[index], - base::size(expected.fsave.st[index]))) + std::size(expected.fsave.st[index]))) << "index " << index; } if (snapshot) { @@ -383,7 +383,15 @@ void ExpectMinidumpContextAMD64( MinidumpContextAMD64 expected; InitializeMinidumpContextAMD64(&expected, expect_seed); - EXPECT_EQ(observed->context_flags, expected.context_flags); + // Allow context_flags to include xstate bit - this is added if we will write + // an extended context, but is not generated in the fixed context for testing. + if ((observed->context_flags & kMinidumpContextAMD64Xstate) == + kMinidumpContextAMD64Xstate) { + EXPECT_EQ(observed->context_flags, + (expected.context_flags | kMinidumpContextAMD64Xstate)); + } else { + EXPECT_EQ(observed->context_flags, expected.context_flags); + } if (snapshot) { EXPECT_EQ(observed->p1_home, 0u); @@ -448,8 +456,7 @@ void ExpectMinidumpContextAMD64( ExpectMinidumpContextFxsave(&expected.fxsave, &observed->fxsave); - for (size_t index = 0; index < base::size(expected.vector_register); - ++index) { + for (size_t index = 0; index < std::size(expected.vector_register); ++index) { if (snapshot) { EXPECT_EQ(observed->vector_register[index].lo, 0u) << "index " << index; EXPECT_EQ(observed->vector_register[index].hi, 0u) << "index " << index; @@ -489,7 +496,7 @@ void ExpectMinidumpContextARM(uint32_t expect_seed, EXPECT_EQ(observed->context_flags, expected.context_flags); - for (size_t index = 0; index < base::size(expected.regs); ++index) { + for (size_t index = 0; index < std::size(expected.regs); ++index) { EXPECT_EQ(observed->regs[index], expected.regs[index]); } EXPECT_EQ(observed->fp, expected.fp); @@ -500,10 +507,10 @@ void ExpectMinidumpContextARM(uint32_t expect_seed, EXPECT_EQ(observed->cpsr, expected.cpsr); EXPECT_EQ(observed->fpscr, expected.fpscr); - for (size_t index = 0; index < base::size(expected.vfp); ++index) { + for (size_t index = 0; index < std::size(expected.vfp); ++index) { EXPECT_EQ(observed->vfp[index], expected.vfp[index]); } - for (size_t index = 0; index < base::size(expected.extra); ++index) { + for (size_t index = 0; index < std::size(expected.extra); ++index) { EXPECT_EQ(observed->extra[index], snapshot ? 0 : expected.extra[index]); } } @@ -516,14 +523,14 @@ void ExpectMinidumpContextARM64(uint32_t expect_seed, EXPECT_EQ(observed->context_flags, expected.context_flags); - for (size_t index = 0; index < base::size(expected.regs); ++index) { + for (size_t index = 0; index < std::size(expected.regs); ++index) { EXPECT_EQ(observed->regs[index], expected.regs[index]); } EXPECT_EQ(observed->cpsr, expected.cpsr); EXPECT_EQ(observed->fpsr, expected.fpsr); EXPECT_EQ(observed->fpcr, expected.fpcr); - for (size_t index = 0; index < base::size(expected.fpsimd); ++index) { + for (size_t index = 0; index < std::size(expected.fpsimd); ++index) { EXPECT_EQ(observed->fpsimd[index].lo, expected.fpsimd[index].lo); EXPECT_EQ(observed->fpsimd[index].hi, expected.fpsimd[index].hi); } @@ -537,7 +544,7 @@ void ExpectMinidumpContextMIPS(uint32_t expect_seed, EXPECT_EQ(observed->context_flags, expected.context_flags); - for (size_t index = 0; index < base::size(expected.regs); ++index) { + for (size_t index = 0; index < std::size(expected.regs); ++index) { EXPECT_EQ(observed->regs[index], expected.regs[index]); } @@ -548,7 +555,7 @@ void ExpectMinidumpContextMIPS(uint32_t expect_seed, EXPECT_EQ(observed->status, expected.status); EXPECT_EQ(observed->cause, expected.cause); - for (size_t index = 0; index < base::size(expected.fpregs.fregs); ++index) { + for (size_t index = 0; index < std::size(expected.fpregs.fregs); ++index) { EXPECT_EQ(observed->fpregs.fregs[index]._fp_fregs, expected.fpregs.fregs[index]._fp_fregs); } @@ -570,7 +577,7 @@ void ExpectMinidumpContextMIPS64(uint32_t expect_seed, EXPECT_EQ(observed->context_flags, expected.context_flags); - for (size_t index = 0; index < base::size(expected.regs); ++index) { + for (size_t index = 0; index < std::size(expected.regs); ++index) { EXPECT_EQ(observed->regs[index], expected.regs[index]); } @@ -581,7 +588,7 @@ void ExpectMinidumpContextMIPS64(uint32_t expect_seed, EXPECT_EQ(observed->status, expected.status); EXPECT_EQ(observed->cause, expected.cause); - for (size_t index = 0; index < base::size(expected.fpregs.dregs); ++index) { + for (size_t index = 0; index < std::size(expected.fpregs.dregs); ++index) { EXPECT_EQ(observed->fpregs.dregs[index], expected.fpregs.dregs[index]); } EXPECT_EQ(observed->fpcsr, expected.fpcsr); diff --git a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.cc b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.cc index a8eb5aa46a..0001bda0a3 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.cc @@ -25,8 +25,11 @@ namespace test { namespace { -template -const T* TMinidumpStringAtRVA(const std::string& file_contents, RVA rva) { +template < + typename T, + typename RVAType = RVA, + typename MinidumpLocationDescriptorType = MINIDUMP_LOCATION_DESCRIPTOR> +const T* TMinidumpStringAtRVA(const std::string& file_contents, RVAType rva) { const T* string_base = MinidumpWritableAtRVA(file_contents, rva); if (!string_base) { return nullptr; @@ -41,7 +44,7 @@ const T* TMinidumpStringAtRVA(const std::string& file_contents, RVA rva) { } // |Length| does not include space for the required NUL terminator. - MINIDUMP_LOCATION_DESCRIPTOR location; + MinidumpLocationDescriptorType location; location.DataSize = sizeof(*string_base) + string_base->Length + kCodeUnitSize; location.Rva = rva; @@ -62,11 +65,16 @@ const T* TMinidumpStringAtRVA(const std::string& file_contents, RVA rva) { return string; } -template +template StringType TMinidumpStringAtRVAAsString(const std::string& file_contents, - RVA rva) { + RVAType rva) { const MinidumpStringType* minidump_string = - TMinidumpStringAtRVA(file_contents, rva); + TMinidumpStringAtRVA(file_contents, rva); if (!minidump_string) { return StringType(); } @@ -82,24 +90,69 @@ StringType TMinidumpStringAtRVAAsString(const std::string& file_contents, const MINIDUMP_STRING* MinidumpStringAtRVA(const std::string& file_contents, RVA rva) { - return TMinidumpStringAtRVA(file_contents, rva); + return TMinidumpStringAtRVA(file_contents, rva); +} + +const MINIDUMP_STRING* MinidumpStringAtRVA(const std::string& file_contents, + RVA64 rva) { + return TMinidumpStringAtRVA(file_contents, + rva); } const MinidumpUTF8String* MinidumpUTF8StringAtRVA( const std::string& file_contents, RVA rva) { - return TMinidumpStringAtRVA(file_contents, rva); + return TMinidumpStringAtRVA(file_contents, rva); +} + +const MinidumpUTF8String* MinidumpUTF8StringAtRVA( + const std::string& file_contents, + RVA64 rva) { + return TMinidumpStringAtRVA(file_contents, + rva); } std::u16string MinidumpStringAtRVAAsString(const std::string& file_contents, RVA rva) { - return TMinidumpStringAtRVAAsString( + return TMinidumpStringAtRVAAsString( + file_contents, rva); +} + +std::u16string MinidumpStringAtRVAAsString(const std::string& file_contents, + RVA64 rva) { + return TMinidumpStringAtRVAAsString( file_contents, rva); } std::string MinidumpUTF8StringAtRVAAsString(const std::string& file_contents, RVA rva) { - return TMinidumpStringAtRVAAsString( + return TMinidumpStringAtRVAAsString( + file_contents, rva); +} + +std::string MinidumpUTF8StringAtRVAAsString(const std::string& file_contents, + RVA64 rva) { + return TMinidumpStringAtRVAAsString( file_contents, rva); } diff --git a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.h b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.h index c92027a70d..f2c0f04039 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.h +++ b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_string_writer_test_util.h @@ -20,6 +20,11 @@ #include +#include "minidump/minidump_extensions.h" +#include "minidump/test/minidump_writable_test_util.h" + +#include "gtest/gtest.h" + namespace crashpad { struct MinidumpUTF8String; @@ -44,6 +49,10 @@ namespace test { const MINIDUMP_STRING* MinidumpStringAtRVA(const std::string& file_contents, RVA rva); +//! \brief 64-bit specialization of MinidumpStringAtRVA. +const MINIDUMP_STRING* MinidumpStringAtRVA(const std::string& file_contents, + RVA64 rva); + //! \brief Returns a MinidumpUTF8String located within a minidump file’s //! contents. //! @@ -64,6 +73,11 @@ const MinidumpUTF8String* MinidumpUTF8StringAtRVA( const std::string& file_contents, RVA rva); +//! \brief 64-bit specialization of MinidumpUTF8StringAtRVA. +const MinidumpUTF8String* MinidumpUTF8StringAtRVA( + const std::string& file_contents, + RVA64 rva); + //! \brief Returns the contents of a MINIDUMP_STRING as a `std::u16string`. //! //! This function uses MinidumpStringAtRVA() to obtain a MINIDUMP_STRING, and @@ -80,6 +94,10 @@ const MinidumpUTF8String* MinidumpUTF8StringAtRVA( std::u16string MinidumpStringAtRVAAsString(const std::string& file_contents, RVA rva); +//! \brief 64-bit specialization of MinidumpStringAtRVAAsString. +std::u16string MinidumpStringAtRVAAsString(const std::string& file_contents, + RVA64 rva); + //! \brief Returns the contents of a MinidumpUTF8String as a `std::string`. //! //! This function uses MinidumpUTF8StringAtRVA() to obtain a MinidumpUTF8String, @@ -96,6 +114,10 @@ std::u16string MinidumpStringAtRVAAsString(const std::string& file_contents, std::string MinidumpUTF8StringAtRVAAsString(const std::string& file_contents, RVA rva); +//! \brief 64-bit specialization of MinidumpUTF8StringAtRVAAsString. +std::string MinidumpUTF8StringAtRVAAsString(const std::string& file_contents, + RVA64 rva); + } // namespace test } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.cc b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.cc index 2ae6a9b14c..429588dae6 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.cc +++ b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.cc @@ -21,6 +21,7 @@ #include "gtest/gtest.h" #include "util/file/file_writer.h" #include "util/misc/implicit_cast.h" +#include "util/numeric/in_range_cast.h" namespace crashpad { namespace test { @@ -39,25 +40,26 @@ namespace { //! //! Do not call this function. Use the typed version, MinidumpWritableAtRVA<>(), //! or another type-specific function. +template const void* MinidumpWritableAtRVAInternal(const std::string& file_contents, - RVA rva) { - if (rva >= file_contents.size()) { - EXPECT_LT(rva, file_contents.size()); + RVAType rva) { + const auto rva_offset = crashpad::InRangeCast(rva, file_contents.size()); + if (rva_offset >= file_contents.size()) { + EXPECT_LT(rva_offset, file_contents.size()); return nullptr; } - return &file_contents[rva]; + return &file_contents[rva_offset]; } -} // namespace - -const void* MinidumpWritableAtLocationDescriptorInternal( +template +const void* TMinidumpWritableAtLocationDescriptorInternal( const std::string& file_contents, - const MINIDUMP_LOCATION_DESCRIPTOR& location, + const MinidumpLocationDescriptorType& location, size_t expected_size, bool allow_oversized_data) { if (location.DataSize == 0) { - EXPECT_EQ(location.Rva, 0u); + EXPECT_EQ(location.Rva, RVAType(0)); return nullptr; } @@ -71,17 +73,42 @@ const void* MinidumpWritableAtLocationDescriptorInternal( return nullptr; } - RVA end = location.Rva + location.DataSize; + RVAType end = location.Rva + location.DataSize; if (end > file_contents.size()) { EXPECT_LE(end, file_contents.size()); return nullptr; } - const void* rv = MinidumpWritableAtRVAInternal(file_contents, location.Rva); + const void* rv = + MinidumpWritableAtRVAInternal(file_contents, location.Rva); return rv; } +} // namespace + +const void* MinidumpWritableAtLocationDescriptorInternal( + const std::string& file_contents, + const MINIDUMP_LOCATION_DESCRIPTOR& location, + size_t expected_size, + bool allow_oversized_data) { + return TMinidumpWritableAtLocationDescriptorInternal< + RVA, + MINIDUMP_LOCATION_DESCRIPTOR>( + file_contents, location, expected_size, allow_oversized_data); +} + +const void* MinidumpWritableAtLocationDescriptorInternal( + const std::string& file_contents, + const MINIDUMP_LOCATION_DESCRIPTOR64& location, + size_t expected_size, + bool allow_oversized_data) { + return TMinidumpWritableAtLocationDescriptorInternal< + RVA64, + MINIDUMP_LOCATION_DESCRIPTOR64>( + file_contents, location, expected_size, allow_oversized_data); +} + template <> const IMAGE_DEBUG_MISC* MinidumpWritableAtLocationDescriptor( const std::string& file_contents, @@ -189,6 +216,14 @@ struct MinidumpThreadListTraits { } }; +struct MinidumpThreadNameListTraits { + using ListType = MINIDUMP_THREAD_NAME_LIST; + enum : size_t { kElementSize = sizeof(MINIDUMP_THREAD_NAME) }; + static size_t ElementCount(const ListType* list) { + return list->NumberOfThreadNames; + } +}; + struct MinidumpHandleDataStreamTraits { using ListType = MINIDUMP_HANDLE_DATA_STREAM; enum : size_t { kElementSize = sizeof(MINIDUMP_HANDLE_DESCRIPTOR) }; @@ -282,6 +317,15 @@ MinidumpWritableAtLocationDescriptor( file_contents, location); } +template <> +const MINIDUMP_THREAD_NAME_LIST* +MinidumpWritableAtLocationDescriptor( + const std::string& file_contents, + const MINIDUMP_LOCATION_DESCRIPTOR& location) { + return MinidumpListAtLocationDescriptor( + file_contents, location); +} + template <> const MINIDUMP_HANDLE_DATA_STREAM* MinidumpWritableAtLocationDescriptor( diff --git a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.h b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.h index 9ebb9d0266..3a11fbf0a2 100644 --- a/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.h +++ b/thirdparty/sentry-native/external/crashpad/minidump/test/minidump_writable_test_util.h @@ -59,6 +59,17 @@ const void* MinidumpWritableAtLocationDescriptorInternal( size_t expected_size, bool allow_oversized_data); +//! \brief 64-bit specialization of +//! MinidumpWritableAtLocationDescriptorInternal. +//! +//! Do not call this function. Use the typed version, +//! MinidumpWritableAtLocationDescriptor<>(), or another type-specific function. +const void* MinidumpWritableAtLocationDescriptorInternal( + const std::string& file_contents, + const MINIDUMP_LOCATION_DESCRIPTOR64& location, + size_t expected_size, + bool allow_oversized_data); + //! \brief A traits class defining whether a minidump object type is required to //! appear only as a fixed-size object or if it is variable-sized. //! @@ -90,6 +101,7 @@ MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_LIST); MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MODULE_LIST); MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_UNLOADED_MODULE_LIST); MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_THREAD_LIST); +MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_THREAD_NAME_LIST); MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_HANDLE_DATA_STREAM); MINIDUMP_ALLOW_OVERSIZED_DATA(MINIDUMP_MEMORY_INFO_LIST); MINIDUMP_ALLOW_OVERSIZED_DATA(MinidumpModuleCrashpadInfoList); @@ -134,6 +146,22 @@ const T* TMinidumpWritableAtLocationDescriptor( MinidumpWritableTraits::kAllowOversizedData)); } +//! \brief 64-bit specialization of TMinidumpWritableAtLocationDescriptor. +//! +//! Do not call this function directly. Use +//! MinidumpWritableAtLocationDescriptor<>() instead. +template +const T* TMinidumpWritableAtLocationDescriptor( + const std::string& file_contents, + const MINIDUMP_LOCATION_DESCRIPTOR64& location) { + return reinterpret_cast( + MinidumpWritableAtLocationDescriptorInternal( + file_contents, + location, + sizeof(T), + MinidumpWritableTraits::kAllowOversizedData)); +} + //! \brief Returns a typed minidump object located within a minidump file’s //! contents, where the offset and size of the object are known. //! @@ -141,7 +169,8 @@ const T* TMinidumpWritableAtLocationDescriptor( //! checking than the default implementation: //! - With a MINIDUMP_HEADER template parameter, a template specialization //! ensures that the structure’s magic number and version fields are correct. -//! - With a MINIDUMP_MEMORY_LIST, MINIDUMP_THREAD_LIST, MINIDUMP_MODULE_LIST, +//! - With a MINIDUMP_MEMORY_LIST, MINIDUMP_THREAD_LIST, +//! MINIDUMP_THREAD_NAME_LIST, MINIDUMP_MODULE_LIST, //! MINIDUMP_MEMORY_INFO_LIST, MinidumpSimpleStringDictionary, or //! MinidumpAnnotationList template parameter, template specializations //! ensure that the size given by \a location matches the size expected of a @@ -168,6 +197,14 @@ const T* MinidumpWritableAtLocationDescriptor( return TMinidumpWritableAtLocationDescriptor(file_contents, location); } +//! \brief 64-bit specialization of MinidumpWritableAtLocationDescriptor. +template +const T* MinidumpWritableAtLocationDescriptor( + const std::string& file_contents, + const MINIDUMP_LOCATION_DESCRIPTOR64& location) { + return TMinidumpWritableAtLocationDescriptor(file_contents, location); +} + template <> const IMAGE_DEBUG_MISC* MinidumpWritableAtLocationDescriptor( const std::string& file_contents, @@ -202,6 +239,12 @@ MinidumpWritableAtLocationDescriptor( const std::string& file_contents, const MINIDUMP_LOCATION_DESCRIPTOR& location); +template <> +const MINIDUMP_THREAD_NAME_LIST* +MinidumpWritableAtLocationDescriptor( + const std::string& file_contents, + const MINIDUMP_LOCATION_DESCRIPTOR& location); + template <> const MINIDUMP_HANDLE_DATA_STREAM* MinidumpWritableAtLocationDescriptor( @@ -270,6 +313,15 @@ const T* MinidumpWritableAtRVA(const std::string& file_contents, RVA rva) { return MinidumpWritableAtLocationDescriptor(file_contents, location); } +//! \brief 64-bit specialization of MinidumpWritableAtRVA. +template +const T* MinidumpWritableAtRVA(const std::string& file_contents, RVA64 rva) { + MINIDUMP_LOCATION_DESCRIPTOR64 location; + location.DataSize = sizeof(T); + location.Rva = rva; + return MinidumpWritableAtLocationDescriptor(file_contents, location); +} + //! \brief An internal::MinidumpWritable that carries a `uint32_t` for testing. class TestUInt32MinidumpWritable final : public internal::MinidumpWritable { public: diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/BUILD.gn b/thirdparty/sentry-native/external/crashpad/snapshot/BUILD.gn index e3ad7f67e7..b331598283 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/snapshot/BUILD.gn @@ -254,7 +254,6 @@ crashpad_static_library("snapshot") { ] if (crashpad_is_win) { - deps += [ "../client" ] cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union libs = [ "powrprof.lib" ] } @@ -364,6 +363,7 @@ source_set("snapshot_test") { if (crashpad_is_ios) { sources += [ + "ios/memory_snapshot_ios_intermediate_dump_test.cc", "ios/process_snapshot_ios_intermediate_dump_test.cc", "mac/cpu_context_mac_test.cc", ] @@ -441,10 +441,6 @@ source_set("snapshot_test") { "../util", ] - if (crashpad_is_win) { - deps += [ "../client" ] - } - if (crashpad_is_ios) { deps += [ ":snapshot_test_ios_data", @@ -496,6 +492,7 @@ bundle_data("snapshot_test_ios_data") { sources = [ "ios/testdata/crash-1fa088dda0adb41459d063078a0f384a0bb8eefa", "ios/testdata/crash-5726011582644224", + "ios/testdata/crash-6605504629637120", ] outputs = [ "{{bundle_resources_dir}}/crashpad_test_data/" + diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/capture_memory.cc b/thirdparty/sentry-native/external/crashpad/snapshot/capture_memory.cc index 5c7ded46b1..cb8231bdb9 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/capture_memory.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/capture_memory.cc @@ -15,11 +15,15 @@ #include "snapshot/capture_memory.h" #include +#include +// dbghelp must be after windows.h. +#include + +#include #include #include -#include "base/cxx17_backports.h" #include "base/logging.h" #include "snapshot/memory_snapshot.h" @@ -86,6 +90,7 @@ void CaptureMemory::PointedToByContext(const CPUContext& context, MaybeCaptureMemoryAround(delegate, context.x86_64->r14); MaybeCaptureMemoryAround(delegate, context.x86_64->r15); MaybeCaptureMemoryAround(delegate, context.x86_64->rip); + // Note: Shadow stack region is directly captured. } else { MaybeCaptureMemoryAround(delegate, context.x86->eax); MaybeCaptureMemoryAround(delegate, context.x86->ebx); @@ -99,17 +104,17 @@ void CaptureMemory::PointedToByContext(const CPUContext& context, #elif defined(ARCH_CPU_ARM_FAMILY) if (context.architecture == kCPUArchitectureARM64) { MaybeCaptureMemoryAround(delegate, context.arm64->pc); - for (size_t i = 0; i < base::size(context.arm64->regs); ++i) { + for (size_t i = 0; i < std::size(context.arm64->regs); ++i) { MaybeCaptureMemoryAround(delegate, context.arm64->regs[i]); } } else { MaybeCaptureMemoryAround(delegate, context.arm->pc); - for (size_t i = 0; i < base::size(context.arm->regs); ++i) { + for (size_t i = 0; i < std::size(context.arm->regs); ++i) { MaybeCaptureMemoryAround(delegate, context.arm->regs[i]); } } #elif defined(ARCH_CPU_MIPS_FAMILY) - for (size_t i = 0; i < base::size(context.mipsel->regs); ++i) { + for (size_t i = 0; i < std::size(context.mipsel->regs); ++i) { MaybeCaptureMemoryAround(delegate, context.mipsel->regs[i]); } #else diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.cc b/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.cc index 643ad80f01..9b7b3f14f1 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.cc @@ -17,7 +17,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/notreached.h" #include "util/misc/arraysize.h" #include "util/misc/implicit_cast.h" @@ -58,7 +59,7 @@ void CPUContextX86::FxsaveToFsave(const Fxsave& fxsave, Fsave* fsave) { fsave->reserved_4 = 0; static_assert(ArraySize(fsave->st) == ArraySize(fxsave.st_mm), "FPU stack registers must be equivalent"); - for (size_t index = 0; index < base::size(fsave->st); ++index) { + for (size_t index = 0; index < std::size(fsave->st); ++index) { memcpy(fsave->st[index], fxsave.st_mm[index].st, sizeof(fsave->st[index])); } } @@ -80,7 +81,7 @@ void CPUContextX86::FsaveToFxsave(const Fsave& fsave, Fxsave* fxsave) { fxsave->mxcsr_mask = 0; static_assert(ArraySize(fxsave->st_mm) == ArraySize(fsave.st), "FPU stack registers must be equivalent"); - for (size_t index = 0; index < base::size(fsave.st); ++index) { + for (size_t index = 0; index < std::size(fsave.st); ++index) { memcpy(fxsave->st_mm[index].st, fsave.st[index], sizeof(fsave.st[index])); memset(fxsave->st_mm[index].st_reserved, 0, @@ -191,6 +192,35 @@ uint64_t CPUContext::StackPointer() const { } } +uint64_t CPUContext::ShadowStackPointer() const { + switch (architecture) { + case kCPUArchitectureX86: + case kCPUArchitectureARM: + case kCPUArchitectureARM64: + NOTREACHED(); + return 0; + case kCPUArchitectureX86_64: + return x86_64->xstate.cet_u.ssp; + default: + NOTREACHED(); + return ~0ull; + } +} + +bool CPUContext::HasShadowStack() const { + switch (architecture) { + case kCPUArchitectureX86: + case kCPUArchitectureARM: + case kCPUArchitectureARM64: + return false; + case kCPUArchitectureX86_64: + return x86_64->xstate.cet_u.cetmsr != 0; + default: + NOTREACHED(); + return false; + } +} + bool CPUContext::Is64Bit() const { switch (architecture) { case kCPUArchitectureX86_64: diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.h b/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.h index fb23c4679f..4e21b56c59 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context.h @@ -257,6 +257,16 @@ struct CPUContextX86_64 { uint64_t dr5; // obsolete, normally an alias for dr7 uint64_t dr6; uint64_t dr7; + + struct { + // If 0 then none of the xsave areas are valid. + uint64_t enabled_features; + // CET_U registers if XSTATE_CET_U bit is set in enabled_features. + struct { + uint64_t cetmsr; + uint64_t ssp; + } cet_u; + } xstate; }; //! \brief A context structure carrying ARM CPU state. @@ -369,9 +379,19 @@ struct CPUContext { //! context structure. uint64_t StackPointer() const; + //! \brief Returns the shadow stack pointer value from the context structure. + //! + //! This is a CPU architecture-independent method that is capable of + //! recovering the shadow stack pointer from any supported CPU architecture’s + //! context structure. + uint64_t ShadowStackPointer() const; + //! \brief Returns `true` if this context is for a 64-bit architecture. bool Is64Bit() const; + //! \brief Returns `true` if this context has an active shadow stack pointer. + bool HasShadowStack() const; + //! \brief The CPU architecture of a context structure. This field controls //! the expression of the union. CPUArchitecture architecture; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context_test.cc index b1340d6ee1..019c7694f5 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/cpu_context_test.cc @@ -18,7 +18,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "gtest/gtest.h" #include "test/hex_string.h" @@ -124,7 +125,7 @@ TEST(CPUContextX86, FxsaveToFsave) { &fxsave.st_mm[6].st, kExponentAllZero, false, kFractionAllZero); SetX87Register( &fxsave.st_mm[7].st, kExponentNormal, true, kFractionNormal); // valid - for (size_t index = 0; index < base::size(fxsave.st_mm); ++index) { + for (size_t index = 0; index < std::size(fxsave.st_mm); ++index) { memset(&fxsave.st_mm[index].st_reserved, 0x5a, sizeof(fxsave.st_mm[index].st_reserved)); @@ -148,10 +149,10 @@ TEST(CPUContextX86, FxsaveToFsave) { EXPECT_EQ(fsave.fpu_dp, fxsave.fpu_dp); EXPECT_EQ(fsave.fpu_ds, fxsave.fpu_ds); EXPECT_EQ(fsave.reserved_4, 0); - for (size_t index = 0; index < base::size(fsave.st); ++index) { - EXPECT_EQ(BytesToHexString(fsave.st[index], base::size(fsave.st[index])), + for (size_t index = 0; index < std::size(fsave.st); ++index) { + EXPECT_EQ(BytesToHexString(fsave.st[index], std::size(fsave.st[index])), BytesToHexString(fxsave.st_mm[index].st, - base::size(fxsave.st_mm[index].st))) + std::size(fxsave.st_mm[index].st))) << "index " << index; } } @@ -204,14 +205,14 @@ TEST(CPUContextX86, FsaveToFxsave) { EXPECT_EQ(fxsave.reserved_3, 0); EXPECT_EQ(fxsave.mxcsr, 0u); EXPECT_EQ(fxsave.mxcsr_mask, 0u); - for (size_t index = 0; index < base::size(fxsave.st_mm); ++index) { + for (size_t index = 0; index < std::size(fxsave.st_mm); ++index) { EXPECT_EQ(BytesToHexString(fxsave.st_mm[index].st, - base::size(fxsave.st_mm[index].st)), - BytesToHexString(fsave.st[index], base::size(fsave.st[index]))) + std::size(fxsave.st_mm[index].st)), + BytesToHexString(fsave.st[index], std::size(fsave.st[index]))) << "index " << index; EXPECT_EQ(BytesToHexString(fxsave.st_mm[index].st_reserved, - base::size(fxsave.st_mm[index].st_reserved)), - std::string(base::size(fxsave.st_mm[index].st_reserved) * 2, '0')) + std::size(fxsave.st_mm[index].st_reserved)), + std::string(std::size(fxsave.st_mm[index].st_reserved) * 2, '0')) << "index " << index; } size_t unused_len = sizeof(fxsave) - offsetof(decltype(fxsave), xmm); @@ -318,7 +319,7 @@ TEST(CPUContextX86, FxsaveToFsaveTagWord) { // In this set, everything is valid. fsw = 0 << 11; // top = 0: logical 0-7 maps to physical 0-7 fxsave_tag = 0xff; // nothing empty - for (size_t index = 0; index < base::size(st_mm); ++index) { + for (size_t index = 0; index < std::size(st_mm); ++index) { SetX87OrMMXRegister(&st_mm[index], kExponentNormal, true, kFractionAllZero); } EXPECT_EQ(CPUContextX86::FxsaveToFsaveTagWord(fsw, fxsave_tag, st_mm), 0); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test.cc index f5baa5bc68..73df677b53 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test.cc @@ -24,13 +24,13 @@ #include "test/scoped_module_handle.h" #include "test/test_paths.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include #include "snapshot/mac/process_snapshot_mac.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include "snapshot/win/process_snapshot_win.h" -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #include #include "snapshot/fuchsia/process_snapshot_fuchsia.h" #endif @@ -79,19 +79,19 @@ class ScopedUnsetCrashpadInfoOptions { }; CrashpadInfoClientOptions SelfProcessSnapshotAndGetCrashpadOptions() { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) ProcessSnapshotMac process_snapshot; EXPECT_TRUE(process_snapshot.Initialize(mach_task_self())); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) ProcessSnapshotWin process_snapshot; EXPECT_TRUE(process_snapshot.Initialize( GetCurrentProcess(), ProcessSuspensionState::kRunning, 0, 0)); -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) ProcessSnapshotFuchsia process_snapshot; EXPECT_TRUE(process_snapshot.Initialize(*zx::process::self())); #else #error Port. -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) CrashpadInfoClientOptions options; process_snapshot.GetCrashpadOptions(&options); @@ -144,7 +144,7 @@ TEST(CrashpadInfoClientOptions, OneModule) { EXPECT_EQ(options.crashpad_handler_behavior, TriState::kUnset); EXPECT_EQ(options.system_crash_reporter_forwarding, TriState::kUnset); EXPECT_EQ(options.gather_indirectly_referenced_memory, TriState::kEnabled); - EXPECT_EQ(options.indirectly_referenced_memory_cap, 1234u); + EXPECT_LE(options.indirectly_referenced_memory_cap, 1234u); } } @@ -154,19 +154,19 @@ TEST(CrashpadInfoClientOptions, TwoModules) { TestPaths::BuildArtifact(FILE_PATH_LITERAL("snapshot"), FILE_PATH_LITERAL("module"), TestPaths::FileType::kLoadableModule); -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) ScopedModuleHandle module( dlopen(module_path.value().c_str(), RTLD_LAZY | RTLD_LOCAL)); ASSERT_TRUE(module.valid()) << "dlopen " << module_path.value() << ": " << dlerror(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) ScopedModuleHandle module(LoadLibrary(module_path.value().c_str())); ASSERT_TRUE(module.valid()) << "LoadLibrary " << base::WideToUTF8(module_path.value()) << ": " << ErrorMessage(); #else #error Port. -#endif // OS_APPLE +#endif // BUILDFLAG(IS_POSIX) // Get the function pointer from the module. This wraps GetCrashpadInfo(), but // because it runs in the module, it returns the remote module’s CrashpadInfo @@ -252,19 +252,19 @@ TEST_P(CrashpadInfoSizes_ClientOptions, DifferentlySizedStruct) { TestPaths::BuildArtifact(FILE_PATH_LITERAL("snapshot"), artifact, TestPaths::FileType::kLoadableModule); -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) ScopedModuleHandle module( dlopen(module_path.value().c_str(), RTLD_LAZY | RTLD_LOCAL)); ASSERT_TRUE(module.valid()) << "dlopen " << module_path.value() << ": " << dlerror(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) ScopedModuleHandle module(LoadLibrary(module_path.value().c_str())); ASSERT_TRUE(module.valid()) << "LoadLibrary " << base::WideToUTF8(module_path.value()) << ": " << ErrorMessage(); #else #error Port. -#endif // OS_APPLE +#endif // BUILDFLAG(IS_POSIX) // Get the function pointer from the module. CrashpadInfo* (*TestModule_GetCrashpadInfo)() = diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test_module.cc b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test_module.cc index 357d35e659..48795e3c80 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test_module.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_client_options_test_module.cc @@ -15,12 +15,12 @@ #include "build/build_config.h" #include "client/crashpad_info.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #define EXPORT __attribute__((visibility("default"))) -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #define EXPORT __declspec(dllexport) -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) extern "C" { @@ -40,8 +40,8 @@ EXPORT crashpad::CrashpadInfo* TestModule_GetCrashpadInfo() { } // extern "C" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) { return TRUE; } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_module.cc b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_module.cc index 584f83b0b7..0a9186c249 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_module.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_module.cc @@ -16,11 +16,11 @@ #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) namespace crashpad { @@ -65,9 +65,9 @@ struct TestCrashpadInfo { // to get this test version to be interpreted as a genuine CrashpadInfo // structure. The size is set to the actual size of this structure (that’s kind // of the point of this test). -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) __attribute__(( -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) section(SEG_DATA ",crashpad_info"), #endif #if defined(ADDRESS_SANITIZER) @@ -75,12 +75,12 @@ __attribute__(( #endif // defined(ADDRESS_SANITIZER) visibility("hidden"), used)) -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #pragma section("CPADinfo", read, write) __declspec(allocate("CPADinfo")) -#else // !defined(OS_POSIX) && !defined(OS_WIN) +#else // !BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_WIN) #error Port -#endif // !defined(OS_POSIX) && !defined(OS_WIN) +#endif // !BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_WIN) TestCrashpadInfo g_test_crashpad_info = {'CPad', sizeof(TestCrashpadInfo), 1, @@ -105,14 +105,15 @@ TestCrashpadInfo g_test_crashpad_info = {'CPad', extern "C" { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) __attribute__((visibility("default"))) -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) __declspec(dllexport) #else #error Port -#endif // OS_POSIX -crashpad::TestCrashpadInfo* TestModule_GetCrashpadInfo() { +#endif // BUILDFLAG(IS_POSIX) +crashpad::TestCrashpadInfo* +TestModule_GetCrashpadInfo() { // Note that there's no need to do the back-reference here to the note on // POSIX like CrashpadInfo::GetCrashpadInfo() because the note .S file is // directly included into this test binary. @@ -121,8 +122,8 @@ crashpad::TestCrashpadInfo* TestModule_GetCrashpadInfo() { } // extern "C" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) { return TRUE; } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_note.S b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_note.S index 8b1a0bd842..ebc0d8f6d7 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_note.S +++ b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_info_size_test_note.S @@ -17,7 +17,7 @@ // that symbol to be in the dynamic symbol table. #include "util/misc/elf_note_types.h" -#include "util/misc/arm64_bti_note.S" +#include "util/misc/arm64_pac_bti.S" // namespace crashpad { // CrashpadInfo g_test_crashpad_info; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc index cedab59a72..ad75292bd7 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc @@ -20,11 +20,11 @@ #include "client/crashpad_info.h" #include "util/misc/as_underlying_type.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include "util/win/traits.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "util/linux/traits.h" -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #include "util/fuchsia/traits.h" #endif diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc index 3a1806a383..9c6e3c3723 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc @@ -30,7 +30,7 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "test/linux/fake_ptrace_connection.h" #endif @@ -109,7 +109,7 @@ void ExpectCrashpadInfo(ProcessType process, VMAddress extra_memory_address, VMAddress simple_annotations_address, VMAddress annotations_list_address) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc index b5289e7a7f..f7f18cbd69 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc @@ -32,7 +32,7 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "test/linux/fake_ptrace_connection.h" #endif @@ -94,7 +94,7 @@ void ExpectAnnotations(ProcessType process, bool is_64_bit, VMAddress simple_map_address, VMAddress annotation_list_address) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader.cc index 5ea14c0fe3..0b7d0145f2 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader.cc @@ -733,13 +733,13 @@ bool ElfImageReader::GetAddressFromDynamicArray(uint64_t tag, if (!dynamic_array_->GetValue(tag, log, address)) { return false; } -#if defined(OS_ANDROID) || defined(OS_FUCHSIA) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) // The GNU loader updates the dynamic array according to the load bias. // The Android and Fuchsia loaders only update the debug address. if (tag != DT_DEBUG) { *address += GetLoadBias(); } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) return true; } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test.cc index 2ea55ad10b..161eab0292 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test.cc @@ -30,12 +30,12 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) #include #include "base/fuchsia/fuchsia_logging.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "test/linux/fake_ptrace_connection.h" #include "util/linux/auxiliary_vector.h" @@ -45,7 +45,7 @@ #error Port. -#endif // OS_FUCHSIA +#endif // BUILDFLAG(IS_FUCHSIA) extern "C" { __attribute__((visibility("default"))) void ElfImageReaderTestExportedSymbol() { @@ -56,8 +56,7 @@ namespace crashpad { namespace test { namespace { - -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) void LocateExecutable(const ProcessType& process, ProcessMemory* memory, @@ -84,7 +83,7 @@ void LocateExecutable(const ProcessType& process, *elf_address = base; } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) void LocateExecutable(PtraceConnection* connection, ProcessMemory* memory, @@ -104,7 +103,7 @@ void LocateExecutable(PtraceConnection* connection, *elf_address = possible_mappings->Next()->range.Base(); } -#endif // OS_FUCHSIA +#endif // BUILDFLAG(IS_FUCHSIA) void ExpectSymbol(ElfImageReader* reader, const std::string& symbol_name, @@ -128,12 +127,12 @@ void ReadThisExecutableInTarget(ProcessType process, #endif // ARCH_CPU_64_BITS VMAddress elf_address; -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); LocateExecutable(&connection, &memory, &elf_address); -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) ProcessMemoryFuchsia memory; ASSERT_TRUE(memory.Initialize(process)); LocateExecutable(process, &memory, &elf_address); @@ -192,7 +191,7 @@ void ReadLibcInTarget(ProcessType process, constexpr bool am_64_bit = false; #endif // ARCH_CPU_64_BITS -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); @@ -301,7 +300,7 @@ TEST(ElfImageReader, OneModuleChild) { test.Run(); } -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) // crashpad_snapshot_test_both_dt_hash_styles is specially built and forced to // include both .hash and .gnu.hash sections. Linux, Android, and Fuchsia have @@ -356,7 +355,7 @@ TEST(ElfImageReader, DtHashAndDtGnuHashMatch) { EXPECT_EQ(from_dt_hash, from_dt_gnu_hash); } -#endif // OS_FUCHSIA +#endif // BUILDFLAG(IS_FUCHSIA) } // namespace } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test_note.S b/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test_note.S index 08f1829fe4..b6c17ff327 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test_note.S +++ b/thirdparty/sentry-native/external/crashpad/snapshot/elf/elf_image_reader_test_note.S @@ -13,7 +13,7 @@ // limitations under the License. #include "util/misc/elf_note_types.h" -#include "util/misc/arm64_bti_note.S" +#include "util/misc/arm64_pac_bti.S" #define NOTE_ALIGN 4 .section .note.crashpad.test,"a",%note diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/memory_map_region_snapshot_fuchsia.cc b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/memory_map_region_snapshot_fuchsia.cc index a5885b06c6..8d7f9b867e 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/memory_map_region_snapshot_fuchsia.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/memory_map_region_snapshot_fuchsia.cc @@ -14,8 +14,9 @@ #include "snapshot/fuchsia/memory_map_region_snapshot_fuchsia.h" +#include + #include "base/check_op.h" -#include "base/cxx17_backports.h" namespace crashpad { namespace internal { @@ -50,7 +51,7 @@ uint32_t MmuFlagsToProtectFlags(zx_vm_option_t flags) { const uint32_t index = flags & (ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_PERM_EXECUTE); - DCHECK_LT(index, base::size(mapping)); + DCHECK_LT(index, std::size(mapping)); const uint32_t protect_flags = mapping[index]; DCHECK_NE(protect_flags, 0u); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_reader_fuchsia_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_reader_fuchsia_test.cc index f5a8aea750..3c8f827001 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_reader_fuchsia_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_reader_fuchsia_test.cc @@ -20,9 +20,12 @@ #include #include -#include "base/cxx17_backports.h" +#include + +#include "base/strings/stringprintf.h" #include "gtest/gtest.h" #include "test/multiprocess_exec.h" +#include "test/scoped_set_thread_name.h" #include "test/test_paths.h" #include "util/fuchsia/scoped_task_suspend.h" @@ -31,11 +34,13 @@ namespace test { namespace { TEST(ProcessReaderFuchsia, SelfBasic) { + const ScopedSetThreadName scoped_set_thread_name("SelfBasic"); + ProcessReaderFuchsia process_reader; ASSERT_TRUE(process_reader.Initialize(*zx::process::self())); static constexpr char kTestMemory[] = "Some test memory"; - char buffer[base::size(kTestMemory)]; + char buffer[std::size(kTestMemory)]; ASSERT_TRUE(process_reader.Memory()->Read( reinterpret_cast(kTestMemory), sizeof(kTestMemory), &buffer)); EXPECT_STREQ(kTestMemory, buffer); @@ -74,7 +79,7 @@ TEST(ProcessReaderFuchsia, SelfBasic) { ZX_OK); EXPECT_EQ(threads[0].id, info.koid); EXPECT_EQ(threads[0].state, ZX_THREAD_STATE_RUNNING); - EXPECT_EQ(threads[0].name, "initial-thread"); + EXPECT_EQ(threads[0].name, "SelfBasic"); } constexpr char kTestMemory[] = "Read me from another process"; @@ -117,27 +122,44 @@ TEST(ProcessReaderFuchsia, ChildBasic) { test.Run(); } +struct ThreadData { + zx_handle_t port; + std::string name; +}; + void* SignalAndSleep(void* arg) { + const ThreadData* thread_data = reinterpret_cast(arg); + const ScopedSetThreadName scoped_set_thread_name(thread_data->name); zx_port_packet_t packet = {}; packet.type = ZX_PKT_TYPE_USER; - zx_port_queue(*reinterpret_cast(arg), &packet); + zx_port_queue(thread_data->port, &packet); zx_nanosleep(ZX_TIME_INFINITE); return nullptr; } CRASHPAD_CHILD_TEST_MAIN(ProcessReaderChildThreadsTestMain) { + const ScopedSetThreadName scoped_set_thread_name( + "ProcessReaderChildThreadsTest-Main"); + // Create 5 threads with stack sizes of 4096, 8192, ... zx_handle_t port; zx_status_t status = zx_port_create(0, &port); EXPECT_EQ(status, ZX_OK); constexpr size_t kNumThreads = 5; + struct ThreadData thread_data[kNumThreads] = {{0}}; + for (size_t i = 0; i < kNumThreads; ++i) { + thread_data[i] = { + .port = port, + .name = base::StringPrintf("ProcessReaderChildThreadsTest-%zu", i + 1), + }; pthread_attr_t attr; EXPECT_EQ(pthread_attr_init(&attr), 0); EXPECT_EQ(pthread_attr_setstacksize(&attr, (i + 1) * 4096), 0); pthread_t thread; - EXPECT_EQ(pthread_create(&thread, &attr, &SignalAndSleep, &port), 0); + EXPECT_EQ(pthread_create(&thread, &attr, &SignalAndSleep, &thread_data[i]), + 0); } // Wait until all threads are ready. @@ -178,10 +200,14 @@ class ThreadsChildTest : public MultiprocessExec { const auto& threads = process_reader.Threads(); EXPECT_EQ(threads.size(), 6u); + EXPECT_EQ(threads[0].name, "ProcessReaderChildThreadsTest-main"); + for (size_t i = 1; i < 6; ++i) { ASSERT_GT(threads[i].stack_regions.size(), 0u); EXPECT_GT(threads[i].stack_regions[0].size(), 0u); EXPECT_LE(threads[i].stack_regions[0].size(), i * 4096u); + EXPECT_EQ(threads[i].name, + base::StringPrintf("ProcessReaderChildThreadsTest-%zu", i)); } } }; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_snapshot_fuchsia_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_snapshot_fuchsia_test.cc index 496d97a82d..874f159054 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_snapshot_fuchsia_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/process_snapshot_fuchsia_test.cc @@ -12,17 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "snapshot/fuchsia/memory_map_region_snapshot_fuchsia.h" +#include "snapshot/fuchsia/process_snapshot_fuchsia.h" #include #include -#include "base/cxx17_backports.h" +#include + #include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" -#include "snapshot/fuchsia/process_snapshot_fuchsia.h" +#include "snapshot/fuchsia/memory_map_region_snapshot_fuchsia.h" #include "test/multiprocess_exec.h" #include "util/fuchsia/koid_utilities.h" #include "util/fuchsia/scoped_task_suspend.h" @@ -56,7 +57,7 @@ CRASHPAD_CHILD_TEST_MAIN(AddressSpaceChildTestMain) { // correctly. for (const auto& t : kTestMappingPermAndSizes) { zx_handle_t vmo = ZX_HANDLE_INVALID; - const size_t size = t.pages * PAGE_SIZE; + const size_t size = t.pages * zx_system_get_page_size(); zx_status_t status = zx_vmo_create(size, 0, &vmo); ZX_CHECK(status == ZX_OK, status) << "zx_vmo_create"; status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &vmo); @@ -111,8 +112,8 @@ class AddressSpaceTest : public MultiprocessExec { private: void MultiprocessParent() override { - uintptr_t test_addresses[base::size(kTestMappingPermAndSizes)]; - for (size_t i = 0; i < base::size(test_addresses); ++i) { + uintptr_t test_addresses[std::size(kTestMappingPermAndSizes)]; + for (size_t i = 0; i < std::size(test_addresses); ++i) { ASSERT_TRUE(ReadFileExactly( ReadPipeHandle(), &test_addresses[i], sizeof(test_addresses[i]))); } @@ -122,11 +123,11 @@ class AddressSpaceTest : public MultiprocessExec { ProcessSnapshotFuchsia process_snapshot; ASSERT_TRUE(process_snapshot.Initialize(*ChildProcess())); - for (size_t i = 0; i < base::size(test_addresses); ++i) { + for (size_t i = 0; i < std::size(test_addresses); ++i) { const auto& t = kTestMappingPermAndSizes[i]; EXPECT_TRUE(HasSingleMatchingMapping(process_snapshot.MemoryMap(), test_addresses[i], - t.pages * PAGE_SIZE, + t.pages * zx_system_get_page_size(), t.minidump_perm)) << base::StringPrintf( "index %zu, zircon_perm 0x%x, minidump_perm 0x%x", diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc index 369203ae3c..b12ee86152 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc @@ -25,6 +25,7 @@ ThreadSnapshotFuchsia::ThreadSnapshotFuchsia() context_arch_(), context_(), stack_(), + thread_name_(), thread_id_(ZX_KOID_INVALID), thread_specific_data_address_(0), initialized_() {} @@ -60,6 +61,7 @@ bool ThreadSnapshotFuchsia::Initialize( // TODO(scottmg): Handle split stack by adding other parts to ExtraMemory(). } + thread_name_ = thread.name; thread_id_ = thread.id; INITIALIZATION_STATE_SET_VALID(initialized_); @@ -81,6 +83,11 @@ uint64_t ThreadSnapshotFuchsia::ThreadID() const { return thread_id_; } +std::string ThreadSnapshotFuchsia::ThreadName() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return thread_name_; +} + int ThreadSnapshotFuchsia::SuspendCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); // There is not (currently) a suspend count for threads on Fuchsia. diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h index b91a514d92..5c804fb107 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h @@ -18,6 +18,8 @@ #include #include +#include + #include "build/build_config.h" #include "snapshot/cpu_context.h" #include "snapshot/fuchsia/process_reader_fuchsia.h" @@ -56,6 +58,7 @@ class ThreadSnapshotFuchsia final : public ThreadSnapshot { const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; @@ -71,6 +74,7 @@ class ThreadSnapshotFuchsia final : public ThreadSnapshot { #endif CPUContext context_; MemorySnapshotGeneric stack_; + std::string thread_name_; zx_koid_t thread_id_; zx_vaddr_t thread_specific_data_address_; InitializationStateDcheck initialized_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc b/thirdparty/sentry-native/external/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc index c4d99e77a6..7530912a9d 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc @@ -66,6 +66,13 @@ using Key = IntermediateDumpKey; ExceptionSnapshotIOSIntermediateDump::ExceptionSnapshotIOSIntermediateDump() : ExceptionSnapshot(), +#if defined(ARCH_CPU_X86_64) + context_x86_64_(), +#elif defined(ARCH_CPU_ARM64) + context_arm64_(), +#else +#error Port to your CPU architecture +#endif context_(), codes_(), thread_id_(0), @@ -131,10 +138,16 @@ bool ExceptionSnapshotIOSIntermediateDump::InitializeFromSignal( #endif } - GetDataValueFromMap(exception_data, Key::kSignalNumber, &exception_); - GetDataValueFromMap(exception_data, Key::kSignalCode, &exception_info_); + exception_ = EXC_SOFT_SIGNAL; + GetDataValueFromMap(exception_data, Key::kSignalNumber, &exception_info_); GetDataValueFromMap(exception_data, Key::kSignalAddress, &exception_address_); + codes_.push_back(exception_); + codes_.push_back(exception_info_); + uint32_t code; + GetDataValueFromMap(exception_data, Key::kSignalCode, &code); + codes_.push_back(code); + INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -373,11 +386,9 @@ void ExceptionSnapshotIOSIntermediateDump:: } #if defined(ARCH_CPU_X86_64) - context_x86_64_ = {}; context_x86_64_.rip = frames[0]; // instruction pointer context_x86_64_.rsp = frames[1]; #elif defined(ARCH_CPU_ARM64) - context_arm64_ = {}; context_arm64_.sp = 0; context_arm64_.pc = frames[0]; context_arm64_.regs[30] = frames[1]; // link register diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc b/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc index 8e521d904f..84275aa918 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.cc @@ -50,12 +50,37 @@ bool MemorySnapshotIOSIntermediateDump::Read(Delegate* delegate) const { const MemorySnapshot* MemorySnapshotIOSIntermediateDump::MergeWithOtherSnapshot( const MemorySnapshot* other) const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + auto other_snapshot = + reinterpret_cast(other); + + INITIALIZATION_STATE_DCHECK_VALID(other_snapshot->initialized_); + if (other_snapshot->address_ < address_) { + return other_snapshot->MergeWithOtherSnapshot(this); + } + CheckedRange merged(0, 0); if (!LoggingDetermineMergedRange(this, other, &merged)) return nullptr; auto result = std::make_unique(); result->Initialize(merged.base(), data_, merged.size()); + if (size_ == merged.size()) { + return result.release(); + } + + const uint8_t* data = reinterpret_cast(data_); + const uint8_t* other_data = + reinterpret_cast(other_snapshot->data_); + vm_size_t overlap = merged.size() - other_snapshot->size_; + result->merged_data_.reserve(merged.size()); + result->merged_data_.insert(result->merged_data_.end(), data, data + overlap); + result->merged_data_.insert(result->merged_data_.end(), + other_data, + other_data + other_snapshot->size_); + result->data_ = + reinterpret_cast(result->merged_data_.data()); + DCHECK_EQ(result->merged_data_.size(), merged.size()); return result.release(); } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h b/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h index a93200020c..244bbd8be4 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump.h @@ -15,6 +15,8 @@ #ifndef CRASHPAD_SNAPSHOT_IOS_INTERMEDIATE_DUMP_MEMORY_SNAPSHOT_IOS_INTERMEDIATEDUMP_H_ #define CRASHPAD_SNAPSHOT_IOS_INTERMEDIATE_DUMP_MEMORY_SNAPSHOT_IOS_INTERMEDIATEDUMP_H_ +#include + #include "snapshot/memory_snapshot.h" #include "util/misc/address_types.h" #include "util/misc/initialization_state_dcheck.h" @@ -55,6 +57,12 @@ class MemorySnapshotIOSIntermediateDump final : public MemorySnapshot { vm_address_t address_; vm_address_t data_; + + // Because the iOS snapshot memory region is owned by the intermediate dump, + // it's necessary to copy the merged data into a vector owned by the memory + // snapshot itself. + std::vector merged_data_; + vm_size_t size_; InitializationStateDcheck initialized_; }; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump_test.cc new file mode 100644 index 0000000000..bbe2a88bd5 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/memory_snapshot_ios_intermediate_dump_test.cc @@ -0,0 +1,161 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "snapshot/ios/memory_snapshot_ios_intermediate_dump.h" + +#include +#include + +#include "gtest/gtest.h" + +namespace crashpad { +namespace test { +namespace { + +using internal::MemorySnapshotIOSIntermediateDump; + +const vm_address_t kDefaultAddress = 0x1000; + +class ReadToString : public crashpad::MemorySnapshot::Delegate { + public: + const std::string& result() { return result_; } + + private: + // MemorySnapshot::Delegate: + bool MemorySnapshotDelegateRead(void* data, size_t size) override { + result_ = std::string(reinterpret_cast(data), size); + return true; + } + + std::string result_; +}; + +std::unique_ptr CreateMemorySnapshot( + vm_address_t address, + std::vector& data) { + auto memory = std::make_unique(); + memory->Initialize( + address, reinterpret_cast(data.data()), data.size()); + return memory; +} + +TEST(MemorySnapshotIOSIntermediateDumpTest, MergeSame) { + std::vector data(10, 'a'); + auto memory = CreateMemorySnapshot(kDefaultAddress, data); + std::unique_ptr merged( + memory->MergeWithOtherSnapshot(memory.get())); + EXPECT_EQ(merged->Address(), kDefaultAddress); + EXPECT_EQ(merged->Size(), data.size()); + ReadToString delegate; + merged->Read(&delegate); + EXPECT_EQ(delegate.result(), "aaaaaaaaaa"); +} + +TEST(MemorySnapshotIOSIntermediateDumpTest, MergeNoOverlap) { + std::vector data1(10, 'a'); + auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); + + std::vector data2(10, 'b'); + auto memory2 = CreateMemorySnapshot(kDefaultAddress + 10, data2); + + std::unique_ptr merged( + memory1->MergeWithOtherSnapshot(memory2.get())); + EXPECT_EQ(merged->Address(), kDefaultAddress); + EXPECT_EQ(merged->Size(), 20u); + ReadToString delegate; + merged->Read(&delegate); + EXPECT_EQ(delegate.result(), "aaaaaaaaaabbbbbbbbbb"); +} + +TEST(MemorySnapshotIOSIntermediateDumpTest, MergePartial) { + std::vector data1(10, 'a'); + auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); + + std::vector data2(10, 'b'); + auto memory2 = CreateMemorySnapshot(kDefaultAddress + 5, data2); + + std::unique_ptr merged( + memory1->MergeWithOtherSnapshot(memory2.get())); + EXPECT_EQ(merged->Address(), kDefaultAddress); + EXPECT_EQ(merged->Size(), 15u); + ReadToString delegate; + merged->Read(&delegate); + EXPECT_EQ(delegate.result(), "aaaaabbbbbbbbbb"); +} + +TEST(MemorySnapshotIOSIntermediateDumpTest, NoMerge) { + std::vector data1(10, 'a'); + auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); + + std::vector data2(10, 'b'); + auto memory2 = CreateMemorySnapshot(kDefaultAddress + 20, data2); + + std::unique_ptr merged( + memory1->MergeWithOtherSnapshot(memory2.get())); + EXPECT_EQ(merged.get(), nullptr); +} + +TEST(MemorySnapshotIOSIntermediateDumpTest, EnvelopeBiggerFirst) { + std::vector data1(30, 'a'); + auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); + + std::vector data2(10, 'b'); + auto memory2 = CreateMemorySnapshot(kDefaultAddress + 15, data2); + + std::unique_ptr merged( + memory1->MergeWithOtherSnapshot(memory2.get())); + EXPECT_EQ(merged->Address(), kDefaultAddress); + EXPECT_EQ(merged->Size(), data1.size()); + + ReadToString delegate; + merged->Read(&delegate); + EXPECT_EQ(delegate.result(), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); +} + +TEST(MemorySnapshotIOSIntermediateDumpTest, EnvelopeBiggerSecond) { + std::vector data1(10, 'a'); + auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); + + std::vector data2(20, 'b'); + auto memory2 = CreateMemorySnapshot(kDefaultAddress, data2); + + std::unique_ptr merged( + memory1->MergeWithOtherSnapshot(memory2.get())); + EXPECT_EQ(merged->Address(), kDefaultAddress); + EXPECT_EQ(merged->Size(), data2.size()); + + ReadToString delegate; + merged->Read(&delegate); + EXPECT_EQ(delegate.result(), "bbbbbbbbbbbbbbbbbbbb"); +} + +TEST(MemorySnapshotIOSIntermediateDumpTest, SmallerAddressSecond) { + std::vector data1(10, 'a'); + auto memory1 = CreateMemorySnapshot(kDefaultAddress, data1); + + std::vector data2(20, 'b'); + auto memory2 = CreateMemorySnapshot(kDefaultAddress - 10, data2); + + std::unique_ptr merged( + memory1->MergeWithOtherSnapshot(memory2.get())); + EXPECT_EQ(merged->Address(), kDefaultAddress - 10); + EXPECT_EQ(merged->Size(), data2.size()); + ReadToString delegate; + merged->Read(&delegate); + EXPECT_EQ(delegate.result(), "bbbbbbbbbbbbbbbbbbbb"); +} + +} // namespace +} // namespace test +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/module_snapshot_ios_intermediate_dump.cc b/thirdparty/sentry-native/external/crashpad/snapshot/ios/module_snapshot_ios_intermediate_dump.cc index cdef7697ce..b7541b73b8 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/ios/module_snapshot_ios_intermediate_dump.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/module_snapshot_ios_intermediate_dump.cc @@ -19,6 +19,7 @@ #include "base/files/file_path.h" #include "base/mac/mach_logging.h" +#include "client/annotation.h" #include "snapshot/ios/intermediate_dump_reader_util.h" #include "util/ios/ios_intermediate_dump_data.h" #include "util/ios/ios_intermediate_dump_list.h" @@ -81,8 +82,11 @@ bool ModuleSnapshotIOSIntermediateDump::Initialize( std::string name; if (!GetDataStringFromMap( annotation.get(), Key::kAnnotationName, &name) || - name.empty() || name.length() > 64) { // Annotation::kNameMaxLength - LOG(ERROR) << "Invalid annotation name length."; + name.empty() || name.length() > Annotation::kNameMaxLength) { + LOG(ERROR) << "Invalid annotation name (" << name + << "), size=" << name.size() + << ", max size=" << Annotation::kNameMaxLength + << ", discarding annotation."; continue; } @@ -94,8 +98,10 @@ bool ModuleSnapshotIOSIntermediateDump::Initialize( if (type_dump && value_dump && type_dump->GetValue(&type)) { const std::vector& bytes = value_dump->bytes(); uint64_t length = bytes.size(); - if (!bytes.data() || length > 20480) { // Annotation::kValueMaxSize - LOG(ERROR) << "Invalid annotation value length."; + if (!bytes.data() || length > Annotation::kValueMaxSize) { + LOG(ERROR) << "Invalid annotation value, size=" << length + << ", max size=" << Annotation::kValueMaxSize + << ", discarding annotation."; continue; } annotation_objects_.push_back(AnnotationSnapshot(name, type, bytes)); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc index 5f56082eb1..0a170e7bf7 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc @@ -51,7 +51,9 @@ class ReadToString : public crashpad::MemorySnapshot::Delegate { class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { protected: - // testing::Test: + ProcessSnapshotIOSIntermediateDumpTest() + : long_annotation_name_(Annotation::kNameMaxLength, 'a'), + long_annotation_value_(Annotation::kValueMaxSize, 'b') {} void SetUp() override { path_ = temp_dir_.path().Append("dump_file"); @@ -61,6 +63,7 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { } void TearDown() override { + EXPECT_TRUE(writer_->Close()); writer_.reset(); EXPECT_FALSE(IsRegularFile(path_)); } @@ -158,9 +161,16 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { } } - void WriteAnnotations(IOSIntermediateDumpWriter* writer) { - constexpr char annotation_name[] = "annotation_name"; - constexpr char annotation_value[] = "annotation_value"; + void WriteAnnotations(IOSIntermediateDumpWriter* writer, + bool use_long_annotations) { + constexpr char short_annotation_name[] = "annotation_name"; + constexpr char short_annotation_value[] = "annotation_value"; + const char* const annotation_name = use_long_annotations + ? long_annotation_name_.c_str() + : short_annotation_name; + const char* const annotation_value = use_long_annotations + ? long_annotation_value_.c_str() + : short_annotation_value; { IOSIntermediateDumpWriter::ScopedArray annotationObjectArray( writer, Key::kAnnotationObjects); @@ -198,14 +208,18 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { } } - void WriteModules(IOSIntermediateDumpWriter* writer) { + void WriteModules(IOSIntermediateDumpWriter* writer, + bool has_module_path, + bool use_long_annotations) { IOSIntermediateDumpWriter::ScopedArray moduleArray(writer, Key::kModules); for (uint32_t image_index = 0; image_index < 2; ++image_index) { IOSIntermediateDumpWriter::ScopedArrayMap modules(writer); - constexpr char image_file[] = "/path/to/module"; - EXPECT_TRUE( - writer->AddProperty(Key::kName, image_file, strlen(image_file))); + if (has_module_path) { + constexpr char image_file[] = "/path/to/module"; + EXPECT_TRUE( + writer->AddProperty(Key::kName, image_file, strlen(image_file))); + } uint64_t address = 0; uint64_t vmsize = 1; @@ -237,38 +251,60 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { EXPECT_TRUE(writer->AddProperty(Key::kSourceVersion, &source_version)); EXPECT_TRUE(writer->AddProperty(Key::kUUID, &uuid)); EXPECT_TRUE(writer->AddProperty(Key::kFileType, &filetype)); - WriteAnnotations(writer); + WriteAnnotations(writer, use_long_annotations); } } - void ExpectModules(const std::vector& modules) { + void ExpectModules(const std::vector& modules, + bool expect_module_path, + bool expect_long_annotations) { for (auto module : modules) { EXPECT_EQ(module->GetModuleType(), ModuleSnapshot::kModuleTypeSharedLibrary); - EXPECT_STREQ(module->Name().c_str(), "/path/to/module"); - EXPECT_STREQ(module->DebugFileName().c_str(), "module"); + + if (expect_module_path) { + EXPECT_STREQ(module->Name().c_str(), "/path/to/module"); + EXPECT_STREQ(module->DebugFileName().c_str(), "module"); + } UUID uuid; uint32_t age; module->UUIDAndAge(&uuid, &age); EXPECT_EQ(uuid.ToString(), "00010203-0405-0607-0809-0a0b0c0d0e0f"); for (auto annotation : module->AnnotationsVector()) { - EXPECT_STREQ(annotation.c_str(), "annotation_value"); + if (expect_long_annotations) { + EXPECT_EQ(annotation, long_annotation_value_); + } else { + EXPECT_STREQ(annotation.c_str(), "annotation_value"); + } } for (const auto& it : module->AnnotationsSimpleMap()) { - EXPECT_STREQ(it.first.c_str(), "annotation_name"); - EXPECT_STREQ(it.second.c_str(), "annotation_value"); + if (expect_long_annotations) { + EXPECT_EQ(it.first, long_annotation_name_); + EXPECT_EQ(it.second, long_annotation_value_); + } else { + EXPECT_STREQ(it.first.c_str(), "annotation_name"); + EXPECT_STREQ(it.second.c_str(), "annotation_value"); + } } for (auto annotation_object : module->AnnotationObjects()) { - EXPECT_STREQ(annotation_object.name.c_str(), "annotation_name"); EXPECT_EQ(annotation_object.type, (short)Annotation::Type::kString); - EXPECT_STREQ(std::string(reinterpret_cast( - annotation_object.value.data()), - annotation_object.value.size()) - .c_str(), - "annotation_value"); + if (expect_long_annotations) { + EXPECT_EQ(annotation_object.name, long_annotation_name_); + EXPECT_EQ(std::string(reinterpret_cast( + annotation_object.value.data()), + annotation_object.value.size()), + long_annotation_value_); + } else { + EXPECT_STREQ(annotation_object.name.c_str(), "annotation_name"); + EXPECT_STREQ(std::string(reinterpret_cast( + annotation_object.value.data()), + annotation_object.value.size()) + .c_str(), + "annotation_value"); + } } } } @@ -356,6 +392,7 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { Key::kThreadContextMemoryRegionData, "string", 6)); } } + EXPECT_TRUE(writer->AddPropertyBytes(Key::kThreadName, "ariadne", 7)); } } @@ -375,6 +412,7 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { uint64_t thread_id = 1; for (auto thread : threads) { EXPECT_EQ(thread->ThreadID(), thread_id); + EXPECT_EQ(thread->ThreadName(), "ariadne"); EXPECT_EQ(thread->SuspendCount(), 666); EXPECT_EQ(thread->Priority(), 5); EXPECT_EQ(thread->ThreadSpecificDataAddress(), thread_id++); @@ -424,7 +462,9 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { EXPECT_STREQ(daylight_name.c_str(), "Daylight"); } - void ExpectSnapshot(const ProcessSnapshot& snapshot) { + void ExpectSnapshot(const ProcessSnapshot& snapshot, + bool expect_module_path, + bool expect_long_annotations) { EXPECT_EQ(snapshot.ProcessID(), 2); EXPECT_EQ(snapshot.ParentProcessID(), 1); @@ -447,7 +487,8 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { ExpectSystem(*snapshot.System()); ExpectThreads(snapshot.Threads()); - ExpectModules(snapshot.Modules()); + ExpectModules( + snapshot.Modules(), expect_module_path, expect_long_annotations); ExpectMachException(*snapshot.Exception()); } @@ -456,6 +497,8 @@ class ProcessSnapshotIOSIntermediateDumpTest : public testing::Test { ScopedTempDir temp_dir_; base::FilePath path_; std::map annotations_; + const std::string long_annotation_name_; + const std::string long_annotation_value_; }; TEST_F(ProcessSnapshotIOSIntermediateDumpTest, InitializeNoFile) { @@ -626,14 +669,38 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, ShortContext) { WriteSystemInfo(writer()); WriteProcessInfo(writer()); WriteThreads(writer()); - WriteModules(writer()); + WriteModules( + writer(), /*has_module_path=*/false, /*use_long_annotations=*/false); WriteMachException(writer(), true /* short_context=true*/); } ProcessSnapshotIOSIntermediateDump process_snapshot; ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), annotations())); EXPECT_FALSE(IsRegularFile(path())); EXPECT_TRUE(DumpSnapshot(process_snapshot)); - ExpectSnapshot(process_snapshot); + ExpectSnapshot(process_snapshot, + /*expect_module_path=*/false, + /*expect_long_annotations=*/false); +} + +TEST_F(ProcessSnapshotIOSIntermediateDumpTest, LongAnnotations) { + { + IOSIntermediateDumpWriter::ScopedRootMap rootMap(writer()); + uint8_t version = 1; + EXPECT_TRUE(writer()->AddProperty(Key::kVersion, &version)); + WriteSystemInfo(writer()); + WriteProcessInfo(writer()); + WriteThreads(writer()); + WriteModules( + writer(), /*has_module_path=*/false, /*use_long_annotations=*/true); + WriteMachException(writer()); + } + ProcessSnapshotIOSIntermediateDump process_snapshot; + ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), annotations())); + EXPECT_FALSE(IsRegularFile(path())); + EXPECT_TRUE(DumpSnapshot(process_snapshot)); + ExpectSnapshot(process_snapshot, + /*expect_module_path=*/false, + /*expect_long_annotations=*/true); } TEST_F(ProcessSnapshotIOSIntermediateDumpTest, FullReport) { @@ -644,14 +711,17 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, FullReport) { WriteSystemInfo(writer()); WriteProcessInfo(writer()); WriteThreads(writer()); - WriteModules(writer()); + WriteModules( + writer(), /*has_module_path=*/true, /*use_long_annotations=*/false); WriteMachException(writer()); } ProcessSnapshotIOSIntermediateDump process_snapshot; ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), annotations())); EXPECT_FALSE(IsRegularFile(path())); EXPECT_TRUE(DumpSnapshot(process_snapshot)); - ExpectSnapshot(process_snapshot); + ExpectSnapshot(process_snapshot, + /*expect_module_path=*/true, + /*expect_long_annotations=*/false); } TEST_F(ProcessSnapshotIOSIntermediateDumpTest, FuzzTestCases) { @@ -672,6 +742,11 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, FuzzTestCases) { map = process_snapshot2.AnnotationsSimpleMap(); ASSERT_TRUE(map.find("crashpad_intermediate_dump_incomplete") != map.end()); EXPECT_EQ(map["crashpad_intermediate_dump_incomplete"], "yes"); + + fuzz_path = TestPaths::TestDataRoot().Append( + FILE_PATH_LITERAL("snapshot/ios/testdata/crash-6605504629637120")); + crashpad::internal::ProcessSnapshotIOSIntermediateDump process_snapshot3; + EXPECT_FALSE(process_snapshot3.InitializeWithFilePath(fuzz_path, {})); } } // namespace diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-6605504629637120 b/thirdparty/sentry-native/external/crashpad/snapshot/ios/testdata/crash-6605504629637120 new file mode 100644 index 0000000000000000000000000000000000000000..1e041d9021eda5d220ac847f7dbe4a6b8b813e19 GIT binary patch literal 42751 zcmeI3;c=rd5QR;cNmu!kQqsxIHF6DHbyon#B38&k8*CzEX8AnhAs{5s)7z)jlk?sU zL;ulr{l{(mj>pgUaGb8m^}@B!(zUE!(oQ!wU2H0=_9f@x+S~d?^re!}OMA@DJQ(aeyH(L^uEsz`#8ZP<>QC=B+3misxSO?$%f^9>$xD zSEfXLob7^mZnH-WgyT$vjY)go!++1cn;M`0jy=uK>3J}f49t`{4`CVFc*aCJ^Z47$ zXjy_MgfAu$3J<^l9<)?m_y*tL8>=ee06YK#co2SaKr9do!~(G}x;-2A4N8GhoLDK; z+r%4QAz??ZM7>6S@Ovl!_#1!NiyxfyR`L3#*EuR)P*^eJAq-Zv(wN)9r+QmFI+S{R zs5^lQZih4ujy-JkOE9=G95Ed0#}%xCRj`VMm~a3dfB`(fw$cSWdVn6F2j~HMu-J8I zBAVz-6V=;{zFuNwPkyJ(c~J&chrCw#+>0xE>7J*IFagc-uw46!i_6d9jt zL~+-wSWEA`?yQpH_CsymGi;l6UbPW7V)3d+6V0rFCEtSwVBnAk>5QZEuU^~W{H0ex z0Na^sdm$MJ1B^5>|OZVWojd zA8ia)wbGc|!6*LxTliE71$%H>max%*@hk!Y55NE(v{YXB2H)VDtEKJ6B975!w1ork z01V&(CjV$zF=K#1H078VT+It=SI6=C{FGlyJd!91JWR36fw_}15 zSL#USvoG^WHKMo)XvYcKTGmc`12x>A&#i}0mkpTis+&*}v3Ar_0y^y&Qcs5JwZuLV z8h{40(*Ur366>7_;Z^gUeG8wRAVcOS$sCO*CY{rA2NNK&G+)x&ti}Gwv3l%0w?CSb z&(#mEFY9tJ>qpJ9HR`1$%>!E>SoE=Tak8P=C+w9}C3(%Kx)bW<+ImQmixY$BUfn~h z7X$TLy84)$c6oJ(3NzaF3{J@@W1(&wXnG{aV#a5)U|)u(4=g?`$=f!%x$*E}2>*Yd jJVmm)s_A9*21ShGcY5<-{&eH#t-tmE{`~rT>u>)7l)8-t literal 0 HcmV?d00001 diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.cc b/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.cc index b7ede298ed..40387fa0dc 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.cc @@ -68,8 +68,14 @@ using Key = IntermediateDumpKey; ThreadSnapshotIOSIntermediateDump::ThreadSnapshotIOSIntermediateDump() : ThreadSnapshot(), +#if defined(ARCH_CPU_X86_64) + context_x86_64_(), +#elif defined(ARCH_CPU_ARM64) + context_arm64_(), +#endif context_(), stack_(), + thread_name_(), thread_id_(0), thread_specific_data_address_(0), suspend_count_(0), @@ -95,6 +101,7 @@ bool ThreadSnapshotIOSIntermediateDump::Initialize( GetDataValueFromMap(thread_data, Key::kThreadID, &thread_id_); GetDataValueFromMap( thread_data, Key::kThreadDataAddress, &thread_specific_data_address_); + GetDataStringFromMap(thread_data, Key::kThreadName, &thread_name_); #if defined(ARCH_CPU_X86_64) typedef x86_thread_state64_t thread_state_type; @@ -213,6 +220,11 @@ uint64_t ThreadSnapshotIOSIntermediateDump::ThreadID() const { return thread_id_; } +std::string ThreadSnapshotIOSIntermediateDump::ThreadName() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return thread_name_; +} + int ThreadSnapshotIOSIntermediateDump::SuspendCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return suspend_count_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.h b/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.h index cf9ccec023..dafa455826 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/ios/thread_snapshot_ios_intermediate_dump.h @@ -15,6 +15,8 @@ #ifndef CRASHPAD_SNAPSHOT_IOS_INTERMEDIATE_DUMP_THREAD_SNAPSHOT_IOS_INTERMEDIATEDUMP_H_ #define CRASHPAD_SNAPSHOT_IOS_INTERMEDIATE_DUMP_THREAD_SNAPSHOT_IOS_INTERMEDIATEDUMP_H_ +#include + #include "build/build_config.h" #include "snapshot/cpu_context.h" #include "snapshot/ios/memory_snapshot_ios_intermediate_dump.h" @@ -49,6 +51,7 @@ class ThreadSnapshotIOSIntermediateDump final : public ThreadSnapshot { const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; @@ -65,6 +68,7 @@ class ThreadSnapshotIOSIntermediateDump final : public ThreadSnapshot { CPUContext context_; std::vector exception_stack_memory_; MemorySnapshotIOSIntermediateDump stack_; + std::string thread_name_; uint64_t thread_id_; uint64_t thread_specific_data_address_; int suspend_count_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/capture_memory_delegate_linux.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/capture_memory_delegate_linux.cc index 4f1587400c..918e572d59 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/capture_memory_delegate_linux.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/capture_memory_delegate_linux.cc @@ -57,19 +57,17 @@ void CaptureMemoryDelegateLinux::AddNewMemorySnapshot( return; if (range.size() == 0) return; - if (budget_remaining_ && *budget_remaining_ == 0) + if (!budget_remaining_ || *budget_remaining_ == 0) return; snapshots_->push_back(std::make_unique()); internal::MemorySnapshotGeneric* snapshot = snapshots_->back().get(); snapshot->Initialize(process_reader_->Memory(), range.base(), range.size()); - if (budget_remaining_) { - if (!base::IsValueInRangeForNumericType(range.size())) { - *budget_remaining_ = 0; - } else { - int64_t temp = *budget_remaining_; - temp -= range.size(); - *budget_remaining_ = base::saturated_cast(temp); - } + if (!base::IsValueInRangeForNumericType(range.size())) { + *budget_remaining_ = 0; + } else { + int64_t temp = *budget_remaining_; + temp -= range.size(); + *budget_remaining_ = base::saturated_cast(temp); } } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous.cc index 42384f7433..e0af2b3b18 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous.cc @@ -21,7 +21,7 @@ #include "base/logging.h" #include "build/build_config.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif @@ -142,7 +142,7 @@ bool DebugRendezvous::InitializeSpecific(const ProcessMemoryRange& memory, modules_.push_back(entry); } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // Android P (API 28) mistakenly places the vdso in the first entry in the // link map. const int android_runtime_api = android_get_device_api_level(); @@ -151,7 +151,7 @@ bool DebugRendezvous::InitializeSpecific(const ProcessMemoryRange& memory, modules_[0] = executable_; executable_ = executable; } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) return true; } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous_test.cc index 4754528e85..9fa6d63114 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/debug_rendezvous_test.cc @@ -41,7 +41,7 @@ #include "util/process/process_memory_linux.h" #include "util/process/process_memory_range.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif @@ -103,7 +103,7 @@ void TestAgainstTarget(PtraceConnection* connection) { DebugRendezvous debug; ASSERT_TRUE(debug.Initialize(range, debug_address)); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) const int android_runtime_api = android_get_device_api_level(); ASSERT_GE(android_runtime_api, 1); @@ -125,7 +125,7 @@ void TestAgainstTarget(PtraceConnection* connection) { // glibc's loader does not set the name for the executable. EXPECT_TRUE(debug.Executable()->name.empty()); EXPECT_EQ(debug.Executable()->dynamic_array, exe_dynamic_address); -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) // Android's loader doesn't set the load bias until Android 4.3 (API 18). if (android_runtime_api >= 18) { @@ -162,7 +162,7 @@ void TestAgainstTarget(PtraceConnection* connection) { ASSERT_GE(possible_mappings->Count(), 1u); std::unique_ptr module_reader; -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) const MemoryMap::Mapping* module_mapping = nullptr; #endif const MemoryMap::Mapping* mapping = nullptr; @@ -174,7 +174,7 @@ void TestAgainstTarget(PtraceConnection* connection) { parsed_module->GetDynamicArrayAddress(&dynamic_address) && dynamic_address == module.dynamic_array) { module_reader = std::move(parsed_module); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) module_mapping = mapping; #endif break; @@ -182,7 +182,7 @@ void TestAgainstTarget(PtraceConnection* connection) { } ASSERT_TRUE(module_reader.get()); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_FALSE(module.name.empty()); #else // glibc's loader doesn't always set the name in the link map for the vdso. @@ -206,7 +206,7 @@ void TestAgainstTarget(PtraceConnection* connection) { module_mapping->device, module_mapping->inode, module.name); -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) // Android's loader stops setting its own load bias after Android 4.4.4 // (API 20) until Android 6.0 (API 23). diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.cc index 42d0eb0b29..efc9e5694e 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.cc @@ -24,6 +24,7 @@ #include "util/linux/traits.h" #include "util/misc/reinterpret_bytes.h" #include "util/numeric/safe_assignment.h" +#include "util/posix/signals.h" namespace crashpad { namespace internal { @@ -326,10 +327,12 @@ bool ExceptionSnapshotLinux::ReadContext( #endif // ARCH_CPU_X86_FAMILY -bool ExceptionSnapshotLinux::Initialize(ProcessReaderLinux* process_reader, - LinuxVMAddress siginfo_address, - LinuxVMAddress context_address, - pid_t thread_id) { +bool ExceptionSnapshotLinux::Initialize( + ProcessReaderLinux* process_reader, + LinuxVMAddress siginfo_address, + LinuxVMAddress context_address, + pid_t thread_id, + uint32_t* gather_indirectly_referenced_memory_cap) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); thread_id_ = thread_id; @@ -359,7 +362,10 @@ bool ExceptionSnapshotLinux::Initialize(ProcessReaderLinux* process_reader, } CaptureMemoryDelegateLinux capture_memory_delegate( - process_reader, thread, &extra_memory_, nullptr); + process_reader, + thread, + &extra_memory_, + gather_indirectly_referenced_memory_cap); CaptureMemory::PointedToByContext(context_, &capture_memory_delegate); INITIALIZATION_STATE_SET_VALID(initialized_); @@ -440,6 +446,9 @@ bool ExceptionSnapshotLinux::ReadSiginfo(ProcessReaderLinux* reader, PUSH_CODE(siginfo.sigval.sigval); break; + case Signals::kSimulatedSigno: + break; + default: LOG(WARNING) << "Unhandled signal " << siginfo.signo; } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.h b/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.h index 1719f0be76..05f6004e11 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux.h @@ -59,7 +59,8 @@ class ExceptionSnapshotLinux final : public ExceptionSnapshot { bool Initialize(ProcessReaderLinux* process_reader, LinuxVMAddress siginfo_address, LinuxVMAddress context_address, - pid_t thread_id); + pid_t thread_id, + uint32_t* gather_indirectly_referenced_memory_cap); // ExceptionSnapshot: diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux_test.cc index 51d3fd3808..a045f36594 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/exception_snapshot_linux_test.cc @@ -21,8 +21,9 @@ #include #include +#include + #include "base/bit_cast.h" -#include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" #include "snapshot/cpu_architecture.h" @@ -170,7 +171,7 @@ void InitializeContext(NativeCPUContext* context) { test_context->vfp.head.magic = VFP_MAGIC; test_context->vfp.head.size = sizeof(test_context->vfp); memset(&test_context->vfp.context, 'v', sizeof(test_context->vfp.context)); - for (size_t reg = 0; reg < base::size(test_context->vfp.context.vfp.fpregs); + for (size_t reg = 0; reg < std::size(test_context->vfp.context.vfp.fpregs); ++reg) { test_context->vfp.context.vfp.fpregs[reg] = reg; } @@ -218,7 +219,7 @@ struct TestCoprocessorContext { void InitializeContext(NativeCPUContext* context) { memset(context, 'x', sizeof(*context)); - for (size_t index = 0; index < base::size(context->uc_mcontext.regs); + for (size_t index = 0; index < std::size(context->uc_mcontext.regs); ++index) { context->uc_mcontext.regs[index] = index; } @@ -237,7 +238,7 @@ void InitializeContext(NativeCPUContext* context) { test_context->fpsimd.head.size = sizeof(test_context->fpsimd); test_context->fpsimd.fpsr = 1; test_context->fpsimd.fpcr = 2; - for (size_t reg = 0; reg < base::size(test_context->fpsimd.vregs); ++reg) { + for (size_t reg = 0; reg < std::size(test_context->fpsimd.vregs); ++reg) { test_context->fpsimd.vregs[reg] = reg; } @@ -270,7 +271,7 @@ void ExpectContext(const CPUContext& actual, const NativeCPUContext& expected) { using NativeCPUContext = ucontext_t; void InitializeContext(NativeCPUContext* context) { - for (size_t reg = 0; reg < base::size(context->uc_mcontext.gregs); ++reg) { + for (size_t reg = 0; reg < std::size(context->uc_mcontext.gregs); ++reg) { context->uc_mcontext.gregs[reg] = reg; } memset(&context->uc_mcontext.fpregs, 44, sizeof(context->uc_mcontext.fpregs)); @@ -285,7 +286,7 @@ void ExpectContext(const CPUContext& actual, const NativeCPUContext& expected) { #define CPU_ARCH_NAME mips64 #endif - for (size_t reg = 0; reg < base::size(expected.uc_mcontext.gregs); ++reg) { + for (size_t reg = 0; reg < std::size(expected.uc_mcontext.gregs); ++reg) { EXPECT_EQ(actual.CPU_ARCH_NAME->regs[reg], expected.uc_mcontext.gregs[reg]); } @@ -320,7 +321,8 @@ TEST(ExceptionSnapshotLinux, SelfBasic) { ASSERT_TRUE(exception.Initialize(&process_reader, FromPointerCast(&siginfo), FromPointerCast(&context), - gettid())); + gettid(), + nullptr)); EXPECT_EQ(exception.Exception(), static_cast(siginfo.si_signo)); EXPECT_EQ(exception.ExceptionInfo(), static_cast(siginfo.si_code)); EXPECT_EQ(exception.ExceptionAddress(), @@ -393,7 +395,8 @@ class RaiseTest { ASSERT_TRUE(exception.Initialize(&process_reader, FromPointerCast(siginfo), FromPointerCast(context), - gettid())); + gettid(), + nullptr)); EXPECT_EQ(exception.Exception(), static_cast(kSigno)); @@ -464,7 +467,8 @@ class TimerTest { ASSERT_TRUE(exception.Initialize(&process_reader, FromPointerCast(siginfo), FromPointerCast(context), - gettid())); + gettid(), + nullptr)); EXPECT_EQ(exception.Exception(), static_cast(kSigno)); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.cc index a9098ac803..4b663bbdfe 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.cc @@ -24,12 +24,13 @@ #include #include "base/logging.h" +#include "base/strings/stringprintf.h" #include "build/build_config.h" #include "snapshot/linux/debug_rendezvous.h" #include "util/linux/auxiliary_vector.h" #include "util/linux/proc_stat_reader.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif @@ -52,6 +53,7 @@ ProcessReaderLinux::Thread::Thread() : thread_info(), stack_region_address(0), stack_region_size(0), + name(), tid(-1), static_priority(-1), nice_value(-1) {} @@ -64,6 +66,23 @@ bool ProcessReaderLinux::Thread::InitializePtrace( return false; } + // From man proc(5): + // + // /proc/[pid]/comm (since Linux 2.6.33) + // + // Different threads in the same process may have different comm values, + // accessible via /proc/[pid]/task/[tid]/comm. + const std::string path = base::StringPrintf( + "/proc/%d/task/%d/comm", connection->GetProcessID(), tid); + if (connection->ReadFileContents(base::FilePath(path), &name)) { + if (!name.empty() && name.back() == '\n') { + // Remove the final newline character. + name.pop_back(); + } + } else { + // Continue on without the thread name. + } + // TODO(jperaza): Collect scheduling priorities via the broker when they can't // be collected directly. have_priorities = false; @@ -282,7 +301,7 @@ const std::vector& ProcessReaderLinux::Modules() { } void ProcessReaderLinux::InitializeAbortMessage() { -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) const MemoryMap::Mapping* mapping = memory_map_.FindMappingWithName("[anon:abort message]"); if (!mapping) { @@ -297,7 +316,7 @@ void ProcessReaderLinux::InitializeAbortMessage() { #endif } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // These structure definitions and the magic numbers below were copied from // bionic/libc/bionic/android_set_abort_message.cpp @@ -346,7 +365,7 @@ void ProcessReaderLinux::ReadAbortMessage(const MemoryMap::Mapping* mapping) { } } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) const std::string& ProcessReaderLinux::AbortMessage() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); @@ -486,7 +505,7 @@ void ProcessReaderLinux::InitializeModules() { continue; } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // Beginning at API 21, Bionic provides android_dlopen_ext() which allows // passing a file descriptor with an existing relro segment to the loader. // This means that the mapping attributes of dyn_mapping may be unrelated diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.h b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.h index f44e15f5f5..e8cf107028 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux.h @@ -60,6 +60,7 @@ class ProcessReaderLinux { ThreadInfo thread_info; LinuxVMAddress stack_region_address; LinuxVMSize stack_region_size; + std::string name; pid_t tid; int sched_policy; int static_priority; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux_test.cc index f3791f85ba..e4179de1f2 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_reader_linux_test.cc @@ -26,12 +26,12 @@ #include #include +#include #include #include #include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/memory/free_deleter.h" #include "base/strings/stringprintf.h" @@ -43,6 +43,7 @@ #include "test/linux/get_tls.h" #include "test/multiprocess.h" #include "test/scoped_module_handle.h" +#include "test/scoped_set_thread_name.h" #include "test/test_paths.h" #include "util/file/file_io.h" #include "util/file/file_writer.h" @@ -53,7 +54,7 @@ #include "util/misc/memory_sanitizer.h" #include "util/synchronization/semaphore.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #include #include "dlfcn_internal.h" @@ -88,7 +89,7 @@ TEST(ProcessReaderLinux, SelfBasic) { EXPECT_EQ(process_reader.ParentProcessID(), getppid()); static constexpr char kTestMemory[] = "Some test memory"; - char buffer[base::size(kTestMemory)]; + char buffer[std::size(kTestMemory)]; ASSERT_TRUE(process_reader.Memory()->Read( reinterpret_cast(kTestMemory), sizeof(kTestMemory), @@ -169,7 +170,9 @@ class TestThreadPool { void StartThreads(size_t thread_count, size_t stack_size = 0) { for (size_t thread_index = 0; thread_index < thread_count; ++thread_index) { - threads_.push_back(std::make_unique()); + const std::string thread_name = + base::StringPrintf("ThreadPool-%zu", thread_index); + threads_.push_back(std::make_unique(thread_name)); Thread* thread = threads_.back().get(); pthread_attr_t attr; @@ -211,22 +214,26 @@ class TestThreadPool { } pid_t GetThreadExpectation(size_t thread_index, - ThreadExpectation* expectation) { + ThreadExpectation* expectation, + std::string* thread_name_expectation) { CHECK_LT(thread_index, threads_.size()); const Thread* thread = threads_[thread_index].get(); *expectation = thread->expectation; + *thread_name_expectation = thread->name; return thread->tid; } private: struct Thread { - Thread() + explicit Thread(const std::string& name) : pthread(), expectation(), ready_semaphore(0), exit_semaphore(0), - tid(-1) {} + tid(-1), + name(name) { + } ~Thread() {} pthread_t pthread; @@ -235,10 +242,12 @@ class TestThreadPool { Semaphore ready_semaphore; Semaphore exit_semaphore; pid_t tid; + const std::string name; }; static void* ThreadMain(void* argument) { Thread* thread = static_cast(argument); + const ScopedSetThreadName scoped_set_thread_name(thread->name); CHECK_EQ(setpriority(PRIO_PROCESS, 0, thread->expectation.nice_value), 0) << ErrnoMessage("setpriority"); @@ -260,20 +269,24 @@ class TestThreadPool { }; using ThreadMap = std::map; +using ThreadNameMap = std::map; void ExpectThreads(const ThreadMap& thread_map, + const ThreadNameMap& thread_name_map, const std::vector& threads, PtraceConnection* connection) { ASSERT_EQ(threads.size(), thread_map.size()); + ASSERT_EQ(threads.size(), thread_name_map.size()); MemoryMap memory_map; ASSERT_TRUE(memory_map.Initialize(connection)); for (const auto& thread : threads) { SCOPED_TRACE( - base::StringPrintf("Thread id %d, tls 0x%" PRIx64 + base::StringPrintf("Thread id %d, name %s, tls 0x%" PRIx64 ", stack addr 0x%" PRIx64 ", stack size 0x%" PRIx64, thread.tid, + thread.name.c_str(), thread.thread_info.thread_specific_data_address, thread.stack_region_address, thread.stack_region_size)); @@ -306,6 +319,10 @@ void ExpectThreads(const ThreadMap& thread_map, EXPECT_EQ(thread.sched_policy, iterator->second.sched_policy); EXPECT_EQ(thread.static_priority, iterator->second.static_priority); EXPECT_EQ(thread.nice_value, iterator->second.nice_value); + + const auto& thread_name_iterator = thread_name_map.find(thread.tid); + ASSERT_NE(thread_name_iterator, thread_name_map.end()); + EXPECT_EQ(thread.name, thread_name_iterator->second); } } @@ -322,6 +339,7 @@ class ChildThreadTest : public Multiprocess { private: void MultiprocessParent() override { ThreadMap thread_map; + ThreadNameMap thread_name_map; for (size_t thread_index = 0; thread_index < kThreadCount + 1; ++thread_index) { pid_t tid; @@ -331,6 +349,14 @@ class ChildThreadTest : public Multiprocess { CheckedReadFileExactly( ReadPipeHandle(), &expectation, sizeof(expectation)); thread_map[tid] = expectation; + + std::string::size_type thread_name_length; + CheckedReadFileExactly( + ReadPipeHandle(), &thread_name_length, sizeof(thread_name_length)); + std::string thread_name(thread_name_length, '\0'); + CheckedReadFileExactly( + ReadPipeHandle(), thread_name.data(), thread_name_length); + thread_name_map[tid] = thread_name; } DirectPtraceConnection connection; @@ -340,19 +366,22 @@ class ChildThreadTest : public Multiprocess { ASSERT_TRUE(process_reader.Initialize(&connection)); const std::vector& threads = process_reader.Threads(); - ExpectThreads(thread_map, threads, &connection); + ExpectThreads(thread_map, thread_name_map, threads, &connection); } void MultiprocessChild() override { TestThreadPool thread_pool; thread_pool.StartThreads(kThreadCount, stack_size_); + const std::string current_thread_name = "MultiprocChild"; + const ScopedSetThreadName scoped_set_thread_name(current_thread_name); + TestThreadPool::ThreadExpectation expectation; #if defined(MEMORY_SANITIZER) // memset() + re-initialization is required to zero padding bytes for MSan. memset(&expectation, 0, sizeof(expectation)); #endif // defined(MEMORY_SANITIZER) - expectation = {}; + expectation = {0}; expectation.tls = GetTLS(); expectation.stack_address = reinterpret_cast(&thread_pool); @@ -373,11 +402,28 @@ class ChildThreadTest : public Multiprocess { CheckedWriteFile(WritePipeHandle(), &tid, sizeof(tid)); CheckedWriteFile(WritePipeHandle(), &expectation, sizeof(expectation)); + const std::string::size_type current_thread_name_length = + current_thread_name.length(); + CheckedWriteFile(WritePipeHandle(), + ¤t_thread_name_length, + sizeof(current_thread_name_length)); + CheckedWriteFile(WritePipeHandle(), + current_thread_name.data(), + current_thread_name_length); for (size_t thread_index = 0; thread_index < kThreadCount; ++thread_index) { - tid = thread_pool.GetThreadExpectation(thread_index, &expectation); + std::string thread_name_expectation; + tid = thread_pool.GetThreadExpectation( + thread_index, &expectation, &thread_name_expectation); CheckedWriteFile(WritePipeHandle(), &tid, sizeof(tid)); CheckedWriteFile(WritePipeHandle(), &expectation, sizeof(expectation)); + const std::string::size_type thread_name_length = + thread_name_expectation.length(); + CheckedWriteFile( + WritePipeHandle(), &thread_name_length, sizeof(thread_name_length)); + CheckedWriteFile(WritePipeHandle(), + thread_name_expectation.data(), + thread_name_length); } CheckedReadFileAtEOF(ReadPipeHandle()); @@ -492,7 +538,7 @@ TEST(ProcessReaderLinux, MAYBE_ChildWithSplitStack) { } // Android doesn't provide dl_iterate_phdr on ARM until API 21. -#if !defined(OS_ANDROID) || !defined(ARCH_CPU_ARMEL) || __ANDROID_API__ >= 21 +#if !BUILDFLAG(IS_ANDROID) || !defined(ARCH_CPU_ARMEL) || __ANDROID_API__ >= 21 int ExpectFindModule(dl_phdr_info* info, size_t size, void* data) { SCOPED_TRACE( base::StringPrintf("module %s at 0x%" PRIx64 " phdrs 0x%" PRIx64, @@ -502,8 +548,7 @@ int ExpectFindModule(dl_phdr_info* info, size_t size, void* data) { auto modules = reinterpret_cast*>(data); - -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // Prior to API 27, Bionic includes a null entry for /system/bin/linker. if (!info->dlpi_name) { EXPECT_EQ(info->dlpi_addr, 0u); @@ -532,7 +577,7 @@ int ExpectFindModule(dl_phdr_info* info, size_t size, void* data) { EXPECT_TRUE(found); return 0; } -#endif // !OS_ANDROID || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21 +#endif // !BUILDFLAG(IS_ANDROID) || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21 void ExpectModulesFromSelf( const std::vector& modules) { @@ -542,14 +587,14 @@ void ExpectModulesFromSelf( } // Android doesn't provide dl_iterate_phdr on ARM until API 21. -#if !defined(OS_ANDROID) || !defined(ARCH_CPU_ARMEL) || __ANDROID_API__ >= 21 +#if !BUILDFLAG(IS_ANDROID) || !defined(ARCH_CPU_ARMEL) || __ANDROID_API__ >= 21 EXPECT_EQ( dl_iterate_phdr( ExpectFindModule, reinterpret_cast( const_cast*>(&modules))), 0); -#endif // !OS_ANDROID || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21 +#endif // !BUILDFLAG(IS_ANDROID) || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21 } #if !defined(ADDRESS_SANITIZER) && !defined(MEMORY_SANITIZER) @@ -641,7 +686,7 @@ TEST(ProcessReaderLinux, ChildModules) { test.Run(); } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) const char kTestAbortMessage[] = "test abort message"; TEST(ProcessReaderLinux, AbortMessage) { diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_snapshot_linux.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_snapshot_linux.cc index 14d32f2c6c..cdb69a3ada 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_snapshot_linux.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/process_snapshot_linux.cc @@ -17,6 +17,7 @@ #include #include "base/logging.h" +#include "build/build_config.h" #include "util/linux/exception_information.h" namespace crashpad { @@ -42,10 +43,9 @@ bool ProcessSnapshotLinux::Initialize(PtraceConnection* connection) { client_id_.InitializeToZero(); system_.Initialize(&process_reader_, &snapshot_time_); - GetCrashpadOptionsInternal((&options_)); - - InitializeThreads(); InitializeModules(); + GetCrashpadOptionsInternal((&options_)); + InitializeThreads(); InitializeAnnotations(); INITIALIZATION_STATE_SET_VALID(initialized_); @@ -83,11 +83,17 @@ bool ProcessSnapshotLinux::InitializeException( info.thread_id = exception_thread_id; } + uint32_t* budget_remaining_pointer = + options_.gather_indirectly_referenced_memory == TriState::kEnabled + ? &options_.indirectly_referenced_memory_cap + : nullptr; + exception_.reset(new internal::ExceptionSnapshotLinux()); if (!exception_->Initialize(&process_reader_, info.siginfo_address, info.context_address, - info.thread_id)) { + info.thread_id, + budget_remaining_pointer)) { exception_.reset(); return false; } @@ -274,11 +280,11 @@ const ProcessMemory* ProcessSnapshotLinux::Memory() const { void ProcessSnapshotLinux::InitializeThreads() { const std::vector& process_reader_threads = process_reader_.Threads(); - uint32_t* budget_remaining_pointer = nullptr; - uint32_t budget_remaining = options_.indirectly_referenced_memory_cap; - if (options_.gather_indirectly_referenced_memory == TriState::kEnabled) { - budget_remaining_pointer = &budget_remaining; - } + uint32_t* budget_remaining_pointer = + options_.gather_indirectly_referenced_memory == TriState::kEnabled + ? &options_.indirectly_referenced_memory_cap + : nullptr; + for (const ProcessReaderLinux::Thread& process_reader_thread : process_reader_threads) { auto thread = std::make_unique(); @@ -306,7 +312,7 @@ void ProcessSnapshotLinux::InitializeModules() { } void ProcessSnapshotLinux::InitializeAnnotations() { -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) const std::string& abort_message = process_reader_.AbortMessage(); if (!abort_message.empty()) { annotations_simple_map_["abort_message"] = abort_message; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/signal_context.h b/thirdparty/sentry-native/external/crashpad/snapshot/linux/signal_context.h index 110024680b..c004f8f6df 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/signal_context.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/signal_context.h @@ -119,11 +119,11 @@ template struct Sigset< Traits, typename std::enable_if::value>::type> { -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) uint64_t val; #else typename Traits::ULong val[16]; -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) }; #if defined(ARCH_CPU_X86_FAMILY) diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux.cc index a99da3e4b6..e77bcafa9c 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux.cc @@ -26,13 +26,14 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" +#include "build/build_config.h" #include "snapshot/cpu_context.h" #include "snapshot/posix/timezone.h" #include "util/file/file_io.h" #include "util/numeric/in_range_cast.h" #include "util/string/split_string.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif @@ -118,7 +119,7 @@ bool ReadFreqFile(const std::string& filename, uint64_t* hz) { return true; } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) bool ReadProperty(const char* property, std::string* value) { char value_buffer[PROP_VALUE_MAX]; int length = __system_property_get(property, value_buffer); @@ -129,7 +130,7 @@ bool ReadProperty(const char* property, std::string* value) { *value = value_buffer; return true; } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) } // namespace @@ -158,13 +159,13 @@ void SystemSnapshotLinux::Initialize(ProcessReaderLinux* process_reader, process_reader_ = process_reader; snapshot_time_ = snapshot_time; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) std::string build_string; if (ReadProperty("ro.build.fingerprint", &build_string)) { os_version_build_ = build_string; os_version_full_ = build_string; } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) utsname uts; if (uname(&uts) != 0) { @@ -314,11 +315,11 @@ bool SystemSnapshotLinux::CPUX86SupportsDAZ() const { SystemSnapshot::OperatingSystem SystemSnapshotLinux::GetOperatingSystem() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) return kOperatingSystemAndroid; #else return kOperatingSystemLinux; -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) } bool SystemSnapshotLinux::OSServer() const { @@ -344,7 +345,7 @@ std::string SystemSnapshotLinux::OSVersionFull() const { std::string SystemSnapshotLinux::MachineDescription() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) std::string description; std::string prop; if (ReadProperty("ro.product.model", &prop)) { @@ -359,7 +360,7 @@ std::string SystemSnapshotLinux::MachineDescription() const { return description; #else return std::string(); -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) } bool SystemSnapshotLinux::NXEnabled() const { diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux_test.cc index f5d26a1e74..09c219602a 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/system_snapshot_linux_test.cc @@ -65,11 +65,11 @@ TEST(SystemSnapshotLinux, Basic) { system.CPURevision(); system.NXEnabled(); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_FALSE(system.MachineDescription().empty()); #else system.MachineDescription(); -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) #if defined(ARCH_CPU_X86_FAMILY) system.CPUX86Signature(); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.cc b/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.cc index bfbeac6c36..788a11b8fb 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.cc @@ -139,6 +139,7 @@ ThreadSnapshotLinux::ThreadSnapshotLinux() context_(), stack_(), thread_specific_data_address_(0), + thread_name_(), thread_id_(-1), priority_(-1), initialized_() {} @@ -206,6 +207,7 @@ bool ThreadSnapshotLinux::Initialize( thread_specific_data_address_ = thread.thread_info.thread_specific_data_address; + thread_name_ = thread.name; thread_id_ = thread.tid; #ifdef CLIENT_STACKTRACES_ENABLED @@ -271,6 +273,11 @@ uint64_t ThreadSnapshotLinux::ThreadID() const { return thread_id_; } +std::string ThreadSnapshotLinux::ThreadName() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return thread_name_; +} + int ThreadSnapshotLinux::SuspendCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return 0; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.h b/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.h index 38f8c7d26d..a2eddbbed4 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/linux/thread_snapshot_linux.h @@ -57,6 +57,7 @@ class ThreadSnapshotLinux final : public ThreadSnapshot { const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; @@ -84,6 +85,7 @@ class ThreadSnapshotLinux final : public ThreadSnapshot { CPUContext context_; MemorySnapshotGeneric stack_; LinuxVMAddress thread_specific_data_address_; + std::string thread_name_; pid_t thread_id_; int priority_; InitializationStateDcheck initialized_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_reader.cc index 4e66f3db8c..5c5bcb00f2 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_reader.cc @@ -18,10 +18,10 @@ #include #include +#include #include #include -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/strings/stringprintf.h" #include "client/crashpad_info.h" @@ -183,7 +183,7 @@ bool MachOImageReader::Initialize(ProcessReaderMac* process_reader, // This vector is parallel to the kLoadCommandReaders array, and tracks // whether a singleton load command matching the |command| field has been // found yet. - std::vector singleton_indices(base::size(kLoadCommandReaders), + std::vector singleton_indices(std::size(kLoadCommandReaders), kInvalidSegmentIndex); size_t offset = mach_header.Size(); @@ -236,8 +236,7 @@ bool MachOImageReader::Initialize(ProcessReaderMac* process_reader, return false; } - for (size_t reader_index = 0; - reader_index < base::size(kLoadCommandReaders); + for (size_t reader_index = 0; reader_index < std::size(kLoadCommandReaders); ++reader_index) { if (load_command.cmd != kLoadCommandReaders[reader_index].command) { continue; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_segment_reader_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_segment_reader_test.cc index f89b475f50..38e55dfa1f 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_segment_reader_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/mach_o_image_segment_reader_test.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -63,7 +64,7 @@ TEST(MachOImageSegmentReader, SegmentNameString) { SEG_IMPORT, }; - for (size_t index = 0; index < base::size(kSegmentTestData); ++index) { + for (size_t index = 0; index < std::size(kSegmentTestData); ++index) { EXPECT_EQ( MachOImageSegmentReader::SegmentNameString(kSegmentTestData[index]), kSegmentTestData[index]) @@ -106,7 +107,7 @@ TEST(MachOImageSegmentReader, SectionNameString) { SECT_ICON_TIFF, }; - for (size_t index = 0; index < base::size(kSectionTestData); ++index) { + for (size_t index = 0; index < std::size(kSectionTestData); ++index) { EXPECT_EQ( MachOImageSegmentReader::SectionNameString(kSectionTestData[index]), kSectionTestData[index]) @@ -169,7 +170,7 @@ TEST(MachOImageSegmentReader, SegmentAndSectionNameString) { {SEG_IMPORT, "", "__IMPORT,"}, }; - for (size_t index = 0; index < base::size(kSegmentAndSectionTestData); + for (size_t index = 0; index < std::size(kSegmentAndSectionTestData); ++index) { const auto& test = kSegmentAndSectionTestData[index]; EXPECT_EQ(MachOImageSegmentReader::SegmentAndSectionNameString( diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.cc index 9b2a235627..5f9f8b7b43 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.cc @@ -75,6 +75,7 @@ ProcessReaderMac::Thread::Thread() : thread_context(), float_context(), debug_context(), + name(), id(0), stack_region_address(0), stack_region_size(0), @@ -365,6 +366,20 @@ void ProcessReaderMac::InitializeThreads() { thread.thread_specific_data_address = identifier_info.thread_handle; } + thread_extended_info extended_info; + count = THREAD_EXTENDED_INFO_COUNT; + kr = thread_info(thread.port, + THREAD_EXTENDED_INFO, + reinterpret_cast(&extended_info), + &count); + if (kr != KERN_SUCCESS) { + MACH_LOG(WARNING, kr) << "thread_info(THREAD_EXTENDED_INFO)"; + } else { + thread.name.assign( + extended_info.pth_name, + strnlen(extended_info.pth_name, sizeof(extended_info.pth_name))); + } + thread_precedence_policy precedence; count = THREAD_PRECEDENCE_POLICY_COUNT; boolean_t get_default = FALSE; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.h b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.h index 5b58a29185..ba41c94586 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac.h @@ -75,6 +75,7 @@ class ProcessReaderMac { ThreadContext thread_context; FloatContext float_context; DebugContext debug_context; + std::string name; uint64_t id; mach_vm_address_t stack_region_address; mach_vm_size_t stack_region_size; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac_test.cc index 6b4e108b99..aef4a7a3d5 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_reader_mac_test.cc @@ -25,11 +25,11 @@ #include #include +#include #include #include #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/mac/mach_logging.h" #include "base/posix/eintr_wrapper.h" @@ -42,6 +42,7 @@ #include "test/mac/dyld.h" #include "test/mac/mach_errors.h" #include "test/mac/mach_multiprocess.h" +#include "test/scoped_set_thread_name.h" #include "util/file/file_io.h" #include "util/mac/mac_util.h" #include "util/mach/mach_extensions.h" @@ -68,7 +69,7 @@ TEST(ProcessReaderMac, SelfBasic) { EXPECT_EQ(process_reader.ParentProcessID(), getppid()); static constexpr char kTestMemory[] = "Some test memory"; - char buffer[base::size(kTestMemory)]; + char buffer[std::size(kTestMemory)]; ASSERT_TRUE(process_reader.Memory()->Read( FromPointerCast(kTestMemory), sizeof(kTestMemory), @@ -139,6 +140,9 @@ uint64_t PthreadToThreadID(pthread_t pthread) { } TEST(ProcessReaderMac, SelfOneThread) { + const ScopedSetThreadName scoped_set_thread_name( + "ProcessReaderMac/SelfOneThread"); + ProcessReaderMac process_reader; ASSERT_TRUE(process_reader.Initialize(mach_task_self())); @@ -151,6 +155,7 @@ TEST(ProcessReaderMac, SelfOneThread) { ASSERT_GE(threads.size(), 1u); EXPECT_EQ(threads[0].id, PthreadToThreadID(pthread_self())); + EXPECT_EQ(threads[0].name, "ProcessReaderMac/SelfOneThread"); thread_t thread_self = MachThreadSelf(); EXPECT_EQ(threads[0].port, thread_self); @@ -163,9 +168,11 @@ class TestThreadPool { struct ThreadExpectation { mach_vm_address_t stack_address; int suspend_count; + std::string thread_name; }; - TestThreadPool() : thread_infos_() {} + TestThreadPool(const std::string& thread_name_prefix) + : thread_infos_(), thread_name_prefix_(thread_name_prefix) {} TestThreadPool(const TestThreadPool&) = delete; TestThreadPool& operator=(const TestThreadPool&) = delete; @@ -199,7 +206,10 @@ class TestThreadPool { ASSERT_TRUE(thread_infos_.empty()); for (size_t thread_index = 0; thread_index < thread_count; ++thread_index) { - thread_infos_.push_back(std::make_unique()); + std::string thread_name = base::StringPrintf( + "%s-%zu", thread_name_prefix_.c_str(), thread_index); + thread_infos_.push_back( + std::make_unique(std::move(thread_name))); ThreadInfo* thread_info = thread_infos_.back().get(); int rv = pthread_create( @@ -235,18 +245,20 @@ class TestThreadPool { const auto& thread_info = thread_infos_[thread_index]; expectation->stack_address = thread_info->stack_address; expectation->suspend_count = thread_info->suspend_count; + expectation->thread_name = thread_info->thread_name; return PthreadToThreadID(thread_info->pthread); } private: struct ThreadInfo { - ThreadInfo() + ThreadInfo(const std::string& thread_name) : pthread(nullptr), stack_address(0), ready_semaphore(0), exit_semaphore(0), - suspend_count(0) {} + suspend_count(0), + thread_name(thread_name) {} ~ThreadInfo() {} @@ -270,10 +282,14 @@ class TestThreadPool { // The thread’s suspend count. int suspend_count; + + // The thread's name. + const std::string thread_name; }; static void* ThreadMain(void* argument) { ThreadInfo* thread_info = static_cast(argument); + const ScopedSetThreadName scoped_set_thread_name(thread_info->thread_name); thread_info->stack_address = FromPointerCast(&thread_info); @@ -293,6 +309,9 @@ class TestThreadPool { // This is a vector of pointers because the address of a ThreadInfo object is // passed to each thread’s ThreadMain(), so they cannot move around in memory. std::vector> thread_infos_; + + // Prefix to use for each thread's name, suffixed with "-$threadindex". + const std::string thread_name_prefix_; }; using ThreadMap = std::map; @@ -328,6 +347,7 @@ void ExpectSeveralThreads(ThreadMap* thread_map, EXPECT_LT(iterator->second.stack_address, thread_stack_region_end); EXPECT_EQ(thread.suspend_count, iterator->second.suspend_count); + EXPECT_EQ(thread.name, iterator->second.thread_name); // Remove the thread from the expectation map since it’s already been // found. This makes it easy to check for duplicate thread IDs, and makes @@ -374,7 +394,7 @@ TEST(ProcessReaderMac, SelfSeveralThreads) { ProcessReaderMac process_reader; ASSERT_TRUE(process_reader.Initialize(mach_task_self())); - TestThreadPool thread_pool; + TestThreadPool thread_pool("SelfSeveralThreads"); constexpr size_t kChildThreads = 16; ASSERT_NO_FATAL_FAILURE(thread_pool.StartThreads(kChildThreads)); @@ -392,6 +412,8 @@ TEST(ProcessReaderMac, SelfSeveralThreads) { // There can’t be any duplicate thread IDs. EXPECT_EQ(thread_map.count(thread_id), 0u); + expectation.thread_name = + base::StringPrintf("SelfSeveralThreads-%zu", thread_index); thread_map[thread_id] = expectation; } @@ -431,8 +453,11 @@ uint64_t GetThreadID() { class ProcessReaderThreadedChild final : public MachMultiprocess { public: - explicit ProcessReaderThreadedChild(size_t thread_count) - : MachMultiprocess(), thread_count_(thread_count) {} + explicit ProcessReaderThreadedChild(const std::string thread_name_prefix, + size_t thread_count) + : MachMultiprocess(), + thread_name_prefix_(thread_name_prefix), + thread_count_(thread_count) {} ProcessReaderThreadedChild(const ProcessReaderThreadedChild&) = delete; ProcessReaderThreadedChild& operator=(const ProcessReaderThreadedChild&) = @@ -463,6 +488,15 @@ class ProcessReaderThreadedChild final : public MachMultiprocess { CheckedReadFileExactly(read_handle, &expectation.suspend_count, sizeof(expectation.suspend_count)); + std::string::size_type expected_thread_name_length; + CheckedReadFileExactly(read_handle, + &expected_thread_name_length, + sizeof(expected_thread_name_length)); + std::string expected_thread_name(expected_thread_name_length, '\0'); + CheckedReadFileExactly(read_handle, + expected_thread_name.data(), + expected_thread_name_length); + expectation.thread_name = expected_thread_name; // There can’t be any duplicate thread IDs. EXPECT_EQ(thread_map.count(thread_id), 0u); @@ -479,9 +513,13 @@ class ProcessReaderThreadedChild final : public MachMultiprocess { } void MachMultiprocessChild() override { - TestThreadPool thread_pool; + TestThreadPool thread_pool(thread_name_prefix_); ASSERT_NO_FATAL_FAILURE(thread_pool.StartThreads(thread_count_)); + const std::string current_thread_name(base::StringPrintf( + "%s-MachMultiprocessChild", thread_name_prefix_.c_str())); + const ScopedSetThreadName scoped_set_thread_name(current_thread_name); + FileHandle write_handle = WritePipeHandle(); // This thread isn’t part of the thread pool, but the parent will be able @@ -500,6 +538,13 @@ class ProcessReaderThreadedChild final : public MachMultiprocess { CheckedWriteFile(write_handle, &expectation.suspend_count, sizeof(expectation.suspend_count)); + const std::string::size_type current_thread_name_length = + current_thread_name.length(); + CheckedWriteFile(write_handle, + ¤t_thread_name_length, + sizeof(current_thread_name_length)); + CheckedWriteFile( + write_handle, current_thread_name.data(), current_thread_name_length); // Write an entry for everything in the thread pool. for (size_t thread_index = 0; thread_index < thread_count_; @@ -513,6 +558,16 @@ class ProcessReaderThreadedChild final : public MachMultiprocess { CheckedWriteFile(write_handle, &expectation.suspend_count, sizeof(expectation.suspend_count)); + const std::string thread_pool_thread_name = base::StringPrintf( + "%s-%zu", thread_name_prefix_.c_str(), thread_index); + const std::string::size_type thread_pool_thread_name_length = + thread_pool_thread_name.length(); + CheckedWriteFile(write_handle, + &thread_pool_thread_name_length, + sizeof(thread_pool_thread_name_length)); + CheckedWriteFile(write_handle, + thread_pool_thread_name.data(), + thread_pool_thread_name_length); } // Wait for the parent to signal that it’s OK to exit by closing its end of @@ -520,19 +575,22 @@ class ProcessReaderThreadedChild final : public MachMultiprocess { CheckedReadFileAtEOF(ReadPipeHandle()); } + const std::string thread_name_prefix_; size_t thread_count_; }; TEST(ProcessReaderMac, ChildOneThread) { // The main thread plus zero child threads equals one thread. constexpr size_t kChildThreads = 0; - ProcessReaderThreadedChild process_reader_threaded_child(kChildThreads); + ProcessReaderThreadedChild process_reader_threaded_child("ChildOneThread", + kChildThreads); process_reader_threaded_child.Run(); } TEST(ProcessReaderMac, ChildSeveralThreads) { constexpr size_t kChildThreads = 64; - ProcessReaderThreadedChild process_reader_threaded_child(kChildThreads); + ProcessReaderThreadedChild process_reader_threaded_child( + "ChildSeveralThreads", kChildThreads); process_reader_threaded_child.Run(); } @@ -702,11 +760,11 @@ class ScopedOpenCLNoOpKernel { const size_t source_lengths[] = { strlen(sources[0]), }; - static_assert(base::size(sources) == base::size(source_lengths), + static_assert(std::size(sources) == std::size(source_lengths), "arrays must be parallel"); program_ = clCreateProgramWithSource( - context_, base::size(sources), sources, source_lengths, &rv); + context_, std::size(sources), sources, source_lengths, &rv); ASSERT_EQ(rv, CL_SUCCESS) << "clCreateProgramWithSource"; rv = clBuildProgram( diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types.cc index 3d4e059020..c91b697d12 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "snapshot/mac/process_types/internal.h" #include "util/process/process_memory_mac.h" @@ -74,7 +74,7 @@ using UInt64Array4 = uint64_t[4]; template <> inline void Assign(UInt64Array4* destination, const UInt32Array4& source) { - for (size_t index = 0; index < base::size(source); ++index) { + for (size_t index = 0; index < std::size(source); ++index) { (*destination)[index] = source[index]; } } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types/custom.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types/custom.cc index 06c13001d0..5c6dec98d2 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types/custom.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types/custom.cc @@ -12,21 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "snapshot/mac/process_types.h" - #include #include #include #include +#include #include #include #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/numerics/safe_math.h" #include "base/strings/stringprintf.h" +#include "snapshot/mac/process_types.h" #include "snapshot/mac/process_types/internal.h" #include "util/mac/mac_util.h" #include "util/process/process_memory_mac.h" @@ -150,8 +149,8 @@ size_t dyld_all_image_infos::ExpectedSizeForVersion( sizeof(dyld_all_image_infos), // 18 }; - if (version >= base::size(kSizeForVersion)) { - return kSizeForVersion[base::size(kSizeForVersion) - 1]; + if (version >= std::size(kSizeForVersion)) { + return kSizeForVersion[std::size(kSizeForVersion) - 1]; } static_assert(std::is_unsigned::value, diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types_test.cc index 90f5c1f679..2946dc25c3 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/process_types_test.cc @@ -18,10 +18,10 @@ #include #include +#include #include #include -#include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gtest/gtest.h" @@ -172,7 +172,7 @@ TEST(ProcessTypes, DyldImagesSelf) { {16, kUnsupported, 328}, {17, kUnsupported, 368}, }; - for (size_t index = 0; index < base::size(kVersionsAndSizes); ++index) { + for (size_t index = 0; index < std::size(kVersionsAndSizes); ++index) { uint32_t version = kVersionsAndSizes[index].version; SCOPED_TRACE(base::StringPrintf("index %zu, version %u", index, version)); @@ -325,7 +325,7 @@ TEST(ProcessTypes, DyldImagesSelf) { self_image_infos->sharedCacheBaseAddress); EXPECT_EQ(proctype_image_infos.dyldPath, reinterpret_cast(self_image_infos->dyldPath)); - for (size_t index = 0; index < base::size(self_image_infos->notifyPorts); + for (size_t index = 0; index < std::size(self_image_infos->notifyPorts); ++index) { EXPECT_EQ(proctype_image_infos.notifyPorts[index], self_image_infos->notifyPorts[index]) @@ -345,7 +345,7 @@ TEST(ProcessTypes, DyldImagesSelf) { // process_types version. It’s difficult to compare the reserved fields in // these older SDKs, so only do it where the declarations match. if (proctype_image_infos.version >= 14) { - for (size_t index = 0; index < base::size(proctype_image_infos.reserved); + for (size_t index = 0; index < std::size(proctype_image_infos.reserved); ++index) { EXPECT_EQ(proctype_image_infos.reserved[index], implicit_cast(self_image_infos->reserved[index])) diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.cc b/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.cc index 7ae5f9fae4..3c4a1991a8 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.cc @@ -30,6 +30,7 @@ ThreadSnapshotMac::ThreadSnapshotMac() context_union_(), context_(), stack_(), + thread_name_(), thread_id_(0), thread_specific_data_address_(0), thread_(MACH_PORT_NULL), @@ -46,6 +47,7 @@ bool ThreadSnapshotMac::Initialize( thread_ = process_reader_thread.port; thread_id_ = process_reader_thread.id; + thread_name_ = process_reader_thread.name; suspend_count_ = process_reader_thread.suspend_count; priority_ = process_reader_thread.priority; thread_specific_data_address_ = @@ -139,6 +141,11 @@ uint64_t ThreadSnapshotMac::ThreadID() const { return thread_id_; } +std::string ThreadSnapshotMac::ThreadName() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return thread_name_; +} + int ThreadSnapshotMac::SuspendCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return suspend_count_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.h b/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.h index 4d9cb3167f..ebdb3ae352 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/mac/thread_snapshot_mac.h @@ -18,6 +18,8 @@ #include #include +#include + #include "build/build_config.h" #include "snapshot/cpu_context.h" #include "snapshot/mac/process_reader_mac.h" @@ -60,6 +62,7 @@ class ThreadSnapshotMac final : public ThreadSnapshot { const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; @@ -78,6 +81,7 @@ class ThreadSnapshotMac final : public ThreadSnapshot { } context_union_; CPUContext context_; MemorySnapshotGeneric stack_; + std::string thread_name_; uint64_t thread_id_; uint64_t thread_specific_data_address_; thread_t thread_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_context_converter.cc b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_context_converter.cc index 981f34c974..5e94ca2cbc 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_context_converter.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_context_converter.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "minidump/minidump_context.h" @@ -147,7 +148,7 @@ bool MinidumpContextConverter::Initialize( return false; } - for (size_t i = 0; i < base::size(src->regs); i++) { + for (size_t i = 0; i < std::size(src->regs); i++) { context_.arm->regs[i] = src->regs[i]; } @@ -159,7 +160,7 @@ bool MinidumpContextConverter::Initialize( context_.arm->cpsr = src->cpsr; context_.arm->vfp_regs.fpscr = src->fpscr; - for (size_t i = 0; i < base::size(src->vfp); i++) { + for (size_t i = 0; i < std::size(src->vfp); i++) { context_.arm->vfp_regs.vfp[i] = src->vfp[i]; } @@ -179,14 +180,14 @@ bool MinidumpContextConverter::Initialize( return false; } - for (size_t i = 0; i < base::size(src->regs); i++) { + for (size_t i = 0; i < std::size(src->regs); i++) { context_.arm64->regs[i] = src->regs[i]; } context_.arm64->regs[29] = src->fp; context_.arm64->regs[30] = src->lr; - for (size_t i = 0; i < base::size(src->fpsimd); i++) { + for (size_t i = 0; i < std::size(src->fpsimd); i++) { context_.arm64->fpsimd[i] = src->fpsimd[i]; } @@ -208,7 +209,7 @@ bool MinidumpContextConverter::Initialize( return false; } - for (size_t i = 0; i < base::size(src->regs); i++) { + for (size_t i = 0; i < std::size(src->regs); i++) { context_.mipsel->regs[i] = src->regs[i]; } @@ -216,7 +217,7 @@ bool MinidumpContextConverter::Initialize( context_.mipsel->mdlo = static_cast(src->mdlo); context_.mipsel->dsp_control = src->dsp_control; - for (size_t i = 0; i < base::size(src->hi); i++) { + for (size_t i = 0; i < std::size(src->hi); i++) { context_.mipsel->hi[i] = src->hi[i]; context_.mipsel->lo[i] = src->lo[i]; } @@ -244,7 +245,7 @@ bool MinidumpContextConverter::Initialize( return false; } - for (size_t i = 0; i < base::size(src->regs); i++) { + for (size_t i = 0; i < std::size(src->regs); i++) { context_.mips64->regs[i] = src->regs[i]; } @@ -252,7 +253,7 @@ bool MinidumpContextConverter::Initialize( context_.mips64->mdlo = src->mdlo; context_.mips64->dsp_control = src->dsp_control; - for (size_t i = 0; i < base::size(src->hi); i++) { + for (size_t i = 0; i < std::size(src->hi); i++) { context_.mips64->hi[i] = src->hi[i]; context_.mips64->lo[i] = src->lo[i]; } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.cc index 0e9527c200..0ef93308a5 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.cc @@ -24,10 +24,10 @@ namespace internal { namespace { -template +template bool ReadMinidumpString(FileReaderInterface* file_reader, - RVA rva, - StringType* string) { + RVAType rva, + StringType* string) { if (rva == 0) { string->clear(); return true; @@ -59,12 +59,24 @@ bool ReadMinidumpUTF8String(FileReaderInterface* file_reader, return ReadMinidumpString(file_reader, rva, string); } +bool ReadMinidumpUTF8String(FileReaderInterface* file_reader, + RVA64 rva, + std::string* string) { + return ReadMinidumpString(file_reader, rva, string); +} + bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, RVA rva, std::u16string* string) { return ReadMinidumpString(file_reader, rva, string); } +bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, + RVA64 rva, + std::u16string* string) { + return ReadMinidumpString(file_reader, rva, string); +} + bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, RVA rva, std::string* string) { @@ -79,5 +91,19 @@ bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, return true; } +bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, + RVA64 rva, + std::string* string) { + std::u16string string_raw; + + if (!ReadMinidumpString(file_reader, rva, &string_raw)) { + return false; + } + + base::UTF16ToUTF8(string_raw.data(), string_raw.size(), string); + + return true; +} + } // namespace internal } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.h b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.h index 370fa8c194..3618aa34f3 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/minidump_string_reader.h @@ -20,6 +20,8 @@ #include +#include "base/strings/utf_string_conversions.h" +#include "minidump/minidump_extensions.h" #include "util/file/file_reader.h" namespace crashpad { @@ -34,6 +36,11 @@ bool ReadMinidumpUTF8String(FileReaderInterface* file_reader, RVA rva, std::string* string); +//! \brief 64-bit specialization of ReadMinidumpUTF8String. +bool ReadMinidumpUTF8String(FileReaderInterface* file_reader, + RVA64 rva, + std::string* string); + //! \brief Reads a MinidumpUTF16String from a minidump file at offset \a rva in //! \a file_reader, and returns it in \a string. //! @@ -43,6 +50,11 @@ bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, RVA rva, std::u16string* string); +//! \brief 64-bit specialization of ReadMinidumpUTF16String. +bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, + RVA64 rva, + std::u16string* string); + //! \brief Reads a MinidumpUTF16String from a minidump file at offset \a rva in //! \a file_reader, and returns it in \a string. //! @@ -52,6 +64,11 @@ bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, RVA rva, std::string* string); +//! \brief 64-bit specialization of ReadMinidumpUTF16String. +bool ReadMinidumpUTF16String(FileReaderInterface* file_reader, + RVA64 rva, + std::string* string); + } // namespace internal } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/module_snapshot_minidump.cc b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/module_snapshot_minidump.cc index 698f535741..7dad87a663 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/module_snapshot_minidump.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/module_snapshot_minidump.cc @@ -100,7 +100,7 @@ bool ModuleSnapshotMinidump::InitializeModuleCodeView( signature = *reinterpret_cast(cv_record.data()); if (signature == CodeViewRecordPDB70::kSignature) { - if (cv_record.size() < offsetof(CodeViewRecordPDB70, pdb_name)) { + if (cv_record.size() < offsetof(CodeViewRecordPDB70, pdb_name) + 1) { LOG(ERROR) << "CodeView record in module marked as PDB70 but too small"; return false; } @@ -111,8 +111,14 @@ bool ModuleSnapshotMinidump::InitializeModuleCodeView( age_ = cv_record_pdb70->age; uuid_ = cv_record_pdb70->uuid; + if (cv_record.back() != '\0') { + LOG(ERROR) << "CodeView record marked as PDB70 missing NUL-terminator in " + "pdb_name"; + return false; + } + std::copy(cv_record.begin() + offsetof(CodeViewRecordPDB70, pdb_name), - cv_record.end(), + cv_record.end() - 1, std::back_inserter(debug_file_name_)); return true; } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.cc b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.cc index db7e595546..4017c91bce 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.cc @@ -23,6 +23,7 @@ #include "minidump/minidump_extensions.h" #include "snapshot/memory_map_region_snapshot.h" #include "snapshot/minidump/minidump_simple_string_dictionary_reader.h" +#include "snapshot/minidump/minidump_string_reader.h" #include "util/file/file_io.h" namespace crashpad { @@ -323,7 +324,7 @@ bool ProcessSnapshotMinidump::InitializeMiscInfo() { full_version_ = base::UTF16ToUTF8(info.BuildString); #endif full_version_ = full_version_.substr(0, full_version_.find(';')); - FALLTHROUGH; + [[fallthrough]]; case sizeof(MINIDUMP_MISC_INFO_3): case sizeof(MINIDUMP_MISC_INFO_2): case sizeof(MINIDUMP_MISC_INFO): @@ -576,12 +577,16 @@ bool ProcessSnapshotMinidump::InitializeThreads() { return false; } + if (!InitializeThreadNames()) { + return false; + } + for (uint32_t thread_index = 0; thread_index < thread_count; ++thread_index) { const RVA thread_rva = stream_it->second->Rva + sizeof(thread_count) + thread_index * sizeof(MINIDUMP_THREAD); auto thread = std::make_unique(); - if (!thread->Initialize(file_reader_, thread_rva, arch_)) { + if (!thread->Initialize(file_reader_, thread_rva, arch_, thread_names_)) { return false; } @@ -591,6 +596,71 @@ bool ProcessSnapshotMinidump::InitializeThreads() { return true; } +bool ProcessSnapshotMinidump::InitializeThreadNames() { + const auto& stream_it = stream_map_.find(kMinidumpStreamTypeThreadNameList); + if (stream_it == stream_map_.end()) { + return true; + } + + if (stream_it->second->DataSize < sizeof(MINIDUMP_THREAD_NAME_LIST)) { + LOG(ERROR) << "thread_name_list size mismatch"; + return false; + } + + if (!file_reader_->SeekSet(stream_it->second->Rva)) { + return false; + } + + uint32_t thread_name_count; + if (!file_reader_->ReadExactly(&thread_name_count, + sizeof(thread_name_count))) { + return false; + } + + if (sizeof(MINIDUMP_THREAD_NAME_LIST) + + thread_name_count * sizeof(MINIDUMP_THREAD_NAME) != + stream_it->second->DataSize) { + LOG(ERROR) << "thread_name_list size mismatch"; + return false; + } + + for (uint32_t thread_name_index = 0; thread_name_index < thread_name_count; + ++thread_name_index) { + const RVA thread_name_rva = + stream_it->second->Rva + sizeof(thread_name_count) + + thread_name_index * sizeof(MINIDUMP_THREAD_NAME); + if (!file_reader_->SeekSet(thread_name_rva)) { + return false; + } + MINIDUMP_THREAD_NAME minidump_thread_name; + if (!file_reader_->ReadExactly(&minidump_thread_name, + sizeof(minidump_thread_name))) { + return false; + } + std::string name; + if (!internal::ReadMinidumpUTF16String( + file_reader_, minidump_thread_name.RvaOfThreadName, &name)) { + return false; + } + + // XXX sentry maintainers: + // the upstream line + // + // thread_names_.emplace(minidump_thread_name.ThreadId, std::move(name)); + // + // fails to compile on GCC (which is untested/-supported by the crashpad + // maintainers). emplace() takes its parameters as rvalue-references + // which is illegal when referencing a bitfield (or packed struct). + // + // Creating an explicit copy by-passes the issue, trading for more + // (typically two) instructions per thread-name. + uint32_t thread_id = minidump_thread_name.ThreadId; + thread_names_.emplace(thread_id, std::move(name)); + } + + return true; +} + bool ProcessSnapshotMinidump::InitializeSystemSnapshot() { const auto& stream_it = stream_map_.find(kMinidumpStreamTypeSystemInfo); if (stream_it == stream_map_.end()) { diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.h b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.h index 18fbc7c367..351fc4e1f0 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump.h @@ -112,6 +112,10 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot { // Initialize(). bool InitializeThreads(); + // Initializes data carried in a MINIDUMP_THREAD_NAME_LIST stream on behalf of + // Initialize(). + bool InitializeThreadNames(); + // Initializes data carried in a MINIDUMP_MEMORY_INFO_LIST stream on behalf of // Initialize(). bool InitializeMemoryInfo(); @@ -147,6 +151,7 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot { std::map stream_map_; std::vector> modules_; std::vector> threads_; + std::map thread_names_; std::vector unloaded_modules_; std::vector> mem_regions_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc index b9fa23d73c..902d699ee8 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc @@ -19,9 +19,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/numerics/safe_math.h" #include "base/strings/utf_string_conversions.h" #include "gtest/gtest.h" @@ -350,6 +350,7 @@ TEST(ProcessSnapshotMinidump, Modules) { "libgeorgism", "librealistutopia", }; + constexpr char debug_name[] = "debugme.pdb"; minidump_module.BaseOfImage = 0xbadf00d; minidump_module.SizeOfImage = 9001; @@ -373,12 +374,15 @@ TEST(ProcessSnapshotMinidump, Modules) { pdb70_cv.signature = CodeViewRecordPDB70::kSignature; pdb70_cv.age = 7; pdb70_cv.uuid.InitializeFromString("00112233-4455-6677-8899-aabbccddeeff"); - pdb70_cv.pdb_name[0] = '\0'; auto pdb70_loc = static_cast(string_file.SeekGet()); - auto pdb70_size = sizeof(pdb70_cv); + auto pdb70_size = offsetof(CodeViewRecordPDB70, pdb_name); - EXPECT_TRUE(string_file.Write(&pdb70_cv, sizeof(pdb70_cv))); + EXPECT_TRUE(string_file.Write(&pdb70_cv, pdb70_size)); + + size_t nul_terminated_length = strlen(debug_name) + 1; + EXPECT_TRUE(string_file.Write(debug_name, nul_terminated_length)); + pdb70_size += nul_terminated_length; CodeViewRecordBuildID build_id_cv; build_id_cv.signature = CodeViewRecordBuildID::kSignature; @@ -545,6 +549,7 @@ TEST(ProcessSnapshotMinidump, Modules) { EXPECT_EQ(uuid.ToString(), "00112233-4455-6677-8899-aabbccddeeff"); EXPECT_EQ(age, 7U); + EXPECT_EQ(modules[i]->DebugFileName(), debug_name); } else { auto build_id = modules[i]->BuildID(); std::string build_id_text(build_id.data(), @@ -723,6 +728,104 @@ TEST(ProcessSnapshotMinidump, Threads) { } } +TEST(ProcessSnapshotMinidump, ThreadsWithNames) { + StringFile string_file; + + MINIDUMP_HEADER header = {}; + EXPECT_TRUE(string_file.Write(&header, sizeof(header))); + + constexpr uint32_t kMinidumpThreadCount = 4; + constexpr uint32_t kBaseThreadId = 42; + + const std::string thread_names[kMinidumpThreadCount] = { + "ariadne", + "theseus", + "pasiphae", + "minos", + }; + + RVA64 thread_name_rva64s[kMinidumpThreadCount]; + for (uint32_t i = 0; i < kMinidumpThreadCount; i++) { + thread_name_rva64s[i] = static_cast(string_file.SeekGet()); + auto name16 = base::UTF8ToUTF16(thread_names[i]); + uint32_t size = + base::checked_cast(sizeof(name16[0]) * name16.size()); + EXPECT_TRUE(string_file.Write(&size, sizeof(size))); + EXPECT_TRUE(string_file.Write(&name16[0], size)); + } + + MINIDUMP_DIRECTORY minidump_thread_list_directory = {}; + minidump_thread_list_directory.StreamType = kMinidumpStreamTypeThreadList; + minidump_thread_list_directory.Location.DataSize = + sizeof(MINIDUMP_THREAD_LIST) + + kMinidumpThreadCount * sizeof(MINIDUMP_THREAD); + minidump_thread_list_directory.Location.Rva = + static_cast(string_file.SeekGet()); + + // Fields in MINIDUMP_THREAD_LIST. + EXPECT_TRUE( + string_file.Write(&kMinidumpThreadCount, sizeof(kMinidumpThreadCount))); + for (uint32_t minidump_thread_index = 0; + minidump_thread_index < kMinidumpThreadCount; + ++minidump_thread_index) { + MINIDUMP_THREAD minidump_thread = {}; + minidump_thread.ThreadId = kBaseThreadId + minidump_thread_index; + EXPECT_TRUE(string_file.Write(&minidump_thread, sizeof(minidump_thread))); + } + + header.StreamDirectoryRva = static_cast(string_file.SeekGet()); + EXPECT_TRUE(string_file.Write(&minidump_thread_list_directory, + sizeof(minidump_thread_list_directory))); + + MINIDUMP_DIRECTORY minidump_thread_name_list_directory = {}; + minidump_thread_name_list_directory.StreamType = + kMinidumpStreamTypeThreadNameList; + minidump_thread_name_list_directory.Location.DataSize = + sizeof(MINIDUMP_THREAD_NAME_LIST) + + kMinidumpThreadCount * sizeof(MINIDUMP_THREAD_NAME); + minidump_thread_name_list_directory.Location.Rva = + static_cast(string_file.SeekGet()); + + // Fields in MINIDUMP_THREAD_NAME_LIST. + EXPECT_TRUE( + string_file.Write(&kMinidumpThreadCount, sizeof(kMinidumpThreadCount))); + for (uint32_t minidump_thread_index = 0; + minidump_thread_index < kMinidumpThreadCount; + ++minidump_thread_index) { + MINIDUMP_THREAD_NAME minidump_thread_name = {0}; + minidump_thread_name.ThreadId = kBaseThreadId + minidump_thread_index; + minidump_thread_name.RvaOfThreadName = + thread_name_rva64s[minidump_thread_index]; + EXPECT_TRUE( + string_file.Write(&minidump_thread_name, sizeof(minidump_thread_name))); + } + + header.StreamDirectoryRva = static_cast(string_file.SeekGet()); + ASSERT_TRUE(string_file.Write(&minidump_thread_list_directory, + sizeof(minidump_thread_list_directory))); + ASSERT_TRUE(string_file.Write(&minidump_thread_name_list_directory, + sizeof(minidump_thread_name_list_directory))); + + header.Signature = MINIDUMP_SIGNATURE; + header.Version = MINIDUMP_VERSION; + header.NumberOfStreams = 2; + EXPECT_TRUE(string_file.SeekSet(0)); + EXPECT_TRUE(string_file.Write(&header, sizeof(header))); + + ProcessSnapshotMinidump process_snapshot; + EXPECT_TRUE(process_snapshot.Initialize(&string_file)); + + std::vector threads = process_snapshot.Threads(); + ASSERT_EQ(threads.size(), kMinidumpThreadCount); + + size_t idx = 0; + for (const auto& thread : threads) { + EXPECT_EQ(thread->ThreadID(), kBaseThreadId + idx); + EXPECT_EQ(thread->ThreadName(), thread_names[idx]); + idx++; + } +} + TEST(ProcessSnapshotMinidump, System) { const char* cpu_info = "GenuineIntel"; const uint32_t* cpu_info_bytes = reinterpret_cast(cpu_info); @@ -975,27 +1078,27 @@ TEST(ProcessSnapshotMinidump, ThreadContextX86_64) { minidump_context.fxsave.fpu_ip_64 = 42; minidump_context.fxsave.fpu_dp_64 = 43; - for (size_t i = 0; i < base::size(minidump_context.vector_register); i++) { + for (size_t i = 0; i < std::size(minidump_context.vector_register); i++) { minidump_context.vector_register[i].lo = i * 2 + 44; minidump_context.vector_register[i].hi = i * 2 + 45; } - for (uint8_t i = 0; i < base::size(minidump_context.fxsave.reserved_4); i++) { + for (uint8_t i = 0; i < std::size(minidump_context.fxsave.reserved_4); i++) { minidump_context.fxsave.reserved_4[i] = i * 2 + 115; minidump_context.fxsave.available[i] = i * 2 + 116; } - for (size_t i = 0; i < base::size(minidump_context.fxsave.st_mm); i++) { + for (size_t i = 0; i < std::size(minidump_context.fxsave.st_mm); i++) { for (uint8_t j = 0; - j < base::size(minidump_context.fxsave.st_mm[0].mm_value); + j < std::size(minidump_context.fxsave.st_mm[0].mm_value); j++) { minidump_context.fxsave.st_mm[i].mm_value[j] = j + 1; minidump_context.fxsave.st_mm[i].mm_reserved[j] = j + 1; } } - for (size_t i = 0; i < base::size(minidump_context.fxsave.xmm); i++) { - for (uint8_t j = 0; j < base::size(minidump_context.fxsave.xmm[0]); j++) { + for (size_t i = 0; i < std::size(minidump_context.fxsave.xmm); i++) { + for (uint8_t j = 0; j < std::size(minidump_context.fxsave.xmm[0]); j++) { minidump_context.fxsave.xmm[i][j] = j + 1; } } @@ -1078,20 +1181,20 @@ TEST(ProcessSnapshotMinidump, ThreadContextX86_64) { EXPECT_EQ(ctx->fxsave.fpu_ip_64, 42U); EXPECT_EQ(ctx->fxsave.fpu_dp_64, 43U); - for (uint8_t i = 0; i < base::size(ctx->fxsave.reserved_4); i++) { + for (uint8_t i = 0; i < std::size(ctx->fxsave.reserved_4); i++) { EXPECT_EQ(ctx->fxsave.reserved_4[i], i * 2 + 115); EXPECT_EQ(ctx->fxsave.available[i], i * 2 + 116); } - for (size_t i = 0; i < base::size(ctx->fxsave.st_mm); i++) { - for (uint8_t j = 0; j < base::size(ctx->fxsave.st_mm[0].mm_value); j++) { + for (size_t i = 0; i < std::size(ctx->fxsave.st_mm); i++) { + for (uint8_t j = 0; j < std::size(ctx->fxsave.st_mm[0].mm_value); j++) { EXPECT_EQ(ctx->fxsave.st_mm[i].mm_value[j], j + 1); EXPECT_EQ(ctx->fxsave.st_mm[i].mm_reserved[j], j + 1); } } - for (size_t i = 0; i < base::size(ctx->fxsave.xmm); i++) { - for (uint8_t j = 0; j < base::size(ctx->fxsave.xmm[0]); j++) { + for (size_t i = 0; i < std::size(ctx->fxsave.xmm); i++) { + for (uint8_t j = 0; j < std::size(ctx->fxsave.xmm[0]); j++) { EXPECT_EQ(ctx->fxsave.xmm[i][j], j + 1); } } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.cc b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.cc index f8f3673f4c..26aabd7039 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.cc @@ -26,15 +26,18 @@ namespace internal { ThreadSnapshotMinidump::ThreadSnapshotMinidump() : ThreadSnapshot(), minidump_thread_(), + thread_name_(), context_(), stack_(), initialized_() {} ThreadSnapshotMinidump::~ThreadSnapshotMinidump() {} -bool ThreadSnapshotMinidump::Initialize(FileReaderInterface* file_reader, - RVA minidump_thread_rva, - CPUArchitecture arch) { +bool ThreadSnapshotMinidump::Initialize( + FileReaderInterface* file_reader, + RVA minidump_thread_rva, + CPUArchitecture arch, + const std::map& thread_names) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); std::vector minidump_context; @@ -67,6 +70,10 @@ bool ThreadSnapshotMinidump::Initialize(FileReaderInterface* file_reader, if (!stack_.Initialize(file_reader, stack_info_location)) { return false; } + const auto thread_name_iter = thread_names.find(minidump_thread_.ThreadId); + if (thread_name_iter != thread_names.end()) { + thread_name_ = thread_name_iter->second; + } INITIALIZATION_STATE_SET_VALID(initialized_); return true; @@ -77,6 +84,11 @@ uint64_t ThreadSnapshotMinidump::ThreadID() const { return minidump_thread_.ThreadId; } +std::string ThreadSnapshotMinidump::ThreadName() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return thread_name_; +} + int ThreadSnapshotMinidump::SuspendCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return minidump_thread_.SuspendCount; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.h b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.h index 7efb18d71c..b0ef424aac 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/minidump/thread_snapshot_minidump.h @@ -17,6 +17,8 @@ #include +#include + #include "minidump/minidump_extensions.h" #include "snapshot/cpu_context.h" #include "snapshot/minidump/memory_snapshot_minidump.h" @@ -46,16 +48,20 @@ class ThreadSnapshotMinidump : public ThreadSnapshot { //! the thread’s MINIDUMP_THREAD structure is located. //! \param[in] arch The architecture of the system this thread is running on. //! Used to decode CPU Context. + //! \param[in] thread_names Map from thread ID to thread name previously read + //! from the minidump's MINIDUMP_THREAD_NAME_LIST. //! //! \return `true` if the snapshot could be created, `false` otherwise with //! an appropriate message logged. bool Initialize(FileReaderInterface* file_reader, RVA minidump_thread_rva, - CPUArchitecture arch); + CPUArchitecture arch, + const std::map& thread_names); const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; @@ -71,6 +77,7 @@ class ThreadSnapshotMinidump : public ThreadSnapshot { bool InitializeContext(const std::vector& minidump_context); MINIDUMP_THREAD minidump_thread_; + std::string thread_name_; MinidumpContextConverter context_; MemorySnapshotMinidump stack_; InitializationStateDcheck initialized_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone.cc b/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone.cc index c413d7080f..3591157e82 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone.cc @@ -17,8 +17,9 @@ #include #include +#include + #include "base/check.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "build/build_config.h" @@ -40,7 +41,7 @@ void TimeZone(const timeval& snapshot_time, bool found_transition = false; long probe_gmtoff = local.tm_gmtoff; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // Some versions of the timezone database on Android have incorrect // information (e.g. Asia/Kolkata and Pacific/Honolulu). These timezones set // daylight to a non-zero value and return incorrect, >= 0 values for tm_isdst @@ -61,8 +62,7 @@ void TimeZone(const timeval& snapshot_time, static constexpr int kMonthDeltas[] = {0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10, 11, -11, 12, -12}; - for (size_t index = 0; - index < base::size(kMonthDeltas) && !found_transition; + for (size_t index = 0; index < std::size(kMonthDeltas) && !found_transition; ++index) { // Look at a day of each month at local noon. Set tm_isdst to -1 to avoid // giving mktime() any hints about whether to consider daylight saving @@ -105,14 +105,14 @@ void TimeZone(const timeval& snapshot_time, } else { *daylight_name = tzname[0]; *dst_status = SystemSnapshot::kDoesNotObserveDaylightSavingTime; -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // timezone is more reliably set correctly on Android. *standard_offset_seconds = -timezone; *daylight_offset_seconds = -timezone; #else *standard_offset_seconds = local.tm_gmtoff; *daylight_offset_seconds = local.tm_gmtoff; -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) } } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone_test.cc index 6a343767e3..990a063ebc 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/posix/timezone_test.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" #include "test/errors.h" @@ -154,7 +154,7 @@ TEST(TimeZone, Basic) { {"UTC", false, 0, 0, "UTC", "UTC"}, }; - for (size_t index = 0; index < base::size(kTestTimeZones); ++index) { + for (size_t index = 0; index < std::size(kTestTimeZones); ++index) { const auto& test_time_zone = kTestTimeZones[index]; const char* tz = test_time_zone.tz; SCOPED_TRACE(base::StringPrintf("index %zu, tz %s", index, tz)); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/process_snapshot_sanitized_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/process_snapshot_sanitized_test.cc index 0bdea432b0..306f2df26a 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/process_snapshot_sanitized_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/process_snapshot_sanitized_test.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/notreached.h" #include "build/build_config.h" #include "gtest/gtest.h" @@ -25,7 +26,7 @@ #include "util/misc/address_sanitizer.h" #include "util/numeric/safe_assignment.h" -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include #include "snapshot/linux/process_snapshot_linux.h" @@ -101,7 +102,7 @@ void ChildTestFunction() { static StringAnnotation<32> non_allowed_annotation(kNonAllowedAnnotationName); non_allowed_annotation.Set(kNonAllowedAnnotationValue); - char string_data[base::size(kSensitiveStackData)]; + char string_data[std::size(kSensitiveStackData)]; strcpy(string_data, kSensitiveStackData); void (*code_pointer)(void) = ChildTestFunction; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/sanitization_information_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/sanitization_information_test.cc index 425ec7528d..65b01f0858 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/sanitization_information_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/sanitization_information_test.cc @@ -14,13 +14,14 @@ #include "snapshot/sanitized/sanitization_information.h" -#include "base/cxx17_backports.h" +#include + #include "build/build_config.h" #include "gtest/gtest.h" #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_linux.h" -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "test/linux/fake_ptrace_connection.h" #endif @@ -66,7 +67,7 @@ const char* const kNonEmptyAllowedAnnotations[] = {"string1", TEST_F(AllowedAnnotationsTest, NonEmptyAllowedAnnotations) { ASSERT_TRUE(DoReadAllowedAnnotations(kNonEmptyAllowedAnnotations)); ASSERT_EQ(allowed_annotations_.size(), - base::size(kNonEmptyAllowedAnnotations) - 1); + std::size(kNonEmptyAllowedAnnotations) - 1); for (size_t index = 0; index < allowed_annotations_.size(); ++index) { EXPECT_EQ(allowed_annotations_[index], kNonEmptyAllowedAnnotations[index]); } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.cc b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.cc index 186776eae0..4a1fb72ab1 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.cc @@ -39,6 +39,10 @@ uint64_t ThreadSnapshotSanitized::ThreadID() const { return snapshot_->ThreadID(); } +std::string ThreadSnapshotSanitized::ThreadName() const { + return snapshot_->ThreadName(); +} + int ThreadSnapshotSanitized::SuspendCount() const { return snapshot_->SuspendCount(); } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.h b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.h index dca0a0e917..b520579772 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/sanitized/thread_snapshot_sanitized.h @@ -17,6 +17,8 @@ #include "snapshot/thread_snapshot.h" +#include + #include "snapshot/sanitized/memory_snapshot_sanitized.h" #include "util/misc/range_set.h" @@ -44,6 +46,7 @@ class ThreadSnapshotSanitized final : public ThreadSnapshot { const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/test/test_cpu_context.cc b/thirdparty/sentry-native/external/crashpad/snapshot/test/test_cpu_context.cc index 4923d4c4f9..3b51973e26 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/test/test_cpu_context.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/test/test_cpu_context.cc @@ -17,7 +17,7 @@ #include #include -#include "base/cxx17_backports.h" +#include namespace crashpad { namespace test { @@ -44,28 +44,28 @@ void InitializeCPUContextFxsave(FxsaveType* fxsave, uint32_t* seed) { fxsave->reserved_3 = static_cast(value++); fxsave->mxcsr = value++; fxsave->mxcsr_mask = value++; - for (size_t st_mm_index = 0; st_mm_index < base::size(fxsave->st_mm); + for (size_t st_mm_index = 0; st_mm_index < std::size(fxsave->st_mm); ++st_mm_index) { - for (size_t byte = 0; byte < base::size(fxsave->st_mm[st_mm_index].st); + for (size_t byte = 0; byte < std::size(fxsave->st_mm[st_mm_index].st); ++byte) { fxsave->st_mm[st_mm_index].st[byte] = static_cast(value++); } for (size_t byte = 0; - byte < base::size(fxsave->st_mm[st_mm_index].st_reserved); + byte < std::size(fxsave->st_mm[st_mm_index].st_reserved); ++byte) { fxsave->st_mm[st_mm_index].st_reserved[byte] = static_cast(value); } } - for (size_t xmm_index = 0; xmm_index < base::size(fxsave->xmm); ++xmm_index) { - for (size_t byte = 0; byte < base::size(fxsave->xmm[xmm_index]); ++byte) { + for (size_t xmm_index = 0; xmm_index < std::size(fxsave->xmm); ++xmm_index) { + for (size_t byte = 0; byte < std::size(fxsave->xmm[xmm_index]); ++byte) { fxsave->xmm[xmm_index][byte] = static_cast(value++); } } - for (size_t byte = 0; byte < base::size(fxsave->reserved_4); ++byte) { + for (size_t byte = 0; byte < std::size(fxsave->reserved_4); ++byte) { fxsave->reserved_4[byte] = static_cast(value++); } - for (size_t byte = 0; byte < base::size(fxsave->available); ++byte) { + for (size_t byte = 0; byte < std::size(fxsave->available); ++byte) { fxsave->available[byte] = static_cast(value++); } @@ -161,6 +161,9 @@ void InitializeCPUContextX86_64(CPUContext* context, uint32_t seed) { context->x86_64->dr5 = value++; context->x86_64->dr6 = value++; context->x86_64->dr7 = value++; + + // Make sure this is sensible. When supplied the size/state come from the OS. + memset(&context->x86_64->xstate, 0, sizeof(context->x86_64->xstate)); } void InitializeCPUContextARM(CPUContext* context, uint32_t seed) { @@ -174,7 +177,7 @@ void InitializeCPUContextARM(CPUContext* context, uint32_t seed) { uint32_t value = seed; - for (size_t index = 0; index < base::size(arm->regs); ++index) { + for (size_t index = 0; index < std::size(arm->regs); ++index) { arm->regs[index] = value++; } arm->fp = value++; @@ -185,7 +188,7 @@ void InitializeCPUContextARM(CPUContext* context, uint32_t seed) { arm->pc = value++; arm->cpsr = value++; - for (size_t index = 0; index < base::size(arm->vfp_regs.vfp); ++index) { + for (size_t index = 0; index < std::size(arm->vfp_regs.vfp); ++index) { arm->vfp_regs.vfp[index] = value++; } arm->vfp_regs.fpscr = value++; @@ -205,14 +208,14 @@ void InitializeCPUContextARM64(CPUContext* context, uint32_t seed) { uint32_t value = seed; - for (size_t index = 0; index < base::size(arm64->regs); ++index) { + for (size_t index = 0; index < std::size(arm64->regs); ++index) { arm64->regs[index] = value++; } arm64->sp = value++; arm64->pc = value++; arm64->spsr = value++; - for (size_t index = 0; index < base::size(arm64->fpsimd); ++index) { + for (size_t index = 0; index < std::size(arm64->fpsimd); ++index) { arm64->fpsimd[index].lo = value++; arm64->fpsimd[index].hi = value++; } @@ -231,7 +234,7 @@ void InitializeCPUContextMIPS(CPUContext* context, uint32_t seed) { uint32_t value = seed; - for (size_t index = 0; index < base::size(mipsel->regs); ++index) { + for (size_t index = 0; index < std::size(mipsel->regs); ++index) { mipsel->regs[index] = value++; } @@ -242,7 +245,7 @@ void InitializeCPUContextMIPS(CPUContext* context, uint32_t seed) { mipsel->cp0_status = value++; mipsel->cp0_cause = value++; - for (size_t index = 0; index < base::size(mipsel->fpregs.fregs); ++index) { + for (size_t index = 0; index < std::size(mipsel->fpregs.fregs); ++index) { mipsel->fpregs.fregs[index]._fp_fregs = static_cast(value++); } @@ -267,7 +270,7 @@ void InitializeCPUContextMIPS64(CPUContext* context, uint32_t seed) { uint64_t value = seed; - for (size_t index = 0; index < base::size(mips64->regs); ++index) { + for (size_t index = 0; index < std::size(mips64->regs); ++index) { mips64->regs[index] = value++; } @@ -278,7 +281,7 @@ void InitializeCPUContextMIPS64(CPUContext* context, uint32_t seed) { mips64->cp0_status = value++; mips64->cp0_cause = value++; - for (size_t index = 0; index < base::size(mips64->fpregs.dregs); ++index) { + for (size_t index = 0; index < std::size(mips64->fpregs.dregs); ++index) { mips64->fpregs.dregs[index] = static_cast(value++); } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.cc b/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.cc index ed6d9fdab2..3e73ecdaac 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.cc @@ -43,6 +43,10 @@ uint64_t TestThreadSnapshot::ThreadID() const { return thread_id_; } +std::string TestThreadSnapshot::ThreadName() const { + return thread_name_; +} + int TestThreadSnapshot::SuspendCount() const { return suspend_count_; } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.h b/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.h index f865bdfea7..a1cef21be3 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/test/test_thread_snapshot.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -63,6 +64,9 @@ class TestThreadSnapshot final : public ThreadSnapshot { } void SetThreadID(uint64_t thread_id) { thread_id_ = thread_id; } + void SetThreadName(const std::string& thread_name) { + thread_name_ = thread_name; + } void SetSuspendCount(int suspend_count) { suspend_count_ = suspend_count; } void SetPriority(int priority) { priority_ = priority; } void SetThreadSpecificDataAddress(uint64_t thread_specific_data_address) { @@ -83,6 +87,7 @@ class TestThreadSnapshot final : public ThreadSnapshot { const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; @@ -96,6 +101,7 @@ class TestThreadSnapshot final : public ThreadSnapshot { CPUContext context_; std::unique_ptr stack_; uint64_t thread_id_; + std::string thread_name_; int suspend_count_; int priority_; uint64_t thread_specific_data_address_; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/thread_snapshot.h b/thirdparty/sentry-native/external/crashpad/snapshot/thread_snapshot.h index 08604a8836..8fd7420879 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/thread_snapshot.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/thread_snapshot.h @@ -17,9 +17,7 @@ #include -#ifdef CLIENT_STACKTRACES_ENABLED #include -#endif #include namespace crashpad { @@ -73,6 +71,9 @@ class ThreadSnapshot { //! unique system-wide. virtual uint64_t ThreadID() const = 0; + //! \brief Returns the thread's name. + virtual std::string ThreadName() const = 0; + //! \brief Returns the thread’s suspend count. //! //! A suspend count of `0` denotes a schedulable (not suspended) thread. diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/capture_memory_delegate_win.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/capture_memory_delegate_win.cc index ee5e5d644b..43067caa6d 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/capture_memory_delegate_win.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/capture_memory_delegate_win.cc @@ -55,19 +55,17 @@ void CaptureMemoryDelegateWin::AddNewMemorySnapshot( return; if (range.size() == 0) return; - if (budget_remaining_ && *budget_remaining_ == 0) + if (!budget_remaining_ || *budget_remaining_ == 0) return; snapshots_->push_back(std::make_unique()); internal::MemorySnapshotGeneric* snapshot = snapshots_->back().get(); snapshot->Initialize(process_reader_->Memory(), range.base(), range.size()); - if (budget_remaining_) { - if (!base::IsValueInRangeForNumericType(range.size())) { - *budget_remaining_ = 0; - } else { - int64_t temp = *budget_remaining_; - temp -= range.size(); - *budget_remaining_ = base::saturated_cast(temp); - } + if (!base::IsValueInRangeForNumericType(range.size())) { + *budget_remaining_ = 0; + } else { + int64_t temp = *budget_remaining_; + temp -= range.size(); + *budget_remaining_ = base::saturated_cast(temp); } } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.cc index db2e80362c..e79c94b307 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.cc @@ -36,12 +36,12 @@ static_assert(sizeof(CPUContextX86::Fsave) == #endif // ARCH_CPU_X86 template -bool HasContextPart(const T& context, uint32_t bits) { - return (context.ContextFlags & bits) == bits; +bool HasContextPart(const T* context, uint32_t bits) { + return (context->ContextFlags & bits) == bits; } template -void CommonInitializeX86Context(const T& context, CPUContextX86* out) { +void CommonInitializeX86Context(const T* context, CPUContextX86* out) { // This function assumes that the WOW64_CONTEXT_* and x86 CONTEXT_* values // for ContextFlags are identical. This can be tested when targeting 32-bit // x86. @@ -72,157 +72,187 @@ void CommonInitializeX86Context(const T& context, CPUContextX86* out) { << "non-x86 context"; if (HasContextPart(context, WOW64_CONTEXT_CONTROL)) { - out->ebp = context.Ebp; - out->eip = context.Eip; - out->cs = static_cast(context.SegCs); - out->eflags = context.EFlags; - out->esp = context.Esp; - out->ss = static_cast(context.SegSs); + out->ebp = context->Ebp; + out->eip = context->Eip; + out->cs = static_cast(context->SegCs); + out->eflags = context->EFlags; + out->esp = context->Esp; + out->ss = static_cast(context->SegSs); } if (HasContextPart(context, WOW64_CONTEXT_INTEGER)) { - out->eax = context.Eax; - out->ebx = context.Ebx; - out->ecx = context.Ecx; - out->edx = context.Edx; - out->edi = context.Edi; - out->esi = context.Esi; + out->eax = context->Eax; + out->ebx = context->Ebx; + out->ecx = context->Ecx; + out->edx = context->Edx; + out->edi = context->Edi; + out->esi = context->Esi; } if (HasContextPart(context, WOW64_CONTEXT_SEGMENTS)) { - out->ds = static_cast(context.SegDs); - out->es = static_cast(context.SegEs); - out->fs = static_cast(context.SegFs); - out->gs = static_cast(context.SegGs); + out->ds = static_cast(context->SegDs); + out->es = static_cast(context->SegEs); + out->fs = static_cast(context->SegFs); + out->gs = static_cast(context->SegGs); } if (HasContextPart(context, WOW64_CONTEXT_DEBUG_REGISTERS)) { - out->dr0 = context.Dr0; - out->dr1 = context.Dr1; - out->dr2 = context.Dr2; - out->dr3 = context.Dr3; + out->dr0 = context->Dr0; + out->dr1 = context->Dr1; + out->dr2 = context->Dr2; + out->dr3 = context->Dr3; // DR4 and DR5 are obsolete synonyms for DR6 and DR7, see // https://en.wikipedia.org/wiki/X86_debug_register. - out->dr4 = context.Dr6; - out->dr5 = context.Dr7; + out->dr4 = context->Dr6; + out->dr5 = context->Dr7; - out->dr6 = context.Dr6; - out->dr7 = context.Dr7; + out->dr6 = context->Dr6; + out->dr7 = context->Dr7; } if (HasContextPart(context, WOW64_CONTEXT_EXTENDED_REGISTERS)) { - static_assert(sizeof(out->fxsave) == sizeof(context.ExtendedRegisters), + static_assert(sizeof(out->fxsave) == sizeof(context->ExtendedRegisters), "fxsave types must be equivalent"); - memcpy(&out->fxsave, &context.ExtendedRegisters, sizeof(out->fxsave)); + memcpy(&out->fxsave, &context->ExtendedRegisters, sizeof(out->fxsave)); } else if (HasContextPart(context, WOW64_CONTEXT_FLOATING_POINT)) { // The static_assert that validates this cast can’t be here because it // relies on field names that vary based on the template parameter. CPUContextX86::FsaveToFxsave( - *reinterpret_cast(&context.FloatSave), + *reinterpret_cast(&context->FloatSave), &out->fxsave); } } +#if defined(ARCH_CPU_X86_64) +DWORD64 CallGetEnabledXStateFeatures() { + // GetEnabledXStateFeatures needs Windows 7 SP1. + HINSTANCE kernel32 = GetModuleHandle(L"Kernel32.dll"); + decltype(GetEnabledXStateFeatures)* get_enabled_xstate_features = + reinterpret_cast( + GetProcAddress(kernel32, "GetEnabledXStateFeatures")); + if (!get_enabled_xstate_features) + return 0; + return get_enabled_xstate_features(); +} +#endif // defined(ARCH_CPU_X64) + } // namespace #if defined(ARCH_CPU_X86) -void InitializeX86Context(const CONTEXT& context, CPUContextX86* out) { +void InitializeX86Context(const CONTEXT* context, CPUContextX86* out) { CommonInitializeX86Context(context, out); } #elif defined(ARCH_CPU_X86_64) -void InitializeX86Context(const WOW64_CONTEXT& context, CPUContextX86* out) { +void InitializeX86Context(const WOW64_CONTEXT* context, CPUContextX86* out) { CommonInitializeX86Context(context, out); } -void InitializeX64Context(const CONTEXT& context, CPUContextX86_64* out) { +void InitializeX64Context(const CONTEXT* context, CPUContextX86_64* out) { memset(out, 0, sizeof(*out)); LOG_IF(ERROR, !HasContextPart(context, CONTEXT_AMD64)) << "non-x64 context"; if (HasContextPart(context, CONTEXT_CONTROL)) { - out->cs = context.SegCs; - out->rflags = context.EFlags; - out->rip = context.Rip; - out->rsp = context.Rsp; + out->cs = context->SegCs; + out->rflags = context->EFlags; + out->rip = context->Rip; + out->rsp = context->Rsp; // SegSs ignored. } if (HasContextPart(context, CONTEXT_INTEGER)) { - out->rax = context.Rax; - out->rbx = context.Rbx; - out->rcx = context.Rcx; - out->rdx = context.Rdx; - out->rdi = context.Rdi; - out->rsi = context.Rsi; - out->rbp = context.Rbp; - out->r8 = context.R8; - out->r9 = context.R9; - out->r10 = context.R10; - out->r11 = context.R11; - out->r12 = context.R12; - out->r13 = context.R13; - out->r14 = context.R14; - out->r15 = context.R15; + out->rax = context->Rax; + out->rbx = context->Rbx; + out->rcx = context->Rcx; + out->rdx = context->Rdx; + out->rdi = context->Rdi; + out->rsi = context->Rsi; + out->rbp = context->Rbp; + out->r8 = context->R8; + out->r9 = context->R9; + out->r10 = context->R10; + out->r11 = context->R11; + out->r12 = context->R12; + out->r13 = context->R13; + out->r14 = context->R14; + out->r15 = context->R15; } if (HasContextPart(context, CONTEXT_SEGMENTS)) { - out->fs = context.SegFs; - out->gs = context.SegGs; + out->fs = context->SegFs; + out->gs = context->SegGs; // SegDs ignored. // SegEs ignored. } if (HasContextPart(context, CONTEXT_DEBUG_REGISTERS)) { - out->dr0 = context.Dr0; - out->dr1 = context.Dr1; - out->dr2 = context.Dr2; - out->dr3 = context.Dr3; + out->dr0 = context->Dr0; + out->dr1 = context->Dr1; + out->dr2 = context->Dr2; + out->dr3 = context->Dr3; // DR4 and DR5 are obsolete synonyms for DR6 and DR7, see // https://en.wikipedia.org/wiki/X86_debug_register. - out->dr4 = context.Dr6; - out->dr5 = context.Dr7; + out->dr4 = context->Dr6; + out->dr5 = context->Dr7; - out->dr6 = context.Dr6; - out->dr7 = context.Dr7; + out->dr6 = context->Dr6; + out->dr7 = context->Dr7; } if (HasContextPart(context, CONTEXT_FLOATING_POINT)) { - static_assert(sizeof(out->fxsave) == sizeof(context.FltSave), + static_assert(sizeof(out->fxsave) == sizeof(context->FltSave), "types must be equivalent"); - memcpy(&out->fxsave, &context.FltSave, sizeof(out->fxsave)); + memcpy(&out->fxsave, &context->FltSave, sizeof(out->fxsave)); } } +void InitializeX64XStateCet(const CONTEXT* context, + XSAVE_CET_U_FORMAT* cet_u, + CPUContextX86_64* out) { + if (HasContextPart(context, CONTEXT_XSTATE)) { + if (cet_u) { + out->xstate.enabled_features |= XSTATE_MASK_CET_U; + out->xstate.cet_u.cetmsr = cet_u->Ia32CetUMsr; + out->xstate.cet_u.ssp = cet_u->Ia32Pl3SspMsr; + } + } +} + +bool IsXStateFeatureEnabled(DWORD64 features) { + static DWORD64 flags = CallGetEnabledXStateFeatures(); + return (flags & features) == features; +} + #elif defined(ARCH_CPU_ARM64) -void InitializeARM64Context(const CONTEXT& context, CPUContextARM64* out) { +void InitializeARM64Context(const CONTEXT* context, CPUContextARM64* out) { memset(out, 0, sizeof(*out)); LOG_IF(ERROR, !HasContextPart(context, CONTEXT_ARM64)) << "non-arm64 context"; if (HasContextPart(context, CONTEXT_CONTROL)) { - out->spsr = context.Cpsr; - out->pc = context.Pc; - out->regs[30] = context.Lr; - out->sp = context.Sp; - out->regs[29] = context.Fp; + out->spsr = context->Cpsr; + out->pc = context->Pc; + out->regs[30] = context->Lr; + out->sp = context->Sp; + out->regs[29] = context->Fp; } if (HasContextPart(context, CONTEXT_INTEGER)) { - memcpy(&out->regs[0], &context.X0, 18 * sizeof(context.X0)); + memcpy(&out->regs[0], &context->X0, 18 * sizeof(context->X0)); // Don't copy x18 which is reserved as platform register. - memcpy(&out->regs[19], &context.X19, 10 * sizeof(context.X0)); + memcpy(&out->regs[19], &context->X19, 10 * sizeof(context->X0)); } if (HasContextPart(context, CONTEXT_FLOATING_POINT)) { - static_assert(sizeof(out->fpsimd) == sizeof(context.V), + static_assert(sizeof(out->fpsimd) == sizeof(context->V), "types must be equivalent"); - memcpy(&out->fpsimd, &context.V, sizeof(out->fpsimd)); + memcpy(&out->fpsimd, &context->V, sizeof(out->fpsimd)); } } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.h b/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.h index 9718f49cb0..720474d3c7 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win.h @@ -29,7 +29,7 @@ struct CPUContextARM64; //! \brief Initializes a CPUContextX86 structure from a native context structure //! on Windows. -void InitializeX86Context(const CONTEXT& context, CPUContextX86* out); +void InitializeX86Context(const CONTEXT* context, CPUContextX86* out); #endif // ARCH_CPU_X86 @@ -37,11 +37,22 @@ void InitializeX86Context(const CONTEXT& context, CPUContextX86* out); //! \brief Initializes a CPUContextX86 structure from a native context structure //! on Windows. -void InitializeX86Context(const WOW64_CONTEXT& context, CPUContextX86* out); +void InitializeX86Context(const WOW64_CONTEXT* context, CPUContextX86* out); //! \brief Initializes a CPUContextX86_64 structure from a native context //! structure on Windows. -void InitializeX64Context(const CONTEXT& context, CPUContextX86_64* out); +//! Only reads a max of sizeof(CONTEXT) so will not initialize extended values. +void InitializeX64Context(const CONTEXT* context, CPUContextX86_64* out); + +//! \brief Initializes CET fields of a CPUContextX86_64 structure from +//! an xsave location if |context| flags support cet_u values. +void InitializeX64XStateCet(const CONTEXT* context, + XSAVE_CET_U_FORMAT* cet_u, + CPUContextX86_64* out); + +//! \brief Wraps GetXStateEnabledFeatures(), returns true if the specified set +//! of flags are all supported. +bool IsXStateFeatureEnabled(DWORD64 feature); #endif // ARCH_CPU_X86_64 @@ -49,7 +60,7 @@ void InitializeX64Context(const CONTEXT& context, CPUContextX86_64* out); //! \brief Initializes a CPUContextARM64 structure from a native context //! structure on Windows. -void InitializeARM64Context(const CONTEXT& context, CPUContextARM64* out); +void InitializeARM64Context(const CONTEXT* context, CPUContextARM64* out); #endif // ARCH_CPU_ARM64 diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win_test.cc index 15f766777b..c6639e4b54 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/cpu_context_win_test.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "build/build_config.h" #include "gtest/gtest.h" #include "snapshot/cpu_context.h" @@ -40,7 +41,7 @@ void TestInitializeX86Context() { // directly from the supplied thread, float, and debug state parameters. { CPUContextX86 cpu_context_x86 = {}; - InitializeX86Context(context, &cpu_context_x86); + InitializeX86Context(&context, &cpu_context_x86); EXPECT_EQ(cpu_context_x86.eax, 1u); EXPECT_EQ(cpu_context_x86.fxsave.ftw, 2u); EXPECT_EQ(cpu_context_x86.dr0, 3u); @@ -72,7 +73,7 @@ void TestInitializeX86Context_FsaveWithoutFxsave() { { CPUContextX86 cpu_context_x86 = {}; - InitializeX86Context(context, &cpu_context_x86); + InitializeX86Context(&context, &cpu_context_x86); EXPECT_EQ(cpu_context_x86.eax, 1u); @@ -87,13 +88,13 @@ void TestInitializeX86Context_FsaveWithoutFxsave() { for (size_t st_mm = 0; st_mm < 7; ++st_mm) { EXPECT_EQ( BytesToHexString(cpu_context_x86.fxsave.st_mm[st_mm].st, - base::size(cpu_context_x86.fxsave.st_mm[st_mm].st)), - std::string(base::size(cpu_context_x86.fxsave.st_mm[st_mm].st) * 2, + std::size(cpu_context_x86.fxsave.st_mm[st_mm].st)), + std::string(std::size(cpu_context_x86.fxsave.st_mm[st_mm].st) * 2, '0')) << "st_mm " << st_mm; } EXPECT_EQ(BytesToHexString(cpu_context_x86.fxsave.st_mm[7].st, - base::size(cpu_context_x86.fxsave.st_mm[7].st)), + std::size(cpu_context_x86.fxsave.st_mm[7].st)), "0000000000000080ff7f"); EXPECT_EQ(cpu_context_x86.dr0, 3u); @@ -116,7 +117,7 @@ TEST(CPUContextWin, InitializeX64Context) { // set directly from the supplied thread, float, and debug state parameters. { CPUContextX86_64 cpu_context_x86_64 = {}; - InitializeX64Context(context, &cpu_context_x86_64); + InitializeX64Context(&context, &cpu_context_x86_64); EXPECT_EQ(cpu_context_x86_64.rax, 10u); EXPECT_EQ(cpu_context_x86_64.fxsave.ftw, 11u); EXPECT_EQ(cpu_context_x86_64.dr0, 12u); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc index 94d0e47d84..65c7783183 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc @@ -14,7 +14,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "client/crashpad_info.h" #include "util/file/file_io.h" @@ -29,7 +30,7 @@ DWORD WINAPI LotsOfReferencesThreadProc(void* param) { // Allocate a bunch of pointers to things on the stack. int* pointers[1000]; - for (size_t i = 0; i < base::size(pointers); ++i) { + for (size_t i = 0; i < std::size(pointers); ++i) { pointers[i] = new int[2048]; } @@ -53,7 +54,7 @@ int wmain(int argc, wchar_t* argv[]) { // verify the cap on pointed-to memory. crashpad::Semaphore semaphore(0); crashpad::ScopedKernelHANDLE threads[100]; - for (size_t i = 0; i < base::size(threads); ++i) { + for (size_t i = 0; i < std::size(threads); ++i) { threads[i].reset(CreateThread(nullptr, 0, &LotsOfReferencesThreadProc, @@ -66,7 +67,7 @@ int wmain(int argc, wchar_t* argv[]) { } } - for (size_t i = 0; i < base::size(threads); ++i) { + for (size_t i = 0; i < std::size(threads); ++i) { semaphore.Wait(); } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/end_to_end_test.py b/thirdparty/sentry-native/external/crashpad/snapshot/win/end_to_end_test.py index b1919adef4..9d319078d8 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/end_to_end_test.py +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/end_to_end_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2015 The Crashpad Authors. All rights reserved. # @@ -14,13 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function - import os import platform import pywintypes import random import re +import struct import subprocess import sys import tempfile @@ -104,7 +103,7 @@ def NamedPipeExistsAndReady(pipe_name): try: win32pipe.WaitNamedPipe(pipe_name, win32pipe.NMPWAIT_WAIT_FOREVER) except pywintypes.error as e: - if e[0] == winerror.ERROR_FILE_NOT_FOUND: + if e.winerror == winerror.ERROR_FILE_NOT_FOUND: return False raise return True @@ -152,6 +151,14 @@ def GetDumpFromProgram(out_dir, pipe_name, executable_name, expect_exit_code, ] + list(args)) print('Running %s' % os.path.basename(command[0])) exit_code = subprocess.call(command) + + # Some win32con codes are negative signed integers, whereas all exit + # codes are unsigned integers. Convert from signed to unsigned. + if expect_exit_code < 0: + expect_exit_code = struct.unpack('I', + struct.pack('i', + expect_exit_code))[0] + if exit_code != expect_exit_code: raise subprocess.CalledProcessError(exit_code, executable_name) @@ -160,7 +167,8 @@ def GetDumpFromProgram(out_dir, pipe_name, executable_name, expect_exit_code, '--database=' + test_database, '--show-pending-reports', '--show-all-report-info', - ]) + ], + text=True) for line in out.splitlines(): if line.strip().startswith('Path:'): return line.partition(':')[2].strip() @@ -205,7 +213,7 @@ class CdbRun(object): # Run a command line that loads the dump, runs the specified cdb # command, and then quits, and capturing stdout. self.out = subprocess.check_output( - [cdb_path, '-z', dump_path, '-c', command + ';q']) + [cdb_path, '-z', dump_path, '-c', command + ';q'], text=True) def Check(self, pattern, message, re_flags=0): match_obj = re.search(pattern, self.out, re_flags) diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.cc index 5759652d45..d1df987c6d 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.cc @@ -15,13 +15,13 @@ #include "snapshot/win/exception_snapshot_win.h" #include "base/logging.h" -#include "client/crashpad_client.h" #include "snapshot/capture_memory.h" #include "snapshot/memory_snapshot.h" #include "snapshot/memory_snapshot_generic.h" #include "snapshot/win/capture_memory_delegate_win.h" #include "snapshot/win/cpu_context_win.h" #include "snapshot/win/process_reader_win.h" +#include "util/win/exception_codes.h" #include "util/win/nt_internals.h" namespace crashpad { @@ -36,7 +36,7 @@ using Context32 = CONTEXT; using Context32 = WOW64_CONTEXT; #endif -void NativeContextToCPUContext32(const Context32& context_record, +void NativeContextToCPUContext32(const Context32* context_record, CPUContext* context, CPUContextUnion* context_union) { context->architecture = kCPUArchitectureX86; @@ -46,13 +46,25 @@ void NativeContextToCPUContext32(const Context32& context_record, #endif // ARCH_CPU_X86_FAMILY #if defined(ARCH_CPU_64_BITS) -void NativeContextToCPUContext64(const CONTEXT& context_record, +void NativeContextToCPUContext64(const CONTEXT* context_record, CPUContext* context, CPUContextUnion* context_union) { #if defined(ARCH_CPU_X86_64) context->architecture = kCPUArchitectureX86_64; context->x86_64 = &context_union->x86_64; + // Note that the context here is not extended, even if the flags suggest so, + // as we only copied in sizeof(CONTEXT). InitializeX64Context(context_record, context->x86_64); + // TODO(1250098) plumb through ssp via message from crashed process. For now + // we zero this if CET is available in the capturing process as otherwise + // WinDBG will show the relevant thread's ssp for the exception which will + // likely be more confusing than showing a zero value. + if (IsXStateFeatureEnabled(XSTATE_MASK_CET_U)) { + XSAVE_CET_U_FORMAT cet_u_fake; + cet_u_fake.Ia32CetUMsr = 0; + cet_u_fake.Ia32Pl3SspMsr = 0; + InitializeX64XStateCet(context_record, &cet_u_fake, context->x86_64); + } #elif defined(ARCH_CPU_ARM64) context->architecture = kCPUArchitectureARM64; context->arm64 = &context_union->arm64; @@ -84,7 +96,8 @@ ExceptionSnapshotWin::~ExceptionSnapshotWin() { bool ExceptionSnapshotWin::Initialize( ProcessReaderWin* process_reader, DWORD thread_id, - WinVMAddress exception_pointers_address) { + WinVMAddress exception_pointers_address, + uint32_t* gather_indirectly_referenced_memory_cap) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); const ProcessReaderWin::Thread* thread = nullptr; @@ -132,7 +145,10 @@ bool ExceptionSnapshotWin::Initialize( #endif CaptureMemoryDelegateWin capture_memory_delegate( - process_reader, *thread, &extra_memory_, nullptr); + process_reader, + *thread, + &extra_memory_, + gather_indirectly_referenced_memory_cap); CaptureMemory::PointedToByContext(context_, &capture_memory_delegate); INITIALIZATION_STATE_SET_VALID(initialized_); @@ -186,7 +202,7 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers( ProcessReaderWin* process_reader, WinVMAddress exception_pointers_address, DWORD exception_thread_id, - void (*native_to_cpu_context)(const ContextType& context_record, + void (*native_to_cpu_context)(const ContextType* context_record, CPUContext* context, CPUContextUnion* context_union)) { ExceptionPointersType exception_pointers; @@ -211,7 +227,7 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers( } const bool triggered_by_client = - first_record.ExceptionCode == CrashpadClient::kTriggeredExceptionCode && + first_record.ExceptionCode == ExceptionCodes::kTriggeredExceptionCode && first_record.NumberParameters == 2; if (triggered_by_client) process_reader->DecrementThreadSuspendCounts(exception_thread_id); @@ -228,10 +244,9 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers( for (const auto& thread : process_reader->Threads()) { if (thread.id == blame_thread_id) { thread_id_ = blame_thread_id; - native_to_cpu_context( - *reinterpret_cast(&thread.context), - &context_, - &context_union_); + native_to_cpu_context(thread.context.context(), + &context_, + &context_union_); exception_address_ = context_.InstructionPointer(); break; } @@ -262,7 +277,7 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers( return false; } - native_to_cpu_context(context_record, &context_, &context_union_); + native_to_cpu_context(&context_record, &context_, &context_union_); } return true; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.h b/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.h index 9167a9ef63..7321d6a93f 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win.h @@ -72,7 +72,8 @@ class ExceptionSnapshotWin final : public ExceptionSnapshot { //! an appropriate message logged. bool Initialize(ProcessReaderWin* process_reader, DWORD thread_id, - WinVMAddress exception_pointers); + WinVMAddress exception_pointers, + uint32_t* gather_indirectly_referenced_memory_cap); // ExceptionSnapshot: @@ -92,7 +93,7 @@ class ExceptionSnapshotWin final : public ExceptionSnapshot { ProcessReaderWin* process_reader, WinVMAddress exception_pointers_address, DWORD exception_thread_id, - void (*native_to_cpu_context)(const ContextType& context_record, + void (*native_to_cpu_context)(const ContextType* context_record, CPUContext* context, CPUContextUnion* context_union)); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win_test.cc index dbf9cfc059..91ff48fa10 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/exception_snapshot_win_test.cc @@ -18,7 +18,6 @@ #include "base/files/file_path.h" #include "base/strings/utf_string_conversions.h" -#include "client/crashpad_client.h" #include "gtest/gtest.h" #include "snapshot/win/process_snapshot_win.h" #include "test/errors.h" diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_annotations_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_annotations_reader.cc index 494b339804..9130e6d4ff 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_annotations_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_annotations_reader.cc @@ -17,7 +17,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "base/strings/utf_string_conversions.h" #include "client/annotation.h" @@ -157,8 +158,7 @@ void PEImageAnnotationsReader::ReadCrashpadAnnotationsList( snapshot.type = current.type; char name[Annotation::kNameMaxLength]; - if (!process_reader_->Memory()->Read( - current.name, base::size(name), name)) { + if (!process_reader_->Memory()->Read(current.name, std::size(name), name)) { LOG(WARNING) << "could not read annotation name at index " << index << " in " << base::WideToUTF8(name_); continue; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_reader.cc index bc4511b376..2a7b151099 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/pe_image_reader.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/strings/stringprintf.h" #include "client/crashpad_info.h" @@ -288,7 +288,7 @@ bool PEImageReader::VSFixedFileInfo( version_info.wType != 0 || wcsncmp(version_info.szKey, L"VS_VERSION_INFO", - base::size(version_info.szKey)) != 0) { + std::size(version_info.szKey)) != 0) { LOG(WARNING) << "unexpected VS_VERSIONINFO in " << module_subrange_reader_.name(); return false; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.cc index ff4a23615b..8704d3d733 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.cc @@ -22,13 +22,18 @@ #include +#include "base/notreached.h" #include "base/numerics/safe_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "snapshot/win/cpu_context_win.h" #include "util/misc/capture_context.h" #include "util/misc/time.h" +#include "util/win/get_function.h" #include "util/win/nt_internals.h" #include "util/win/ntstatus_logging.h" #include "util/win/process_structs.h" #include "util/win/scoped_handle.h" +#include "util/win/scoped_local_alloc.h" namespace crashpad { @@ -148,7 +153,7 @@ void DoStackWalk(ProcessReaderWin::Thread* thread, int machine_type = IMAGE_FILE_MACHINE_I386; LPVOID ctx = NULL; #if defined(ARCH_CPU_X86) - const CONTEXT* ctx_ = &thread->context.native; + const CONTEXT* ctx_ = thread->context.context(); stack_frame.AddrPC.Offset = ctx_->Eip; stack_frame.AddrFrame.Offset = ctx_->Ebp; stack_frame.AddrStack.Offset = ctx_->Esp; @@ -157,7 +162,7 @@ void DoStackWalk(ProcessReaderWin::Thread* thread, // if (!is_64_reading_32) { machine_type = IMAGE_FILE_MACHINE_AMD64; - const CONTEXT* ctx_ = &thread->context.native; + const CONTEXT* ctx_ = thread->context.context(); stack_frame.AddrPC.Offset = ctx_->Rip; stack_frame.AddrFrame.Offset = ctx_->Rbp; stack_frame.AddrStack.Offset = ctx_->Rsp; @@ -227,7 +232,7 @@ bool FillThreadContextAndSuspendCount(HANDLE process, DCHECK(suspension_state == ProcessSuspensionState::kRunning); thread->suspend_count = 0; DCHECK(!is_64_reading_32); - CaptureContext(&thread->context.native); + thread->context.InitializeFromCurrentThread(); #ifdef CLIENT_STACKTRACES_ENABLED DoStackWalk(thread, process, thread_handle, is_64_reading_32); @@ -250,26 +255,25 @@ bool FillThreadContextAndSuspendCount(HANDLE process, (suspension_state == ProcessSuspensionState::kSuspended ? 1 : 0); } - memset(&thread->context, 0, sizeof(thread->context)); #if defined(ARCH_CPU_32_BITS) - const bool is_native = true; -#elif defined(ARCH_CPU_64_BITS) - const bool is_native = !is_64_reading_32; + if (!thread->context.InitializeNative(thread_handle)) + return false; +#endif // ARCH_CPU_32_BITS + +#if defined(ARCH_CPU_64_BITS) if (is_64_reading_32) { - thread->context.wow64.ContextFlags = CONTEXT_ALL; - if (!Wow64GetThreadContext(thread_handle, &thread->context.wow64)) { - PLOG(ERROR) << "Wow64GetThreadContext"; + if (!thread->context.InitializeWow64(thread_handle)) return false; - } - } -#endif - if (is_native) { - thread->context.native.ContextFlags = CONTEXT_ALL; - if (!GetThreadContext(thread_handle, &thread->context.native)) { - PLOG(ERROR) << "GetThreadContext"; +#if defined(ARCH_CPU_X86_64) + } else if (IsXStateFeatureEnabled(XSTATE_MASK_CET_U)) { + if (!thread->context.InitializeXState(thread_handle, XSTATE_MASK_CET_U)) + return false; +#endif // ARCH_CPU_X86_64 + } else { + if (!thread->context.InitializeNative(thread_handle)) return false; - } } +#endif // ARCH_CPU_64_BITS #ifdef CLIENT_STACKTRACES_ENABLED DoStackWalk(thread, process, thread_handle, is_64_reading_32); @@ -286,8 +290,85 @@ bool FillThreadContextAndSuspendCount(HANDLE process, } // namespace +ProcessReaderWin::ThreadContext::ThreadContext() + : offset_(0), initialized_(false), data_() {} + +void ProcessReaderWin::ThreadContext::InitializeFromCurrentThread() { + data_.resize(sizeof(CONTEXT)); + initialized_ = true; + CaptureContext(context()); +} + +bool ProcessReaderWin::ThreadContext::InitializeNative(HANDLE thread_handle) { + data_.resize(sizeof(CONTEXT)); + initialized_ = true; + context()->ContextFlags = CONTEXT_ALL; + if (!GetThreadContext(thread_handle, context())) { + PLOG(ERROR) << "GetThreadContext"; + return false; + } + return true; +} + +#if defined(ARCH_CPU_64_BITS) +bool ProcessReaderWin::ThreadContext::InitializeWow64(HANDLE thread_handle) { + data_.resize(sizeof(WOW64_CONTEXT)); + initialized_ = true; + context()->ContextFlags = CONTEXT_ALL; + if (!Wow64GetThreadContext(thread_handle, context())) { + PLOG(ERROR) << "Wow64GetThreadContext"; + return false; + } + return true; +} +#endif + +#if defined(ARCH_CPU_X86_64) +bool ProcessReaderWin::ThreadContext::InitializeXState( + HANDLE thread_handle, + ULONG64 XStateCompactionMask) { + // InitializeContext2 needs Windows 10 build 20348. + static const auto initialize_context_2 = + GET_FUNCTION(L"kernel32.dll", ::InitializeContext2); + if (!initialize_context_2) + return false; + // We want CET_U xstate to get the ssp, only possible when supported. + PCONTEXT ret_context = nullptr; + DWORD context_size = 0; + if (!initialize_context_2(nullptr, + CONTEXT_ALL | CONTEXT_XSTATE, + &ret_context, + &context_size, + XStateCompactionMask) && + GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + PLOG(ERROR) << "InitializeContext2 - getting required size"; + return false; + } + // NB: ret_context may not be data.begin(). + data_.resize(context_size); + if (!initialize_context_2(data_.data(), + CONTEXT_ALL | CONTEXT_XSTATE, + &ret_context, + &context_size, + XStateCompactionMask)) { + PLOG(ERROR) << "InitializeContext2 - initializing"; + return false; + } + offset_ = reinterpret_cast(ret_context) - data_.data(); + initialized_ = true; + + if (!GetThreadContext(thread_handle, ret_context)) { + PLOG(ERROR) << "GetThreadContext"; + return false; + } + + return true; +} +#endif // defined(ARCH_CPU_X86_64) + ProcessReaderWin::Thread::Thread() : context(), + name(), id(0), teb_address(0), teb_size(0), @@ -477,6 +558,21 @@ void ProcessReaderWin::ReadThreadData(bool is_64_reading_32) { thread.stack_region_size = base - limit; } } + // On Windows 10 build 1607 and later, read the thread name. + static const auto get_thread_description = + GET_FUNCTION(L"kernel32.dll", ::GetThreadDescription); + if (get_thread_description) { + wchar_t* thread_description; + HRESULT hr = + get_thread_description(thread_handle.get(), &thread_description); + if (SUCCEEDED(hr)) { + ScopedLocalAlloc thread_description_owner(thread_description); + thread.name = base::WideToUTF8(thread_description); + } else { + LOG(WARNING) << "GetThreadDescription: " + << logging::SystemErrorCodeToString(hr); + } + } threads_.push_back(thread); } } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.h b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.h index 314dca7e43..1d970c5c6e 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win.h @@ -18,6 +18,7 @@ #include #include +#include #include #include "build/build_config.h" @@ -41,17 +42,44 @@ enum class ProcessSuspensionState : bool { //! \brief Accesses information about another process, identified by a `HANDLE`. class ProcessReaderWin { public: + //! \brief Helper to make the context copyable and resizable. + class ThreadContext { + public: + ThreadContext(); + ~ThreadContext() {} + + template + T* context() const { + DCHECK(initialized_); + return reinterpret_cast( + const_cast(data_.data() + offset_)); + } +#if defined(ARCH_CPU_64_BITS) + bool InitializeWow64(HANDLE thread_handle); +#endif // ARCH_CPU_64_BITS +#if defined(ARCH_CPU_X86_64) + // Initializes internal structures for extended compacted contexts. + bool InitializeXState(HANDLE thread_handle, ULONG64 XStateCompactionMask); +#endif // ARCH_CPU_X86_64 + void InitializeFromCurrentThread(); + bool InitializeNative(HANDLE thread_handle); + + private: + // This is usually 0 but Windows might cause it to be positive when + // fetching the extended context. This needs to be adjusted after + // calls to InitializeContext2(). + size_t offset_; + bool initialized_; + std::vector data_; + }; + //! \brief Contains information about a thread that belongs to a process. struct Thread { Thread(); ~Thread() {} - union { - CONTEXT native; -#if defined(ARCH_CPU_64_BITS) - WOW64_CONTEXT wow64; -#endif - } context; + ThreadContext context; + std::string name; uint64_t id; WinVMAddress teb_address; WinVMSize teb_size; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win_test.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win_test.cc index 68933bbe63..6cfd8a4f45 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win_test.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_reader_win_test.cc @@ -17,8 +17,17 @@ #include #include -#include "base/cxx17_backports.h" +#include +#include +#include +#include +#include + +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "test/scoped_set_thread_name.h" #include "test/win/win_multiprocess.h" #include "util/misc/from_pointer_cast.h" #include "util/synchronization/semaphore.h" @@ -30,6 +39,8 @@ namespace crashpad { namespace test { namespace { +using ::testing::IsSupersetOf; + TEST(ProcessReaderWin, SelfBasic) { ProcessReaderWin process_reader; ASSERT_TRUE(process_reader.Initialize(GetCurrentProcess(), @@ -44,7 +55,7 @@ TEST(ProcessReaderWin, SelfBasic) { EXPECT_EQ(process_reader.GetProcessInfo().ProcessID(), GetCurrentProcessId()); static constexpr char kTestMemory[] = "Some test memory"; - char buffer[base::size(kTestMemory)]; + char buffer[std::size(kTestMemory)]; ASSERT_TRUE(process_reader.Memory()->Read( reinterpret_cast(kTestMemory), sizeof(kTestMemory), &buffer)); EXPECT_STREQ(kTestMemory, buffer); @@ -97,6 +108,7 @@ TEST(ProcessReaderWin, ChildBasic) { } TEST(ProcessReaderWin, SelfOneThread) { + const ScopedSetThreadName scoped_set_thread_name("SelfBasic"); ProcessReaderWin process_reader; ASSERT_TRUE(process_reader.Initialize(GetCurrentProcess(), ProcessSuspensionState::kRunning)); @@ -110,7 +122,9 @@ TEST(ProcessReaderWin, SelfOneThread) { ASSERT_GE(threads.size(), 1u); EXPECT_EQ(threads[0].id, GetCurrentThreadId()); - EXPECT_NE(ProgramCounterFromCONTEXT(&threads[0].context.native), nullptr); + EXPECT_EQ(threads[0].name, "SelfBasic"); + EXPECT_NE(ProgramCounterFromCONTEXT(threads[0].context.context()), + nullptr); EXPECT_EQ(threads[0].suspend_count, 0u); } @@ -130,18 +144,21 @@ class ProcessReaderChildThreadSuspendCount final : public WinMultiprocess { class SleepingThread : public Thread { public: - SleepingThread() : done_(nullptr) {} + SleepingThread(const std::string& thread_name) + : done_(nullptr), thread_name_(thread_name) {} void SetHandle(Semaphore* done) { done_= done; } void ThreadMain() override { + const ScopedSetThreadName scoped_set_thread_name(thread_name_); done_->Wait(); } private: Semaphore* done_; + const std::string thread_name_; }; void WinMultiprocessParent() override { @@ -156,8 +173,28 @@ class ProcessReaderChildThreadSuspendCount final : public WinMultiprocess { const auto& threads = process_reader.Threads(); ASSERT_GE(threads.size(), kCreatedThreads + 1); - for (const auto& thread : threads) + EXPECT_EQ(threads[0].name, "WinMultiprocessChild-Main"); + + const std::set expected_thread_names = { + "WinMultiprocessChild-1", + "WinMultiprocessChild-2", + "WinMultiprocessChild-3", + }; + // Windows can create threads besides the ones created in + // WinMultiprocessChild(), so keep track of the (non-main) thread names + // and make sure all the expected names are present. + std::set thread_names; + for (size_t i = 1; i < threads.size(); i++) { + if (!threads[i].name.empty()) { + thread_names.emplace(threads[i].name); + } + } + + EXPECT_THAT(thread_names, IsSupersetOf(expected_thread_names)); + + for (const auto& thread : threads) { EXPECT_EQ(thread.suspend_count, 0u); + } } { @@ -171,15 +208,23 @@ class ProcessReaderChildThreadSuspendCount final : public WinMultiprocess { // suspended. const auto& threads = process_reader.Threads(); ASSERT_GE(threads.size(), kCreatedThreads + 1); - for (const auto& thread : threads) + for (const auto& thread : threads) { EXPECT_EQ(thread.suspend_count, 0u); + } } } void WinMultiprocessChild() override { + const ScopedSetThreadName scoped_set_thread_name( + "WinMultiprocessChild-Main"); + // Create three dummy threads so we can confirm we read successfully read // more than just the main thread. - SleepingThread threads[kCreatedThreads]; + std::array threads = { + "WinMultiprocessChild-1", + "WinMultiprocessChild-2", + "WinMultiprocessChild-3", + }; Semaphore done(0); for (auto& thread : threads) thread.SetHandle(&done); @@ -193,7 +238,7 @@ class ProcessReaderChildThreadSuspendCount final : public WinMultiprocess { // the pipe. CheckedReadFileAtEOF(ReadPipeHandle()); - for (size_t i = 0; i < base::size(threads); ++i) + for (size_t i = 0; i < std::size(threads); ++i) done.Signal(); for (auto& thread : threads) thread.Join(); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.cc index b60ea38ea1..844986db59 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -45,8 +45,7 @@ ProcessSnapshotWin::ProcessSnapshotWin() annotations_simple_map_(), snapshot_time_(), options_(), - initialized_() { -} + initialized_() {} ProcessSnapshotWin::~ProcessSnapshotWin() { } @@ -63,24 +62,6 @@ bool ProcessSnapshotWin::Initialize( if (!process_reader_.Initialize(process, suspension_state)) return false; - if (exception_information_address != 0) { - ExceptionInformation exception_information = {}; - if (!process_reader_.Memory()->Read(exception_information_address, - sizeof(exception_information), - &exception_information)) { - LOG(WARNING) << "ReadMemory ExceptionInformation failed"; - return false; - } - - exception_.reset(new internal::ExceptionSnapshotWin()); - if (!exception_->Initialize(&process_reader_, - exception_information.thread_id, - exception_information.exception_pointers)) { - exception_.reset(); - return false; - } - } - client_id_.InitializeToZero(); system_.Initialize(&process_reader_); @@ -96,10 +77,31 @@ bool ProcessSnapshotWin::Initialize( InitializeUnloadedModules(); GetCrashpadOptionsInternal(&options_); + uint32_t* budget_remaining_pointer = + options_.gather_indirectly_referenced_memory == TriState::kEnabled + ? &options_.indirectly_referenced_memory_cap + : nullptr; - InitializeThreads( - options_.gather_indirectly_referenced_memory == TriState::kEnabled, - options_.indirectly_referenced_memory_cap); + if (exception_information_address != 0) { + ExceptionInformation exception_information = {}; + if (!process_reader_.Memory()->Read(exception_information_address, + sizeof(exception_information), + &exception_information)) { + LOG(WARNING) << "ReadMemory ExceptionInformation failed"; + return false; + } + + exception_.reset(new internal::ExceptionSnapshotWin()); + if (!exception_->Initialize(&process_reader_, + exception_information.thread_id, + exception_information.exception_pointers, + budget_remaining_pointer)) { + exception_.reset(); + return false; + } + } + + InitializeThreads(budget_remaining_pointer); for (const MEMORY_BASIC_INFORMATION64& mbi : process_reader_.GetProcessInfo().MemoryInfo()) { @@ -239,15 +241,9 @@ const ProcessMemory* ProcessSnapshotWin::Memory() const { return process_reader_.Memory(); } -void ProcessSnapshotWin::InitializeThreads( - bool gather_indirectly_referenced_memory, - uint32_t indirectly_referenced_memory_cap) { +void ProcessSnapshotWin::InitializeThreads(uint32_t* budget_remaining_pointer) { const std::vector& process_reader_threads = process_reader_.Threads(); - uint32_t* budget_remaining_pointer = nullptr; - uint32_t budget_remaining = indirectly_referenced_memory_cap; - if (gather_indirectly_referenced_memory) - budget_remaining_pointer = &budget_remaining; for (const ProcessReaderWin::Thread& process_reader_thread : process_reader_threads) { auto thread = std::make_unique(); @@ -335,7 +331,7 @@ void ProcessSnapshotWin::InitializeUnloadedModules() { uet.TimeDateStamp, base::WideToUTF8(base::WStringPiece( uet.ImageName, - wcsnlen(uet.ImageName, base::size(uet.ImageName)))))); + wcsnlen(uet.ImageName, std::size(uet.ImageName)))))); } } } @@ -535,9 +531,9 @@ WinVMSize ProcessSnapshotWin::DetermineSizeOfEnvironmentBlock( env_block.resize( static_cast(bytes_read / sizeof(env_block[0]))); static constexpr wchar_t terminator[] = {0, 0}; - size_t at = env_block.find(std::wstring(terminator, base::size(terminator))); + size_t at = env_block.find(std::wstring(terminator, std::size(terminator))); if (at != std::wstring::npos) - env_block.resize(at + base::size(terminator)); + env_block.resize(at + std::size(terminator)); return env_block.size() * sizeof(env_block[0]); } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.h b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.h index 7a8ae2fd3f..002107078b 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/process_snapshot_win.h @@ -137,8 +137,7 @@ class ProcessSnapshotWin final : public ProcessSnapshot { private: // Initializes threads_ on behalf of Initialize(). - void InitializeThreads(bool gather_indirectly_referenced_memory, - uint32_t indirectly_referenced_memory_cap); + void InitializeThreads(uint32_t* indirectly_referenced_memory_cap); // Initializes modules_ on behalf of Initialize(). void InitializeModules(); diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/system_snapshot_win.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/system_snapshot_win.cc index 905976d8b2..a19253f23b 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/system_snapshot_win.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/system_snapshot_win.cc @@ -14,11 +14,14 @@ #include "snapshot/win/system_snapshot_win.h" -#include #include #include +#include #include +// Must be after windows.h. +#include + #include #include #include @@ -30,6 +33,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "util/stdlib/string_number_conversion.h" #include "util/win/module_version.h" #include "util/win/scoped_registry_key.h" @@ -67,6 +71,50 @@ std::string GetStringForFileOS(uint32_t file_os) { return "Unknown"; } +//! \brief Reads a DWORD from the registry and returns it as an int. +bool ReadRegistryDWORD(HKEY key, const wchar_t* name, int* out_value) { + DWORD type; + DWORD local_value; + DWORD size = sizeof(local_value); + if (RegQueryValueExW(key, + name, + nullptr, + &type, + reinterpret_cast(&local_value), + &size) == ERROR_SUCCESS && + type == REG_DWORD) { + *out_value = static_cast(local_value); + return true; + } + return false; +} + +//! \brief Reads a string from the registry and returns it as an int. +bool ReadRegistryDWORDFromSZ(HKEY key, const char* name, int* out_value) { + char string_value[11]; + DWORD type; + // Leave space for a terminating zero. + DWORD size = sizeof(string_value) - sizeof(string_value[0]); + // Use the 'A' version of this function so that we can use + // StringToNumber. + if (RegQueryValueExA(key, + name, + nullptr, + &type, + reinterpret_cast(&string_value), + &size) == ERROR_SUCCESS && + type == REG_SZ) { + // Make sure the string is null-terminated. + string_value[size / sizeof(string_value[0])] = '\0'; + unsigned local_value; + if (StringToNumber(string_value, &local_value)) { + *out_value = local_value; + return true; + } + } + return false; +} + } // namespace namespace internal { @@ -89,16 +137,50 @@ void SystemSnapshotWin::Initialize(ProcessReaderWin* process_reader) { process_reader_ = process_reader; - // We use both GetVersionEx() and GetModuleVersionAndType() (which uses - // VerQueryValue() internally). GetVersionEx() is not trustworthy after - // Windows 8 (depending on the application manifest) so its data is used only - // to fill the os_server_ field, and the rest comes from the version - // information stamped on kernel32.dll. - OSVERSIONINFOEX version_info = {sizeof(version_info)}; - if (!GetVersionEx(reinterpret_cast(&version_info))) { - PLOG(WARNING) << "GetVersionEx"; - } else { - os_server_ = version_info.wProductType != VER_NT_WORKSTATION; + // We use both IsWindowsServer() (which uses VerifyVersionInfo() internally) + // and GetModuleVersionAndType() (which uses VerQueryValue() internally). + // VerifyVersionInfo() is not trustworthy after Windows 8 (depending on the + // application manifest) so its data is used only to fill the os_server_ + // field, and the rest comes from the version information stamped on + // kernel32.dll and from the registry. + os_server_ = IsWindowsServer(); + + // kernel32.dll used to be a good way to get a non-lying version number, but + // kernel32.dll has been refactored into multiple DLLs so it sometimes does + // not get updated when a new version of Windows ships, especially on + // Windows 11. Additionally, pairs of releases such as 19041/19042 + // (20H1/20H2) actually have identical code and have their differences + // enabled by a configuration setting. Therefore the recommended way to get + // OS version information on recent versions of Windows is to read it from the + // registry. If any of the version-number components are missing from the + // registry (on Windows 7, for instance) then kernel32.dll is used as a + // fallback. + bool version_data_found = false; + int os_version_build = 0; + HKEY key; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", + 0, + KEY_QUERY_VALUE, + &key) == ERROR_SUCCESS) { + ScopedRegistryKey scoped_key(key); + + // Read the four components of the version from the registry. + // UBR apparently stands for Update Build Revision and it goes up every + // month when patches are installed. The full version is stored in the + // registry as: + // CurrentMajorVersionNumber.CurrentMinorVersionNumber.CurrentBuildNumber.UBR + if (ReadRegistryDWORD( + key, L"CurrentMajorVersionNumber", &os_version_major_) && + ReadRegistryDWORD( + key, L"CurrentMinorVersionNumber", &os_version_minor_) && + ReadRegistryDWORDFromSZ( + key, "CurrentBuildNumber", &os_version_bugfix_) && + ReadRegistryDWORD(key, L"UBR", &os_version_build)) { + // Since we found all four components in the registry we don't need + // to read them from kernel32.dll. + version_data_found = true; + } } static constexpr wchar_t kSystemDll[] = L"kernel32.dll"; @@ -106,10 +188,15 @@ void SystemSnapshotWin::Initialize(ProcessReaderWin* process_reader) { if (GetModuleVersionAndType(base::FilePath(kSystemDll), &ffi)) { std::string flags_string = GetStringForFileFlags(ffi.dwFileFlags); std::string os_name = GetStringForFileOS(ffi.dwFileOS); - os_version_major_ = ffi.dwFileVersionMS >> 16; - os_version_minor_ = ffi.dwFileVersionMS & 0xffff; - os_version_bugfix_ = ffi.dwFileVersionLS >> 16; - os_version_build_ = base::StringPrintf("%lu", ffi.dwFileVersionLS & 0xffff); + if (!version_data_found) { + os_version_major_ = ffi.dwFileVersionMS >> 16; + os_version_minor_ = ffi.dwFileVersionMS & 0xffff; + os_version_bugfix_ = ffi.dwFileVersionLS >> 16; + os_version_build = static_cast(ffi.dwFileVersionLS & 0xffff); + } + + os_version_build_ = base::StringPrintf("%u", os_version_build); + os_version_full_ = base::StringPrintf( "%s %u.%u.%u.%s%s", os_name.c_str(), @@ -195,11 +282,11 @@ std::string SystemSnapshotWin::CPUVendor() const { #elif defined(ARCH_CPU_ARM64) HKEY key; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", - 0, - KEY_QUERY_VALUE, - &key) != ERROR_SUCCESS) { + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", + 0, + KEY_QUERY_VALUE, + &key) != ERROR_SUCCESS) { return std::string(); } diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.cc b/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.cc index b891b05b94..c0ca8a14de 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.cc @@ -18,6 +18,8 @@ #include #include "base/check_op.h" +#include "base/memory/page_size.h" +#include "base/numerics/safe_conversions.h" #include "snapshot/capture_memory.h" #include "snapshot/win/capture_memory_delegate_win.h" #include "snapshot/win/cpu_context_win.h" @@ -26,6 +28,26 @@ namespace crashpad { namespace internal { +namespace { +#if defined(ARCH_CPU_X86_64) + +XSAVE_CET_U_FORMAT* LocateXStateCetU(CONTEXT* context) { + // GetEnabledXStateFeatures needs Windows 7 SP1. + static auto locate_xstate_feature = []() { + HINSTANCE kernel32 = GetModuleHandle(L"Kernel32.dll"); + return reinterpret_cast( + GetProcAddress(kernel32, "LocateXStateFeature")); + }(); + if (!locate_xstate_feature) + return nullptr; + + DWORD cet_u_size = 0; + return reinterpret_cast( + locate_xstate_feature(context, XSTATE_CET_U, &cet_u_size)); +} +#endif // defined(ARCH_CPU_X86_64) +} // namespace + ThreadSnapshotWin::ThreadSnapshotWin() : ThreadSnapshot(), context_(), @@ -65,21 +87,33 @@ bool ThreadSnapshotWin::Initialize( #if defined(ARCH_CPU_X86) context_.architecture = kCPUArchitectureX86; context_.x86 = &context_union_.x86; - InitializeX86Context(process_reader_thread.context.native, context_.x86); + InitializeX86Context(process_reader_thread.context.context(), + context_.x86); #elif defined(ARCH_CPU_X86_64) if (process_reader->Is64Bit()) { context_.architecture = kCPUArchitectureX86_64; context_.x86_64 = &context_union_.x86_64; - InitializeX64Context(process_reader_thread.context.native, context_.x86_64); + CONTEXT* context = process_reader_thread.context.context(); + InitializeX64Context(context, context_.x86_64); + // Capturing process must have CET enabled. If captured process does not, + // then this will not set any state in the context snapshot. + if (IsXStateFeatureEnabled(XSTATE_MASK_CET_U)) { + XSAVE_CET_U_FORMAT* cet_u = LocateXStateCetU(context); + if (cet_u && cet_u->Ia32CetUMsr && cet_u->Ia32Pl3SspMsr) { + InitializeX64XStateCet(context, cet_u, context_.x86_64); + } + } } else { context_.architecture = kCPUArchitectureX86; context_.x86 = &context_union_.x86; - InitializeX86Context(process_reader_thread.context.wow64, context_.x86); + InitializeX86Context(process_reader_thread.context.context(), + context_.x86); } #elif defined(ARCH_CPU_ARM64) context_.architecture = kCPUArchitectureARM64; context_.arm64 = &context_union_.arm64; - InitializeARM64Context(process_reader_thread.context.native, context_.arm64); + InitializeARM64Context(process_reader_thread.context.context(), + context_.arm64); #else #error Unsupported Windows Arch #endif // ARCH_CPU_X86 @@ -88,6 +122,22 @@ bool ThreadSnapshotWin::Initialize( frames_ = thread_.frames; #endif +#if defined(ARCH_CPU_X86_64) + // Unconditionally store page around ssp if it is present. + if (process_reader->Is64Bit() && context_.x86_64->xstate.cet_u.ssp) { + WinVMAddress page_size = + base::checked_cast(base::GetPageSize()); + WinVMAddress page_mask = ~(page_size - 1); + WinVMAddress ssp_base = context_.x86_64->xstate.cet_u.ssp & page_mask; + if (process_reader->GetProcessInfo().LoggingRangeIsFullyReadable( + CheckedRange(ssp_base, page_size))) { + auto region = std::make_unique(); + region->Initialize(process_reader->Memory(), ssp_base, page_size); + pointed_to_memory_.push_back(std::move(region)); + } + } +#endif // ARCH_CPU_X86_64 + CaptureMemoryDelegateWin capture_memory_delegate( process_reader, thread_, @@ -117,6 +167,11 @@ uint64_t ThreadSnapshotWin::ThreadID() const { return thread_.id; } +std::string ThreadSnapshotWin::ThreadName() const { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + return thread_.name; +} + int ThreadSnapshotWin::SuspendCount() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return thread_.suspend_count; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.h b/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.h index b9fafaa23c..af18a14ba8 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.h +++ b/thirdparty/sentry-native/external/crashpad/snapshot/win/thread_snapshot_win.h @@ -68,6 +68,7 @@ class ThreadSnapshotWin final : public ThreadSnapshot { const CPUContext* Context() const override; const MemorySnapshot* Stack() const override; uint64_t ThreadID() const override; + std::string ThreadName() const override; int SuspendCount() const override; int Priority() const override; uint64_t ThreadSpecificDataAddress() const override; diff --git a/thirdparty/sentry-native/external/crashpad/snapshot/x86/cpuid_reader.cc b/thirdparty/sentry-native/external/crashpad/snapshot/x86/cpuid_reader.cc index 583405844f..c1bd837c4d 100644 --- a/thirdparty/sentry-native/external/crashpad/snapshot/x86/cpuid_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/snapshot/x86/cpuid_reader.cc @@ -16,12 +16,13 @@ #include +#include "build/build_config.h" #include "snapshot/cpu_context.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include #include -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) #if defined(ARCH_CPU_X86_FAMILY) @@ -101,7 +102,7 @@ bool CpuidReader::SupportsDAZ() const { using Fxsave = CPUContextX86_64::Fxsave; #endif -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) __declspec(align(16)) Fxsave fxsave = {}; #else Fxsave fxsave __attribute__((aligned(16))) = {}; @@ -111,7 +112,7 @@ bool CpuidReader::SupportsDAZ() const { static_assert(offsetof(decltype(fxsave), mxcsr_mask) == 28, "mxcsr_mask offset"); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) _fxsave(&fxsave); #else asm("fxsave %0" : "=m"(fxsave)); @@ -122,13 +123,13 @@ bool CpuidReader::SupportsDAZ() const { } void CpuidReader::Cpuid(uint32_t cpuinfo[4], uint32_t leaf) const { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) __cpuid(reinterpret_cast(cpuinfo), leaf); #else asm("cpuid" : "=a"(cpuinfo[0]), "=b"(cpuinfo[1]), "=c"(cpuinfo[2]), "=d"(cpuinfo[3]) : "a"(leaf), "b"(0), "c"(0), "d"(0)); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } } // namespace internal diff --git a/thirdparty/sentry-native/external/crashpad/test/BUILD.gn b/thirdparty/sentry-native/external/crashpad/test/BUILD.gn index dfc84d162f..28b4e8d14f 100644 --- a/thirdparty/sentry-native/external/crashpad/test/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/test/BUILD.gn @@ -37,6 +37,7 @@ static_library("test") { "scoped_guarded_page.h", "scoped_module_handle.cc", "scoped_module_handle.h", + "scoped_set_thread_name.h", "scoped_temp_dir.cc", "scoped_temp_dir.h", "test_paths.cc", @@ -57,6 +58,14 @@ static_library("test") { } } + # TODO(crbug.com/812974): Remove !crashpad_is_fuchsia when Fuchsia is no + # longer treated as a posix platform. + if (crashpad_is_posix && !crashpad_is_fuchsia) { + sources += [ + "scoped_set_thread_name_posix.cc", + ] + } + if (crashpad_is_mac || crashpad_is_ios) { sources += [ "mac/mach_errors.cc", @@ -96,6 +105,7 @@ static_library("test") { sources += [ "multiprocess_exec_win.cc", "scoped_guarded_page_win.cc", + "scoped_set_thread_name_win.cc", "scoped_temp_dir_win.cc", "win/child_launcher.cc", "win/child_launcher.h", @@ -109,7 +119,10 @@ static_library("test") { } if (crashpad_is_fuchsia) { - sources += [ "multiprocess_exec_fuchsia.cc" ] + sources += [ + "multiprocess_exec_fuchsia.cc", + "scoped_set_thread_name_fuchsia.cc", + ] } public_configs = [ "..:crashpad_config" ] diff --git a/thirdparty/sentry-native/external/crashpad/test/errors.cc b/thirdparty/sentry-native/external/crashpad/test/errors.cc index 1484506256..1f14db28ca 100644 --- a/thirdparty/sentry-native/external/crashpad/test/errors.cc +++ b/thirdparty/sentry-native/external/crashpad/test/errors.cc @@ -20,9 +20,9 @@ #include "base/strings/stringprintf.h" #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include "base/posix/safe_strerror.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include #endif @@ -31,10 +31,10 @@ namespace crashpad { namespace test { std::string ErrnoMessage(int err, const std::string& base) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) std::string err_as_string = base::safe_strerror(errno); const char* err_string = err_as_string.c_str(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) char err_string[256]; strerror_s(err_string, errno); #endif @@ -49,7 +49,7 @@ std::string ErrnoMessage(const std::string& base) { return ErrnoMessage(errno, base); } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) std::string ErrorMessage(const std::string& base) { return base::StringPrintf( "%s%s%s", diff --git a/thirdparty/sentry-native/external/crashpad/test/errors.h b/thirdparty/sentry-native/external/crashpad/test/errors.h index 471fbb5f7b..5be04f1b9b 100644 --- a/thirdparty/sentry-native/external/crashpad/test/errors.h +++ b/thirdparty/sentry-native/external/crashpad/test/errors.h @@ -67,7 +67,7 @@ std::string ErrnoMessage(int err, const std::string& base = std::string()); //! a colon. std::string ErrnoMessage(const std::string& base = std::string()); -#if defined(OS_WIN) || DOXYGEN +#if BUILDFLAG(IS_WIN) || DOXYGEN //! \brief Formats an error message using `GetLastError()`. //! //! The returned string will combine the \a base string, if supplied, with a diff --git a/thirdparty/sentry-native/external/crashpad/test/file.cc b/thirdparty/sentry-native/external/crashpad/test/file.cc index 04b4625f16..bcfb987ec8 100644 --- a/thirdparty/sentry-native/external/crashpad/test/file.cc +++ b/thirdparty/sentry-native/external/crashpad/test/file.cc @@ -17,19 +17,25 @@ #include #include +#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "gtest/gtest.h" #include "test/errors.h" +#if BUILDFLAG(IS_WIN) +#include +#endif + namespace crashpad { namespace test { bool FileExists(const base::FilePath& path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) struct stat st; int rv = lstat(path.value().c_str(), &st); static constexpr char stat_function[] = "lstat"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) struct _stat st; int rv = _wstat(path.value().c_str(), &st); static constexpr char stat_function[] = "_wstat"; @@ -44,12 +50,30 @@ bool FileExists(const base::FilePath& path) { return true; } +bool RemoveFileIfExists(const base::FilePath& path) { +#if BUILDFLAG(IS_POSIX) + if (unlink(path.value().c_str()) != 0 && errno != ENOENT) { + PLOG(ERROR) << "unlink " << path.value(); + return false; + } +#elif BUILDFLAG(IS_WIN) + if (!DeleteFile(path.value().c_str()) && + GetLastError() != ERROR_FILE_NOT_FOUND) { + PLOG(ERROR) << "DeleteFile " << base::WideToUTF8(path.value()); + return false; + } +#else +#error "Not implemented" +#endif + return true; +} + FileOffset FileSize(const base::FilePath& path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) struct stat st; int rv = lstat(path.value().c_str(), &st); static constexpr char stat_function[] = "lstat"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) struct _stati64 st; int rv = _wstati64(path.value().c_str(), &st); static constexpr char stat_function[] = "_wstati64"; diff --git a/thirdparty/sentry-native/external/crashpad/test/file.h b/thirdparty/sentry-native/external/crashpad/test/file.h index 918cc3915b..451588a4df 100644 --- a/thirdparty/sentry-native/external/crashpad/test/file.h +++ b/thirdparty/sentry-native/external/crashpad/test/file.h @@ -30,6 +30,12 @@ namespace test { //! `false` with a Google Test failure added. bool FileExists(const base::FilePath& path); +//! \brief Removes a file if it exists, logging a message on failure. +//! +//! \param[in] path The path to the file to remove. +//! \return `true` on success. `false` on failure with a message logged. +bool RemoveFileIfExists(const base::FilePath& path); + //! \brief Determines the size of a file. //! //! \param[in] path The path of the file to check. The file must exist. diff --git a/thirdparty/sentry-native/external/crashpad/test/filesystem.cc b/thirdparty/sentry-native/external/crashpad/test/filesystem.cc index 39b864819b..a43421206e 100644 --- a/thirdparty/sentry-native/external/crashpad/test/filesystem.cc +++ b/thirdparty/sentry-native/external/crashpad/test/filesystem.cc @@ -22,6 +22,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "gtest/gtest.h" #include "test/errors.h" #include "test/scoped_temp_dir.h" @@ -29,11 +30,11 @@ #include "util/file/filesystem.h" #include "util/misc/time.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include #include "base/posix/eintr_wrapper.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #endif @@ -42,7 +43,7 @@ namespace test { namespace { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Detects the flags necessary to create symbolic links and stores them in // |flags| if non-nullptr, and returns true on success. If symbolic links can’t @@ -89,7 +90,7 @@ bool SymbolicLinkFlags(DWORD* flags) { return true; } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } // namespace @@ -101,14 +102,14 @@ bool CreateFile(const base::FilePath& file) { } bool PathExists(const base::FilePath& path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) struct stat st; if (lstat(path.value().c_str(), &st) != 0) { EXPECT_EQ(errno, ENOENT) << ErrnoMessage("lstat ") << path.value(); return false; } return true; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) if (GetFileAttributes(path.value().c_str()) == INVALID_FILE_ATTRIBUTES) { EXPECT_EQ(GetLastError(), static_cast(ERROR_FILE_NOT_FOUND)) << ErrorMessage("GetFileAttributes ") << base::WideToUTF8(path.value()); @@ -120,7 +121,7 @@ bool PathExists(const base::FilePath& path) { bool SetFileModificationTime(const base::FilePath& path, const timespec& mtime) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) // utimensat() isn't available on macOS until 10.13, so lutimes() is used // instead. struct stat st; @@ -136,7 +137,7 @@ bool SetFileModificationTime(const base::FilePath& path, return false; } return true; -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) timespec times[2]; times[0].tv_sec = 0; times[0].tv_nsec = UTIME_OMIT; @@ -147,7 +148,7 @@ bool SetFileModificationTime(const base::FilePath& path, return false; } return true; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) DWORD flags = FILE_FLAG_OPEN_REPARSE_POINT; if (IsDirectory(path, true)) { // required for directory handles @@ -172,22 +173,22 @@ bool SetFileModificationTime(const base::FilePath& path, return false; } return true; -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) bool CanCreateSymbolicLinks() { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) return true; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return SymbolicLinkFlags(nullptr); -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } bool CreateSymbolicLink(const base::FilePath& target_path, const base::FilePath& symlink_path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int rv = HANDLE_EINTR( symlink(target_path.value().c_str(), symlink_path.value().c_str())); if (rv != 0) { @@ -195,7 +196,7 @@ bool CreateSymbolicLink(const base::FilePath& target_path, return false; } return true; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) DWORD symbolic_link_flags = 0; SymbolicLinkFlags(&symbolic_link_flags); if (!::CreateSymbolicLink( @@ -208,10 +209,10 @@ bool CreateSymbolicLink(const base::FilePath& target_path, return false; } return true; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) } // namespace test } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/test/filesystem.h b/thirdparty/sentry-native/external/crashpad/test/filesystem.h index 516335bb7c..683213689b 100644 --- a/thirdparty/sentry-native/external/crashpad/test/filesystem.h +++ b/thirdparty/sentry-native/external/crashpad/test/filesystem.h @@ -37,7 +37,7 @@ bool PathExists(const base::FilePath& path); //! \return `true` on success. Otherwise `false` with a message logged. bool SetFileModificationTime(const base::FilePath& path, const timespec& mtime); -#if !defined(OS_FUCHSIA) || DOXYGEN +#if !BUILDFLAG(IS_FUCHSIA) || DOXYGEN // There are no symbolic links on Fuchsia. Don’t bother declaring or defining // symbolic link-related functions at all, because it’s an error to even pretend // that symbolic links might be available on Fuchsia. @@ -67,7 +67,7 @@ bool CanCreateSymbolicLinks(); bool CreateSymbolicLink(const base::FilePath& target_path, const base::FilePath& symlink_path); -#endif // !OS_FUCHSIA || DOXYGEN +#endif // !BUILDFLAG(IS_FUCHSIA) || DOXYGEN } // namespace test } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/test/gtest_death.h b/thirdparty/sentry-native/external/crashpad/test/gtest_death.h index c67d334521..8142c3d130 100644 --- a/thirdparty/sentry-native/external/crashpad/test/gtest_death.h +++ b/thirdparty/sentry-native/external/crashpad/test/gtest_death.h @@ -19,13 +19,13 @@ #include "build/build_config.h" #include "gtest/gtest.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include "test/mac/exception_swallower.h" #endif //! \file -#if defined(OS_MAC) || DOXYGEN +#if BUILDFLAG(IS_MAC) || DOXYGEN //! \brief Wraps the Google Test `ASSERT_DEATH_IF_SUPPORTED()` macro to make //! assertions about death caused by crashes. @@ -73,14 +73,14 @@ regex); \ } while (false) -#else // OS_MAC +#else // BUILDFLAG(IS_MAC) #define ASSERT_DEATH_CRASH(statement, regex) \ ASSERT_DEATH_IF_SUPPORTED(statement, regex) #define EXPECT_DEATH_CRASH(statement, regex) \ EXPECT_DEATH_IF_SUPPORTED(statement, regex) -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) #if !(!defined(MINI_CHROMIUM_BASE_LOGGING_H_) && \ defined(OFFICIAL_BUILD) && \ diff --git a/thirdparty/sentry-native/external/crashpad/test/gtest_main.cc b/thirdparty/sentry-native/external/crashpad/test/gtest_main.cc index c67b8e24bb..04c539b770 100644 --- a/thirdparty/sentry-native/external/crashpad/test/gtest_main.cc +++ b/thirdparty/sentry-native/external/crashpad/test/gtest_main.cc @@ -22,17 +22,17 @@ #include "gmock/gmock.h" #endif // CRASHPAD_TEST_LAUNCHER_GOOGLEMOCK -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include "util/linux/initial_signal_dispositions.h" -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) #include "test/ios/google_test_setup.h" #endif -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include "test/win/win_child_process.h" -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) #if defined(CRASHPAD_IS_IN_CHROMIUM) #include "base/bind.h" @@ -42,7 +42,7 @@ namespace { -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) bool GetChildTestFunctionName(std::string* child_func_name) { constexpr size_t arg_length = sizeof(crashpad::test::internal::kChildTestFunction) - 1; @@ -55,38 +55,38 @@ bool GetChildTestFunctionName(std::string* child_func_name) { } return false; } -#endif // !OS_IOS +#endif // !BUILDFLAG(IS_IOS) } // namespace int main(int argc, char* argv[]) { -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) crashpad::InitializeSignalDispositions(); -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) crashpad::test::InitializeMainArguments(argc, argv); -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) std::string child_func_name; if (GetChildTestFunctionName(&child_func_name)) { return crashpad::test::internal::CheckedInvokeMultiprocessChild( child_func_name); } -#endif // !OS_IOS +#endif // !BUILDFLAG(IS_IOS) #if defined(CRASHPAD_IS_IN_CHROMIUM) -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Chromium’s test launcher interferes with WinMultiprocess-based tests. Allow // their child processes to be launched by the standard Google Test-based test // runner. const bool use_chromium_test_launcher = !crashpad::test::WinChildProcess::IsChildProcess(); -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) constexpr bool use_chromium_test_launcher = false; -#else // OS_WIN +#else // BUILDFLAG(IS_WIN) constexpr bool use_chromium_test_launcher = true; -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) if (use_chromium_test_launcher) { // This supports --test-launcher-summary-output, which writes a JSON file @@ -115,7 +115,7 @@ int main(int argc, char* argv[]) { CRASHPAD_TEST_LAUNCHER_GOOGLEMOCK #endif // CRASHPAD_TEST_LAUNCHER_GOOGLEMOCK -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) // iOS needs to run tests within the context of an app, so call a helper that // invokes UIApplicationMain(). The application delegate will call // RUN_ALL_TESTS() and exit before returning control to this function. diff --git a/thirdparty/sentry-native/external/crashpad/test/hex_string.h b/thirdparty/sentry-native/external/crashpad/test/hex_string.h index b0d445319e..be0143b7b3 100644 --- a/thirdparty/sentry-native/external/crashpad/test/hex_string.h +++ b/thirdparty/sentry-native/external/crashpad/test/hex_string.h @@ -29,8 +29,8 @@ namespace test { //! uint8_t expected[10]; //! uint8_t observed[10]; //! // … -//! EXPECT_EQ(BytesToHexString(observed, base::size(observed)), -//! BytesToHexString(expected, base::size(expected))); +//! EXPECT_EQ(BytesToHexString(observed, std::size(observed)), +//! BytesToHexString(expected, std::size(expected))); //! \endcode std::string BytesToHexString(const void* bytes, size_t length); diff --git a/thirdparty/sentry-native/external/crashpad/test/hex_string_test.cc b/thirdparty/sentry-native/external/crashpad/test/hex_string_test.cc index ac6343bf58..13aa311a31 100644 --- a/thirdparty/sentry-native/external/crashpad/test/hex_string_test.cc +++ b/thirdparty/sentry-native/external/crashpad/test/hex_string_test.cc @@ -14,7 +14,8 @@ #include "test/hex_string.h" -#include "base/cxx17_backports.h" +#include + #include "gtest/gtest.h" namespace crashpad { @@ -25,7 +26,7 @@ TEST(HexString, HexString) { EXPECT_EQ(BytesToHexString(nullptr, 0), ""); static constexpr char kBytes[] = "Abc123xyz \x0a\x7f\xf0\x9f\x92\xa9_"; - EXPECT_EQ(BytesToHexString(kBytes, base::size(kBytes)), + EXPECT_EQ(BytesToHexString(kBytes, std::size(kBytes)), "41626331323378797a200a7ff09f92a95f00"); } diff --git a/thirdparty/sentry-native/external/crashpad/test/ios/crash_type_xctest.mm b/thirdparty/sentry-native/external/crashpad/test/ios/crash_type_xctest.mm index 2dcfac786f..27b4e1f7fe 100644 --- a/thirdparty/sentry-native/external/crashpad/test/ios/crash_type_xctest.mm +++ b/thirdparty/sentry-native/external/crashpad/test/ios/crash_type_xctest.mm @@ -16,6 +16,7 @@ #include #import "Service/Sources/EDOClientService.h" +#include "build/build_config.h" #import "test/ios/host/cptest_shared_object.h" #include "util/mach/exception_types.h" #include "util/mach/mach_extensions.h" @@ -33,15 +34,8 @@ @implementation CPTestTestCase + (void)setUp { - // Swizzle away the handleCrashUnderSymbol callback. Without this, any time - // the host app is intentionally crashed, the test is immediately failed. - SEL originalSelector = NSSelectorFromString(@"handleCrashUnderSymbol:"); - SEL swizzledSelector = @selector(handleCrashUnderSymbol:); - Method originalMethod = class_getInstanceMethod( - objc_getClass("XCUIApplicationImpl"), originalSelector); - Method swizzledMethod = - class_getInstanceMethod([self class], swizzledSelector); - method_exchangeImplementations(originalMethod, swizzledMethod); + [CPTestTestCase swizzleHandleCrashUnderSymbol]; + [CPTestTestCase swizleMayTerminateOutOfBandWithoutCrashReport]; // Override EDO default error handler. Without this, the default EDO error // handler will throw an error and fail the test. @@ -50,12 +44,43 @@ }); } +// Swizzle away the -[XCUIApplicationImpl handleCrashUnderSymbol:] callback. +// Without this, any time the host app is intentionally crashed, the test is +// immediately failed. ++ (void)swizzleHandleCrashUnderSymbol { + SEL originalSelector = NSSelectorFromString(@"handleCrashUnderSymbol:"); + SEL swizzledSelector = @selector(handleCrashUnderSymbol:); + Method originalMethod = class_getInstanceMethod( + objc_getClass("XCUIApplicationImpl"), originalSelector); + Method swizzledMethod = + class_getInstanceMethod([self class], swizzledSelector); + method_exchangeImplementations(originalMethod, swizzledMethod); +} + +// Swizzle away the time consuming 'Checking for crash reports corresponding to' +// from -[XCUIApplicationProcess swizleMayTerminateOutOfBandWithoutCrashReport] +// that is unnecessary for these tests. ++ (void)swizleMayTerminateOutOfBandWithoutCrashReport { + SEL originalSelector = + NSSelectorFromString(@"mayTerminateOutOfBandWithoutCrashReport"); + SEL swizzledSelector = @selector(mayTerminateOutOfBandWithoutCrashReport); + Method originalMethod = class_getInstanceMethod( + objc_getClass("XCUIApplicationProcess"), originalSelector); + Method swizzledMethod = + class_getInstanceMethod([self class], swizzledSelector); + method_exchangeImplementations(originalMethod, swizzledMethod); +} + // This gets called after tearDown, so there's no straightforward way to // test that this is called. However, not swizzling this out will cause every // crashing test to fail. - (void)handleCrashUnderSymbol:(id)arg1 { } +- (BOOL)mayTerminateOutOfBandWithoutCrashReport { + return YES; +} + - (void)setUp { app_ = [[XCUIApplication alloc] init]; [app_ launch]; @@ -65,7 +90,7 @@ XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); } -- (void)verifyCrashReportException:(int)exception { +- (void)verifyCrashReportException:(uint32_t)exception { // Confirm the app is not running. XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]); XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning); @@ -75,7 +100,12 @@ XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); rootObject_ = [EDOClientService rootObjectWithPort:12345]; XCTAssertEqual([rootObject_ pendingReportCount], 1); - XCTAssertEqual([rootObject_ pendingReportException], exception); + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportException:&report_exception]); + XCTAssertEqual(report_exception.unsignedIntValue, exception); + + NSString* rawLogContents = [rootObject_ rawLogContents]; + XCTAssertFalse([rawLogContents containsString:@"allocator used in handler."]); } - (void)testEDO { @@ -83,46 +113,44 @@ XCTAssertEqualObjects(result, @"crashpad"); } -- (void)testSegv { - [rootObject_ crashSegv]; -#if defined(NDEBUG) && TARGET_OS_SIMULATOR - [self verifyCrashReportException:SIGINT]; -#else - [self verifyCrashReportException:SIGHUP]; -#endif -} - - (void)testKillAbort { [rootObject_ crashKillAbort]; - [self verifyCrashReportException:SIGABRT]; + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGABRT); } - (void)testTrap { [rootObject_ crashTrap]; -#if TARGET_OS_SIMULATOR - [self verifyCrashReportException:SIGINT]; +#if defined(ARCH_CPU_X86_64) + [self verifyCrashReportException:EXC_BAD_INSTRUCTION]; +#elif defined(ARCH_CPU_ARM64) + [self verifyCrashReportException:EXC_BREAKPOINT]; #else - [self verifyCrashReportException:SIGABRT]; +#error Port to your CPU architecture #endif } - (void)testAbort { [rootObject_ crashAbort]; - [self verifyCrashReportException:SIGABRT]; + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGABRT); } - (void)testBadAccess { [rootObject_ crashBadAccess]; -#if defined(NDEBUG) && TARGET_OS_SIMULATOR - [self verifyCrashReportException:SIGINT]; -#else - [self verifyCrashReportException:SIGHUP]; -#endif + [self verifyCrashReportException:EXC_BAD_ACCESS]; } - (void)testException { [rootObject_ crashException]; - [self verifyCrashReportException:SIGABRT]; + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGABRT); } - (void)testNSException { @@ -138,6 +166,22 @@ isEqualToString:@"NSInternalInconsistencyException"]); } +- (void)testUnhandledNSException { + [rootObject_ crashUnhandledNSException]; + [self verifyCrashReportException:crashpad::kMachExceptionFromNSException]; + NSDictionary* dict = [rootObject_ getAnnotations]; + NSString* uncaught_flag = + [dict[@"objects"][0] valueForKeyPath:@"UncaughtNSException"]; + XCTAssertTrue([uncaught_flag containsString:@"true"]); + NSString* userInfo = + [dict[@"objects"][1] valueForKeyPath:@"exceptionUserInfo"]; + XCTAssertTrue([userInfo containsString:@"Error Object=* old_args = app_.launchArguments; app_.launchArguments = @[ @"--alternate-client-annotations" ]; - [self verifyCrashReportException:SIGABRT]; + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGABRT); + app_.launchArguments = old_args; // Confirm the initial crash took the standard annotations. @@ -205,7 +253,10 @@ // Confirm passing alternate client annotation args works. [rootObject_ clearPendingReports]; [rootObject_ crashKillAbort]; - [self verifyCrashReportException:SIGABRT]; + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGABRT); + dict = [rootObject_ getProcessAnnotations]; XCTAssertTrue([dict[@"crashpad"] isEqualToString:@"no"]); XCTAssertTrue([dict[@"plat"] isEqualToString:@"macOS"]); @@ -220,7 +271,7 @@ return; } [rootObject_ crashWithCrashInfoMessage]; - [self verifyCrashReportException:SIGHUP]; + [self verifyCrashReportException:EXC_BAD_ACCESS]; NSDictionary* dict = [rootObject_ getAnnotations]; NSString* dyldMessage = dict[@"vector"][0]; XCTAssertTrue([dyldMessage isEqualToString:@"dyld: in dlsym()"]); @@ -235,7 +286,7 @@ return; } [rootObject_ crashWithDyldErrorString]; - [self verifyCrashReportException:SIGINT]; + [self verifyCrashReportException:EXC_BAD_INSTRUCTION]; NSArray* vector = [rootObject_ getAnnotations][@"vector"]; // This message is set by dyld-353.2.1/src/ImageLoaderMachO.cpp // ImageLoaderMachO::doInitialization(). @@ -246,7 +297,11 @@ - (void)testCrashWithAnnotations { [rootObject_ crashWithAnnotations]; - [self verifyCrashReportException:SIGABRT]; + [self verifyCrashReportException:EXC_SOFT_SIGNAL]; + NSNumber* report_exception; + XCTAssertTrue([rootObject_ pendingReportExceptionInfo:&report_exception]); + XCTAssertEqual(report_exception.intValue, SIGABRT); + NSDictionary* dict = [rootObject_ getAnnotations]; NSDictionary* simpleMap = dict[@"simplemap"]; XCTAssertTrue([simpleMap[@"#TEST# empty_value"] isEqualToString:@""]); @@ -263,4 +318,67 @@ isEqualToString:@"moocow"]); } +- (void)testDumpWithoutCrash { + [rootObject_ generateDumpWithoutCrash:10 threads:3]; + + // The app should not crash + XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); + + XCTAssertEqual([rootObject_ pendingReportCount], 30); +} + +- (void)testSimultaneousCrash { + [rootObject_ crashConcurrentSignalAndMach]; + + // Confirm the app is not running. + XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]); + XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning); + + [app_ launch]; + XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); + rootObject_ = [EDOClientService rootObjectWithPort:12345]; + XCTAssertEqual([rootObject_ pendingReportCount], 1); +} + +- (void)testCrashInHandlerReentrant { + XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); + rootObject_ = [EDOClientService rootObjectWithPort:12345]; + + [rootObject_ crashInHandlerReentrant]; + + // Confirm the app is not running. + XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]); + XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning); + + [app_ launch]; + XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); + rootObject_ = [EDOClientService rootObjectWithPort:12345]; + + XCTAssertEqual([rootObject_ pendingReportCount], 0); + + NSString* rawLogContents = [rootObject_ rawLogContents]; + NSString* errmsg = @"Cannot DumpExceptionFromSignal without writer"; + XCTAssertTrue([rawLogContents containsString:errmsg]); +} + +- (void)testFailureWhenHandlerAllocates { + XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); + rootObject_ = [EDOClientService rootObjectWithPort:12345]; + + [rootObject_ allocateWithForbiddenAllocators]; + + // Confirm the app is not running. + XCTAssertTrue([app_ waitForState:XCUIApplicationStateNotRunning timeout:15]); + XCTAssertTrue(app_.state == XCUIApplicationStateNotRunning); + + [app_ launch]; + XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground); + rootObject_ = [EDOClientService rootObjectWithPort:12345]; + + XCTAssertEqual([rootObject_ pendingReportCount], 0); + + NSString* rawLogContents = [rootObject_ rawLogContents]; + XCTAssertTrue([rawLogContents containsString:@"allocator used in handler."]); +} + @end diff --git a/thirdparty/sentry-native/external/crashpad/test/ios/host/BUILD.gn b/thirdparty/sentry-native/external/crashpad/test/ios/host/BUILD.gn index 77842a98ec..a5e04ee79f 100644 --- a/thirdparty/sentry-native/external/crashpad/test/ios/host/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/test/ios/host/BUILD.gn @@ -35,6 +35,8 @@ static_library("app_host_sources") { "cptest_application_delegate.mm", "cptest_crash_view_controller.h", "cptest_crash_view_controller.mm", + "handler_forbidden_allocators.cc", + "handler_forbidden_allocators.h", "main.mm", ] configs += [ "../../..:crashpad_config" ] @@ -43,6 +45,7 @@ static_library("app_host_sources") { "../../../build:ios_enable_arc", "../../../client", "../../../snapshot", + "../../../test", "../../../third_party/edo", ] frameworks = [ diff --git a/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_application_delegate.mm b/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_application_delegate.mm index 44a7d88ad8..503d2febf3 100644 --- a/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_application_delegate.mm +++ b/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_application_delegate.mm @@ -18,16 +18,20 @@ #include #include #include +#include #include +#include #include #include #include +#include #include #import "Service/Sources/EDOHostNamingService.h" #import "Service/Sources/EDOHostService.h" #import "Service/Sources/NSObject+EDOValueObject.h" +#include "base/logging.h" #include "base/strings/sys_string_conversions.h" #include "client/annotation.h" #include "client/annotation_list.h" @@ -35,9 +39,15 @@ #include "client/crashpad_client.h" #include "client/crashpad_info.h" #include "client/simple_string_dictionary.h" +#include "client/simulate_crash.h" #include "snapshot/minidump/process_snapshot_minidump.h" +#include "test/file.h" #import "test/ios/host/cptest_crash_view_controller.h" #import "test/ios/host/cptest_shared_object.h" +#import "test/ios/host/handler_forbidden_allocators.h" +#include "util/file/filesystem.h" +#include "util/ios/raw_logging.h" +#include "util/thread/thread.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -56,6 +66,14 @@ base::FilePath GetDatabaseDir() { return database_dir.Append("crashpad"); } +base::FilePath GetRawLogOutputFile() { + base::FilePath document_directory([NSFileManager.defaultManager + URLsForDirectory:NSDocumentDirectory + inDomains:NSUserDomainMask] + .lastObject.path.UTF8String); + return document_directory.Append("raw_log_output.txt"); +} + std::unique_ptr GetDatabase() { base::FilePath database_dir = GetDatabaseDir(); std::unique_ptr database = @@ -68,6 +86,35 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { return database->GetPendingReports(pending_reports); } +std::unique_ptr +GetProcessSnapshotMinidumpFromSinglePending() { + std::vector pending_reports; + OperationStatus status = GetPendingReports(&pending_reports); + if (status != crashpad::CrashReportDatabase::kNoError || + pending_reports.size() != 1) { + return nullptr; + } + + auto reader = std::make_unique(); + auto process_snapshot = std::make_unique(); + if (!reader->Open(pending_reports[0].file_path) || + !process_snapshot->Initialize(reader.get())) { + return nullptr; + } + return process_snapshot; +} + +UIWindow* GetAnyWindow() { +#if defined(__IPHONE_15_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_15_0 + if (@available(iOS 15.0, *)) { + UIWindowScene* scene = reinterpret_cast( + [UIApplication sharedApplication].connectedScenes.anyObject); + return scene.keyWindow; + } +#endif + return [UIApplication sharedApplication].windows[0]; +} + [[clang::optnone]] void recurse(int counter) { // Fill up the stack faster. int arr[1024]; @@ -81,20 +128,34 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { @interface CPTestApplicationDelegate () - (void)processIntermediateDumps; +@property(copy, nonatomic) NSString* raw_log_output; @end @implementation CPTestApplicationDelegate { crashpad::CrashpadClient client_; + crashpad::ScopedFileHandle raw_logging_file_; } @synthesize window = _window; - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { + base::FilePath raw_log_file_path = GetRawLogOutputFile(); + NSString* path = + [NSString stringWithUTF8String:raw_log_file_path.value().c_str()]; + self.raw_log_output = + [[NSString alloc] initWithContentsOfFile:path + encoding:NSUTF8StringEncoding + error:NULL]; + raw_logging_file_.reset( + LoggingOpenFileForWrite(raw_log_file_path, + crashpad::FileWriteMode::kTruncateOrCreate, + crashpad::FilePermissions::kOwnerOnly)); + crashpad::internal::SetFileHandleForTesting(raw_logging_file_.get()); + // Start up crashpad. std::map annotations = { {"prod", "xcuitest"}, {"ver", "1"}, {"plat", "iOS"}, {"crashpad", "yes"}}; - NSArray* arguments = [[NSProcessInfo processInfo] arguments]; if ([arguments containsObject:@"--alternate-client-annotations"]) { annotations = {{"prod", "some_app"}, @@ -159,40 +220,36 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { return pending_reports.size(); } -- (int)pendingReportException { - std::vector pending_reports; - OperationStatus status = GetPendingReports(&pending_reports); - if (status != crashpad::CrashReportDatabase::kNoError || - pending_reports.size() != 1) { - return -1; - } +- (bool)pendingReportException:(NSNumber**)exception { + auto process_snapshot = GetProcessSnapshotMinidumpFromSinglePending(); + if (!process_snapshot || !process_snapshot->Exception()->Exception()) + return false; + *exception = [NSNumber + numberWithUnsignedInt:process_snapshot->Exception()->Exception()]; + return true; +} - auto reader = std::make_unique(); - reader->Open(pending_reports[0].file_path); - crashpad::ProcessSnapshotMinidump process_snapshot; - process_snapshot.Initialize(reader.get()); - return static_cast(process_snapshot.Exception()->Exception()); +- (bool)pendingReportExceptionInfo:(NSNumber**)exception_info { + auto process_snapshot = GetProcessSnapshotMinidumpFromSinglePending(); + if (!process_snapshot || !process_snapshot->Exception()->ExceptionInfo()) + return false; + + *exception_info = [NSNumber + numberWithUnsignedInt:process_snapshot->Exception()->ExceptionInfo()]; + return true; } - (NSDictionary*)getAnnotations { - std::vector pending_reports; - OperationStatus status = GetPendingReports(&pending_reports); - if (status != crashpad::CrashReportDatabase::kNoError || - pending_reports.size() != 1) { + auto process_snapshot = GetProcessSnapshotMinidumpFromSinglePending(); + if (!process_snapshot) return @{}; - } - - auto reader = std::make_unique(); - reader->Open(pending_reports[0].file_path); - crashpad::ProcessSnapshotMinidump process_snapshot; - process_snapshot.Initialize(reader.get()); NSDictionary* dict = @{ @"simplemap" : [@{} mutableCopy], @"vector" : [@[] mutableCopy], @"objects" : [@[] mutableCopy] }; - for (const auto* module : process_snapshot.Modules()) { + for (const auto* module : process_snapshot->Modules()) { for (const auto& kv : module->AnnotationsSimpleMap()) { [dict[@"simplemap"] setValue:@(kv.second.c_str()) forKey:@(kv.first.c_str())]; @@ -215,43 +272,36 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { } - (NSDictionary*)getProcessAnnotations { - std::vector pending_reports; - OperationStatus status = GetPendingReports(&pending_reports); - if (status != crashpad::CrashReportDatabase::kNoError || - pending_reports.size() != 1) { + auto process_snapshot = GetProcessSnapshotMinidumpFromSinglePending(); + if (!process_snapshot) return @{}; - } - auto reader = std::make_unique(); - reader->Open(pending_reports[0].file_path); - crashpad::ProcessSnapshotMinidump process_snapshot; - process_snapshot.Initialize(reader.get()); NSDictionary* dict = [@{} mutableCopy]; - for (const auto& kv : process_snapshot.AnnotationsSimpleMap()) { + for (const auto& kv : process_snapshot->AnnotationsSimpleMap()) { [dict setValue:@(kv.second.c_str()) forKey:@(kv.first.c_str())]; } return [dict passByValue]; } -- (void)crashBadAccess { +// Use [[clang::optnone]] here to get consistent exception codes, otherwise the +// exception can change depending on optimization level. +- (void)crashBadAccess [[clang::optnone]] { strcpy(nullptr, "bla"); } - (void)crashKillAbort { + crashpad::test::ReplaceAllocatorsWithHandlerForbidden(); kill(getpid(), SIGABRT); } -- (void)crashSegv { - long* zero = nullptr; - *zero = 0xc045004d; -} - - (void)crashTrap { + crashpad::test::ReplaceAllocatorsWithHandlerForbidden(); __builtin_trap(); } - (void)crashAbort { + crashpad::test::ReplaceAllocatorsWithHandlerForbidden(); abort(); } @@ -261,7 +311,8 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { } - (void)crashNSException { - // EDO has its own sinkhole, so dispatch this away. + // EDO has its own sinkhole which will suppress this attempt at an NSException + // crash, so dispatch this out of the sinkhole. dispatch_async(dispatch_get_main_queue(), ^{ NSError* error = [NSError errorWithDomain:@"com.crashpad.xcuitests" code:200 @@ -273,6 +324,27 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { }); } +- (void)crashUnhandledNSException { + std::thread t([self]() { + @autoreleasepool { + @try { + NSError* error = [NSError errorWithDomain:@"com.crashpad.xcuitests" + code:200 + userInfo:@{@"Error Object" : self}]; + + [[NSException exceptionWithName:NSInternalInconsistencyException + reason:@"Intentionally throwing error." + userInfo:@{NSUnderlyingErrorKey : error}] raise]; + } @catch (id reason_exception) { + // Intentionally use throw here to intentionally make a sinkhole that + // will be missed by ObjcPreprocessor. + objc_exception_throw(reason_exception); + } + } + }); + t.join(); +} + - (void)crashUnrecognizedSelectorAfterDelay { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" @@ -290,10 +362,11 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { } - (void)crashCoreAutoLayoutSinkhole { - // EDO has its own sinkhole, so dispatch this away. + // EDO has its own sinkhole which will suppress this attempt at an NSException + // crash, so dispatch this out of the sinkhole. dispatch_async(dispatch_get_main_queue(), ^{ UIView* unattachedView = [[UIView alloc] init]; - UIWindow* window = [UIApplication sharedApplication].windows[0]; + UIWindow* window = GetAnyWindow(); [NSLayoutConstraint activateConstraints:@[ [window.rootViewController.view.bottomAnchor constraintEqualToAnchor:unattachedView.bottomAnchor], @@ -350,4 +423,76 @@ OperationStatus GetPendingReports(std::vector* pending_reports) { abort(); } +class RaceThread : public crashpad::Thread { + public: + explicit RaceThread() : Thread() {} + + void SetCount(int count) { count_ = count; } + + private: + void ThreadMain() override { + for (int i = 0; i < count_; ++i) { + CRASHPAD_SIMULATE_CRASH(); + } + } + + int count_; +}; + +- (void)generateDumpWithoutCrash:(int)dump_count threads:(int)threads { + std::vector race_threads(threads); + for (RaceThread& race_thread : race_threads) { + race_thread.SetCount(dump_count); + race_thread.Start(); + } + + for (RaceThread& race_thread : race_threads) { + race_thread.Join(); + } +} + +class CrashThread : public crashpad::Thread { + public: + explicit CrashThread(bool signal) : Thread(), signal_(signal) {} + + private: + void ThreadMain() override { + sleep(1); + if (signal_) { + abort(); + } else { + __builtin_trap(); + } + } + bool signal_; +}; + +- (void)crashConcurrentSignalAndMach { + CrashThread signal_thread(true); + CrashThread mach_thread(false); + signal_thread.Start(); + mach_thread.Start(); + signal_thread.Join(); + mach_thread.Join(); +} + +- (void)crashInHandlerReentrant { + crashpad::CrashpadClient client_; + client_.SetMachExceptionCallbackForTesting(abort); + + // Trigger a Mach exception. + [self crashTrap]; +} + +- (void)allocateWithForbiddenAllocators { + crashpad::test::ReplaceAllocatorsWithHandlerForbidden(); + (void)malloc(10); +} + +- (NSString*)rawLogContents { + CPTestApplicationDelegate* delegate = + (CPTestApplicationDelegate*)UIApplication.sharedApplication.delegate; + return delegate.raw_log_output; +} + @end diff --git a/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_shared_object.h b/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_shared_object.h index bcd755479d..47ee7ad35d 100644 --- a/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_shared_object.h +++ b/thirdparty/sentry-native/external/crashpad/test/ios/host/cptest_shared_object.h @@ -32,9 +32,15 @@ // report. - (int)pendingReportCount; -// Returns exception code when there's a single pending report, or -1 if there's -// a different number of pending reports. -- (int)pendingReportException; +// Returns true if there's a single pending report and sets the exception code +// in the out |exception| parameter. Returns false if there's a different number +// of pending reports. +- (bool)pendingReportException:(NSNumber**)exception; + +// Returns true if there's a single pending report and sets the second-level +// exception code in the out |exception_info| parameter. Returns false if +// there's a different number of pending reports. +- (bool)pendingReportExceptionInfo:(NSNumber**)exception_info; // Return an NSDictionary with a dictionary named "simplemap", an array named // "vector" and an array named "objects", representing the combination of all @@ -49,16 +55,16 @@ // Triggers an EXC_BAD_ACCESS exception and crash. - (void)crashBadAccess; -// Triggers a crash with a call to kill(SIGABRT). +// Triggers a crash with a call to kill(SIGABRT). This crash runs with +// ReplaceAllocatorsWithHandlerForbidden. - (void)crashKillAbort; -// Triggers a segfault crash. -- (void)crashSegv; - -// Trigger a crash with a __builtin_trap. +// Trigger a crash with a __builtin_trap. This crash runs with +// ReplaceAllocatorsWithHandlerForbidden. - (void)crashTrap; -// Trigger a crash with an abort(). +// Trigger a crash with an abort(). This crash runs with +// ReplaceAllocatorsWithHandlerForbidden. - (void)crashAbort; // Trigger a crash with an uncaught exception. @@ -67,6 +73,9 @@ // Trigger a crash with an uncaught NSException. - (void)crashNSException; +// Trigger a crash with an uncaught and unhandled NSException. +- (void)crashUnhandledNSException; + // Trigger an unrecognized selector after delay. - (void)crashUnrecognizedSelectorAfterDelay; @@ -88,6 +97,24 @@ // Trigger a crash after writing various annotations. - (void)crashWithAnnotations; +// Triggers a DumpWithoutCrash |dump_count| times in each of |threads| threads. +- (void)generateDumpWithoutCrash:(int)dump_count threads:(int)threads; + +// Triggers a simulataneous Mach exception and signal in different threads. +- (void)crashConcurrentSignalAndMach; + +// Triggers a SIGABRT signal while handling an NSException to test reentrant +// exceptions. +- (void)crashInHandlerReentrant; + +// Runs with ReplaceAllocatorsWithHandlerForbidden and allocates memory, testing +// that the handler forbidden allocator works. +- (void)allocateWithForbiddenAllocators; + +// Return the contents of the RawLog output from the previous run of the host +// application. +- (NSString*)rawLogContents; + @end #endif // CRASHPAD_TEST_IOS_HOST_SHARED_OBJECT_H_ diff --git a/thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.cc b/thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.cc new file mode 100644 index 0000000000..dbb499a70c --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.cc @@ -0,0 +1,295 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "test/ios/host/handler_forbidden_allocators.h" + +#include +#include +#include +#include + +#include "base/mac/mach_logging.h" +#include "client/crashpad_client.h" +#include "util/ios/raw_logging.h" + +namespace crashpad { +namespace test { + +namespace { + +uint64_t g_main_thread = 0; +uint64_t g_mach_exception_thread = 0; +malloc_zone_t g_old_zone; + +bool is_handler_thread() { + uint64_t thread_self; + pthread_threadid_np(pthread_self(), &thread_self); + return (thread_self == g_main_thread || + thread_self == g_mach_exception_thread); +} + +void* handler_forbidden_malloc(struct _malloc_zone_t* zone, size_t size) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_malloc allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.malloc(zone, size); +} + +void* handler_forbidden_calloc(struct _malloc_zone_t* zone, + size_t num_items, + size_t size) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_calloc allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.calloc(zone, num_items, size); +} + +void* handler_forbidden_valloc(struct _malloc_zone_t* zone, size_t size) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_valloc allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.valloc(zone, size); +} + +void handler_forbidden_free(struct _malloc_zone_t* zone, void* ptr) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_free allocator used in handler."); + exit(EXIT_FAILURE); + } + g_old_zone.free(zone, ptr); +} + +void* handler_forbidden_realloc(struct _malloc_zone_t* zone, + void* ptr, + size_t size) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_realloc allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.realloc(zone, ptr, size); +} + +void handler_forbidden_destroy(struct _malloc_zone_t* zone) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_destroy allocator used in handler."); + exit(EXIT_FAILURE); + } + g_old_zone.destroy(zone); +} + +void* handler_forbidden_memalign(struct _malloc_zone_t* zone, + size_t alignment, + size_t size) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_memalign allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.memalign(zone, alignment, size); +} + +unsigned handler_forbidden_batch_malloc(struct _malloc_zone_t* zone, + size_t size, + void** results, + unsigned num_requested) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG( + "handler_forbidden_batch_malloc allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.batch_malloc(zone, size, results, num_requested); +} + +void handler_forbidden_batch_free(struct _malloc_zone_t* zone, + void** to_be_freed, + unsigned num_to_be_freed) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_batch_free allocator used in handler."); + exit(EXIT_FAILURE); + } + g_old_zone.batch_free(zone, to_be_freed, num_to_be_freed); +} + +void handler_forbidden_free_definite_size(struct _malloc_zone_t* zone, + void* ptr, + size_t size) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG( + "handler_forbidden_free_definite_size allocator used in handler."); + exit(EXIT_FAILURE); + } + g_old_zone.free_definite_size(zone, ptr, size); +} + +size_t handler_forbidden_pressure_relief(struct _malloc_zone_t* zone, + size_t goal) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG( + "handler_forbidden_pressure_relief allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.pressure_relief(zone, goal); +} + +boolean_t handler_forbidden_claimed_address(struct _malloc_zone_t* zone, + void* ptr) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG( + "handler_forbidden_claimed_address allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.claimed_address(zone, ptr); +} + +size_t handler_forbidden_size(struct _malloc_zone_t* zone, const void* ptr) { + if (is_handler_thread()) { + CRASHPAD_RAW_LOG("handler_forbidden_size allocator used in handler."); + exit(EXIT_FAILURE); + } + return g_old_zone.size(zone, ptr); +} + +bool DeprotectMallocZone(malloc_zone_t* default_zone, + vm_address_t* reprotection_start, + vm_size_t* reprotection_length, + vm_prot_t* reprotection_value) { + mach_port_t unused; + *reprotection_start = reinterpret_cast(default_zone); + struct vm_region_basic_info_64 info; + mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; + kern_return_t result = vm_region_64(mach_task_self(), + reprotection_start, + reprotection_length, + VM_REGION_BASIC_INFO_64, + reinterpret_cast(&info), + &count, + &unused); + if (result != KERN_SUCCESS) { + MACH_LOG(ERROR, result) << "vm_region_64"; + return false; + } + + // The kernel always returns a null object for VM_REGION_BASIC_INFO_64, but + // balance it with a deallocate in case this ever changes. See + // the VM_REGION_BASIC_INFO_64 case in vm_map_region() in 10.15's + // https://opensource.apple.com/source/xnu/xnu-6153.11.26/osfmk/vm/vm_map.c . + mach_port_deallocate(mach_task_self(), unused); + + if (!(info.max_protection & VM_PROT_WRITE)) { + LOG(ERROR) << "Invalid max_protection " << info.max_protection; + return false; + } + + // Does the region fully enclose the zone pointers? Possibly unwarranted + // simplification used: using the size of a full version 10 malloc zone rather + // than the actual smaller size if the passed-in zone is not version 10. + DCHECK_LE(*reprotection_start, reinterpret_cast(default_zone)); + vm_size_t zone_offset = reinterpret_cast(default_zone) - + reinterpret_cast(*reprotection_start); + DCHECK_LE(zone_offset + sizeof(malloc_zone_t), *reprotection_length); + + if (info.protection & VM_PROT_WRITE) { + // No change needed; the zone is already writable. + *reprotection_start = 0; + *reprotection_length = 0; + *reprotection_value = VM_PROT_NONE; + } else { + *reprotection_value = info.protection; + result = vm_protect(mach_task_self(), + *reprotection_start, + *reprotection_length, + false, + info.protection | VM_PROT_WRITE); + if (result != KERN_SUCCESS) { + MACH_LOG(ERROR, result) << "vm_protect"; + return false; + } + } + return true; +} + +void ReplaceZoneFunctions(malloc_zone_t* zone, const malloc_zone_t* functions) { + // Remove protection. + vm_address_t reprotection_start = 0; + vm_size_t reprotection_length = 0; + vm_prot_t reprotection_value = VM_PROT_NONE; + bool success = DeprotectMallocZone( + zone, &reprotection_start, &reprotection_length, &reprotection_value); + if (!success) { + return; + } + + zone->size = functions->size; + zone->malloc = functions->malloc; + zone->calloc = functions->calloc; + zone->valloc = functions->valloc; + zone->free = functions->free; + zone->realloc = functions->realloc; + zone->destroy = functions->destroy; + zone->batch_malloc = functions->batch_malloc; + zone->batch_free = functions->batch_free; + zone->introspect = functions->introspect; + zone->memalign = functions->memalign; + zone->free_definite_size = functions->free_definite_size; + zone->pressure_relief = functions->pressure_relief; + zone->claimed_address = functions->claimed_address; + + // Restore protection if it was active. + if (reprotection_start) { + kern_return_t result = vm_protect(mach_task_self(), + reprotection_start, + reprotection_length, + false, + reprotection_value); + if (result != KERN_SUCCESS) { + MACH_LOG(ERROR, result) << "vm_protect"; + return; + } + } +} + +} // namespace + +void ReplaceAllocatorsWithHandlerForbidden() { + pthread_threadid_np(pthread_self(), &g_main_thread); + + CrashpadClient crashpad_client; + g_mach_exception_thread = crashpad_client.GetThreadIdForTesting(); + + malloc_zone_t* default_zone = malloc_default_zone(); + memcpy(&g_old_zone, default_zone, sizeof(g_old_zone)); + malloc_zone_t new_functions = {}; + new_functions.size = handler_forbidden_size; + new_functions.malloc = handler_forbidden_malloc; + new_functions.calloc = handler_forbidden_calloc; + new_functions.valloc = handler_forbidden_valloc; + new_functions.free = handler_forbidden_free; + new_functions.realloc = handler_forbidden_realloc; + new_functions.destroy = handler_forbidden_destroy; + new_functions.batch_malloc = handler_forbidden_batch_malloc; + new_functions.batch_free = handler_forbidden_batch_free; + new_functions.memalign = handler_forbidden_memalign; + new_functions.free_definite_size = handler_forbidden_free_definite_size; + new_functions.pressure_relief = handler_forbidden_pressure_relief; + new_functions.claimed_address = handler_forbidden_claimed_address; + ReplaceZoneFunctions(default_zone, &new_functions); + + malloc_zone_t* purgeable_zone = malloc_default_purgeable_zone(); + ReplaceZoneFunctions(purgeable_zone, &new_functions); +} + +} // namespace test +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.h b/thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.h new file mode 100644 index 0000000000..c32a092dea --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/test/ios/host/handler_forbidden_allocators.h @@ -0,0 +1,31 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_TEST_IOS_HANDLER_FORBIDDEN_ALLOCATIONS_H_ +#define CRASHPAD_TEST_IOS_HANDLER_FORBIDDEN_ALLOCATIONS_H_ + +namespace crashpad { +namespace test { + +// Override malloc_default_zone and malloc_default_purgeable_zone with functions +// that immediately exit if called from the same thread that this helper is +// called from or from the Crashpad Mach exception handler thread indicated by +// GetThreadIdForTesting. This is used to ensure the allocator is not used by +// the Crashpad InProcessHandler. +void ReplaceAllocatorsWithHandlerForbidden(); + +} // namespace test +} // namespace crashpad + +#endif // CRASHPAD_TEST_IOS_HANDLER_FORBIDDEN_ALLOCATIONS_H_ diff --git a/thirdparty/sentry-native/external/crashpad/test/mac/mach_multiprocess.cc b/thirdparty/sentry-native/external/crashpad/test/mac/mach_multiprocess.cc index 91a06e3acc..5f1b3aca22 100644 --- a/thirdparty/sentry-native/external/crashpad/test/mac/mach_multiprocess.cc +++ b/thirdparty/sentry-native/external/crashpad/test/mac/mach_multiprocess.cc @@ -19,9 +19,9 @@ #include #include +#include #include "base/auto_reset.h" -#include "base/ignore_result.h" #include "base/mac/scoped_mach_port.h" #include "gtest/gtest.h" #include "test/errors.h" @@ -212,7 +212,7 @@ void MachMultiprocess::MultiprocessChild() { ScopedForbidReturn forbid_return; // local_port is not valid in the forked child process. - ignore_result(info_->local_port.release()); + std::ignore = info_->local_port.release(); info_->local_port.reset(NewMachPort(MACH_PORT_RIGHT_RECEIVE)); ASSERT_NE(info_->local_port, kMachPortNull); diff --git a/thirdparty/sentry-native/external/crashpad/test/multiprocess.h b/thirdparty/sentry-native/external/crashpad/test/multiprocess.h index ca48ce80af..dd96a0fe10 100644 --- a/thirdparty/sentry-native/external/crashpad/test/multiprocess.h +++ b/thirdparty/sentry-native/external/crashpad/test/multiprocess.h @@ -28,7 +28,7 @@ namespace internal { struct MultiprocessInfo; } // namespace internal -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) using ReturnCodeType = int64_t; #else using ReturnCodeType = int; @@ -55,13 +55,13 @@ class Multiprocess { //! that call `exit()` or `_exit()`. kTerminationNormal = false, -#if !defined(OS_FUCHSIA) // There are no signals on Fuchsia. +#if !BUILDFLAG(IS_FUCHSIA) // There are no signals on Fuchsia. //! \brief The child terminated by signal. //! //! Signal termination happens as a result of a crash, a call to `abort()`, //! assertion failure (including Google Test assertions), etc. kTerminationSignal, -#endif // !defined(OS_FUCHSIA) +#endif // !BUILDFLAG(IS_FUCHSIA) }; Multiprocess(); @@ -104,11 +104,11 @@ class Multiprocess { void SetExpectedChildTermination(TerminationReason reason, ReturnCodeType code); -#if !defined(OS_WIN) +#if !BUILDFLAG(IS_WIN) //! \brief Sets termination reason and code appropriately for a child that //! terminates via `__builtin_trap()`. void SetExpectedChildTerminationBuiltinTrap(); -#endif // !OS_WIN +#endif // !BUILDFLAG(IS_WIN) protected: ~Multiprocess(); @@ -131,17 +131,17 @@ class Multiprocess { //! Subclass implementations may signal failure by raising their own fatal //! Google Test assertions. virtual void PreFork() -#if defined(OS_WIN) || defined(OS_FUCHSIA) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA) = 0 -#endif // OS_WIN || OS_FUCHSIA +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA) ; -#if !defined(OS_WIN) && !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_FUCHSIA) //! \brief Returns the child process’ process ID. //! //! This method may only be called by the parent process. pid_t ChildPID() const; -#endif // !OS_WIN && !OS_FUCHSIA +#endif // !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_FUCHSIA) //! \brief Returns the read pipe’s file handle. //! diff --git a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.cc b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.cc index cd9a32c0bb..805090d0aa 100644 --- a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.cc +++ b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.cc @@ -18,6 +18,7 @@ #include "base/check.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "test/main_arguments.h" #include "test/test_paths.h" #include "util/stdlib/map_insert.h" @@ -59,7 +60,7 @@ void MultiprocessExec::SetChildTestMainFunction( GetMainArguments().end()); rest.push_back(internal::kChildTestFunction + function_name); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Instead of using argv[0] on Windows, use the actual binary name. This is // necessary because if originally the test isn't run with ".exe" on the // command line, then argv[0] also won't include ".exe". This argument is used diff --git a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.h b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.h index a03f8c1ade..3be9b7a250 100644 --- a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.h +++ b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec.h @@ -141,11 +141,11 @@ class MultiprocessExec : public Multiprocess { base::FilePath command_; std::vector arguments_; -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) std::vector argv_; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) std::wstring command_line_; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) }; } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_posix.cc b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_posix.cc index e14a3b88ad..fa87f08887 100644 --- a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_posix.cc @@ -26,11 +26,11 @@ #include "util/misc/scoped_forbid_return.h" #include "util/posix/close_multiple.h" -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include #endif -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include "util/mach/task_for_pid.h" #endif @@ -90,7 +90,7 @@ void MultiprocessExec::MultiprocessChild() { int rv; -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) __fpurge(stdin); #else rv = fpurge(stdin); @@ -154,7 +154,7 @@ void MultiprocessExec::MultiprocessChild() { } ProcessType MultiprocessExec::ChildProcess() { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) return TaskForPID(ChildPID()); #else return ChildPID(); diff --git a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test.cc b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test.cc index fb77d642fb..8d8f1e2010 100644 --- a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test.cc +++ b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test.cc @@ -101,7 +101,7 @@ TEST(MultiprocessExec, MultiprocessExecSimpleChildReturnsNonZero) { exec.Run(); } -#if !defined(OS_WIN) +#if !BUILDFLAG(IS_WIN) CRASHPAD_CHILD_TEST_MAIN(BuiltinTrapChild) { __builtin_trap(); @@ -130,7 +130,7 @@ TEST(MultiprocessExec, BuiltinTrapTermination) { test.Run(); } -#endif // !OS_WIN +#endif // !BUILDFLAG(IS_WIN) } // namespace } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test_child.cc b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test_child.cc index 8c77015c1b..f74b585606 100644 --- a/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test_child.cc +++ b/thirdparty/sentry-native/external/crashpad/test/multiprocess_exec_test_child.cc @@ -22,19 +22,19 @@ #include "base/logging.h" #include "build/build_config.h" -#if defined(OS_POSIX) -#if !defined(OS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) +#if !BUILDFLAG(IS_FUCHSIA) #include -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #endif int main(int argc, char* argv[]) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) // getrlimit() is not implemented on Fuchsia. By construction, the child only // receieves specific fds that it's given, but check low values as mild // verification. @@ -45,7 +45,7 @@ int main(int argc, char* argv[]) { LOG(FATAL) << "getrlimit"; } int last_fd = static_cast(rlimit_nofile.rlim_cur); -#endif // OS_FUCHSIA +#endif // BUILDFLAG(IS_FUCHSIA) // Make sure that there’s nothing open at any FD higher than 3. All FDs other // than stdin, stdout, and stderr should have been closed prior to or at @@ -69,7 +69,7 @@ int main(int argc, char* argv[]) { if (rv != 1) { LOG(FATAL) << "write"; } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) // TODO(scottmg): Verify that only the handles we expect to be open, are. // Read a byte from stdin, expecting it to be a specific value. @@ -89,7 +89,7 @@ int main(int argc, char* argv[]) { bytes_written != 1) { LOG(FATAL) << "WriteFile"; } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) return 0; } diff --git a/thirdparty/sentry-native/external/crashpad/test/multiprocess_posix.cc b/thirdparty/sentry-native/external/crashpad/test/multiprocess_posix.cc index c16aa08f7b..f1b138f6cc 100644 --- a/thirdparty/sentry-native/external/crashpad/test/multiprocess_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/test/multiprocess_posix.cc @@ -33,7 +33,7 @@ #include "util/misc/scoped_forbid_return.h" #include "util/posix/signals.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include "test/mac/exception_swallower.h" #endif @@ -73,7 +73,7 @@ void Multiprocess::Run() { ASSERT_NO_FATAL_FAILURE(PreFork()); -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) // If the child is expected to crash, set up an exception swallower to swallow // the exception instead of allowing it to be seen by the system’s crash // reporter. @@ -81,7 +81,7 @@ void Multiprocess::Run() { if (reason_ == kTerminationSignal && Signals::IsCrashSignal(code_)) { exception_swallower.reset(new ExceptionSwallower()); } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) pid_t pid = fork(); ASSERT_GE(pid, 0) << ErrnoMessage("fork"); @@ -139,15 +139,15 @@ void Multiprocess::Run() { ADD_FAILURE() << message; } } else { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) if (exception_swallower.get()) { ExceptionSwallower::SwallowExceptions(); } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) if (reason_ == kTerminationSignal && Signals::IsCrashSignal(code_)) { Signals::InstallDefaultHandler(code_); } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) RunChild(); } diff --git a/thirdparty/sentry-native/external/crashpad/test/process_type.cc b/thirdparty/sentry-native/external/crashpad/test/process_type.cc index f6eec36ab1..7c6f88fa9b 100644 --- a/thirdparty/sentry-native/external/crashpad/test/process_type.cc +++ b/thirdparty/sentry-native/external/crashpad/test/process_type.cc @@ -14,9 +14,11 @@ #include "test/process_type.h" -#if defined(OS_FUCHSIA) +#include "build/build_config.h" + +#if BUILDFLAG(IS_FUCHSIA) #include -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include #endif @@ -24,13 +26,13 @@ namespace crashpad { namespace test { ProcessType GetSelfProcess() { -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) return zx::process::self(); -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) return getpid(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return GetCurrentProcess(); -#elif defined(OS_APPLE) +#elif BUILDFLAG(IS_APPLE) return mach_task_self(); #endif } diff --git a/thirdparty/sentry-native/external/crashpad/test/process_type.h b/thirdparty/sentry-native/external/crashpad/test/process_type.h index cacac04fb0..a1c727cb0c 100644 --- a/thirdparty/sentry-native/external/crashpad/test/process_type.h +++ b/thirdparty/sentry-native/external/crashpad/test/process_type.h @@ -17,28 +17,28 @@ #include "build/build_config.h" -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) #include -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include -#elif defined(OS_APPLE) +#elif BUILDFLAG(IS_APPLE) #include #endif namespace crashpad { namespace test { -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) using ProcessType = zx::unowned_process; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ - DOXYGEN +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_ANDROID) || DOXYGEN //! \brief Alias for platform-specific type to represent a process. using ProcessType = pid_t; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) using ProcessType = HANDLE; -#elif defined(OS_APPLE) +#elif BUILDFLAG(IS_APPLE) using ProcessType = task_t; #else #error Port. diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.cc b/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.cc index df246fcf4c..ff8e0bd9c1 100644 --- a/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.cc +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.cc @@ -15,17 +15,18 @@ #include "test/scoped_module_handle.h" #include "base/logging.h" +#include "build/build_config.h" namespace crashpad { namespace test { // static void ScopedModuleHandle::Impl::Close(ModuleHandle handle) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) if (dlclose(handle) != 0) { LOG(ERROR) << "dlclose: " << dlerror(); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) if (!FreeLibrary(handle)) { PLOG(ERROR) << "FreeLibrary"; } diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.h b/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.h index 0e96c9510b..1a8ed1bf94 100644 --- a/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.h +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_module_handle.h @@ -17,9 +17,9 @@ #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #endif @@ -36,13 +36,13 @@ class ScopedModuleHandle { Impl(const Impl&) = delete; Impl& operator=(const Impl&) = delete; -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) using ModuleHandle = void*; static void* LookUpSymbol(ModuleHandle handle, const char* symbol_name) { return dlsym(handle, symbol_name); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) using ModuleHandle = HMODULE; static void* LookUpSymbol(ModuleHandle handle, const char* symbol_name) { diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name.h b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name.h new file mode 100644 index 0000000000..69998c03b9 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name.h @@ -0,0 +1,46 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_TEST_SCOPED_SET_THREAD_NAME_H_ +#define CRASHPAD_TEST_SCOPED_SET_THREAD_NAME_H_ + +#include + +#include "build/build_config.h" + +namespace crashpad { +namespace test { + +//! Sets the name of the current thread for the lifetime of this object. +class ScopedSetThreadName final { + public: + explicit ScopedSetThreadName(const std::string& new_thread_name); + + ScopedSetThreadName(const ScopedSetThreadName&) = delete; + ScopedSetThreadName& operator=(const ScopedSetThreadName&) = delete; + + ~ScopedSetThreadName(); + + private: +#if BUILDFLAG(IS_WIN) + const std::wstring original_name_; +#else + const std::string original_name_; +#endif +}; + +} // namespace test +} // namespace crashpad + +#endif // CRASHPAD_TEST_SCOPED_SET_THREAD_NAME_H_ diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_fuchsia.cc b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_fuchsia.cc new file mode 100644 index 0000000000..7b672d1513 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_fuchsia.cc @@ -0,0 +1,61 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test/scoped_set_thread_name.h" + +#include + +#include +#include +#include + +#include "base/check_op.h" +#include "base/fuchsia/fuchsia_logging.h" + +namespace crashpad { +namespace test { + +namespace { + +std::string GetCurrentThreadName() { + std::string result(ZX_MAX_NAME_LEN, '\0'); + const zx_status_t status = zx::thread::self()->get_property( + ZX_PROP_NAME, result.data(), result.length()); + ZX_CHECK(status == ZX_OK, status) << "get_property(ZX_PROP_NAME)"; + const auto result_nul_idx = result.find('\0'); + CHECK_NE(result_nul_idx, std::string::npos) + << "get_property() did not NUL terminate"; + result.resize(result_nul_idx); + return result; +} + +} // namespace + +ScopedSetThreadName::ScopedSetThreadName(const std::string& new_thread_name) + : original_name_(GetCurrentThreadName()) { + // Fuchsia silently truncates the thread name if it's too long. + CHECK_LT(new_thread_name.length(), ZX_MAX_NAME_LEN); + const zx_status_t status = zx::thread::self()->set_property( + ZX_PROP_NAME, new_thread_name.c_str(), new_thread_name.length()); + ZX_CHECK(status == ZX_OK, status) << "set_property(ZX_PROP_NAME)"; +} + +ScopedSetThreadName::~ScopedSetThreadName() { + const zx_status_t status = zx::thread::self()->set_property( + ZX_PROP_NAME, original_name_.c_str(), original_name_.length()); + ZX_CHECK(status == ZX_OK, status) << "set_property(ZX_PROP_NAME)"; +} + +} // namespace test +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_posix.cc b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_posix.cc new file mode 100644 index 0000000000..66146c066a --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_posix.cc @@ -0,0 +1,80 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test/scoped_set_thread_name.h" + +#include +#include + +#include + +#include "base/check.h" +#include "build/build_config.h" + +#if BUILDFLAG(IS_APPLE) +#include +#endif + +namespace crashpad { +namespace test { + +namespace { + +#if BUILDFLAG(IS_LINUX) +// The kernel headers define this in linux/sched.h as TASK_COMM_LEN, but the +// userspace copy of that header does not define it. +constexpr size_t kPthreadNameMaxLen = 16; +#elif BUILDFLAG(IS_APPLE) +constexpr size_t kPthreadNameMaxLen = MAXTHREADNAMESIZE; +#else +#error Port to your platform +#endif + +void SetCurrentThreadName(const std::string& thread_name) { +#if BUILDFLAG(IS_LINUX) + PCHECK((errno = pthread_setname_np(pthread_self(), thread_name.c_str())) == 0) + << "pthread_setname_np"; +#elif BUILDFLAG(IS_APPLE) + // Apple's pthread_setname_np() sets errno instead of returning it. + PCHECK(pthread_setname_np(thread_name.c_str()) == 0) << "pthread_setname_np"; +#else +#error Port to your platform +#endif +} + +std::string GetCurrentThreadName() { + std::string result(kPthreadNameMaxLen, '\0'); + PCHECK((errno = pthread_getname_np( + pthread_self(), result.data(), result.length())) == 0) + << "pthread_getname_np"; + const auto result_nul_idx = result.find('\0'); + CHECK(result_nul_idx != std::string::npos) + << "pthread_getname_np did not NUL terminate"; + result.resize(result_nul_idx); + return result; +} + +} // namespace + +ScopedSetThreadName::ScopedSetThreadName(const std::string& new_thread_name) + : original_name_(GetCurrentThreadName()) { + SetCurrentThreadName(new_thread_name); +} + +ScopedSetThreadName::~ScopedSetThreadName() { + SetCurrentThreadName(original_name_); +} + +} // namespace test +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_win.cc b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_win.cc new file mode 100644 index 0000000000..482d3c12e5 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_set_thread_name_win.cc @@ -0,0 +1,56 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "test/scoped_set_thread_name.h" + +#include + +#include "base/check.h" +#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" +#include "util/win/scoped_local_alloc.h" + +namespace crashpad { +namespace test { + +namespace { + +std::wstring GetCurrentThreadName() { + wchar_t* thread_description; + HRESULT hr = GetThreadDescription(GetCurrentThread(), &thread_description); + CHECK(SUCCEEDED(hr)) << "GetThreadDescription: " + << logging::SystemErrorCodeToString(hr); + ScopedLocalAlloc thread_description_owner(thread_description); + return std::wstring(thread_description); +} + +} // namespace + +ScopedSetThreadName::ScopedSetThreadName(const std::string& new_thread_name) + : original_name_(GetCurrentThreadName()) { + const std::wstring wnew_thread_name = base::UTF8ToWide(new_thread_name); + HRESULT hr = + SetThreadDescription(GetCurrentThread(), wnew_thread_name.c_str()); + CHECK(SUCCEEDED(hr)) << "SetThreadDescription: " + << logging::SystemErrorCodeToString(hr); +} + +ScopedSetThreadName::~ScopedSetThreadName() { + HRESULT hr = SetThreadDescription(GetCurrentThread(), original_name_.c_str()); + CHECK(SUCCEEDED(hr)) << "SetThreadDescription: " + << logging::SystemErrorCodeToString(hr); +} + +} // namespace test +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_posix.cc b/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_posix.cc index 38aa4fb84f..848ab5692a 100644 --- a/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_posix.cc @@ -42,7 +42,7 @@ base::FilePath ScopedTempDir::CreateTemporaryDirectory() { if (tmpdir && tmpdir[0] != '\0') { dir.assign(tmpdir); } else { -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) dir.assign("/data/local/tmp"); #else dir.assign("/tmp"); diff --git a/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_test.cc b/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_test.cc index 9ad801f7f0..3b5a31642c 100644 --- a/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_test.cc +++ b/thirdparty/sentry-native/external/crashpad/test/scoped_temp_dir_test.cc @@ -23,26 +23,26 @@ #include "test/errors.h" #include "test/file.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) namespace crashpad { namespace test { namespace { void CreateFile(const base::FilePath& path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int fd = HANDLE_EINTR(creat(path.value().c_str(), 0644)); ASSERT_GE(fd, 0) << ErrnoMessage("creat") << " " << path.value(); // gcc refuses to compile ASSERT_EQ(IGNORE_EINTR(close(fd)), 0). int close_rv = IGNORE_EINTR(close(fd)); ASSERT_EQ(close_rv, 0) << ErrnoMessage("close") << " " << path.value(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) int fd = _wcreat(path.value().c_str(), _S_IREAD | _S_IWRITE); ASSERT_GE(fd, 0) << ErrnoMessage("_wcreat") << " " << path.value(); ASSERT_EQ(_close(fd), 0) << ErrnoMessage("_close") << " " << path.value(); @@ -53,10 +53,10 @@ void CreateFile(const base::FilePath& path) { } void CreateDirectory(const base::FilePath& path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) ASSERT_EQ(mkdir(path.value().c_str(), 0755), 0) << ErrnoMessage("mkdir") << " " << path.value(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) ASSERT_EQ(_wmkdir(path.value().c_str()), 0) << ErrnoMessage("_wmkdir") << " " << path.value(); #else diff --git a/thirdparty/sentry-native/external/crashpad/test/test_paths.cc b/thirdparty/sentry-native/external/crashpad/test/test_paths.cc index 475e2b0193..c55aa647bf 100644 --- a/thirdparty/sentry-native/external/crashpad/test/test_paths.cc +++ b/thirdparty/sentry-native/external/crashpad/test/test_paths.cc @@ -31,7 +31,7 @@ bool IsTestDataRoot(const base::FilePath& candidate) { candidate.Append(FILE_PATH_LITERAL("test")) .Append(FILE_PATH_LITERAL("test_paths_test_data_root.txt")); -#if !defined(OS_WIN) +#if !BUILDFLAG(IS_WIN) struct stat stat_buf; int rv = stat(marker_path.value().c_str(), &stat_buf); #else @@ -43,16 +43,16 @@ bool IsTestDataRoot(const base::FilePath& candidate) { } base::FilePath TestDataRootInternal() { -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) base::FilePath asset_path("/pkg/data"); if (!IsTestDataRoot(asset_path)) { LOG(WARNING) << "test data root seems invalid, continuing anyway"; } return asset_path; -#else // defined(OS_FUCHSIA) -#if !defined(OS_WIN) +#else // BUILDFLAG(IS_FUCHSIA) +#if !BUILDFLAG(IS_WIN) const char* environment_value = getenv("CRASHPAD_TEST_DATA_ROOT"); -#else // defined(OS_WIN) +#else // BUILDFLAG(IS_WIN) const wchar_t* environment_value = _wgetenv(L"CRASHPAD_TEST_DATA_ROOT"); #endif @@ -67,21 +67,21 @@ base::FilePath TestDataRootInternal() { base::FilePath executable_path; if (Paths::Executable(&executable_path)) { -#if defined(OS_IOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) // On Android and iOS, test data is in a crashpad_test_data directory // adjacent to the main executable. On iOS, this refers to the main // executable file inside the .app bundle, so crashpad_test_data is also // inside the bundle. base::FilePath candidate = executable_path.DirName() .Append("crashpad_test_data"); -#else // OS_IOS || OS_ANDRID +#else // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDRID) // In a standalone build, the test executable is usually at // out/{Debug,Release} relative to the Crashpad root. base::FilePath candidate = base::FilePath(executable_path.DirName() .Append(base::FilePath::kParentDirectory) .Append(base::FilePath::kParentDirectory)); -#endif // OS_IOS || OS_ANDROID +#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) if (IsTestDataRoot(candidate)) { return candidate; } @@ -104,10 +104,10 @@ base::FilePath TestDataRootInternal() { } return base::FilePath(base::FilePath::kCurrentDirectory); -#endif // defined(OS_FUCHSIA) +#endif // BUILDFLAG(IS_FUCHSIA) } -#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) +#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS) // Returns the pathname of a directory containing 32-bit test build output. // @@ -122,7 +122,7 @@ base::FilePath Output32BitDirectory() { return base::FilePath(environment_value); } -#endif // defined(OS_WIN) && defined(ARCH_CPU_64_BITS) +#endif // BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS) } // namespace @@ -139,10 +139,10 @@ base::FilePath TestPaths::Executable() { // static base::FilePath TestPaths::ExpectedExecutableBasename( const base::FilePath::StringType& name) { -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) // Apps in Fuchsia packages are always named "app". return base::FilePath("app"); -#else // OS_FUCHSIA +#else // BUILDFLAG(IS_FUCHSIA) #if defined(CRASHPAD_IS_IN_CHROMIUM) base::FilePath::StringType executable_name( FILE_PATH_LITERAL("crashpad_tests")); @@ -150,12 +150,12 @@ base::FilePath TestPaths::ExpectedExecutableBasename( base::FilePath::StringType executable_name(name); #endif // CRASHPAD_IS_IN_CHROMIUM -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) executable_name += FILE_PATH_LITERAL(".exe"); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) return base::FilePath(executable_name); -#endif // OS_FUCHSIA +#endif // BUILDFLAG(IS_FUCHSIA) } // static @@ -177,17 +177,17 @@ base::FilePath TestPaths::BuildArtifact( directory = Executable().DirName(); break; -#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) +#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS) case Architecture::k32Bit: directory = Output32BitDirectory(); CHECK(!directory.empty()); break; -#endif // OS_WIN && ARCH_CPU_64_BITS +#endif // BUILDFLAG(IS_WIN) && ARCH_CPU_64_BITS } base::FilePath::StringType test_name = FILE_PATH_LITERAL("crashpad_") + module + FILE_PATH_LITERAL("_test"); -#if !defined(CRASHPAD_IS_IN_CHROMIUM) && !defined(OS_FUCHSIA) +#if !defined(CRASHPAD_IS_IN_CHROMIUM) && !BUILDFLAG(IS_FUCHSIA) CHECK(Executable().BaseName().RemoveFinalExtension().value() == test_name); #endif // !CRASHPAD_IS_IN_CHROMIUM @@ -197,21 +197,21 @@ base::FilePath TestPaths::BuildArtifact( break; case FileType::kExecutable: -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) extension = FILE_PATH_LITERAL(".exe"); -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) directory = base::FilePath(FILE_PATH_LITERAL("/pkg/bin")); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) break; case FileType::kLoadableModule: -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) extension = FILE_PATH_LITERAL(".dll"); -#else // OS_WIN +#else // BUILDFLAG(IS_WIN) extension = FILE_PATH_LITERAL(".so"); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) // TODO(scottmg): .so files are currently deployed into /boot/lib, where // they'll be found (without a path) by the loader. Application packaging // infrastructure is in progress, so this will likely change again in the @@ -232,14 +232,14 @@ base::FilePath TestPaths::BuildArtifact( extension); } -#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) +#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS) // static bool TestPaths::Has32BitBuildArtifacts() { return !Output32BitDirectory().empty(); } -#endif // defined(OS_WIN) && defined(ARCH_CPU_64_BITS) +#endif // BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS) } // namespace test } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/test/test_paths.h b/thirdparty/sentry-native/external/crashpad/test/test_paths.h index 72bb155392..0fc021e139 100644 --- a/thirdparty/sentry-native/external/crashpad/test/test_paths.h +++ b/thirdparty/sentry-native/external/crashpad/test/test_paths.h @@ -49,14 +49,14 @@ class TestPaths { //! architecture as the running process. kDefault = 0, -#if (defined(OS_WIN) && defined(ARCH_CPU_64_BITS)) || DOXYGEN +#if (BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)) || DOXYGEN //! \brief The 32-bit variant is requested. //! //! On Windows, when running 64-bit code, the 32-bit variant can be //! requested. Before doing so, Has32BitBuildArtifacts() must be called and //! must return `true`. Otherwise, execution will be aborted. k32Bit, -#endif // OS_WIN && ARCH_CPU_64_BITS +#endif // BUILDFLAG(IS_WIN) && ARCH_CPU_64_BITS }; TestPaths() = delete; @@ -128,7 +128,7 @@ class TestPaths { FileType file_type, Architecture architecture = Architecture::kDefault); -#if (defined(OS_WIN) && defined(ARCH_CPU_64_BITS)) || DOXYGEN +#if (BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)) || DOXYGEN //! \return `true` if 32-bit build artifacts are available. //! //! Tests that require the use of 32-bit build output should call this @@ -142,7 +142,7 @@ class TestPaths { //! can be found its own directory, and located by calling BuildArtifact() //! with Architecture::kDefault. static bool Has32BitBuildArtifacts(); -#endif // OS_WIN && ARCH_CPU_64_BITS +#endif // BUILDFLAG(IS_WIN) && ARCH_CPU_64_BITS }; } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/third_party/edo/BUILD.gn b/thirdparty/sentry-native/external/crashpad/third_party/edo/BUILD.gn index 73dca1aab4..ea6e9d38b4 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/edo/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/third_party/edo/BUILD.gn @@ -7,9 +7,7 @@ import("../../build/crashpad_buildconfig.gni") if (crashpad_is_in_chromium) { group("edo") { testonly = true - public_deps = [ - "//ios/third_party/edo", - ] + public_deps = [ "//ios/third_party/edo" ] } } else { config("config") { @@ -103,6 +101,8 @@ if (crashpad_is_in_chromium) { "edo/Service/Sources/EDORemoteException.m", "edo/Service/Sources/EDORemoteVariable.h", "edo/Service/Sources/EDORemoteVariable.m", + "edo/Service/Sources/EDORuntimeUtils.h", + "edo/Service/Sources/EDORuntimeUtils.m", "edo/Service/Sources/EDOServiceError.h", "edo/Service/Sources/EDOServiceError.m", "edo/Service/Sources/EDOServiceException.h", @@ -139,8 +139,6 @@ if (crashpad_is_in_chromium) { ] public_configs = [ ":config" ] - deps = [ - "../../build:ios_enable_arc", - ] + deps = [ "../../build:ios_enable_arc" ] } } diff --git a/thirdparty/sentry-native/external/crashpad/third_party/glibc/BUILD.gn b/thirdparty/sentry-native/external/crashpad/third_party/glibc/BUILD.gn deleted file mode 100644 index 3f2b08bc0d..0000000000 --- a/thirdparty/sentry-native/external/crashpad/third_party/glibc/BUILD.gn +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2019 The Crashpad Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -source_set("glibc") { - sources = [ "elf/elf.h" ] -} diff --git a/thirdparty/sentry-native/external/crashpad/third_party/glibc/COPYING.LIB b/thirdparty/sentry-native/external/crashpad/third_party/glibc/COPYING.LIB deleted file mode 100644 index 4362b49151..0000000000 --- a/thirdparty/sentry-native/external/crashpad/third_party/glibc/COPYING.LIB +++ /dev/null @@ -1,502 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/thirdparty/sentry-native/external/crashpad/third_party/glibc/README.crashpad b/thirdparty/sentry-native/external/crashpad/third_party/glibc/README.crashpad deleted file mode 100644 index b550ad98a7..0000000000 --- a/thirdparty/sentry-native/external/crashpad/third_party/glibc/README.crashpad +++ /dev/null @@ -1,16 +0,0 @@ -Name: GNU C Library -Short Name: glibc -URL: https://www.gnu.org/software/libc/ -URL: https://sourceware.org/git/?p=glibc.git -Version: 2.29 -License: GNU LGPL 2.1 -License File: COPYING.LIB -Security Critical: no - -Description: -glibc is the GNU Project’s implementation of the C standard library. - -Local Modifications: - - Only elf/elf.h is included. Its #include of has been removed, - and it uses of __BEGIN_DECLS and __END_DECLS have been replaced with inline - versions in the manner that misc/sys/cdefs.h defines those macros. diff --git a/thirdparty/sentry-native/external/crashpad/third_party/glibc/elf/elf.h b/thirdparty/sentry-native/external/crashpad/third_party/glibc/elf/elf.h deleted file mode 100644 index 331536b497..0000000000 --- a/thirdparty/sentry-native/external/crashpad/third_party/glibc/elf/elf.h +++ /dev/null @@ -1,4003 +0,0 @@ -/* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-2019 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _ELF_H -#define _ELF_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Standard ELF types. */ - -#include - -/* Type for a 16-bit quantity. */ -typedef uint16_t Elf32_Half; -typedef uint16_t Elf64_Half; - -/* Types for signed and unsigned 32-bit quantities. */ -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; - -/* Types for signed and unsigned 64-bit quantities. */ -typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; - -/* Type of addresses. */ -typedef uint32_t Elf32_Addr; -typedef uint64_t Elf64_Addr; - -/* Type of file offsets. */ -typedef uint32_t Elf32_Off; -typedef uint64_t Elf64_Off; - -/* Type for section indices, which are 16-bit quantities. */ -typedef uint16_t Elf32_Section; -typedef uint16_t Elf64_Section; - -/* Type for version symbol information. */ -typedef Elf32_Half Elf32_Versym; -typedef Elf64_Half Elf64_Versym; - - -/* The ELF file header. This appears at the start of every ELF file. */ - -#define EI_NIDENT (16) - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ -} Elf32_Ehdr; - -typedef struct -{ - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf64_Half e_type; /* Object file type */ - Elf64_Half e_machine; /* Architecture */ - Elf64_Word e_version; /* Object file version */ - Elf64_Addr e_entry; /* Entry point virtual address */ - Elf64_Off e_phoff; /* Program header table file offset */ - Elf64_Off e_shoff; /* Section header table file offset */ - Elf64_Word e_flags; /* Processor-specific flags */ - Elf64_Half e_ehsize; /* ELF header size in bytes */ - Elf64_Half e_phentsize; /* Program header table entry size */ - Elf64_Half e_phnum; /* Program header table entry count */ - Elf64_Half e_shentsize; /* Section header table entry size */ - Elf64_Half e_shnum; /* Section header table entry count */ - Elf64_Half e_shstrndx; /* Section header string table index */ -} Elf64_Ehdr; - -/* Fields in the e_ident array. The EI_* macros are indices into the - array. The macros under each EI_* macro are the values the byte - may have. */ - -#define EI_MAG0 0 /* File identification byte 0 index */ -#define ELFMAG0 0x7f /* Magic number byte 0 */ - -#define EI_MAG1 1 /* File identification byte 1 index */ -#define ELFMAG1 'E' /* Magic number byte 1 */ - -#define EI_MAG2 2 /* File identification byte 2 index */ -#define ELFMAG2 'L' /* Magic number byte 2 */ - -#define EI_MAG3 3 /* File identification byte 3 index */ -#define ELFMAG3 'F' /* Magic number byte 3 */ - -/* Conglomeration of the identification bytes, for easy testing as a word. */ -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASSNONE 0 /* Invalid class */ -#define ELFCLASS32 1 /* 32-bit objects */ -#define ELFCLASS64 2 /* 64-bit objects */ -#define ELFCLASSNUM 3 - -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATANONE 0 /* Invalid data encoding */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ -#define ELFDATANUM 3 - -#define EI_VERSION 6 /* File version byte index */ - /* Value must be EV_CURRENT */ - -#define EI_OSABI 7 /* OS ABI identification */ -#define ELFOSABI_NONE 0 /* UNIX System V ABI */ -#define ELFOSABI_SYSV 0 /* Alias. */ -#define ELFOSABI_HPUX 1 /* HP-UX */ -#define ELFOSABI_NETBSD 2 /* NetBSD. */ -#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ -#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ -#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ -#define ELFOSABI_AIX 7 /* IBM AIX. */ -#define ELFOSABI_IRIX 8 /* SGI Irix. */ -#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ -#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ -#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ -#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ -#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ -#define ELFOSABI_ARM 97 /* ARM */ -#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ - -#define EI_ABIVERSION 8 /* ABI version */ - -#define EI_PAD 9 /* Byte index of padding bytes */ - -/* Legal values for e_type (object file type). */ - -#define ET_NONE 0 /* No file type */ -#define ET_REL 1 /* Relocatable file */ -#define ET_EXEC 2 /* Executable file */ -#define ET_DYN 3 /* Shared object file */ -#define ET_CORE 4 /* Core file */ -#define ET_NUM 5 /* Number of defined types */ -#define ET_LOOS 0xfe00 /* OS-specific range start */ -#define ET_HIOS 0xfeff /* OS-specific range end */ -#define ET_LOPROC 0xff00 /* Processor-specific range start */ -#define ET_HIPROC 0xffff /* Processor-specific range end */ - -/* Legal values for e_machine (architecture). */ - -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 /* AT&T WE 32100 */ -#define EM_SPARC 2 /* SUN SPARC */ -#define EM_386 3 /* Intel 80386 */ -#define EM_68K 4 /* Motorola m68k family */ -#define EM_88K 5 /* Motorola m88k family */ -#define EM_IAMCU 6 /* Intel MCU */ -#define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS R3000 big-endian */ -#define EM_S370 9 /* IBM System/370 */ -#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ - /* reserved 11-14 */ -#define EM_PARISC 15 /* HPPA */ - /* reserved 16 */ -#define EM_VPP500 17 /* Fujitsu VPP500 */ -#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -#define EM_960 19 /* Intel 80960 */ -#define EM_PPC 20 /* PowerPC */ -#define EM_PPC64 21 /* PowerPC 64-bit */ -#define EM_S390 22 /* IBM S390 */ -#define EM_SPU 23 /* IBM SPU/SPC */ - /* reserved 24-35 */ -#define EM_V800 36 /* NEC V800 series */ -#define EM_FR20 37 /* Fujitsu FR20 */ -#define EM_RH32 38 /* TRW RH-32 */ -#define EM_RCE 39 /* Motorola RCE */ -#define EM_ARM 40 /* ARM */ -#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -#define EM_SH 42 /* Hitachi SH */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_TRICORE 44 /* Siemens Tricore */ -#define EM_ARC 45 /* Argonaut RISC Core */ -#define EM_H8_300 46 /* Hitachi H8/300 */ -#define EM_H8_300H 47 /* Hitachi H8/300H */ -#define EM_H8S 48 /* Hitachi H8S */ -#define EM_H8_500 49 /* Hitachi H8/500 */ -#define EM_IA_64 50 /* Intel Merced */ -#define EM_MIPS_X 51 /* Stanford MIPS-X */ -#define EM_COLDFIRE 52 /* Motorola Coldfire */ -#define EM_68HC12 53 /* Motorola M68HC12 */ -#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */ -#define EM_PCP 55 /* Siemens PCP */ -#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -#define EM_STARCORE 58 /* Motorola Start*Core processor */ -#define EM_ME16 59 /* Toyota ME16 processor */ -#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam */ -#define EM_X86_64 62 /* AMD x86-64 architecture */ -#define EM_PDSP 63 /* Sony DSP Processor */ -#define EM_PDP10 64 /* Digital PDP-10 */ -#define EM_PDP11 65 /* Digital PDP-11 */ -#define EM_FX66 66 /* Siemens FX66 microcontroller */ -#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -#define EM_SVX 73 /* Silicon Graphics SVx */ -#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -#define EM_VAX 75 /* Digital VAX */ -#define EM_CRIS 76 /* Axis Communications 32-bit emb.proc */ -#define EM_JAVELIN 77 /* Infineon Technologies 32-bit emb.proc */ -#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc */ -#define EM_HUANY 81 /* Harvard University machine-independent object files */ -#define EM_PRISM 82 /* SiTera Prism */ -#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -#define EM_FR30 84 /* Fujitsu FR30 */ -#define EM_D10V 85 /* Mitsubishi D10V */ -#define EM_D30V 86 /* Mitsubishi D30V */ -#define EM_V850 87 /* NEC v850 */ -#define EM_M32R 88 /* Mitsubishi M32R */ -#define EM_MN10300 89 /* Matsushita MN10300 */ -#define EM_MN10200 90 /* Matsushita MN10200 */ -#define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -#define EM_ARC_COMPACT 93 /* ARC International ARCompact */ -#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore */ -#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Proc */ -#define EM_NS32K 97 /* National Semi. 32000 */ -#define EM_TPC 98 /* Tenor Network TPC */ -#define EM_SNP1K 99 /* Trebia SNP 1000 */ -#define EM_ST200 100 /* STMicroelectronics ST200 */ -#define EM_IP2K 101 /* Ubicom IP2xxx */ -#define EM_MAX 102 /* MAX processor */ -#define EM_CR 103 /* National Semi. CompactRISC */ -#define EM_F2MC16 104 /* Fujitsu F2MC16 */ -#define EM_MSP430 105 /* Texas Instruments msp430 */ -#define EM_BLACKFIN 106 /* Analog Devices Blackfin DSP */ -#define EM_SE_C33 107 /* Seiko Epson S1C33 family */ -#define EM_SEP 108 /* Sharp embedded microprocessor */ -#define EM_ARCA 109 /* Arca RISC */ -#define EM_UNICORE 110 /* PKU-Unity & MPRC Peking Uni. mc series */ -#define EM_EXCESS 111 /* eXcess configurable cpu */ -#define EM_DXP 112 /* Icera Semi. Deep Execution Processor */ -#define EM_ALTERA_NIOS2 113 /* Altera Nios II */ -#define EM_CRX 114 /* National Semi. CompactRISC CRX */ -#define EM_XGATE 115 /* Motorola XGATE */ -#define EM_C166 116 /* Infineon C16x/XC16x */ -#define EM_M16C 117 /* Renesas M16C */ -#define EM_DSPIC30F 118 /* Microchip Technology dsPIC30F */ -#define EM_CE 119 /* Freescale Communication Engine RISC */ -#define EM_M32C 120 /* Renesas M32C */ - /* reserved 121-130 */ -#define EM_TSK3000 131 /* Altium TSK3000 */ -#define EM_RS08 132 /* Freescale RS08 */ -#define EM_SHARC 133 /* Analog Devices SHARC family */ -#define EM_ECOG2 134 /* Cyan Technology eCOG2 */ -#define EM_SCORE7 135 /* Sunplus S+core7 RISC */ -#define EM_DSP24 136 /* New Japan Radio (NJR) 24-bit DSP */ -#define EM_VIDEOCORE3 137 /* Broadcom VideoCore III */ -#define EM_LATTICEMICO32 138 /* RISC for Lattice FPGA */ -#define EM_SE_C17 139 /* Seiko Epson C17 */ -#define EM_TI_C6000 140 /* Texas Instruments TMS320C6000 DSP */ -#define EM_TI_C2000 141 /* Texas Instruments TMS320C2000 DSP */ -#define EM_TI_C5500 142 /* Texas Instruments TMS320C55x DSP */ -#define EM_TI_ARP32 143 /* Texas Instruments App. Specific RISC */ -#define EM_TI_PRU 144 /* Texas Instruments Prog. Realtime Unit */ - /* reserved 145-159 */ -#define EM_MMDSP_PLUS 160 /* STMicroelectronics 64bit VLIW DSP */ -#define EM_CYPRESS_M8C 161 /* Cypress M8C */ -#define EM_R32C 162 /* Renesas R32C */ -#define EM_TRIMEDIA 163 /* NXP Semi. TriMedia */ -#define EM_QDSP6 164 /* QUALCOMM DSP6 */ -#define EM_8051 165 /* Intel 8051 and variants */ -#define EM_STXP7X 166 /* STMicroelectronics STxP7x */ -#define EM_NDS32 167 /* Andes Tech. compact code emb. RISC */ -#define EM_ECOG1X 168 /* Cyan Technology eCOG1X */ -#define EM_MAXQ30 169 /* Dallas Semi. MAXQ30 mc */ -#define EM_XIMO16 170 /* New Japan Radio (NJR) 16-bit DSP */ -#define EM_MANIK 171 /* M2000 Reconfigurable RISC */ -#define EM_CRAYNV2 172 /* Cray NV2 vector architecture */ -#define EM_RX 173 /* Renesas RX */ -#define EM_METAG 174 /* Imagination Tech. META */ -#define EM_MCST_ELBRUS 175 /* MCST Elbrus */ -#define EM_ECOG16 176 /* Cyan Technology eCOG16 */ -#define EM_CR16 177 /* National Semi. CompactRISC CR16 */ -#define EM_ETPU 178 /* Freescale Extended Time Processing Unit */ -#define EM_SLE9X 179 /* Infineon Tech. SLE9X */ -#define EM_L10M 180 /* Intel L10M */ -#define EM_K10M 181 /* Intel K10M */ - /* reserved 182 */ -#define EM_AARCH64 183 /* ARM AARCH64 */ - /* reserved 184 */ -#define EM_AVR32 185 /* Amtel 32-bit microprocessor */ -#define EM_STM8 186 /* STMicroelectronics STM8 */ -#define EM_TILE64 187 /* Tileta TILE64 */ -#define EM_TILEPRO 188 /* Tilera TILEPro */ -#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ -#define EM_CUDA 190 /* NVIDIA CUDA */ -#define EM_TILEGX 191 /* Tilera TILE-Gx */ -#define EM_CLOUDSHIELD 192 /* CloudShield */ -#define EM_COREA_1ST 193 /* KIPO-KAIST Core-A 1st gen. */ -#define EM_COREA_2ND 194 /* KIPO-KAIST Core-A 2nd gen. */ -#define EM_ARC_COMPACT2 195 /* Synopsys ARCompact V2 */ -#define EM_OPEN8 196 /* Open8 RISC */ -#define EM_RL78 197 /* Renesas RL78 */ -#define EM_VIDEOCORE5 198 /* Broadcom VideoCore V */ -#define EM_78KOR 199 /* Renesas 78KOR */ -#define EM_56800EX 200 /* Freescale 56800EX DSC */ -#define EM_BA1 201 /* Beyond BA1 */ -#define EM_BA2 202 /* Beyond BA2 */ -#define EM_XCORE 203 /* XMOS xCORE */ -#define EM_MCHP_PIC 204 /* Microchip 8-bit PIC(r) */ - /* reserved 205-209 */ -#define EM_KM32 210 /* KM211 KM32 */ -#define EM_KMX32 211 /* KM211 KMX32 */ -#define EM_EMX16 212 /* KM211 KMX16 */ -#define EM_EMX8 213 /* KM211 KMX8 */ -#define EM_KVARC 214 /* KM211 KVARC */ -#define EM_CDP 215 /* Paneve CDP */ -#define EM_COGE 216 /* Cognitive Smart Memory Processor */ -#define EM_COOL 217 /* Bluechip CoolEngine */ -#define EM_NORC 218 /* Nanoradio Optimized RISC */ -#define EM_CSR_KALIMBA 219 /* CSR Kalimba */ -#define EM_Z80 220 /* Zilog Z80 */ -#define EM_VISIUM 221 /* Controls and Data Services VISIUMcore */ -#define EM_FT32 222 /* FTDI Chip FT32 */ -#define EM_MOXIE 223 /* Moxie processor */ -#define EM_AMDGPU 224 /* AMD GPU */ - /* reserved 225-242 */ -#define EM_RISCV 243 /* RISC-V */ - -#define EM_BPF 247 /* Linux BPF -- in-kernel virtual machine */ -#define EM_CSKY 252 /* C_SKY */ - -#define EM_NUM 253 - -/* Old spellings/synonyms. */ - -#define EM_ARC_A5 EM_ARC_COMPACT - -/* If it is necessary to assign new unofficial EM_* values, please - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the - chances of collision with official or non-GNU unofficial values. */ - -#define EM_ALPHA 0x9026 - -/* Legal values for e_version (version). */ - -#define EV_NONE 0 /* Invalid ELF version */ -#define EV_CURRENT 1 /* Current version */ -#define EV_NUM 2 - -/* Section header. */ - -typedef struct -{ - Elf32_Word sh_name; /* Section name (string tbl index) */ - Elf32_Word sh_type; /* Section type */ - Elf32_Word sh_flags; /* Section flags */ - Elf32_Addr sh_addr; /* Section virtual addr at execution */ - Elf32_Off sh_offset; /* Section file offset */ - Elf32_Word sh_size; /* Section size in bytes */ - Elf32_Word sh_link; /* Link to another section */ - Elf32_Word sh_info; /* Additional section information */ - Elf32_Word sh_addralign; /* Section alignment */ - Elf32_Word sh_entsize; /* Entry size if section holds table */ -} Elf32_Shdr; - -typedef struct -{ - Elf64_Word sh_name; /* Section name (string tbl index) */ - Elf64_Word sh_type; /* Section type */ - Elf64_Xword sh_flags; /* Section flags */ - Elf64_Addr sh_addr; /* Section virtual addr at execution */ - Elf64_Off sh_offset; /* Section file offset */ - Elf64_Xword sh_size; /* Section size in bytes */ - Elf64_Word sh_link; /* Link to another section */ - Elf64_Word sh_info; /* Additional section information */ - Elf64_Xword sh_addralign; /* Section alignment */ - Elf64_Xword sh_entsize; /* Entry size if section holds table */ -} Elf64_Shdr; - -/* Special section indices. */ - -#define SHN_UNDEF 0 /* Undefined section */ -#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ -#define SHN_LOPROC 0xff00 /* Start of processor-specific */ -#define SHN_BEFORE 0xff00 /* Order section before all others - (Solaris). */ -#define SHN_AFTER 0xff01 /* Order section after all others - (Solaris). */ -#define SHN_HIPROC 0xff1f /* End of processor-specific */ -#define SHN_LOOS 0xff20 /* Start of OS-specific */ -#define SHN_HIOS 0xff3f /* End of OS-specific */ -#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ -#define SHN_COMMON 0xfff2 /* Associated symbol is common */ -#define SHN_XINDEX 0xffff /* Index is in extra table. */ -#define SHN_HIRESERVE 0xffff /* End of reserved indices */ - -/* Legal values for sh_type (section type). */ - -#define SHT_NULL 0 /* Section header table entry unused */ -#define SHT_PROGBITS 1 /* Program data */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addends */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Dynamic linking information */ -#define SHT_NOTE 7 /* Notes */ -#define SHT_NOBITS 8 /* Program space with no data (bss) */ -#define SHT_REL 9 /* Relocation entries, no addends */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ -#define SHT_INIT_ARRAY 14 /* Array of constructors */ -#define SHT_FINI_ARRAY 15 /* Array of destructors */ -#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ -#define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -#define SHT_NUM 19 /* Number of defined types. */ -#define SHT_LOOS 0x60000000 /* Start OS-specific. */ -#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ -#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ -#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ -#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ -#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ -#define SHT_SUNW_move 0x6ffffffa -#define SHT_SUNW_COMDAT 0x6ffffffb -#define SHT_SUNW_syminfo 0x6ffffffc -#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ -#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ -#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ -#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ -#define SHT_HIOS 0x6fffffff /* End OS-specific type */ -#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ -#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ -#define SHT_LOUSER 0x80000000 /* Start of application-specific */ -#define SHT_HIUSER 0x8fffffff /* End of application-specific */ - -/* Legal values for sh_flags (section flags). */ - -#define SHF_WRITE (1 << 0) /* Writable */ -#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -#define SHF_EXECINSTR (1 << 2) /* Executable */ -#define SHF_MERGE (1 << 4) /* Might be merged */ -#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling - required */ -#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ -#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ -#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ -#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ -#define SHF_ORDERED (1 << 30) /* Special ordering requirement - (Solaris). */ -#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless - referenced or allocated (Solaris).*/ - -/* Section compression header. Used when SHF_COMPRESSED is set. */ - -typedef struct -{ - Elf32_Word ch_type; /* Compression format. */ - Elf32_Word ch_size; /* Uncompressed data size. */ - Elf32_Word ch_addralign; /* Uncompressed data alignment. */ -} Elf32_Chdr; - -typedef struct -{ - Elf64_Word ch_type; /* Compression format. */ - Elf64_Word ch_reserved; - Elf64_Xword ch_size; /* Uncompressed data size. */ - Elf64_Xword ch_addralign; /* Uncompressed data alignment. */ -} Elf64_Chdr; - -/* Legal values for ch_type (compression algorithm). */ -#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */ -#define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */ -#define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */ -#define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */ -#define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */ - -/* Section group handling. */ -#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ - -/* Symbol table entry. */ - -typedef struct -{ - Elf32_Word st_name; /* Symbol name (string tbl index) */ - Elf32_Addr st_value; /* Symbol value */ - Elf32_Word st_size; /* Symbol size */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - Elf32_Section st_shndx; /* Section index */ -} Elf32_Sym; - -typedef struct -{ - Elf64_Word st_name; /* Symbol name (string tbl index) */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - Elf64_Section st_shndx; /* Section index */ - Elf64_Addr st_value; /* Symbol value */ - Elf64_Xword st_size; /* Symbol size */ -} Elf64_Sym; - -/* The syminfo section if available contains additional information about - every dynamic symbol. */ - -typedef struct -{ - Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf32_Half si_flags; /* Per symbol flags */ -} Elf32_Syminfo; - -typedef struct -{ - Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ - Elf64_Half si_flags; /* Per symbol flags */ -} Elf64_Syminfo; - -/* Possible values for si_boundto. */ -#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ -#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ -#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ - -/* Possible bitmasks for si_flags. */ -#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ -#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ -#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy - loaded */ -/* Syminfo version values. */ -#define SYMINFO_NONE 0 -#define SYMINFO_CURRENT 1 -#define SYMINFO_NUM 2 - - -/* How to extract and insert information held in the st_info field. */ - -#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) -#define ELF32_ST_TYPE(val) ((val) & 0xf) -#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) - -/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ -#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) -#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) -#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) - -/* Legal values for ST_BIND subfield of st_info (symbol binding). */ - -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* Weak symbol */ -#define STB_NUM 3 /* Number of defined types. */ -#define STB_LOOS 10 /* Start of OS-specific */ -#define STB_GNU_UNIQUE 10 /* Unique symbol. */ -#define STB_HIOS 12 /* End of OS-specific */ -#define STB_LOPROC 13 /* Start of processor-specific */ -#define STB_HIPROC 15 /* End of processor-specific */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_NOTYPE 0 /* Symbol type is unspecified */ -#define STT_OBJECT 1 /* Symbol is a data object */ -#define STT_FUNC 2 /* Symbol is a code object */ -#define STT_SECTION 3 /* Symbol associated with a section */ -#define STT_FILE 4 /* Symbol's name is file name */ -#define STT_COMMON 5 /* Symbol is a common data object */ -#define STT_TLS 6 /* Symbol is thread-local data object*/ -#define STT_NUM 7 /* Number of defined types. */ -#define STT_LOOS 10 /* Start of OS-specific */ -#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ -#define STT_HIOS 12 /* End of OS-specific */ -#define STT_LOPROC 13 /* Start of processor-specific */ -#define STT_HIPROC 15 /* End of processor-specific */ - - -/* Symbol table indices are found in the hash buckets and chain table - of a symbol hash table section. This special index value indicates - the end of a chain, meaning no further symbols are found in that bucket. */ - -#define STN_UNDEF 0 /* End of a chain. */ - - -/* How to extract and insert information held in the st_other field. */ - -#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) - -/* For ELF64 the definitions are the same. */ -#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) - -/* Symbol visibility specification encoded in the st_other field. */ -#define STV_DEFAULT 0 /* Default symbol visibility rules */ -#define STV_INTERNAL 1 /* Processor specific hidden class */ -#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -#define STV_PROTECTED 3 /* Not preemptible, not exported */ - - -/* Relocation table entry without addend (in section of type SHT_REL). */ - -typedef struct -{ - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ -} Elf32_Rel; - -/* I have seen two different definitions of the Elf64_Rel and - Elf64_Rela structures, so we'll leave them out until Novell (or - whoever) gets their act together. */ -/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ - -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ -} Elf64_Rel; - -/* Relocation table entry with addend (in section of type SHT_RELA). */ - -typedef struct -{ - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ - Elf32_Sword r_addend; /* Addend */ -} Elf32_Rela; - -typedef struct -{ - Elf64_Addr r_offset; /* Address */ - Elf64_Xword r_info; /* Relocation type and symbol index */ - Elf64_Sxword r_addend; /* Addend */ -} Elf64_Rela; - -/* How to extract and insert information held in the r_info field. */ - -#define ELF32_R_SYM(val) ((val) >> 8) -#define ELF32_R_TYPE(val) ((val) & 0xff) -#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) - -#define ELF64_R_SYM(i) ((i) >> 32) -#define ELF64_R_TYPE(i) ((i) & 0xffffffff) -#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) - -/* Program segment header. */ - -typedef struct -{ - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Word p_filesz; /* Segment size in file */ - Elf32_Word p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Word p_align; /* Segment alignment */ -} Elf32_Phdr; - -typedef struct -{ - Elf64_Word p_type; /* Segment type */ - Elf64_Word p_flags; /* Segment flags */ - Elf64_Off p_offset; /* Segment file offset */ - Elf64_Addr p_vaddr; /* Segment virtual address */ - Elf64_Addr p_paddr; /* Segment physical address */ - Elf64_Xword p_filesz; /* Segment size in file */ - Elf64_Xword p_memsz; /* Segment size in memory */ - Elf64_Xword p_align; /* Segment alignment */ -} Elf64_Phdr; - -/* Special value for e_phnum. This indicates that the real number of - program headers is too large to fit into e_phnum. Instead the real - value is in the field sh_info of section 0. */ - -#define PN_XNUM 0xffff - -/* Legal values for p_type (segment type). */ - -#define PT_NULL 0 /* Program header table entry unused */ -#define PT_LOAD 1 /* Loadable program segment */ -#define PT_DYNAMIC 2 /* Dynamic linking information */ -#define PT_INTERP 3 /* Program interpreter */ -#define PT_NOTE 4 /* Auxiliary information */ -#define PT_SHLIB 5 /* Reserved */ -#define PT_PHDR 6 /* Entry for header table itself */ -#define PT_TLS 7 /* Thread-local storage segment */ -#define PT_NUM 8 /* Number of defined types */ -#define PT_LOOS 0x60000000 /* Start of OS-specific */ -#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ -#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ -#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ -#define PT_LOSUNW 0x6ffffffa -#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ -#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ -#define PT_HISUNW 0x6fffffff -#define PT_HIOS 0x6fffffff /* End of OS-specific */ -#define PT_LOPROC 0x70000000 /* Start of processor-specific */ -#define PT_HIPROC 0x7fffffff /* End of processor-specific */ - -/* Legal values for p_flags (segment flags). */ - -#define PF_X (1 << 0) /* Segment is executable */ -#define PF_W (1 << 1) /* Segment is writable */ -#define PF_R (1 << 2) /* Segment is readable */ -#define PF_MASKOS 0x0ff00000 /* OS-specific */ -#define PF_MASKPROC 0xf0000000 /* Processor-specific */ - -/* Legal values for note segment descriptor types for core files. */ - -#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ -#define NT_PRFPREG 2 /* Contains copy of fpregset - struct. */ -#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ -#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ -#define NT_PRXREG 4 /* Contains copy of prxregset struct */ -#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ -#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ -#define NT_AUXV 6 /* Contains copy of auxv array */ -#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ -#define NT_ASRS 8 /* Contains copy of asrset struct */ -#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ -#define NT_PSINFO 13 /* Contains copy of psinfo struct */ -#define NT_PRCRED 14 /* Contains copy of prcred struct */ -#define NT_UTSNAME 15 /* Contains copy of utsname struct */ -#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ -#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ -#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ -#define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t, - size might increase */ -#define NT_FILE 0x46494c45 /* Contains information about mapped - files */ -#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ -#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ -#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ -#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ -#define NT_PPC_TAR 0x103 /* Target Address Register */ -#define NT_PPC_PPR 0x104 /* Program Priority Register */ -#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */ -#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */ -#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */ -#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */ -#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */ -#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */ -#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */ -#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */ -#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address - Register */ -#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority - Register */ -#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control - Register */ -#define NT_PPC_PKEY 0x110 /* Memory Protection Keys - registers. */ -#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ -#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ -#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ -#define NT_S390_TIMER 0x301 /* s390 timer register */ -#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ -#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */ -#define NT_S390_CTRS 0x304 /* s390 control registers */ -#define NT_S390_PREFIX 0x305 /* s390 prefix register */ -#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ -#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ -#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */ -#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 - upper half. */ -#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31. */ -#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers. */ -#define NT_S390_GS_BC 0x30c /* s390 guarded storage - broadcast control block. */ -#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation. */ -#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ -#define NT_ARM_TLS 0x401 /* ARM TLS register */ -#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ -#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ -#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ -#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension - registers */ -#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */ -#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */ -#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */ - -/* Legal values for the note segment descriptor types for object files. */ - -#define NT_VERSION 1 /* Contains a version string. */ - - -/* Dynamic section entry. */ - -typedef struct -{ - Elf32_Sword d_tag; /* Dynamic entry type */ - union - { - Elf32_Word d_val; /* Integer value */ - Elf32_Addr d_ptr; /* Address value */ - } d_un; -} Elf32_Dyn; - -typedef struct -{ - Elf64_Sxword d_tag; /* Dynamic entry type */ - union - { - Elf64_Xword d_val; /* Integer value */ - Elf64_Addr d_ptr; /* Address value */ - } d_un; -} Elf64_Dyn; - -/* Legal values for d_tag (dynamic entry type). */ - -#define DT_NULL 0 /* Marks end of dynamic section */ -#define DT_NEEDED 1 /* Name of needed library */ -#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ -#define DT_PLTGOT 3 /* Processor defined value */ -#define DT_HASH 4 /* Address of symbol hash table */ -#define DT_STRTAB 5 /* Address of string table */ -#define DT_SYMTAB 6 /* Address of symbol table */ -#define DT_RELA 7 /* Address of Rela relocs */ -#define DT_RELASZ 8 /* Total size of Rela relocs */ -#define DT_RELAENT 9 /* Size of one Rela reloc */ -#define DT_STRSZ 10 /* Size of string table */ -#define DT_SYMENT 11 /* Size of one symbol table entry */ -#define DT_INIT 12 /* Address of init function */ -#define DT_FINI 13 /* Address of termination function */ -#define DT_SONAME 14 /* Name of shared object */ -#define DT_RPATH 15 /* Library search path (deprecated) */ -#define DT_SYMBOLIC 16 /* Start symbol search here */ -#define DT_REL 17 /* Address of Rel relocs */ -#define DT_RELSZ 18 /* Total size of Rel relocs */ -#define DT_RELENT 19 /* Size of one Rel reloc */ -#define DT_PLTREL 20 /* Type of reloc in PLT */ -#define DT_DEBUG 21 /* For debugging; unspecified */ -#define DT_TEXTREL 22 /* Reloc might modify .text */ -#define DT_JMPREL 23 /* Address of PLT relocs */ -#define DT_BIND_NOW 24 /* Process relocations of object */ -#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ -#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ -#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ -#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ -#define DT_RUNPATH 29 /* Library search path */ -#define DT_FLAGS 30 /* Flags for the object being loaded */ -#define DT_ENCODING 32 /* Start of encoded range */ -#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ -#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -#define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */ -#define DT_NUM 35 /* Number used */ -#define DT_LOOS 0x6000000d /* Start of OS-specific */ -#define DT_HIOS 0x6ffff000 /* End of OS-specific */ -#define DT_LOPROC 0x70000000 /* Start of processor-specific */ -#define DT_HIPROC 0x7fffffff /* End of processor-specific */ -#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ - -/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the - Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's - approach. */ -#define DT_VALRNGLO 0x6ffffd00 -#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ -#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ -#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ -#define DT_CHECKSUM 0x6ffffdf8 -#define DT_PLTPADSZ 0x6ffffdf9 -#define DT_MOVEENT 0x6ffffdfa -#define DT_MOVESZ 0x6ffffdfb -#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ -#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting - the following DT_* entry. */ -#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ -#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ -#define DT_VALRNGHI 0x6ffffdff -#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ -#define DT_VALNUM 12 - -/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the - Dyn.d_un.d_ptr field of the Elf*_Dyn structure. - - If any adjustment is made to the ELF object after it has been - built these entries will need to be adjusted. */ -#define DT_ADDRRNGLO 0x6ffffe00 -#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ -#define DT_TLSDESC_PLT 0x6ffffef6 -#define DT_TLSDESC_GOT 0x6ffffef7 -#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ -#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ -#define DT_CONFIG 0x6ffffefa /* Configuration information. */ -#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ -#define DT_AUDIT 0x6ffffefc /* Object auditing. */ -#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ -#define DT_MOVETAB 0x6ffffefe /* Move table. */ -#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ -#define DT_ADDRRNGHI 0x6ffffeff -#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ -#define DT_ADDRNUM 11 - -/* The versioning entry types. The next are defined as part of the - GNU extension. */ -#define DT_VERSYM 0x6ffffff0 - -#define DT_RELACOUNT 0x6ffffff9 -#define DT_RELCOUNT 0x6ffffffa - -/* These were chosen by Sun. */ -#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ -#define DT_VERDEF 0x6ffffffc /* Address of version definition - table */ -#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ -#define DT_VERNEED 0x6ffffffe /* Address of table with needed - versions */ -#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ -#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ -#define DT_VERSIONTAGNUM 16 - -/* Sun added these machine-independent extensions in the "processor-specific" - range. Be compatible. */ -#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ -#define DT_FILTER 0x7fffffff /* Shared object to get values from */ -#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) -#define DT_EXTRANUM 3 - -/* Values of `d_un.d_val' in the DT_FLAGS entry. */ -#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ -#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ -#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ -#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ -#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ - -/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 - entry in the dynamic section. */ -#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ -#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ -#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ -#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ -#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ -#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ -#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ -#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ -#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ -#define DF_1_TRANS 0x00000200 -#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ -#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ -#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ -#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ -#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ -#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ -#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ -#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */ -#define DF_1_IGNMULDEF 0x00040000 -#define DF_1_NOKSYMS 0x00080000 -#define DF_1_NOHDR 0x00100000 -#define DF_1_EDITED 0x00200000 /* Object is modified after built. */ -#define DF_1_NORELOC 0x00400000 -#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */ -#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */ -#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */ -#define DF_1_STUB 0x04000000 -#define DF_1_PIE 0x08000000 - -/* Flags for the feature selection in DT_FEATURE_1. */ -#define DTF_1_PARINIT 0x00000001 -#define DTF_1_CONFEXP 0x00000002 - -/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ -#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ -#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not - generally available. */ - -/* Version definition sections. */ - -typedef struct -{ - Elf32_Half vd_version; /* Version revision */ - Elf32_Half vd_flags; /* Version information */ - Elf32_Half vd_ndx; /* Version Index */ - Elf32_Half vd_cnt; /* Number of associated aux entries */ - Elf32_Word vd_hash; /* Version name hash value */ - Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf32_Word vd_next; /* Offset in bytes to next verdef - entry */ -} Elf32_Verdef; - -typedef struct -{ - Elf64_Half vd_version; /* Version revision */ - Elf64_Half vd_flags; /* Version information */ - Elf64_Half vd_ndx; /* Version Index */ - Elf64_Half vd_cnt; /* Number of associated aux entries */ - Elf64_Word vd_hash; /* Version name hash value */ - Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ - Elf64_Word vd_next; /* Offset in bytes to next verdef - entry */ -} Elf64_Verdef; - - -/* Legal values for vd_version (version revision). */ -#define VER_DEF_NONE 0 /* No version */ -#define VER_DEF_CURRENT 1 /* Current version */ -#define VER_DEF_NUM 2 /* Given version number */ - -/* Legal values for vd_flags (version information flags). */ -#define VER_FLG_BASE 0x1 /* Version definition of file itself */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ - -/* Versym symbol index values. */ -#define VER_NDX_LOCAL 0 /* Symbol is local. */ -#define VER_NDX_GLOBAL 1 /* Symbol is global. */ -#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ -#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ - -/* Auxialiary version information. */ - -typedef struct -{ - Elf32_Word vda_name; /* Version or dependency names */ - Elf32_Word vda_next; /* Offset in bytes to next verdaux - entry */ -} Elf32_Verdaux; - -typedef struct -{ - Elf64_Word vda_name; /* Version or dependency names */ - Elf64_Word vda_next; /* Offset in bytes to next verdaux - entry */ -} Elf64_Verdaux; - - -/* Version dependency section. */ - -typedef struct -{ - Elf32_Half vn_version; /* Version of structure */ - Elf32_Half vn_cnt; /* Number of associated aux entries */ - Elf32_Word vn_file; /* Offset of filename for this - dependency */ - Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf32_Word vn_next; /* Offset in bytes to next verneed - entry */ -} Elf32_Verneed; - -typedef struct -{ - Elf64_Half vn_version; /* Version of structure */ - Elf64_Half vn_cnt; /* Number of associated aux entries */ - Elf64_Word vn_file; /* Offset of filename for this - dependency */ - Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ - Elf64_Word vn_next; /* Offset in bytes to next verneed - entry */ -} Elf64_Verneed; - - -/* Legal values for vn_version (version revision). */ -#define VER_NEED_NONE 0 /* No version */ -#define VER_NEED_CURRENT 1 /* Current version */ -#define VER_NEED_NUM 2 /* Given version number */ - -/* Auxiliary needed version information. */ - -typedef struct -{ - Elf32_Word vna_hash; /* Hash value of dependency name */ - Elf32_Half vna_flags; /* Dependency specific information */ - Elf32_Half vna_other; /* Unused */ - Elf32_Word vna_name; /* Dependency name string offset */ - Elf32_Word vna_next; /* Offset in bytes to next vernaux - entry */ -} Elf32_Vernaux; - -typedef struct -{ - Elf64_Word vna_hash; /* Hash value of dependency name */ - Elf64_Half vna_flags; /* Dependency specific information */ - Elf64_Half vna_other; /* Unused */ - Elf64_Word vna_name; /* Dependency name string offset */ - Elf64_Word vna_next; /* Offset in bytes to next vernaux - entry */ -} Elf64_Vernaux; - - -/* Legal values for vna_flags. */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ - - -/* Auxiliary vector. */ - -/* This vector is normally only used by the program interpreter. The - usual definition in an ABI supplement uses the name auxv_t. The - vector is not usually defined in a standard file, but it - can't hurt. We rename it to avoid conflicts. The sizes of these - types are an arrangement between the exec server and the program - interpreter, so we don't fully specify them here. */ - -typedef struct -{ - uint32_t a_type; /* Entry type */ - union - { - uint32_t a_val; /* Integer value */ - /* We use to have pointer elements added here. We cannot do that, - though, since it does not work when using 32-bit definitions - on 64-bit platforms and vice versa. */ - } a_un; -} Elf32_auxv_t; - -typedef struct -{ - uint64_t a_type; /* Entry type */ - union - { - uint64_t a_val; /* Integer value */ - /* We use to have pointer elements added here. We cannot do that, - though, since it does not work when using 32-bit definitions - on 64-bit platforms and vice versa. */ - } a_un; -} Elf64_auxv_t; - -/* Legal values for a_type (entry type). */ - -#define AT_NULL 0 /* End of vector */ -#define AT_IGNORE 1 /* Entry should be ignored */ -#define AT_EXECFD 2 /* File descriptor of program */ -#define AT_PHDR 3 /* Program headers for program */ -#define AT_PHENT 4 /* Size of program header entry */ -#define AT_PHNUM 5 /* Number of program headers */ -#define AT_PAGESZ 6 /* System page size */ -#define AT_BASE 7 /* Base address of interpreter */ -#define AT_FLAGS 8 /* Flags */ -#define AT_ENTRY 9 /* Entry point of program */ -#define AT_NOTELF 10 /* Program is not ELF */ -#define AT_UID 11 /* Real uid */ -#define AT_EUID 12 /* Effective uid */ -#define AT_GID 13 /* Real gid */ -#define AT_EGID 14 /* Effective gid */ -#define AT_CLKTCK 17 /* Frequency of times() */ - -/* Some more special a_type values describing the hardware. */ -#define AT_PLATFORM 15 /* String identifying platform. */ -#define AT_HWCAP 16 /* Machine-dependent hints about - processor capabilities. */ - -/* This entry gives some information about the FPU initialization - performed by the kernel. */ -#define AT_FPUCW 18 /* Used FPU control word. */ - -/* Cache block sizes. */ -#define AT_DCACHEBSIZE 19 /* Data cache block size. */ -#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ -#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ - -/* A special ignored value for PPC, used by the kernel to control the - interpretation of the AUXV. Must be > 16. */ -#define AT_IGNOREPPC 22 /* Entry should be ignored. */ - -#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ - -#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ - -#define AT_RANDOM 25 /* Address of 16 random bytes. */ - -#define AT_HWCAP2 26 /* More machine-dependent hints about - processor capabilities. */ - -#define AT_EXECFN 31 /* Filename of executable. */ - -/* Pointer to the global system page used for system calls and other - nice things. */ -#define AT_SYSINFO 32 -#define AT_SYSINFO_EHDR 33 - -/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains - log2 of line size; mask those to get cache size. */ -#define AT_L1I_CACHESHAPE 34 -#define AT_L1D_CACHESHAPE 35 -#define AT_L2_CACHESHAPE 36 -#define AT_L3_CACHESHAPE 37 - -/* Shapes of the caches, with more room to describe them. - *GEOMETRY are comprised of cache line size in bytes in the bottom 16 bits - and the cache associativity in the next 16 bits. */ -#define AT_L1I_CACHESIZE 40 -#define AT_L1I_CACHEGEOMETRY 41 -#define AT_L1D_CACHESIZE 42 -#define AT_L1D_CACHEGEOMETRY 43 -#define AT_L2_CACHESIZE 44 -#define AT_L2_CACHEGEOMETRY 45 -#define AT_L3_CACHESIZE 46 -#define AT_L3_CACHEGEOMETRY 47 - -#define AT_MINSIGSTKSZ 51 /* Stack needed for signal delivery - (AArch64). */ - -/* Note section contents. Each entry in the note section begins with - a header of a fixed form. */ - -typedef struct -{ - Elf32_Word n_namesz; /* Length of the note's name. */ - Elf32_Word n_descsz; /* Length of the note's descriptor. */ - Elf32_Word n_type; /* Type of the note. */ -} Elf32_Nhdr; - -typedef struct -{ - Elf64_Word n_namesz; /* Length of the note's name. */ - Elf64_Word n_descsz; /* Length of the note's descriptor. */ - Elf64_Word n_type; /* Type of the note. */ -} Elf64_Nhdr; - -/* Known names of notes. */ - -/* Solaris entries in the note section have this name. */ -#define ELF_NOTE_SOLARIS "SUNW Solaris" - -/* Note entries for GNU systems have this name. */ -#define ELF_NOTE_GNU "GNU" - - -/* Defined types of notes for Solaris. */ - -/* Value of descriptor (one word) is desired pagesize for the binary. */ -#define ELF_NOTE_PAGESIZE_HINT 1 - - -/* Defined note types for GNU systems. */ - -/* ABI information. The descriptor consists of words: - word 0: OS descriptor - word 1: major version of the ABI - word 2: minor version of the ABI - word 3: subminor version of the ABI -*/ -#define NT_GNU_ABI_TAG 1 -#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ - -/* Known OSes. These values can appear in word 0 of an - NT_GNU_ABI_TAG note section entry. */ -#define ELF_NOTE_OS_LINUX 0 -#define ELF_NOTE_OS_GNU 1 -#define ELF_NOTE_OS_SOLARIS2 2 -#define ELF_NOTE_OS_FREEBSD 3 - -/* Synthetic hwcap information. The descriptor begins with two words: - word 0: number of entries - word 1: bitmask of enabled entries - Then follow variable-length entries, one byte followed by a - '\0'-terminated hwcap name string. The byte gives the bit - number to test if enabled, (1U << bit) & bitmask. */ -#define NT_GNU_HWCAP 2 - -/* Build ID bits as generated by ld --build-id. - The descriptor consists of any nonzero number of bytes. */ -#define NT_GNU_BUILD_ID 3 - -/* Version note generated by GNU gold containing a version string. */ -#define NT_GNU_GOLD_VERSION 4 - -/* Program property. */ -#define NT_GNU_PROPERTY_TYPE_0 5 - -/* Note section name of program property. */ -#define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property" - -/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */ - -/* Stack size. */ -#define GNU_PROPERTY_STACK_SIZE 1 -/* No copy relocation on protected data symbol. */ -#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 - -/* Processor-specific semantics, lo */ -#define GNU_PROPERTY_LOPROC 0xc0000000 -/* Processor-specific semantics, hi */ -#define GNU_PROPERTY_HIPROC 0xdfffffff -/* Application-specific semantics, lo */ -#define GNU_PROPERTY_LOUSER 0xe0000000 -/* Application-specific semantics, hi */ -#define GNU_PROPERTY_HIUSER 0xffffffff - -/* The x86 instruction sets indicated by the corresponding bits are - used in program. Their support in the hardware is optional. */ -#define GNU_PROPERTY_X86_ISA_1_USED 0xc0000000 -/* The x86 instruction sets indicated by the corresponding bits are - used in program and they must be supported by the hardware. */ -#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0000001 -/* X86 processor-specific features used in program. */ -#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 - -#define GNU_PROPERTY_X86_ISA_1_486 (1U << 0) -#define GNU_PROPERTY_X86_ISA_1_586 (1U << 1) -#define GNU_PROPERTY_X86_ISA_1_686 (1U << 2) -#define GNU_PROPERTY_X86_ISA_1_SSE (1U << 3) -#define GNU_PROPERTY_X86_ISA_1_SSE2 (1U << 4) -#define GNU_PROPERTY_X86_ISA_1_SSE3 (1U << 5) -#define GNU_PROPERTY_X86_ISA_1_SSSE3 (1U << 6) -#define GNU_PROPERTY_X86_ISA_1_SSE4_1 (1U << 7) -#define GNU_PROPERTY_X86_ISA_1_SSE4_2 (1U << 8) -#define GNU_PROPERTY_X86_ISA_1_AVX (1U << 9) -#define GNU_PROPERTY_X86_ISA_1_AVX2 (1U << 10) -#define GNU_PROPERTY_X86_ISA_1_AVX512F (1U << 11) -#define GNU_PROPERTY_X86_ISA_1_AVX512CD (1U << 12) -#define GNU_PROPERTY_X86_ISA_1_AVX512ER (1U << 13) -#define GNU_PROPERTY_X86_ISA_1_AVX512PF (1U << 14) -#define GNU_PROPERTY_X86_ISA_1_AVX512VL (1U << 15) -#define GNU_PROPERTY_X86_ISA_1_AVX512DQ (1U << 16) -#define GNU_PROPERTY_X86_ISA_1_AVX512BW (1U << 17) - -/* This indicates that all executable sections are compatible with - IBT. */ -#define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0) -/* This indicates that all executable sections are compatible with - SHSTK. */ -#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1) - -/* Move records. */ -typedef struct -{ - Elf32_Xword m_value; /* Symbol value. */ - Elf32_Word m_info; /* Size and index. */ - Elf32_Word m_poffset; /* Symbol offset. */ - Elf32_Half m_repeat; /* Repeat count. */ - Elf32_Half m_stride; /* Stride info. */ -} Elf32_Move; - -typedef struct -{ - Elf64_Xword m_value; /* Symbol value. */ - Elf64_Xword m_info; /* Size and index. */ - Elf64_Xword m_poffset; /* Symbol offset. */ - Elf64_Half m_repeat; /* Repeat count. */ - Elf64_Half m_stride; /* Stride info. */ -} Elf64_Move; - -/* Macro to construct move records. */ -#define ELF32_M_SYM(info) ((info) >> 8) -#define ELF32_M_SIZE(info) ((unsigned char) (info)) -#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) - -#define ELF64_M_SYM(info) ELF32_M_SYM (info) -#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) -#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) - - -/* Motorola 68k specific definitions. */ - -/* Values for Elf32_Ehdr.e_flags. */ -#define EF_CPU32 0x00810000 - -/* m68k relocs. */ - -#define R_68K_NONE 0 /* No reloc */ -#define R_68K_32 1 /* Direct 32 bit */ -#define R_68K_16 2 /* Direct 16 bit */ -#define R_68K_8 3 /* Direct 8 bit */ -#define R_68K_PC32 4 /* PC relative 32 bit */ -#define R_68K_PC16 5 /* PC relative 16 bit */ -#define R_68K_PC8 6 /* PC relative 8 bit */ -#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ -#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ -#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ -#define R_68K_GOT32O 10 /* 32 bit GOT offset */ -#define R_68K_GOT16O 11 /* 16 bit GOT offset */ -#define R_68K_GOT8O 12 /* 8 bit GOT offset */ -#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ -#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ -#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ -#define R_68K_PLT32O 16 /* 32 bit PLT offset */ -#define R_68K_PLT16O 17 /* 16 bit PLT offset */ -#define R_68K_PLT8O 18 /* 8 bit PLT offset */ -#define R_68K_COPY 19 /* Copy symbol at runtime */ -#define R_68K_GLOB_DAT 20 /* Create GOT entry */ -#define R_68K_JMP_SLOT 21 /* Create PLT entry */ -#define R_68K_RELATIVE 22 /* Adjust by program base */ -#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ -#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ -#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ -#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ -#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ -#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ -#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ -#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ -#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ -#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ -#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ -#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ -#define R_68K_TLS_LE32 37 /* 32 bit offset relative to - static TLS block */ -#define R_68K_TLS_LE16 38 /* 16 bit offset relative to - static TLS block */ -#define R_68K_TLS_LE8 39 /* 8 bit offset relative to - static TLS block */ -#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ -#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ -#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ -/* Keep this the last entry. */ -#define R_68K_NUM 43 - -/* Intel 80386 specific definitions. */ - -/* i386 relocs. */ - -#define R_386_NONE 0 /* No reloc */ -#define R_386_32 1 /* Direct 32 bit */ -#define R_386_PC32 2 /* PC relative 32 bit */ -#define R_386_GOT32 3 /* 32 bit GOT entry */ -#define R_386_PLT32 4 /* 32 bit PLT address */ -#define R_386_COPY 5 /* Copy symbol at runtime */ -#define R_386_GLOB_DAT 6 /* Create GOT entry */ -#define R_386_JMP_SLOT 7 /* Create PLT entry */ -#define R_386_RELATIVE 8 /* Adjust by program base */ -#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ -#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ -#define R_386_32PLT 11 -#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ -#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS - block offset */ -#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block - offset */ -#define R_386_TLS_LE 17 /* Offset relative to static TLS - block */ -#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of - general dynamic thread local data */ -#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of - local dynamic thread local data - in LE code */ -#define R_386_16 20 -#define R_386_PC16 21 -#define R_386_8 22 -#define R_386_PC8 23 -#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic - thread local data */ -#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ -#define R_386_TLS_GD_CALL 26 /* Relocation for call to - __tls_get_addr() */ -#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ -#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic - thread local data in LE code */ -#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ -#define R_386_TLS_LDM_CALL 30 /* Relocation for call to - __tls_get_addr() in LDM code */ -#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ -#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ -#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS - block offset */ -#define R_386_TLS_LE_32 34 /* Negated offset relative to static - TLS block */ -#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ -#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ -#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ -#define R_386_SIZE32 38 /* 32-bit symbol size */ -#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ -#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS - descriptor for - relaxation. */ -#define R_386_TLS_DESC 41 /* TLS descriptor containing - pointer to code and to - argument, returning the TLS - offset for the symbol. */ -#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ -#define R_386_GOT32X 43 /* Load from 32 bit GOT entry, - relaxable. */ -/* Keep this the last entry. */ -#define R_386_NUM 44 - -/* SUN SPARC specific definitions. */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ - -/* Values for Elf64_Ehdr.e_flags. */ - -#define EF_SPARCV9_MM 3 -#define EF_SPARCV9_TSO 0 -#define EF_SPARCV9_PSO 1 -#define EF_SPARCV9_RMO 2 -#define EF_SPARC_LEDATA 0x800000 /* little endian data */ -#define EF_SPARC_EXT_MASK 0xFFFF00 -#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ -#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ -#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ -#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ - -/* SPARC relocs. */ - -#define R_SPARC_NONE 0 /* No reloc */ -#define R_SPARC_8 1 /* Direct 8 bit */ -#define R_SPARC_16 2 /* Direct 16 bit */ -#define R_SPARC_32 3 /* Direct 32 bit */ -#define R_SPARC_DISP8 4 /* PC relative 8 bit */ -#define R_SPARC_DISP16 5 /* PC relative 16 bit */ -#define R_SPARC_DISP32 6 /* PC relative 32 bit */ -#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ -#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ -#define R_SPARC_HI22 9 /* High 22 bit */ -#define R_SPARC_22 10 /* Direct 22 bit */ -#define R_SPARC_13 11 /* Direct 13 bit */ -#define R_SPARC_LO10 12 /* Truncated 10 bit */ -#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ -#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ -#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ -#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ -#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ -#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ -#define R_SPARC_COPY 19 /* Copy symbol at runtime */ -#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ -#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ -#define R_SPARC_RELATIVE 22 /* Adjust by program base */ -#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ - -/* Additional Sparc64 relocs. */ - -#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ -#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ -#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ -#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ -#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ -#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ -#define R_SPARC_10 30 /* Direct 10 bit */ -#define R_SPARC_11 31 /* Direct 11 bit */ -#define R_SPARC_64 32 /* Direct 64 bit */ -#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ -#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ -#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ -#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ -#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ -#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ -#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ -#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ -#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ -#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ -#define R_SPARC_7 43 /* Direct 7 bit */ -#define R_SPARC_5 44 /* Direct 5 bit */ -#define R_SPARC_6 45 /* Direct 6 bit */ -#define R_SPARC_DISP64 46 /* PC relative 64 bit */ -#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ -#define R_SPARC_HIX22 48 /* High 22 bit complemented */ -#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ -#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ -#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ -#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ -#define R_SPARC_REGISTER 53 /* Global register usage */ -#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ -#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ -#define R_SPARC_TLS_GD_HI22 56 -#define R_SPARC_TLS_GD_LO10 57 -#define R_SPARC_TLS_GD_ADD 58 -#define R_SPARC_TLS_GD_CALL 59 -#define R_SPARC_TLS_LDM_HI22 60 -#define R_SPARC_TLS_LDM_LO10 61 -#define R_SPARC_TLS_LDM_ADD 62 -#define R_SPARC_TLS_LDM_CALL 63 -#define R_SPARC_TLS_LDO_HIX22 64 -#define R_SPARC_TLS_LDO_LOX10 65 -#define R_SPARC_TLS_LDO_ADD 66 -#define R_SPARC_TLS_IE_HI22 67 -#define R_SPARC_TLS_IE_LO10 68 -#define R_SPARC_TLS_IE_LD 69 -#define R_SPARC_TLS_IE_LDX 70 -#define R_SPARC_TLS_IE_ADD 71 -#define R_SPARC_TLS_LE_HIX22 72 -#define R_SPARC_TLS_LE_LOX10 73 -#define R_SPARC_TLS_DTPMOD32 74 -#define R_SPARC_TLS_DTPMOD64 75 -#define R_SPARC_TLS_DTPOFF32 76 -#define R_SPARC_TLS_DTPOFF64 77 -#define R_SPARC_TLS_TPOFF32 78 -#define R_SPARC_TLS_TPOFF64 79 -#define R_SPARC_GOTDATA_HIX22 80 -#define R_SPARC_GOTDATA_LOX10 81 -#define R_SPARC_GOTDATA_OP_HIX22 82 -#define R_SPARC_GOTDATA_OP_LOX10 83 -#define R_SPARC_GOTDATA_OP 84 -#define R_SPARC_H34 85 -#define R_SPARC_SIZE32 86 -#define R_SPARC_SIZE64 87 -#define R_SPARC_WDISP10 88 -#define R_SPARC_JMP_IREL 248 -#define R_SPARC_IRELATIVE 249 -#define R_SPARC_GNU_VTINHERIT 250 -#define R_SPARC_GNU_VTENTRY 251 -#define R_SPARC_REV32 252 -/* Keep this the last entry. */ -#define R_SPARC_NUM 253 - -/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ - -#define DT_SPARC_REGISTER 0x70000001 -#define DT_SPARC_NUM 2 - -/* MIPS R3000 specific definitions. */ - -/* Legal values for e_flags field of Elf32_Ehdr. */ - -#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used. */ -#define EF_MIPS_PIC 2 /* Contains PIC code. */ -#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */ -#define EF_MIPS_XGOT 8 -#define EF_MIPS_64BIT_WHIRL 16 -#define EF_MIPS_ABI2 32 -#define EF_MIPS_ABI_ON32 64 -#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */ -#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */ -#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */ - -/* Legal values for MIPS architecture level. */ - -#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ -#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ -#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ -#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ -#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ -#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */ -#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */ -#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */ -#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */ - -/* The following are unofficial names and should not be used. */ - -#define E_MIPS_ARCH_1 EF_MIPS_ARCH_1 -#define E_MIPS_ARCH_2 EF_MIPS_ARCH_2 -#define E_MIPS_ARCH_3 EF_MIPS_ARCH_3 -#define E_MIPS_ARCH_4 EF_MIPS_ARCH_4 -#define E_MIPS_ARCH_5 EF_MIPS_ARCH_5 -#define E_MIPS_ARCH_32 EF_MIPS_ARCH_32 -#define E_MIPS_ARCH_64 EF_MIPS_ARCH_64 - -/* Special section indices. */ - -#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols. */ -#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ -#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ -#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols. */ -#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols. */ - -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link. */ -#define SHT_MIPS_MSYM 0x70000001 -#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols. */ -#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes. */ -#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging info. */ -#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information. */ -#define SHT_MIPS_PACKAGE 0x70000007 -#define SHT_MIPS_PACKSYM 0x70000008 -#define SHT_MIPS_RELD 0x70000009 -#define SHT_MIPS_IFACE 0x7000000b -#define SHT_MIPS_CONTENT 0x7000000c -#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ -#define SHT_MIPS_SHDR 0x70000010 -#define SHT_MIPS_FDESC 0x70000011 -#define SHT_MIPS_EXTSYM 0x70000012 -#define SHT_MIPS_DENSE 0x70000013 -#define SHT_MIPS_PDESC 0x70000014 -#define SHT_MIPS_LOCSYM 0x70000015 -#define SHT_MIPS_AUXSYM 0x70000016 -#define SHT_MIPS_OPTSYM 0x70000017 -#define SHT_MIPS_LOCSTR 0x70000018 -#define SHT_MIPS_LINE 0x70000019 -#define SHT_MIPS_RFDESC 0x7000001a -#define SHT_MIPS_DELTASYM 0x7000001b -#define SHT_MIPS_DELTAINST 0x7000001c -#define SHT_MIPS_DELTACLASS 0x7000001d -#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -#define SHT_MIPS_DELTADECL 0x7000001f -#define SHT_MIPS_SYMBOL_LIB 0x70000020 -#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ -#define SHT_MIPS_TRANSLATE 0x70000022 -#define SHT_MIPS_PIXIE 0x70000023 -#define SHT_MIPS_XLATE 0x70000024 -#define SHT_MIPS_XLATE_DEBUG 0x70000025 -#define SHT_MIPS_WHIRL 0x70000026 -#define SHT_MIPS_EH_REGION 0x70000027 -#define SHT_MIPS_XLATE_OLD 0x70000028 -#define SHT_MIPS_PDR_EXCEPTION 0x70000029 - -/* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_MIPS_GPREL 0x10000000 /* Must be in global data area. */ -#define SHF_MIPS_MERGE 0x20000000 -#define SHF_MIPS_ADDR 0x40000000 -#define SHF_MIPS_STRINGS 0x80000000 -#define SHF_MIPS_NOSTRIP 0x08000000 -#define SHF_MIPS_LOCAL 0x04000000 -#define SHF_MIPS_NAMES 0x02000000 -#define SHF_MIPS_NODUPE 0x01000000 - - -/* Symbol tables. */ - -/* MIPS specific values for `st_other'. */ -#define STO_MIPS_DEFAULT 0x0 -#define STO_MIPS_INTERNAL 0x1 -#define STO_MIPS_HIDDEN 0x2 -#define STO_MIPS_PROTECTED 0x3 -#define STO_MIPS_PLT 0x8 -#define STO_MIPS_SC_ALIGN_UNUSED 0xff - -/* MIPS specific values for `st_info'. */ -#define STB_MIPS_SPLIT_COMMON 13 - -/* Entries found in sections of type SHT_MIPS_GPTAB. */ - -typedef union -{ - struct - { - Elf32_Word gt_current_g_value; /* -G value used for compilation. */ - Elf32_Word gt_unused; /* Not used. */ - } gt_header; /* First entry in section. */ - struct - { - Elf32_Word gt_g_value; /* If this value were used for -G. */ - Elf32_Word gt_bytes; /* This many bytes would be used. */ - } gt_entry; /* Subsequent entries in section. */ -} Elf32_gptab; - -/* Entry found in sections of type SHT_MIPS_REGINFO. */ - -typedef struct -{ - Elf32_Word ri_gprmask; /* General registers used. */ - Elf32_Word ri_cprmask[4]; /* Coprocessor registers used. */ - Elf32_Sword ri_gp_value; /* $gp register value. */ -} Elf32_RegInfo; - -/* Entries found in sections of type SHT_MIPS_OPTIONS. */ - -typedef struct -{ - unsigned char kind; /* Determines interpretation of the - variable part of descriptor. */ - unsigned char size; /* Size of descriptor, including header. */ - Elf32_Section section; /* Section header index of section affected, - 0 for global options. */ - Elf32_Word info; /* Kind-specific information. */ -} Elf_Options; - -/* Values for `kind' field in Elf_Options. */ - -#define ODK_NULL 0 /* Undefined. */ -#define ODK_REGINFO 1 /* Register usage information. */ -#define ODK_EXCEPTIONS 2 /* Exception processing options. */ -#define ODK_PAD 3 /* Section padding options. */ -#define ODK_HWPATCH 4 /* Hardware workarounds performed */ -#define ODK_FILL 5 /* record the fill value used by the linker. */ -#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ -#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ -#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ - -/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ - -#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ -#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ -#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ -#define OEX_SMM 0x20000 /* Force sequential memory mode? */ -#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ -#define OEX_PRECISEFP OEX_FPDBUG -#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ - -#define OEX_FPU_INVAL 0x10 -#define OEX_FPU_DIV0 0x08 -#define OEX_FPU_OFLO 0x04 -#define OEX_FPU_UFLO 0x02 -#define OEX_FPU_INEX 0x01 - -/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ - -#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ -#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ -#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ -#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ - -#define OPAD_PREFIX 0x1 -#define OPAD_POSTFIX 0x2 -#define OPAD_SYMBOL 0x4 - -/* Entry found in `.options' section. */ - -typedef struct -{ - Elf32_Word hwp_flags1; /* Extra flags. */ - Elf32_Word hwp_flags2; /* Extra flags. */ -} Elf_Options_Hw; - -/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ - -#define OHWA0_R4KEOP_CHECKED 0x00000001 -#define OHWA1_R4KEOP_CLEAN 0x00000002 - -/* MIPS relocs. */ - -#define R_MIPS_NONE 0 /* No reloc */ -#define R_MIPS_16 1 /* Direct 16 bit */ -#define R_MIPS_32 2 /* Direct 32 bit */ -#define R_MIPS_REL32 3 /* PC relative 32 bit */ -#define R_MIPS_26 4 /* Direct 26 bit shifted */ -#define R_MIPS_HI16 5 /* High 16 bit */ -#define R_MIPS_LO16 6 /* Low 16 bit */ -#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ -#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ -#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ -#define R_MIPS_PC16 10 /* PC relative 16 bit */ -#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ -#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ - -#define R_MIPS_SHIFT5 16 -#define R_MIPS_SHIFT6 17 -#define R_MIPS_64 18 -#define R_MIPS_GOT_DISP 19 -#define R_MIPS_GOT_PAGE 20 -#define R_MIPS_GOT_OFST 21 -#define R_MIPS_GOT_HI16 22 -#define R_MIPS_GOT_LO16 23 -#define R_MIPS_SUB 24 -#define R_MIPS_INSERT_A 25 -#define R_MIPS_INSERT_B 26 -#define R_MIPS_DELETE 27 -#define R_MIPS_HIGHER 28 -#define R_MIPS_HIGHEST 29 -#define R_MIPS_CALL_HI16 30 -#define R_MIPS_CALL_LO16 31 -#define R_MIPS_SCN_DISP 32 -#define R_MIPS_REL16 33 -#define R_MIPS_ADD_IMMEDIATE 34 -#define R_MIPS_PJUMP 35 -#define R_MIPS_RELGOT 36 -#define R_MIPS_JALR 37 -#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ -#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ -#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ -#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ -#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ -#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ -#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ -#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ -#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ -#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ -#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ -#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ -#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -#define R_MIPS_GLOB_DAT 51 -#define R_MIPS_COPY 126 -#define R_MIPS_JUMP_SLOT 127 -/* Keep this the last entry. */ -#define R_MIPS_NUM 128 - -/* Legal values for p_type field of Elf32_Phdr. */ - -#define PT_MIPS_REGINFO 0x70000000 /* Register usage information. */ -#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ -#define PT_MIPS_OPTIONS 0x70000002 -#define PT_MIPS_ABIFLAGS 0x70000003 /* FP mode requirement. */ - -/* Special program header types. */ - -#define PF_MIPS_LOCAL 0x10000000 - -/* Legal values for d_tag field of Elf32_Dyn. */ - -#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ -#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ -#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ -#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ -#define DT_MIPS_FLAGS 0x70000005 /* Flags */ -#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ -#define DT_MIPS_MSYM 0x70000007 -#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ -#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ -#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ -#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ -#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ -#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ -#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ -#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ -#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ -#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ -#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ -#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in - DT_MIPS_DELTA_CLASS. */ -#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ -#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in - DT_MIPS_DELTA_INSTANCE. */ -#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ -#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in - DT_MIPS_DELTA_RELOC. */ -#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta - relocations refer to. */ -#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in - DT_MIPS_DELTA_SYM. */ -#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the - class declaration. */ -#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in - DT_MIPS_DELTA_CLASSSYM. */ -#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ -#define DT_MIPS_PIXIE_INIT 0x70000023 -#define DT_MIPS_SYMBOL_LIB 0x70000024 -#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 -#define DT_MIPS_LOCAL_GOTIDX 0x70000026 -#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 -#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 -#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ -#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ -#define DT_MIPS_DYNSTR_ALIGN 0x7000002b -#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ -#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve - function stored in GOT. */ -#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added - by rld on dlopen() calls. */ -#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ -#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ -#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ -/* The address of .got.plt in an executable using the new non-PIC ABI. */ -#define DT_MIPS_PLTGOT 0x70000032 -/* The base of the PLT in an executable using the new non-PIC ABI if that - PLT is writable. For a non-writable PLT, this is omitted or has a zero - value. */ -#define DT_MIPS_RWPLT 0x70000034 -/* An alternative description of the classic MIPS RLD_MAP that is usable - in a PIE as it stores a relative offset from the address of the tag - rather than an absolute address. */ -#define DT_MIPS_RLD_MAP_REL 0x70000035 -#define DT_MIPS_NUM 0x36 - -/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ - -#define RHF_NONE 0 /* No flags */ -#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ -#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ -#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ -#define RHF_NO_MOVE (1 << 3) -#define RHF_SGI_ONLY (1 << 4) -#define RHF_GUARANTEE_INIT (1 << 5) -#define RHF_DELTA_C_PLUS_PLUS (1 << 6) -#define RHF_GUARANTEE_START_INIT (1 << 7) -#define RHF_PIXIE (1 << 8) -#define RHF_DEFAULT_DELAY_LOAD (1 << 9) -#define RHF_REQUICKSTART (1 << 10) -#define RHF_REQUICKSTARTED (1 << 11) -#define RHF_CORD (1 << 12) -#define RHF_NO_UNRES_UNDEF (1 << 13) -#define RHF_RLD_ORDER_SAFE (1 << 14) - -/* Entries found in sections of type SHT_MIPS_LIBLIST. */ - -typedef struct -{ - Elf32_Word l_name; /* Name (string table index) */ - Elf32_Word l_time_stamp; /* Timestamp */ - Elf32_Word l_checksum; /* Checksum */ - Elf32_Word l_version; /* Interface version */ - Elf32_Word l_flags; /* Flags */ -} Elf32_Lib; - -typedef struct -{ - Elf64_Word l_name; /* Name (string table index) */ - Elf64_Word l_time_stamp; /* Timestamp */ - Elf64_Word l_checksum; /* Checksum */ - Elf64_Word l_version; /* Interface version */ - Elf64_Word l_flags; /* Flags */ -} Elf64_Lib; - - -/* Legal values for l_flags. */ - -#define LL_NONE 0 -#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ -#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ -#define LL_REQUIRE_MINOR (1 << 2) -#define LL_EXPORTS (1 << 3) -#define LL_DELAY_LOAD (1 << 4) -#define LL_DELTA (1 << 5) - -/* Entries found in sections of type SHT_MIPS_CONFLICT. */ - -typedef Elf32_Addr Elf32_Conflict; - -typedef struct -{ - /* Version of flags structure. */ - Elf32_Half version; - /* The level of the ISA: 1-5, 32, 64. */ - unsigned char isa_level; - /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise. */ - unsigned char isa_rev; - /* The size of general purpose registers. */ - unsigned char gpr_size; - /* The size of co-processor 1 registers. */ - unsigned char cpr1_size; - /* The size of co-processor 2 registers. */ - unsigned char cpr2_size; - /* The floating-point ABI. */ - unsigned char fp_abi; - /* Processor-specific extension. */ - Elf32_Word isa_ext; - /* Mask of ASEs used. */ - Elf32_Word ases; - /* Mask of general flags. */ - Elf32_Word flags1; - Elf32_Word flags2; -} Elf_MIPS_ABIFlags_v0; - -/* Values for the register size bytes of an abi flags structure. */ - -#define MIPS_AFL_REG_NONE 0x00 /* No registers. */ -#define MIPS_AFL_REG_32 0x01 /* 32-bit registers. */ -#define MIPS_AFL_REG_64 0x02 /* 64-bit registers. */ -#define MIPS_AFL_REG_128 0x03 /* 128-bit registers. */ - -/* Masks for the ases word of an ABI flags structure. */ - -#define MIPS_AFL_ASE_DSP 0x00000001 /* DSP ASE. */ -#define MIPS_AFL_ASE_DSPR2 0x00000002 /* DSP R2 ASE. */ -#define MIPS_AFL_ASE_EVA 0x00000004 /* Enhanced VA Scheme. */ -#define MIPS_AFL_ASE_MCU 0x00000008 /* MCU (MicroController) ASE. */ -#define MIPS_AFL_ASE_MDMX 0x00000010 /* MDMX ASE. */ -#define MIPS_AFL_ASE_MIPS3D 0x00000020 /* MIPS-3D ASE. */ -#define MIPS_AFL_ASE_MT 0x00000040 /* MT ASE. */ -#define MIPS_AFL_ASE_SMARTMIPS 0x00000080 /* SmartMIPS ASE. */ -#define MIPS_AFL_ASE_VIRT 0x00000100 /* VZ ASE. */ -#define MIPS_AFL_ASE_MSA 0x00000200 /* MSA ASE. */ -#define MIPS_AFL_ASE_MIPS16 0x00000400 /* MIPS16 ASE. */ -#define MIPS_AFL_ASE_MICROMIPS 0x00000800 /* MICROMIPS ASE. */ -#define MIPS_AFL_ASE_XPA 0x00001000 /* XPA ASE. */ -#define MIPS_AFL_ASE_MASK 0x00001fff /* All ASEs. */ - -/* Values for the isa_ext word of an ABI flags structure. */ - -#define MIPS_AFL_EXT_XLR 1 /* RMI Xlr instruction. */ -#define MIPS_AFL_EXT_OCTEON2 2 /* Cavium Networks Octeon2. */ -#define MIPS_AFL_EXT_OCTEONP 3 /* Cavium Networks OcteonP. */ -#define MIPS_AFL_EXT_LOONGSON_3A 4 /* Loongson 3A. */ -#define MIPS_AFL_EXT_OCTEON 5 /* Cavium Networks Octeon. */ -#define MIPS_AFL_EXT_5900 6 /* MIPS R5900 instruction. */ -#define MIPS_AFL_EXT_4650 7 /* MIPS R4650 instruction. */ -#define MIPS_AFL_EXT_4010 8 /* LSI R4010 instruction. */ -#define MIPS_AFL_EXT_4100 9 /* NEC VR4100 instruction. */ -#define MIPS_AFL_EXT_3900 10 /* Toshiba R3900 instruction. */ -#define MIPS_AFL_EXT_10000 11 /* MIPS R10000 instruction. */ -#define MIPS_AFL_EXT_SB1 12 /* Broadcom SB-1 instruction. */ -#define MIPS_AFL_EXT_4111 13 /* NEC VR4111/VR4181 instruction. */ -#define MIPS_AFL_EXT_4120 14 /* NEC VR4120 instruction. */ -#define MIPS_AFL_EXT_5400 15 /* NEC VR5400 instruction. */ -#define MIPS_AFL_EXT_5500 16 /* NEC VR5500 instruction. */ -#define MIPS_AFL_EXT_LOONGSON_2E 17 /* ST Microelectronics Loongson 2E. */ -#define MIPS_AFL_EXT_LOONGSON_2F 18 /* ST Microelectronics Loongson 2F. */ - -/* Masks for the flags1 word of an ABI flags structure. */ -#define MIPS_AFL_FLAGS1_ODDSPREG 1 /* Uses odd single-precision registers. */ - -/* Object attribute values. */ -enum -{ - /* Not tagged or not using any ABIs affected by the differences. */ - Val_GNU_MIPS_ABI_FP_ANY = 0, - /* Using hard-float -mdouble-float. */ - Val_GNU_MIPS_ABI_FP_DOUBLE = 1, - /* Using hard-float -msingle-float. */ - Val_GNU_MIPS_ABI_FP_SINGLE = 2, - /* Using soft-float. */ - Val_GNU_MIPS_ABI_FP_SOFT = 3, - /* Using -mips32r2 -mfp64. */ - Val_GNU_MIPS_ABI_FP_OLD_64 = 4, - /* Using -mfpxx. */ - Val_GNU_MIPS_ABI_FP_XX = 5, - /* Using -mips32r2 -mfp64. */ - Val_GNU_MIPS_ABI_FP_64 = 6, - /* Using -mips32r2 -mfp64 -mno-odd-spreg. */ - Val_GNU_MIPS_ABI_FP_64A = 7, - /* Maximum allocated FP ABI value. */ - Val_GNU_MIPS_ABI_FP_MAX = 7 -}; - -/* HPPA specific definitions. */ - -/* Legal values for e_flags field of Elf32_Ehdr. */ - -#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ -#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ -#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ -#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ -#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch - prediction. */ -#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ -#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ - -/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ - -#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ -#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ -#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ - -/* Additional section indeces. */ - -#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared - symbols in ANSI C. */ -#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ - -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ -#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ -#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ - -/* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ -#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ -#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ - -/* Legal values for ST_TYPE subfield of st_info (symbol type). */ - -#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ - -#define STT_HP_OPAQUE (STT_LOOS + 0x1) -#define STT_HP_STUB (STT_LOOS + 0x2) - -/* HPPA relocs. */ - -#define R_PARISC_NONE 0 /* No reloc. */ -#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ -#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ -#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ -#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ -#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ -#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ -#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ -#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ -#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ -#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ -#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ -#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ -#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ -#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ -#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ -#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ -#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ -#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ -#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ -#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ -#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ -#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ -#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ -#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ -#define R_PARISC_FPTR64 64 /* 64 bits function address. */ -#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ -#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ -#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ -#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ -#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ -#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ -#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ -#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ -#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ -#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ -#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ -#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ -#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ -#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ -#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ -#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ -#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ -#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ -#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ -#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ -#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ -#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ -#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ -#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ -#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ -#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ -#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ -#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ -#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ -#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ -#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ -#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ -#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ -#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ -#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ -#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ -#define R_PARISC_LORESERVE 128 -#define R_PARISC_COPY 128 /* Copy relocation. */ -#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ -#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ -#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ -#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ -#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ -#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ -#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ -#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ -#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ -#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ -#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ -#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ -#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ -#define R_PARISC_GNU_VTENTRY 232 -#define R_PARISC_GNU_VTINHERIT 233 -#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ -#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ -#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ -#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ -#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ -#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ -#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ -#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ -#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ -#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ -#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ -#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ -#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L -#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R -#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L -#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R -#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 -#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 -#define R_PARISC_HIRESERVE 255 - -/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ - -#define PT_HP_TLS (PT_LOOS + 0x0) -#define PT_HP_CORE_NONE (PT_LOOS + 0x1) -#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) -#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) -#define PT_HP_CORE_COMM (PT_LOOS + 0x4) -#define PT_HP_CORE_PROC (PT_LOOS + 0x5) -#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) -#define PT_HP_CORE_STACK (PT_LOOS + 0x7) -#define PT_HP_CORE_SHM (PT_LOOS + 0x8) -#define PT_HP_CORE_MMF (PT_LOOS + 0x9) -#define PT_HP_PARALLEL (PT_LOOS + 0x10) -#define PT_HP_FASTBIND (PT_LOOS + 0x11) -#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) -#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) -#define PT_HP_STACK (PT_LOOS + 0x14) - -#define PT_PARISC_ARCHEXT 0x70000000 -#define PT_PARISC_UNWIND 0x70000001 - -/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ - -#define PF_PARISC_SBP 0x08000000 - -#define PF_HP_PAGE_SIZE 0x00100000 -#define PF_HP_FAR_SHARED 0x00200000 -#define PF_HP_NEAR_SHARED 0x00400000 -#define PF_HP_CODE 0x01000000 -#define PF_HP_MODIFY 0x02000000 -#define PF_HP_LAZYSWAP 0x04000000 -#define PF_HP_SBP 0x08000000 - - -/* Alpha specific definitions. */ - -/* Legal values for e_flags field of Elf64_Ehdr. */ - -#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ -#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ - -/* Legal values for sh_type field of Elf64_Shdr. */ - -/* These two are primerily concerned with ECOFF debugging info. */ -#define SHT_ALPHA_DEBUG 0x70000001 -#define SHT_ALPHA_REGINFO 0x70000002 - -/* Legal values for sh_flags field of Elf64_Shdr. */ - -#define SHF_ALPHA_GPREL 0x10000000 - -/* Legal values for st_other field of Elf64_Sym. */ -#define STO_ALPHA_NOPV 0x80 /* No PV required. */ -#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ - -/* Alpha relocs. */ - -#define R_ALPHA_NONE 0 /* No reloc */ -#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ -#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ -#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ -#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ -#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ -#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ -#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ -#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ -#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ -#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ -#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ -#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ -#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ -#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ -#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ -#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ -#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ -#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ -#define R_ALPHA_TLS_GD_HI 28 -#define R_ALPHA_TLSGD 29 -#define R_ALPHA_TLS_LDM 30 -#define R_ALPHA_DTPMOD64 31 -#define R_ALPHA_GOTDTPREL 32 -#define R_ALPHA_DTPREL64 33 -#define R_ALPHA_DTPRELHI 34 -#define R_ALPHA_DTPRELLO 35 -#define R_ALPHA_DTPREL16 36 -#define R_ALPHA_GOTTPREL 37 -#define R_ALPHA_TPREL64 38 -#define R_ALPHA_TPRELHI 39 -#define R_ALPHA_TPRELLO 40 -#define R_ALPHA_TPREL16 41 -/* Keep this the last entry. */ -#define R_ALPHA_NUM 46 - -/* Magic values of the LITUSE relocation addend. */ -#define LITUSE_ALPHA_ADDR 0 -#define LITUSE_ALPHA_BASE 1 -#define LITUSE_ALPHA_BYTOFF 2 -#define LITUSE_ALPHA_JSR 3 -#define LITUSE_ALPHA_TLS_GD 4 -#define LITUSE_ALPHA_TLS_LDM 5 - -/* Legal values for d_tag of Elf64_Dyn. */ -#define DT_ALPHA_PLTRO (DT_LOPROC + 0) -#define DT_ALPHA_NUM 1 - -/* PowerPC specific declarations */ - -/* Values for Elf32/64_Ehdr.e_flags. */ -#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ - -/* Cygnus local bits below */ -#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ -#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib - flag */ - -/* PowerPC relocations defined by the ABIs */ -#define R_PPC_NONE 0 -#define R_PPC_ADDR32 1 /* 32bit absolute address */ -#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ -#define R_PPC_ADDR16 3 /* 16bit absolute address */ -#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ -#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ -#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ -#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ -#define R_PPC_ADDR14_BRTAKEN 8 -#define R_PPC_ADDR14_BRNTAKEN 9 -#define R_PPC_REL24 10 /* PC relative 26 bit */ -#define R_PPC_REL14 11 /* PC relative 16 bit */ -#define R_PPC_REL14_BRTAKEN 12 -#define R_PPC_REL14_BRNTAKEN 13 -#define R_PPC_GOT16 14 -#define R_PPC_GOT16_LO 15 -#define R_PPC_GOT16_HI 16 -#define R_PPC_GOT16_HA 17 -#define R_PPC_PLTREL24 18 -#define R_PPC_COPY 19 -#define R_PPC_GLOB_DAT 20 -#define R_PPC_JMP_SLOT 21 -#define R_PPC_RELATIVE 22 -#define R_PPC_LOCAL24PC 23 -#define R_PPC_UADDR32 24 -#define R_PPC_UADDR16 25 -#define R_PPC_REL32 26 -#define R_PPC_PLT32 27 -#define R_PPC_PLTREL32 28 -#define R_PPC_PLT16_LO 29 -#define R_PPC_PLT16_HI 30 -#define R_PPC_PLT16_HA 31 -#define R_PPC_SDAREL16 32 -#define R_PPC_SECTOFF 33 -#define R_PPC_SECTOFF_LO 34 -#define R_PPC_SECTOFF_HI 35 -#define R_PPC_SECTOFF_HA 36 - -/* PowerPC relocations defined for the TLS access ABI. */ -#define R_PPC_TLS 67 /* none (sym+add)@tls */ -#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ -#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ -#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ -#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ -#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ -#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ -#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ -#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ -#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ -#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ -#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ -#define R_PPC_TLSGD 95 /* none (sym+add)@tlsgd */ -#define R_PPC_TLSLD 96 /* none (sym+add)@tlsld */ - -/* The remaining relocs are from the Embedded ELF ABI, and are not - in the SVR4 ELF ABI. */ -#define R_PPC_EMB_NADDR32 101 -#define R_PPC_EMB_NADDR16 102 -#define R_PPC_EMB_NADDR16_LO 103 -#define R_PPC_EMB_NADDR16_HI 104 -#define R_PPC_EMB_NADDR16_HA 105 -#define R_PPC_EMB_SDAI16 106 -#define R_PPC_EMB_SDA2I16 107 -#define R_PPC_EMB_SDA2REL 108 -#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ -#define R_PPC_EMB_MRKREF 110 -#define R_PPC_EMB_RELSEC16 111 -#define R_PPC_EMB_RELST_LO 112 -#define R_PPC_EMB_RELST_HI 113 -#define R_PPC_EMB_RELST_HA 114 -#define R_PPC_EMB_BIT_FLD 115 -#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ - -/* Diab tool relocations. */ -#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ -#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ -#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ -#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ -#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ -#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ - -/* GNU extension to support local ifunc. */ -#define R_PPC_IRELATIVE 248 - -/* GNU relocs used in PIC code sequences. */ -#define R_PPC_REL16 249 /* half16 (sym+add-.) */ -#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ -#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ -#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ - -/* This is a phony reloc to handle any old fashioned TOC16 references - that may still be in object files. */ -#define R_PPC_TOC16 255 - -/* PowerPC specific values for the Dyn d_tag field. */ -#define DT_PPC_GOT (DT_LOPROC + 0) -#define DT_PPC_OPT (DT_LOPROC + 1) -#define DT_PPC_NUM 2 - -/* PowerPC specific values for the DT_PPC_OPT Dyn entry. */ -#define PPC_OPT_TLS 1 - -/* PowerPC64 relocations defined by the ABIs */ -#define R_PPC64_NONE R_PPC_NONE -#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ -#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ -#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ -#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ -#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ -#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ -#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ -#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN -#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN -#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ -#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ -#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN -#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN -#define R_PPC64_GOT16 R_PPC_GOT16 -#define R_PPC64_GOT16_LO R_PPC_GOT16_LO -#define R_PPC64_GOT16_HI R_PPC_GOT16_HI -#define R_PPC64_GOT16_HA R_PPC_GOT16_HA - -#define R_PPC64_COPY R_PPC_COPY -#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT -#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT -#define R_PPC64_RELATIVE R_PPC_RELATIVE - -#define R_PPC64_UADDR32 R_PPC_UADDR32 -#define R_PPC64_UADDR16 R_PPC_UADDR16 -#define R_PPC64_REL32 R_PPC_REL32 -#define R_PPC64_PLT32 R_PPC_PLT32 -#define R_PPC64_PLTREL32 R_PPC_PLTREL32 -#define R_PPC64_PLT16_LO R_PPC_PLT16_LO -#define R_PPC64_PLT16_HI R_PPC_PLT16_HI -#define R_PPC64_PLT16_HA R_PPC_PLT16_HA - -#define R_PPC64_SECTOFF R_PPC_SECTOFF -#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO -#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI -#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA -#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ -#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ -#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ -#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ -#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ -#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ -#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ -#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ -#define R_PPC64_PLT64 45 /* doubleword64 L + A */ -#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ -#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ -#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ -#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ -#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ -#define R_PPC64_TOC 51 /* doubleword64 .TOC */ -#define R_PPC64_PLTGOT16 52 /* half16* M + A */ -#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ -#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ -#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ - -#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ -#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ -#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ -#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ -#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ -#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ -#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ -#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ -#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ -#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ -#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ - -/* PowerPC64 relocations defined for the TLS access ABI. */ -#define R_PPC64_TLS 67 /* none (sym+add)@tls */ -#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ -#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ -#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ -#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ -#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ -#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ -#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ -#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ -#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ -#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ -#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ -#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ -#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ -#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ -#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ -#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ -#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ -#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ -#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ -#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ -#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ -#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ -#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ -#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ -#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ -#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ -#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ -#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ -#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ -#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ -#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ -#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ -#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ -#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ -#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ -#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ -#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ -#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ -#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ -#define R_PPC64_TLSGD 107 /* none (sym+add)@tlsgd */ -#define R_PPC64_TLSLD 108 /* none (sym+add)@tlsld */ -#define R_PPC64_TOCSAVE 109 /* none */ - -/* Added when HA and HI relocs were changed to report overflows. */ -#define R_PPC64_ADDR16_HIGH 110 -#define R_PPC64_ADDR16_HIGHA 111 -#define R_PPC64_TPREL16_HIGH 112 -#define R_PPC64_TPREL16_HIGHA 113 -#define R_PPC64_DTPREL16_HIGH 114 -#define R_PPC64_DTPREL16_HIGHA 115 - -/* GNU extension to support local ifunc. */ -#define R_PPC64_JMP_IREL 247 -#define R_PPC64_IRELATIVE 248 -#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ -#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ -#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ -#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ - -/* e_flags bits specifying ABI. - 1 for original function descriptor using ABI, - 2 for revised ABI without function descriptors, - 0 for unspecified or not using any features affected by the differences. */ -#define EF_PPC64_ABI 3 - -/* PowerPC64 specific values for the Dyn d_tag field. */ -#define DT_PPC64_GLINK (DT_LOPROC + 0) -#define DT_PPC64_OPD (DT_LOPROC + 1) -#define DT_PPC64_OPDSZ (DT_LOPROC + 2) -#define DT_PPC64_OPT (DT_LOPROC + 3) -#define DT_PPC64_NUM 4 - -/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry. */ -#define PPC64_OPT_TLS 1 -#define PPC64_OPT_MULTI_TOC 2 -#define PPC64_OPT_LOCALENTRY 4 - -/* PowerPC64 specific values for the Elf64_Sym st_other field. */ -#define STO_PPC64_LOCAL_BIT 5 -#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT) -#define PPC64_LOCAL_ENTRY_OFFSET(other) \ - (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2) - - -/* ARM specific declarations */ - -/* Processor specific flags for the ELF header e_flags field. */ -#define EF_ARM_RELEXEC 0x01 -#define EF_ARM_HASENTRY 0x02 -#define EF_ARM_INTERWORK 0x04 -#define EF_ARM_APCS_26 0x08 -#define EF_ARM_APCS_FLOAT 0x10 -#define EF_ARM_PIC 0x20 -#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ -#define EF_ARM_NEW_ABI 0x80 -#define EF_ARM_OLD_ABI 0x100 -#define EF_ARM_SOFT_FLOAT 0x200 -#define EF_ARM_VFP_FLOAT 0x400 -#define EF_ARM_MAVERICK_FLOAT 0x800 - -#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */ -#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */ - - -/* Other constants defined in the ARM ELF spec. version B-01. */ -/* NB. These conflict with values defined above. */ -#define EF_ARM_SYMSARESORTED 0x04 -#define EF_ARM_DYNSYMSUSESEGIDX 0x08 -#define EF_ARM_MAPSYMSFIRST 0x10 -#define EF_ARM_EABIMASK 0XFF000000 - -/* Constants defined in AAELF. */ -#define EF_ARM_BE8 0x00800000 -#define EF_ARM_LE8 0x00400000 - -#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) -#define EF_ARM_EABI_UNKNOWN 0x00000000 -#define EF_ARM_EABI_VER1 0x01000000 -#define EF_ARM_EABI_VER2 0x02000000 -#define EF_ARM_EABI_VER3 0x03000000 -#define EF_ARM_EABI_VER4 0x04000000 -#define EF_ARM_EABI_VER5 0x05000000 - -/* Additional symbol types for Thumb. */ -#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ -#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ - -/* ARM-specific values for sh_flags */ -#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ -#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined - in the input to a link step. */ - -/* ARM-specific program header flags */ -#define PF_ARM_SB 0x10000000 /* Segment contains the location - addressed by the static base. */ -#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ -#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ - -/* Processor specific values for the Phdr p_type field. */ -#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ - -/* Processor specific values for the Shdr sh_type field. */ -#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ -#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ -#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ - - -/* AArch64 relocs. */ - -#define R_AARCH64_NONE 0 /* No relocation. */ - -/* ILP32 AArch64 relocs. */ -#define R_AARCH64_P32_ABS32 1 /* Direct 32 bit. */ -#define R_AARCH64_P32_COPY 180 /* Copy symbol at runtime. */ -#define R_AARCH64_P32_GLOB_DAT 181 /* Create GOT entry. */ -#define R_AARCH64_P32_JUMP_SLOT 182 /* Create PLT entry. */ -#define R_AARCH64_P32_RELATIVE 183 /* Adjust by program base. */ -#define R_AARCH64_P32_TLS_DTPMOD 184 /* Module number, 32 bit. */ -#define R_AARCH64_P32_TLS_DTPREL 185 /* Module-relative offset, 32 bit. */ -#define R_AARCH64_P32_TLS_TPREL 186 /* TP-relative offset, 32 bit. */ -#define R_AARCH64_P32_TLSDESC 187 /* TLS Descriptor. */ -#define R_AARCH64_P32_IRELATIVE 188 /* STT_GNU_IFUNC relocation. */ - -/* LP64 AArch64 relocs. */ -#define R_AARCH64_ABS64 257 /* Direct 64 bit. */ -#define R_AARCH64_ABS32 258 /* Direct 32 bit. */ -#define R_AARCH64_ABS16 259 /* Direct 16-bit. */ -#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */ -#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */ -#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */ -#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */ -#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */ -#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */ -#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */ -#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */ -#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */ -#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */ -#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */ -#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */ -#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */ -#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */ -#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */ -#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */ -#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */ -#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */ -#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */ -#define R_AARCH64_CALL26 283 /* Likewise for CALL. */ -#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */ -#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */ -#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */ -#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */ -#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */ -#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */ -#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */ -#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */ -#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */ -#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */ -#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */ -#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */ -#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */ -#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */ -#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */ -#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */ -#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */ -#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */ -#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */ -#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */ -#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */ -#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */ -#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */ -#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */ -#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */ -#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */ -#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */ -#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */ -#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */ -#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */ -#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */ -#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */ -#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */ -#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */ -#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */ -#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */ -#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */ -#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */ -#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */ -#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */ -#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */ -#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */ -#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */ -#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */ -#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */ -#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */ -#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */ -#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */ -#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */ -#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */ -#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */ -#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */ -#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */ -#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */ -#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */ -#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */ -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */ -#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */ -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */ -#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */ -#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */ -#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ -#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ -#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ -#define R_AARCH64_TLS_DTPMOD 1028 /* Module number, 64 bit. */ -#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset, 64 bit. */ -#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset, 64 bit. */ -#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ -#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ - -/* ARM relocs. */ - -#define R_ARM_NONE 0 /* No reloc */ -#define R_ARM_PC24 1 /* Deprecated PC relative 26 - bit branch. */ -#define R_ARM_ABS32 2 /* Direct 32 bit */ -#define R_ARM_REL32 3 /* PC relative 32 bit */ -#define R_ARM_PC13 4 -#define R_ARM_ABS16 5 /* Direct 16 bit */ -#define R_ARM_ABS12 6 /* Direct 12 bit */ -#define R_ARM_THM_ABS5 7 /* Direct & 0x7C (LDR, STR). */ -#define R_ARM_ABS8 8 /* Direct 8 bit */ -#define R_ARM_SBREL32 9 -#define R_ARM_THM_PC22 10 /* PC relative 24 bit (Thumb32 BL). */ -#define R_ARM_THM_PC8 11 /* PC relative & 0x3FC - (Thumb16 LDR, ADD, ADR). */ -#define R_ARM_AMP_VCALL9 12 -#define R_ARM_SWI24 13 /* Obsolete static relocation. */ -#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ -#define R_ARM_THM_SWI8 14 /* Reserved. */ -#define R_ARM_XPC25 15 /* Reserved. */ -#define R_ARM_THM_XPC22 16 /* Reserved. */ -#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ -#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ -#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ -#define R_ARM_COPY 20 /* Copy symbol at runtime */ -#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ -#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ -#define R_ARM_RELATIVE 23 /* Adjust by program base */ -#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ -#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ -#define R_ARM_GOT32 26 /* 32 bit GOT entry */ -#define R_ARM_PLT32 27 /* Deprecated, 32 bit PLT address. */ -#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */ -#define R_ARM_JUMP24 29 /* PC relative 24 bit - (B, BL). */ -#define R_ARM_THM_JUMP24 30 /* PC relative 24 bit (Thumb32 B.W). */ -#define R_ARM_BASE_ABS 31 /* Adjust by program base. */ -#define R_ARM_ALU_PCREL_7_0 32 /* Obsolete. */ -#define R_ARM_ALU_PCREL_15_8 33 /* Obsolete. */ -#define R_ARM_ALU_PCREL_23_15 34 /* Obsolete. */ -#define R_ARM_LDR_SBREL_11_0 35 /* Deprecated, prog. base relative. */ -#define R_ARM_ALU_SBREL_19_12 36 /* Deprecated, prog. base relative. */ -#define R_ARM_ALU_SBREL_27_20 37 /* Deprecated, prog. base relative. */ -#define R_ARM_TARGET1 38 -#define R_ARM_SBREL31 39 /* Program base relative. */ -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 /* 32 bit PC relative. */ -#define R_ARM_MOVW_ABS_NC 43 /* Direct 16-bit (MOVW). */ -#define R_ARM_MOVT_ABS 44 /* Direct high 16-bit (MOVT). */ -#define R_ARM_MOVW_PREL_NC 45 /* PC relative 16-bit (MOVW). */ -#define R_ARM_MOVT_PREL 46 /* PC relative (MOVT). */ -#define R_ARM_THM_MOVW_ABS_NC 47 /* Direct 16 bit (Thumb32 MOVW). */ -#define R_ARM_THM_MOVT_ABS 48 /* Direct high 16 bit - (Thumb32 MOVT). */ -#define R_ARM_THM_MOVW_PREL_NC 49 /* PC relative 16 bit - (Thumb32 MOVW). */ -#define R_ARM_THM_MOVT_PREL 50 /* PC relative high 16 bit - (Thumb32 MOVT). */ -#define R_ARM_THM_JUMP19 51 /* PC relative 20 bit - (Thumb32 B.W). */ -#define R_ARM_THM_JUMP6 52 /* PC relative X & 0x7E - (Thumb16 CBZ, CBNZ). */ -#define R_ARM_THM_ALU_PREL_11_0 53 /* PC relative 12 bit - (Thumb32 ADR.W). */ -#define R_ARM_THM_PC12 54 /* PC relative 12 bit - (Thumb32 LDR{D,SB,H,SH}). */ -#define R_ARM_ABS32_NOI 55 /* Direct 32-bit. */ -#define R_ARM_REL32_NOI 56 /* PC relative 32-bit. */ -#define R_ARM_ALU_PC_G0_NC 57 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G0 58 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G1_NC 59 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G1 60 /* PC relative (ADD, SUB). */ -#define R_ARM_ALU_PC_G2 61 /* PC relative (ADD, SUB). */ -#define R_ARM_LDR_PC_G1 62 /* PC relative (LDR,STR,LDRB,STRB). */ -#define R_ARM_LDR_PC_G2 63 /* PC relative (LDR,STR,LDRB,STRB). */ -#define R_ARM_LDRS_PC_G0 64 /* PC relative (STR{D,H}, - LDR{D,SB,H,SH}). */ -#define R_ARM_LDRS_PC_G1 65 /* PC relative (STR{D,H}, - LDR{D,SB,H,SH}). */ -#define R_ARM_LDRS_PC_G2 66 /* PC relative (STR{D,H}, - LDR{D,SB,H,SH}). */ -#define R_ARM_LDC_PC_G0 67 /* PC relative (LDC, STC). */ -#define R_ARM_LDC_PC_G1 68 /* PC relative (LDC, STC). */ -#define R_ARM_LDC_PC_G2 69 /* PC relative (LDC, STC). */ -#define R_ARM_ALU_SB_G0_NC 70 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G0 71 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G1_NC 72 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G1 73 /* Program base relative (ADD,SUB). */ -#define R_ARM_ALU_SB_G2 74 /* Program base relative (ADD,SUB). */ -#define R_ARM_LDR_SB_G0 75 /* Program base relative (LDR, - STR, LDRB, STRB). */ -#define R_ARM_LDR_SB_G1 76 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDR_SB_G2 77 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDRS_SB_G0 78 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDRS_SB_G1 79 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDRS_SB_G2 80 /* Program base relative - (LDR, STR, LDRB, STRB). */ -#define R_ARM_LDC_SB_G0 81 /* Program base relative (LDC,STC). */ -#define R_ARM_LDC_SB_G1 82 /* Program base relative (LDC,STC). */ -#define R_ARM_LDC_SB_G2 83 /* Program base relative (LDC,STC). */ -#define R_ARM_MOVW_BREL_NC 84 /* Program base relative 16 - bit (MOVW). */ -#define R_ARM_MOVT_BREL 85 /* Program base relative high - 16 bit (MOVT). */ -#define R_ARM_MOVW_BREL 86 /* Program base relative 16 - bit (MOVW). */ -#define R_ARM_THM_MOVW_BREL_NC 87 /* Program base relative 16 - bit (Thumb32 MOVW). */ -#define R_ARM_THM_MOVT_BREL 88 /* Program base relative high - 16 bit (Thumb32 MOVT). */ -#define R_ARM_THM_MOVW_BREL 89 /* Program base relative 16 - bit (Thumb32 MOVW). */ -#define R_ARM_TLS_GOTDESC 90 -#define R_ARM_TLS_CALL 91 -#define R_ARM_TLS_DESCSEQ 92 /* TLS relaxation. */ -#define R_ARM_THM_TLS_CALL 93 -#define R_ARM_PLT32_ABS 94 -#define R_ARM_GOT_ABS 95 /* GOT entry. */ -#define R_ARM_GOT_PREL 96 /* PC relative GOT entry. */ -#define R_ARM_GOT_BREL12 97 /* GOT entry relative to GOT - origin (LDR). */ -#define R_ARM_GOTOFF12 98 /* 12 bit, GOT entry relative - to GOT origin (LDR, STR). */ -#define R_ARM_GOTRELAX 99 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 -#define R_ARM_THM_PC11 102 /* PC relative & 0xFFE (Thumb16 B). */ -#define R_ARM_THM_PC9 103 /* PC relative & 0x1FE - (Thumb16 B/B). */ -#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic - thread local data */ -#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic - thread local data */ -#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS - block */ -#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of - static TLS block offset */ -#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static - TLS block */ -#define R_ARM_TLS_LDO12 109 /* 12 bit relative to TLS - block (LDR, STR). */ -#define R_ARM_TLS_LE12 110 /* 12 bit relative to static - TLS block (LDR, STR). */ -#define R_ARM_TLS_IE12GP 111 /* 12 bit GOT entry relative - to GOT origin (LDR). */ -#define R_ARM_ME_TOO 128 /* Obsolete. */ -#define R_ARM_THM_TLS_DESCSEQ 129 -#define R_ARM_THM_TLS_DESCSEQ16 129 -#define R_ARM_THM_TLS_DESCSEQ32 130 -#define R_ARM_THM_GOT_BREL12 131 /* GOT entry relative to GOT - origin, 12 bit (Thumb32 LDR). */ -#define R_ARM_IRELATIVE 160 -#define R_ARM_RXPC25 249 -#define R_ARM_RSBREL32 250 -#define R_ARM_THM_RPC22 251 -#define R_ARM_RREL32 252 -#define R_ARM_RABS22 253 -#define R_ARM_RPC24 254 -#define R_ARM_RBASE 255 -/* Keep this the last entry. */ -#define R_ARM_NUM 256 - -/* csky */ -#define R_CKCORE_NONE 0 /* no reloc */ -#define R_CKCORE_ADDR32 1 /* direct 32 bit (S + A) */ -#define R_CKCORE_PCRELIMM8BY4 2 /* disp ((S + A - P) >> 2) & 0xff */ -#define R_CKCORE_PCRELIMM11BY2 3 /* disp ((S + A - P) >> 1) & 0x7ff */ -#define R_CKCORE_PCREL32 5 /* 32-bit rel (S + A - P) */ -#define R_CKCORE_PCRELJSR_IMM11BY2 6 /* disp ((S + A - P) >>1) & 0x7ff */ -#define R_CKCORE_RELATIVE 9 /* 32 bit adjust program base(B + A)*/ -#define R_CKCORE_COPY 10 /* 32 bit adjust by program base */ -#define R_CKCORE_GLOB_DAT 11 /* off between got and sym (S) */ -#define R_CKCORE_JUMP_SLOT 12 /* PLT entry (S) */ -#define R_CKCORE_GOTOFF 13 /* offset to GOT (S + A - GOT) */ -#define R_CKCORE_GOTPC 14 /* PC offset to GOT (GOT + A - P) */ -#define R_CKCORE_GOT32 15 /* 32 bit GOT entry (G) */ -#define R_CKCORE_PLT32 16 /* 32 bit PLT entry (G) */ -#define R_CKCORE_ADDRGOT 17 /* GOT entry in GLOB_DAT (GOT + G) */ -#define R_CKCORE_ADDRPLT 18 /* PLT entry in GLOB_DAT (GOT + G) */ -#define R_CKCORE_PCREL_IMM26BY2 19 /* ((S + A - P) >> 1) & 0x3ffffff */ -#define R_CKCORE_PCREL_IMM16BY2 20 /* disp ((S + A - P) >> 1) & 0xffff */ -#define R_CKCORE_PCREL_IMM16BY4 21 /* disp ((S + A - P) >> 2) & 0xffff */ -#define R_CKCORE_PCREL_IMM10BY2 22 /* disp ((S + A - P) >> 1) & 0x3ff */ -#define R_CKCORE_PCREL_IMM10BY4 23 /* disp ((S + A - P) >> 2) & 0x3ff */ -#define R_CKCORE_ADDR_HI16 24 /* high & low 16 bit ADDR */ - /* ((S + A) >> 16) & 0xffff */ -#define R_CKCORE_ADDR_LO16 25 /* (S + A) & 0xffff */ -#define R_CKCORE_GOTPC_HI16 26 /* high & low 16 bit GOTPC */ - /* ((GOT + A - P) >> 16) & 0xffff */ -#define R_CKCORE_GOTPC_LO16 27 /* (GOT + A - P) & 0xffff */ -#define R_CKCORE_GOTOFF_HI16 28 /* high & low 16 bit GOTOFF */ - /* ((S + A - GOT) >> 16) & 0xffff */ -#define R_CKCORE_GOTOFF_LO16 29 /* (S + A - GOT) & 0xffff */ -#define R_CKCORE_GOT12 30 /* 12 bit disp GOT entry (G) */ -#define R_CKCORE_GOT_HI16 31 /* high & low 16 bit GOT */ - /* (G >> 16) & 0xffff */ -#define R_CKCORE_GOT_LO16 32 /* (G & 0xffff) */ -#define R_CKCORE_PLT12 33 /* 12 bit disp PLT entry (G) */ -#define R_CKCORE_PLT_HI16 34 /* high & low 16 bit PLT */ - /* (G >> 16) & 0xffff */ -#define R_CKCORE_PLT_LO16 35 /* G & 0xffff */ -#define R_CKCORE_ADDRGOT_HI16 36 /* high & low 16 bit ADDRGOT */ - /* (GOT + G * 4) & 0xffff */ -#define R_CKCORE_ADDRGOT_LO16 37 /* (GOT + G * 4) & 0xffff */ -#define R_CKCORE_ADDRPLT_HI16 38 /* high & low 16 bit ADDRPLT */ - /* ((GOT + G * 4) >> 16) & 0xFFFF */ -#define R_CKCORE_ADDRPLT_LO16 39 /* (GOT+G*4) & 0xffff */ -#define R_CKCORE_PCREL_JSR_IMM26BY2 40 /* disp ((S+A-P) >>1) & x3ffffff */ -#define R_CKCORE_TOFFSET_LO16 41 /* (S+A-BTEXT) & 0xffff */ -#define R_CKCORE_DOFFSET_LO16 42 /* (S+A-BTEXT) & 0xffff */ -#define R_CKCORE_PCREL_IMM18BY2 43 /* disp ((S+A-P) >>1) & 0x3ffff */ -#define R_CKCORE_DOFFSET_IMM18 44 /* disp (S+A-BDATA) & 0x3ffff */ -#define R_CKCORE_DOFFSET_IMM18BY2 45 /* disp ((S+A-BDATA)>>1) & 0x3ffff */ -#define R_CKCORE_DOFFSET_IMM18BY4 46 /* disp ((S+A-BDATA)>>2) & 0x3ffff */ -#define R_CKCORE_GOT_IMM18BY4 48 /* disp (G >> 2) */ -#define R_CKCORE_PLT_IMM18BY4 49 /* disp (G >> 2) */ -#define R_CKCORE_PCREL_IMM7BY4 50 /* disp ((S+A-P) >>2) & 0x7f */ -#define R_CKCORE_TLS_LE32 51 /* 32 bit offset to TLS block */ -#define R_CKCORE_TLS_IE32 52 -#define R_CKCORE_TLS_GD32 53 -#define R_CKCORE_TLS_LDM32 54 -#define R_CKCORE_TLS_LDO32 55 -#define R_CKCORE_TLS_DTPMOD32 56 -#define R_CKCORE_TLS_DTPOFF32 57 -#define R_CKCORE_TLS_TPOFF32 58 - -/* IA-64 specific declarations. */ - -/* Processor specific flags for the Ehdr e_flags field. */ -#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ -#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ -#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ - -/* Processor specific values for the Phdr p_type field. */ -#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ -#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ -#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) -#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) -#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) - -/* Processor specific flags for the Phdr p_flags field. */ -#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ - -/* Processor specific values for the Shdr sh_type field. */ -#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ -#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ - -/* Processor specific flags for the Shdr sh_flags field. */ -#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ -#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ - -/* Processor specific values for the Dyn d_tag field. */ -#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) -#define DT_IA_64_NUM 1 - -/* IA-64 relocations. */ -#define R_IA64_NONE 0x00 /* none */ -#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ -#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ -#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ -#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ -#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ -#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ -#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ -#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ -#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ -#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ -#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ -#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ -#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ -#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ -#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ -#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ -#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ -#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ -#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ -#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ -#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ -#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ -#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ -#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ -#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ -#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ -#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ -#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ -#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ -#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ -#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ -#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ -#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ -#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ -#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ -#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ -#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ -#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ -#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ -#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ -#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ -#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ -#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ -#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ -#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ -#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ -#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ -#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ -#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ -#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ -#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ -#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ -#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ -#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ -#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ -#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ -#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ -#define R_IA64_COPY 0x84 /* copy relocation */ -#define R_IA64_SUB 0x85 /* Addend and symbol difference */ -#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ -#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ -#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ -#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ -#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ -#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ -#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ -#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ -#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ -#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ -#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ -#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ -#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ -#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ -#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ -#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ -#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ -#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ - -/* SH specific declarations */ - -/* Processor specific flags for the ELF header e_flags field. */ -#define EF_SH_MACH_MASK 0x1f -#define EF_SH_UNKNOWN 0x0 -#define EF_SH1 0x1 -#define EF_SH2 0x2 -#define EF_SH3 0x3 -#define EF_SH_DSP 0x4 -#define EF_SH3_DSP 0x5 -#define EF_SH4AL_DSP 0x6 -#define EF_SH3E 0x8 -#define EF_SH4 0x9 -#define EF_SH2E 0xb -#define EF_SH4A 0xc -#define EF_SH2A 0xd -#define EF_SH4_NOFPU 0x10 -#define EF_SH4A_NOFPU 0x11 -#define EF_SH4_NOMMU_NOFPU 0x12 -#define EF_SH2A_NOFPU 0x13 -#define EF_SH3_NOMMU 0x14 -#define EF_SH2A_SH4_NOFPU 0x15 -#define EF_SH2A_SH3_NOFPU 0x16 -#define EF_SH2A_SH4 0x17 -#define EF_SH2A_SH3E 0x18 - -/* SH relocs. */ -#define R_SH_NONE 0 -#define R_SH_DIR32 1 -#define R_SH_REL32 2 -#define R_SH_DIR8WPN 3 -#define R_SH_IND12W 4 -#define R_SH_DIR8WPL 5 -#define R_SH_DIR8WPZ 6 -#define R_SH_DIR8BP 7 -#define R_SH_DIR8W 8 -#define R_SH_DIR8L 9 -#define R_SH_SWITCH16 25 -#define R_SH_SWITCH32 26 -#define R_SH_USES 27 -#define R_SH_COUNT 28 -#define R_SH_ALIGN 29 -#define R_SH_CODE 30 -#define R_SH_DATA 31 -#define R_SH_LABEL 32 -#define R_SH_SWITCH8 33 -#define R_SH_GNU_VTINHERIT 34 -#define R_SH_GNU_VTENTRY 35 -#define R_SH_TLS_GD_32 144 -#define R_SH_TLS_LD_32 145 -#define R_SH_TLS_LDO_32 146 -#define R_SH_TLS_IE_32 147 -#define R_SH_TLS_LE_32 148 -#define R_SH_TLS_DTPMOD32 149 -#define R_SH_TLS_DTPOFF32 150 -#define R_SH_TLS_TPOFF32 151 -#define R_SH_GOT32 160 -#define R_SH_PLT32 161 -#define R_SH_COPY 162 -#define R_SH_GLOB_DAT 163 -#define R_SH_JMP_SLOT 164 -#define R_SH_RELATIVE 165 -#define R_SH_GOTOFF 166 -#define R_SH_GOTPC 167 -/* Keep this the last entry. */ -#define R_SH_NUM 256 - -/* S/390 specific definitions. */ - -/* Valid values for the e_flags field. */ - -#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ - -/* Additional s390 relocs */ - -#define R_390_NONE 0 /* No reloc. */ -#define R_390_8 1 /* Direct 8 bit. */ -#define R_390_12 2 /* Direct 12 bit. */ -#define R_390_16 3 /* Direct 16 bit. */ -#define R_390_32 4 /* Direct 32 bit. */ -#define R_390_PC32 5 /* PC relative 32 bit. */ -#define R_390_GOT12 6 /* 12 bit GOT offset. */ -#define R_390_GOT32 7 /* 32 bit GOT offset. */ -#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ -#define R_390_COPY 9 /* Copy symbol at runtime. */ -#define R_390_GLOB_DAT 10 /* Create GOT entry. */ -#define R_390_JMP_SLOT 11 /* Create PLT entry. */ -#define R_390_RELATIVE 12 /* Adjust by program base. */ -#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ -#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ -#define R_390_GOT16 15 /* 16 bit GOT offset. */ -#define R_390_PC16 16 /* PC relative 16 bit. */ -#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ -#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ -#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ -#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ -#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ -#define R_390_64 22 /* Direct 64 bit. */ -#define R_390_PC64 23 /* PC relative 64 bit. */ -#define R_390_GOT64 24 /* 64 bit GOT offset. */ -#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ -#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ -#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ -#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ -#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ -#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ -#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ -#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ -#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ -#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ -#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ -#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ -#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ -#define R_390_TLS_GDCALL 38 /* Tag for function call in general - dynamic TLS code. */ -#define R_390_TLS_LDCALL 39 /* Tag for function call in local - dynamic TLS code. */ -#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic - thread local data. */ -#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic - thread local data. */ -#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS - block offset. */ -#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic - thread local data in LE code. */ -#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic - thread local data in LE code. */ -#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for - negated static TLS block offset. */ -#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to - static TLS block. */ -#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to - static TLS block. */ -#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS - block. */ -#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS - block. */ -#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ -#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ -#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS - block. */ -#define R_390_20 57 /* Direct 20 bit. */ -#define R_390_GOT20 58 /* 20 bit GOT offset. */ -#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ -#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS - block offset. */ -#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ -/* Keep this the last entry. */ -#define R_390_NUM 62 - - -/* CRIS relocations. */ -#define R_CRIS_NONE 0 -#define R_CRIS_8 1 -#define R_CRIS_16 2 -#define R_CRIS_32 3 -#define R_CRIS_8_PCREL 4 -#define R_CRIS_16_PCREL 5 -#define R_CRIS_32_PCREL 6 -#define R_CRIS_GNU_VTINHERIT 7 -#define R_CRIS_GNU_VTENTRY 8 -#define R_CRIS_COPY 9 -#define R_CRIS_GLOB_DAT 10 -#define R_CRIS_JUMP_SLOT 11 -#define R_CRIS_RELATIVE 12 -#define R_CRIS_16_GOT 13 -#define R_CRIS_32_GOT 14 -#define R_CRIS_16_GOTPLT 15 -#define R_CRIS_32_GOTPLT 16 -#define R_CRIS_32_GOTREL 17 -#define R_CRIS_32_PLT_GOTREL 18 -#define R_CRIS_32_PLT_PCREL 19 - -#define R_CRIS_NUM 20 - - -/* AMD x86-64 relocations. */ -#define R_X86_64_NONE 0 /* No reloc */ -#define R_X86_64_64 1 /* Direct 64 bit */ -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ -#define R_X86_64_PLT32 4 /* 32 bit PLT address */ -#define R_X86_64_COPY 5 /* Copy symbol at runtime */ -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ -#define R_X86_64_RELATIVE 8 /* Adjust by program base */ -#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative - offset to GOT */ -#define R_X86_64_32 10 /* Direct 32 bit zero extended */ -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ -#define R_X86_64_16 12 /* Direct 16 bit zero extended */ -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ -#define R_X86_64_8 14 /* Direct 8 bit sign extended */ -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ -#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ -#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ -#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ -#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset - to two GOT entries for GD symbol */ -#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset - to two GOT entries for LD symbol */ -#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ -#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset - to GOT entry for IE symbol */ -#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ -#define R_X86_64_PC64 24 /* PC relative 64 bit */ -#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ -#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative - offset to GOT */ -#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ -#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset - to GOT entry */ -#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ -#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ -#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset - to PLT entry */ -#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ -#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ -#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ -#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS - descriptor. */ -#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ -#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ - /* 39 Reserved was R_X86_64_PC32_BND */ - /* 40 Reserved was R_X86_64_PLT32_BND */ -#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative - offset to GOT entry without REX - prefix, relaxable. */ -#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative - offset to GOT entry with REX prefix, - relaxable. */ -#define R_X86_64_NUM 43 - -/* x86-64 sh_type values. */ -#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */ - - -/* AM33 relocations. */ -#define R_MN10300_NONE 0 /* No reloc. */ -#define R_MN10300_32 1 /* Direct 32 bit. */ -#define R_MN10300_16 2 /* Direct 16 bit. */ -#define R_MN10300_8 3 /* Direct 8 bit. */ -#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ -#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ -#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ -#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ -#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ -#define R_MN10300_24 9 /* Direct 24 bit. */ -#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ -#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ -#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ -#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ -#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ -#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ -#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ -#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ -#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ -#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ -#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ -#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ -#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ -#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ -#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */ -#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */ -#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */ -#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block - offset. */ -#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block - offset. */ -#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS - block. */ -#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */ -#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */ -#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */ -#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed - by linker relaxation. */ -#define R_MN10300_ALIGN 34 /* Alignment requirement for linker - relaxation. */ -#define R_MN10300_NUM 35 - - -/* M32R relocs. */ -#define R_M32R_NONE 0 /* No reloc. */ -#define R_M32R_16 1 /* Direct 16 bit. */ -#define R_M32R_32 2 /* Direct 32 bit. */ -#define R_M32R_24 3 /* Direct 24 bit. */ -#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ -#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ -#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ -#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ -#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ -#define R_M32R_LO16 9 /* Low 16 bit. */ -#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ -#define R_M32R_GNU_VTINHERIT 11 -#define R_M32R_GNU_VTENTRY 12 -/* M32R relocs use SHT_RELA. */ -#define R_M32R_16_RELA 33 /* Direct 16 bit. */ -#define R_M32R_32_RELA 34 /* Direct 32 bit. */ -#define R_M32R_24_RELA 35 /* Direct 24 bit. */ -#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ -#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ -#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ -#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ -#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ -#define R_M32R_LO16_RELA 41 /* Low 16 bit */ -#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ -#define R_M32R_RELA_GNU_VTINHERIT 43 -#define R_M32R_RELA_GNU_VTENTRY 44 -#define R_M32R_REL32 45 /* PC relative 32 bit. */ - -#define R_M32R_GOT24 48 /* 24 bit GOT entry */ -#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ -#define R_M32R_COPY 50 /* Copy symbol at runtime */ -#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ -#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ -#define R_M32R_RELATIVE 53 /* Adjust by program base */ -#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ -#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ -#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned - low */ -#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed - low */ -#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ -#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to - GOT with unsigned low */ -#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to - GOT with signed low */ -#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to - GOT */ -#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT - with unsigned low */ -#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT - with signed low */ -#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ -#define R_M32R_NUM 256 /* Keep this the last entry. */ - -/* MicroBlaze relocations */ -#define R_MICROBLAZE_NONE 0 /* No reloc. */ -#define R_MICROBLAZE_32 1 /* Direct 32 bit. */ -#define R_MICROBLAZE_32_PCREL 2 /* PC relative 32 bit. */ -#define R_MICROBLAZE_64_PCREL 3 /* PC relative 64 bit. */ -#define R_MICROBLAZE_32_PCREL_LO 4 /* Low 16 bits of PCREL32. */ -#define R_MICROBLAZE_64 5 /* Direct 64 bit. */ -#define R_MICROBLAZE_32_LO 6 /* Low 16 bit. */ -#define R_MICROBLAZE_SRO32 7 /* Read-only small data area. */ -#define R_MICROBLAZE_SRW32 8 /* Read-write small data area. */ -#define R_MICROBLAZE_64_NONE 9 /* No reloc. */ -#define R_MICROBLAZE_32_SYM_OP_SYM 10 /* Symbol Op Symbol relocation. */ -#define R_MICROBLAZE_GNU_VTINHERIT 11 /* GNU C++ vtable hierarchy. */ -#define R_MICROBLAZE_GNU_VTENTRY 12 /* GNU C++ vtable member usage. */ -#define R_MICROBLAZE_GOTPC_64 13 /* PC-relative GOT offset. */ -#define R_MICROBLAZE_GOT_64 14 /* GOT entry offset. */ -#define R_MICROBLAZE_PLT_64 15 /* PLT offset (PC-relative). */ -#define R_MICROBLAZE_REL 16 /* Adjust by program base. */ -#define R_MICROBLAZE_JUMP_SLOT 17 /* Create PLT entry. */ -#define R_MICROBLAZE_GLOB_DAT 18 /* Create GOT entry. */ -#define R_MICROBLAZE_GOTOFF_64 19 /* 64 bit offset to GOT. */ -#define R_MICROBLAZE_GOTOFF_32 20 /* 32 bit offset to GOT. */ -#define R_MICROBLAZE_COPY 21 /* Runtime copy. */ -#define R_MICROBLAZE_TLS 22 /* TLS Reloc. */ -#define R_MICROBLAZE_TLSGD 23 /* TLS General Dynamic. */ -#define R_MICROBLAZE_TLSLD 24 /* TLS Local Dynamic. */ -#define R_MICROBLAZE_TLSDTPMOD32 25 /* TLS Module ID. */ -#define R_MICROBLAZE_TLSDTPREL32 26 /* TLS Offset Within TLS Block. */ -#define R_MICROBLAZE_TLSDTPREL64 27 /* TLS Offset Within TLS Block. */ -#define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */ -#define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */ - -/* Legal values for d_tag (dynamic entry type). */ -#define DT_NIOS2_GP 0x70000002 /* Address of _gp. */ - -/* Nios II relocations. */ -#define R_NIOS2_NONE 0 /* No reloc. */ -#define R_NIOS2_S16 1 /* Direct signed 16 bit. */ -#define R_NIOS2_U16 2 /* Direct unsigned 16 bit. */ -#define R_NIOS2_PCREL16 3 /* PC relative 16 bit. */ -#define R_NIOS2_CALL26 4 /* Direct call. */ -#define R_NIOS2_IMM5 5 /* 5 bit constant expression. */ -#define R_NIOS2_CACHE_OPX 6 /* 5 bit expression, shift 22. */ -#define R_NIOS2_IMM6 7 /* 6 bit constant expression. */ -#define R_NIOS2_IMM8 8 /* 8 bit constant expression. */ -#define R_NIOS2_HI16 9 /* High 16 bit. */ -#define R_NIOS2_LO16 10 /* Low 16 bit. */ -#define R_NIOS2_HIADJ16 11 /* High 16 bit, adjusted. */ -#define R_NIOS2_BFD_RELOC_32 12 /* 32 bit symbol value + addend. */ -#define R_NIOS2_BFD_RELOC_16 13 /* 16 bit symbol value + addend. */ -#define R_NIOS2_BFD_RELOC_8 14 /* 8 bit symbol value + addend. */ -#define R_NIOS2_GPREL 15 /* 16 bit GP pointer offset. */ -#define R_NIOS2_GNU_VTINHERIT 16 /* GNU C++ vtable hierarchy. */ -#define R_NIOS2_GNU_VTENTRY 17 /* GNU C++ vtable member usage. */ -#define R_NIOS2_UJMP 18 /* Unconditional branch. */ -#define R_NIOS2_CJMP 19 /* Conditional branch. */ -#define R_NIOS2_CALLR 20 /* Indirect call through register. */ -#define R_NIOS2_ALIGN 21 /* Alignment requirement for - linker relaxation. */ -#define R_NIOS2_GOT16 22 /* 16 bit GOT entry. */ -#define R_NIOS2_CALL16 23 /* 16 bit GOT entry for function. */ -#define R_NIOS2_GOTOFF_LO 24 /* %lo of offset to GOT pointer. */ -#define R_NIOS2_GOTOFF_HA 25 /* %hiadj of offset to GOT pointer. */ -#define R_NIOS2_PCREL_LO 26 /* %lo of PC relative offset. */ -#define R_NIOS2_PCREL_HA 27 /* %hiadj of PC relative offset. */ -#define R_NIOS2_TLS_GD16 28 /* 16 bit GOT offset for TLS GD. */ -#define R_NIOS2_TLS_LDM16 29 /* 16 bit GOT offset for TLS LDM. */ -#define R_NIOS2_TLS_LDO16 30 /* 16 bit module relative offset. */ -#define R_NIOS2_TLS_IE16 31 /* 16 bit GOT offset for TLS IE. */ -#define R_NIOS2_TLS_LE16 32 /* 16 bit LE TP-relative offset. */ -#define R_NIOS2_TLS_DTPMOD 33 /* Module number. */ -#define R_NIOS2_TLS_DTPREL 34 /* Module-relative offset. */ -#define R_NIOS2_TLS_TPREL 35 /* TP-relative offset. */ -#define R_NIOS2_COPY 36 /* Copy symbol at runtime. */ -#define R_NIOS2_GLOB_DAT 37 /* Create GOT entry. */ -#define R_NIOS2_JUMP_SLOT 38 /* Create PLT entry. */ -#define R_NIOS2_RELATIVE 39 /* Adjust by program base. */ -#define R_NIOS2_GOTOFF 40 /* 16 bit offset to GOT pointer. */ -#define R_NIOS2_CALL26_NOAT 41 /* Direct call in .noat section. */ -#define R_NIOS2_GOT_LO 42 /* %lo() of GOT entry. */ -#define R_NIOS2_GOT_HA 43 /* %hiadj() of GOT entry. */ -#define R_NIOS2_CALL_LO 44 /* %lo() of function GOT entry. */ -#define R_NIOS2_CALL_HA 45 /* %hiadj() of function GOT entry. */ - -/* TILEPro relocations. */ -#define R_TILEPRO_NONE 0 /* No reloc */ -#define R_TILEPRO_32 1 /* Direct 32 bit */ -#define R_TILEPRO_16 2 /* Direct 16 bit */ -#define R_TILEPRO_8 3 /* Direct 8 bit */ -#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ -#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ -#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ -#define R_TILEPRO_LO16 7 /* Low 16 bit */ -#define R_TILEPRO_HI16 8 /* High 16 bit */ -#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ -#define R_TILEPRO_COPY 10 /* Copy relocation */ -#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ -#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ -#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ -#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ -#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ -#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ -#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ -#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ -#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ -#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ -#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ -#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ -#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ -#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ -#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ -#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ -#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ -#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ -#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ -#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ -#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ -#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ -#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ -#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ -#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ -#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ -#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ -#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ -#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ -#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ -#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ -#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ -#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ -#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ -#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ -#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ -#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ -#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ -#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ -/* Relocs 56-59 are currently not defined. */ -#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ -#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ -#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ -#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ -#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ -#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ -#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ -#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ -#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ -#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ -#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ - -#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ - -#define R_TILEPRO_NUM 130 - - -/* TILE-Gx relocations. */ -#define R_TILEGX_NONE 0 /* No reloc */ -#define R_TILEGX_64 1 /* Direct 64 bit */ -#define R_TILEGX_32 2 /* Direct 32 bit */ -#define R_TILEGX_16 3 /* Direct 16 bit */ -#define R_TILEGX_8 4 /* Direct 8 bit */ -#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ -#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ -#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ -#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ -#define R_TILEGX_HW0 9 /* hword 0 16-bit */ -#define R_TILEGX_HW1 10 /* hword 1 16-bit */ -#define R_TILEGX_HW2 11 /* hword 2 16-bit */ -#define R_TILEGX_HW3 12 /* hword 3 16-bit */ -#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ -#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ -#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ -#define R_TILEGX_COPY 16 /* Copy relocation */ -#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ -#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ -#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ -#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ -#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ -#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ -#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ -#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ -#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ -#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ -#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ -#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ -#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ -#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ -#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ -#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ -#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ -#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ -#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ -#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ -#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ -#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ -#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ -#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ -#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ -#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ -#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ -#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ -#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ -#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ -#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ -#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ -#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ -#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ -#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */ -#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */ -#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ -#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ -/* Relocs 90-91 are currently not defined. */ -#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ -#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ -#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */ -#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */ -#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */ -#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */ -#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */ -#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */ -#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ -#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ -#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ -#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ -/* Relocs 104-105 are currently not defined. */ -#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ -#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ -#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ -#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ -#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ -#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ -#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ -#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ -#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ -#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ -#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ -#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ - -#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ -#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ - -#define R_TILEGX_NUM 130 - -/* RISC-V ELF Flags */ -#define EF_RISCV_RVC 0x0001 -#define EF_RISCV_FLOAT_ABI 0x0006 -#define EF_RISCV_FLOAT_ABI_SOFT 0x0000 -#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002 -#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004 -#define EF_RISCV_FLOAT_ABI_QUAD 0x0006 - -/* RISC-V relocations. */ -#define R_RISCV_NONE 0 -#define R_RISCV_32 1 -#define R_RISCV_64 2 -#define R_RISCV_RELATIVE 3 -#define R_RISCV_COPY 4 -#define R_RISCV_JUMP_SLOT 5 -#define R_RISCV_TLS_DTPMOD32 6 -#define R_RISCV_TLS_DTPMOD64 7 -#define R_RISCV_TLS_DTPREL32 8 -#define R_RISCV_TLS_DTPREL64 9 -#define R_RISCV_TLS_TPREL32 10 -#define R_RISCV_TLS_TPREL64 11 -#define R_RISCV_BRANCH 16 -#define R_RISCV_JAL 17 -#define R_RISCV_CALL 18 -#define R_RISCV_CALL_PLT 19 -#define R_RISCV_GOT_HI20 20 -#define R_RISCV_TLS_GOT_HI20 21 -#define R_RISCV_TLS_GD_HI20 22 -#define R_RISCV_PCREL_HI20 23 -#define R_RISCV_PCREL_LO12_I 24 -#define R_RISCV_PCREL_LO12_S 25 -#define R_RISCV_HI20 26 -#define R_RISCV_LO12_I 27 -#define R_RISCV_LO12_S 28 -#define R_RISCV_TPREL_HI20 29 -#define R_RISCV_TPREL_LO12_I 30 -#define R_RISCV_TPREL_LO12_S 31 -#define R_RISCV_TPREL_ADD 32 -#define R_RISCV_ADD8 33 -#define R_RISCV_ADD16 34 -#define R_RISCV_ADD32 35 -#define R_RISCV_ADD64 36 -#define R_RISCV_SUB8 37 -#define R_RISCV_SUB16 38 -#define R_RISCV_SUB32 39 -#define R_RISCV_SUB64 40 -#define R_RISCV_GNU_VTINHERIT 41 -#define R_RISCV_GNU_VTENTRY 42 -#define R_RISCV_ALIGN 43 -#define R_RISCV_RVC_BRANCH 44 -#define R_RISCV_RVC_JUMP 45 -#define R_RISCV_RVC_LUI 46 -#define R_RISCV_GPREL_I 47 -#define R_RISCV_GPREL_S 48 -#define R_RISCV_TPREL_I 49 -#define R_RISCV_TPREL_S 50 -#define R_RISCV_RELAX 51 -#define R_RISCV_SUB6 52 -#define R_RISCV_SET6 53 -#define R_RISCV_SET8 54 -#define R_RISCV_SET16 55 -#define R_RISCV_SET32 56 -#define R_RISCV_32_PCREL 57 - -#define R_RISCV_NUM 58 - -/* BPF specific declarations. */ - -#define R_BPF_NONE 0 /* No reloc */ -#define R_BPF_64_64 1 -#define R_BPF_64_32 10 - -/* Imagination Meta specific relocations. */ - -#define R_METAG_HIADDR16 0 -#define R_METAG_LOADDR16 1 -#define R_METAG_ADDR32 2 /* 32bit absolute address */ -#define R_METAG_NONE 3 /* No reloc */ -#define R_METAG_RELBRANCH 4 -#define R_METAG_GETSETOFF 5 - -/* Backward compatability */ -#define R_METAG_REG32OP1 6 -#define R_METAG_REG32OP2 7 -#define R_METAG_REG32OP3 8 -#define R_METAG_REG16OP1 9 -#define R_METAG_REG16OP2 10 -#define R_METAG_REG16OP3 11 -#define R_METAG_REG32OP4 12 - -#define R_METAG_HIOG 13 -#define R_METAG_LOOG 14 - -#define R_METAG_REL8 15 -#define R_METAG_REL16 16 - -/* GNU */ -#define R_METAG_GNU_VTINHERIT 30 -#define R_METAG_GNU_VTENTRY 31 - -/* PIC relocations */ -#define R_METAG_HI16_GOTOFF 32 -#define R_METAG_LO16_GOTOFF 33 -#define R_METAG_GETSET_GOTOFF 34 -#define R_METAG_GETSET_GOT 35 -#define R_METAG_HI16_GOTPC 36 -#define R_METAG_LO16_GOTPC 37 -#define R_METAG_HI16_PLT 38 -#define R_METAG_LO16_PLT 39 -#define R_METAG_RELBRANCH_PLT 40 -#define R_METAG_GOTOFF 41 -#define R_METAG_PLT 42 -#define R_METAG_COPY 43 -#define R_METAG_JMP_SLOT 44 -#define R_METAG_RELATIVE 45 -#define R_METAG_GLOB_DAT 46 - -/* TLS relocations */ -#define R_METAG_TLS_GD 47 -#define R_METAG_TLS_LDM 48 -#define R_METAG_TLS_LDO_HI16 49 -#define R_METAG_TLS_LDO_LO16 50 -#define R_METAG_TLS_LDO 51 -#define R_METAG_TLS_IE 52 -#define R_METAG_TLS_IENONPIC 53 -#define R_METAG_TLS_IENONPIC_HI16 54 -#define R_METAG_TLS_IENONPIC_LO16 55 -#define R_METAG_TLS_TPOFF 56 -#define R_METAG_TLS_DTPMOD 57 -#define R_METAG_TLS_DTPOFF 58 -#define R_METAG_TLS_LE 59 -#define R_METAG_TLS_LE_HI16 60 -#define R_METAG_TLS_LE_LO16 61 - -/* NDS32 relocations. */ -#define R_NDS32_NONE 0 -#define R_NDS32_32_RELA 20 -#define R_NDS32_COPY 39 -#define R_NDS32_GLOB_DAT 40 -#define R_NDS32_JMP_SLOT 41 -#define R_NDS32_RELATIVE 42 -#define R_NDS32_TLS_TPOFF 102 -#define R_NDS32_TLS_DESC 119 - -#ifdef __cplusplus -} -#endif - -#endif /* elf.h */ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/googletest/BUILD.gn b/thirdparty/sentry-native/external/crashpad/third_party/googletest/BUILD.gn index de1c84d444..2cfb508929 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/googletest/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/third_party/googletest/BUILD.gn @@ -55,6 +55,7 @@ if (crashpad_is_in_chromium) { static_library("googletest") { testonly = true sources = [ + "$googletest_dir/googletest/include/gtest/gtest-assertion-result.h", "$googletest_dir/googletest/include/gtest/gtest-death-test.h", "$googletest_dir/googletest/include/gtest/gtest-matchers.h", "$googletest_dir/googletest/include/gtest/gtest-message.h", @@ -78,6 +79,7 @@ if (crashpad_is_in_chromium) { "$googletest_dir/googletest/include/gtest/internal/gtest-string.h", "$googletest_dir/googletest/include/gtest/internal/gtest-type-util.h", "$googletest_dir/googletest/src/gtest-all.cc", + "$googletest_dir/googletest/src/gtest-assertion-result.cc", "$googletest_dir/googletest/src/gtest-death-test.cc", "$googletest_dir/googletest/src/gtest-filepath.cc", "$googletest_dir/googletest/src/gtest-internal-inl.h", @@ -176,14 +178,6 @@ if (crashpad_is_in_chromium) { configs -= [ "$mini_chromium_dir/build/config:Wexit_time_destructors" ] configs += [ ":googletest_private_config" ] deps = [ ":googletest" ] - - if (crashpad_is_clang) { - cflags_cc = [ - # For googletest/googlemock/test/gmock-matchers_test.cc’s - # Unstreamable::value_. - "-Wno-unused-private-field", - ] - } } test("gtest_premature_exit_test") { @@ -299,7 +293,11 @@ if (crashpad_is_in_chromium) { "$googletest_dir/googlemock/test/gmock-cardinalities_test.cc", "$googletest_dir/googlemock/test/gmock-function-mocker_test.cc", "$googletest_dir/googlemock/test/gmock-internal-utils_test.cc", - "$googletest_dir/googlemock/test/gmock-matchers_test.cc", + "$googletest_dir/googlemock/test/gmock-matchers-arithmetic_test.cc", + "$googletest_dir/googlemock/test/gmock-matchers-comparisons_test.cc", + "$googletest_dir/googlemock/test/gmock-matchers-containers_test.cc", + "$googletest_dir/googlemock/test/gmock-matchers-misc_test.cc", + "$googletest_dir/googlemock/test/gmock-matchers_test.h", "$googletest_dir/googlemock/test/gmock-more-actions_test.cc", "$googletest_dir/googlemock/test/gmock-nice-strict_test.cc", "$googletest_dir/googlemock/test/gmock-port_test.cc", @@ -324,15 +322,21 @@ if (crashpad_is_in_chromium) { # always use the override modifier with MOCK_METHOD. "-Wno-inconsistent-missing-override", - # For googletest/googlemock/test/gmock-matchers_test.cc’s - # testing::googlemock_matchers_test::Unprintable::c_. - "-Wno-unused-private-field", + # For googlemock/test/gmock-matchers-misc_test.cc comparison of + # integers of different signs. + "-Wno-sign-compare", ] } if (crashpad_is_win) { - # TODO: Correct SDK in vc\tools\msvc\14.14.26428\include\functional - cflags = [ "/wd4789" ] # VAR of size N bytes will be overrun + cflags = [ + # TODO: Correct SDK in vc\tools\msvc\14.14.26428\include\functional + "/wd4789", # VAR of size N bytes will be overrun + + # For googlemock/test/gmock-matchers-misc_test.cc comparison of + # integers of different signs. + "/wd4018", + ] } } diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss.h b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss.h index 2646b6c008..0bdd381c63 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss.h @@ -20,7 +20,7 @@ #elif defined(CRASHPAD_LSS_SOURCE_EMBEDDED) #include "third_party/lss/lss/linux_syscall_support.h" #elif defined(CRASHPAD_LSS_SOURCE_FUCHSIA) -#include "../../../../third_party/lss/linux_syscall_support.h" +#include "../../../../third_party/linux-syscall-support/linux_syscall_support.h" #else #error Unknown lss source #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/DIR_METADATA b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/DIR_METADATA new file mode 100644 index 0000000000..eccfd35fab --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/DIR_METADATA @@ -0,0 +1,12 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +os: LINUX +monorail { + project: "linux-syscall-support" +} diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/LICENSE b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/LICENSE new file mode 100644 index 0000000000..58ab3fba9d --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2005-2011, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/OWNERS b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/OWNERS new file mode 100644 index 0000000000..29b02fa114 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/OWNERS @@ -0,0 +1,2 @@ +mseaborn@chromium.org +vapier@chromium.org diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/README.md b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/README.md index 70cbc85311..b0cd12977b 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/README.md +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/README.md @@ -130,7 +130,7 @@ It only compiles things (does not execute at all). If you commit a change to LSS, please also commit a Chromium change to update `lss_revision` in -[Chromium's DEPS](https://chromium.googlesource.com/chromium/src/+/master/DEPS) +[Chromium's DEPS](https://chromium.googlesource.com/chromium/src/+/HEAD/DEPS) file. This ensures that the LSS change gets tested, so that people who commit later diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/linux_syscall_support.h b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/linux_syscall_support.h index a71bea8904..d3791cd4e9 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/linux_syscall_support.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/linux_syscall_support.h @@ -88,7 +88,7 @@ */ #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \ - defined(__aarch64__) || defined(__s390__)) \ + defined(__aarch64__) || defined(__s390__) || defined(__e2k__)) \ && (defined(__linux) || defined(__ANDROID__)) #ifndef SYS_CPLUSPLUS @@ -130,18 +130,25 @@ extern "C" { #endif #endif -/* The Android NDK's #defines these macros as aliases - * to their non-64 counterparts. To avoid naming conflict, remove them. */ -#ifdef __ANDROID__ - /* These are restored by the corresponding #pragma pop_macro near - * the end of this file. */ -# pragma push_macro("stat64") -# pragma push_macro("fstat64") -# pragma push_macro("lstat64") -# undef stat64 -# undef fstat64 -# undef lstat64 -#endif +/* Some libcs, for example Android NDK and musl, #define these + * macros as aliases to their non-64 counterparts. To avoid naming + * conflict, remove them. + * + * These are restored by the corresponding #pragma pop_macro near + * the end of this file. + */ +#pragma push_macro("stat64") +#pragma push_macro("fstat64") +#pragma push_macro("lstat64") +#pragma push_macro("pread64") +#pragma push_macro("pwrite64") +#pragma push_macro("getdents64") +#undef stat64 +#undef fstat64 +#undef lstat64 +#undef pread64 +#undef pwrite64 +#undef getdents64 #if defined(__ANDROID__) && defined(__x86_64__) // A number of x86_64 syscalls are blocked by seccomp on recent Android; @@ -280,7 +287,8 @@ struct kernel_rusage { }; #if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \ - || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) + || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) \ + || defined(__e2k__) /* include/asm-{arm,i386,mips,ppc}/signal.h */ struct kernel_old_sigaction { @@ -394,6 +402,28 @@ struct kernel_stat64 { unsigned long __unused4; unsigned long __unused5; }; +#elif defined(__e2k__) +struct kernel_stat64 { + unsigned long long st_dev; + unsigned long long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned long long st_rdev; + long long st_size; + int st_blksize; + int __pad2; + unsigned long long st_blocks; + int st_atime_; + unsigned int st_atime_nsec_; + int st_mtime_; + unsigned int st_mtime_nsec_; + int st_ctime_; + unsigned int st_ctime_nsec_; + unsigned int __unused4; + unsigned int __unused5; +}; #else struct kernel_stat64 { unsigned long long st_dev; @@ -579,6 +609,25 @@ struct kernel_stat { unsigned long __unused4; unsigned long __unused5; }; +#elif defined(__e2k__) +struct kernel_stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned int st_mode; + unsigned long st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned long st_rdev; + unsigned long st_size; + unsigned long st_blksize; + unsigned long st_blocks; + unsigned long st_atime_; + unsigned long st_atime_nsec_; + unsigned long st_mtime_; + unsigned long st_mtime_nsec_; + unsigned long st_ctime_; + unsigned long st_ctime_nsec_; +}; #endif /* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */ @@ -947,6 +996,9 @@ struct kernel_statfs { #ifndef __NR_fallocate #define __NR_fallocate 324 #endif +#ifndef __NR_getrandom +#define __NR_getrandom 355 +#endif /* End of i386 definitions */ #elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) #ifndef __NR_setresuid @@ -1045,12 +1097,18 @@ struct kernel_statfs { #ifndef __NR_ioprio_get #define __NR_ioprio_get (__NR_SYSCALL_BASE + 315) #endif +#ifndef __NR_fstatat64 +#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327) +#endif #ifndef __NR_move_pages #define __NR_move_pages (__NR_SYSCALL_BASE + 344) #endif #ifndef __NR_getcpu #define __NR_getcpu (__NR_SYSCALL_BASE + 345) #endif +#ifndef __NR_getrandom +#define __NR_getrandom (__NR_SYSCALL_BASE + 384) +#endif /* End of ARM 3/EABI definitions */ #elif defined(__aarch64__) #ifndef __NR_setxattr @@ -1148,6 +1206,9 @@ struct kernel_statfs { #ifndef __NR_move_pages #define __NR_move_pages 239 #endif +#ifndef __NR_getrandom +#define __NR_getrandom 278 +#endif /* End of aarch64 definitions */ #elif defined(__x86_64__) #ifndef __NR_pread64 @@ -1239,6 +1300,9 @@ struct kernel_statfs { #ifndef __NR_fallocate #define __NR_fallocate 285 #endif +#ifndef __NR_getrandom +#define __NR_getrandom 318 +#endif /* End of x86-64 definitions */ #elif defined(__mips__) #if _MIPS_SIM == _MIPS_SIM_ABI32 @@ -1340,6 +1404,9 @@ struct kernel_statfs { #ifndef __NR_ioprio_get #define __NR_ioprio_get (__NR_Linux + 315) #endif +#ifndef __NR_getrandom +#define __NR_getrandom (__NR_Linux + 353) +#endif /* End of MIPS (old 32bit API) definitions */ #elif _MIPS_SIM == _MIPS_SIM_ABI64 #ifndef __NR_pread64 @@ -1418,6 +1485,9 @@ struct kernel_statfs { #ifndef __NR_ioprio_get #define __NR_ioprio_get (__NR_Linux + 274) #endif +#ifndef __NR_getrandom +#define __NR_getrandom (__NR_Linux + 313) +#endif /* End of MIPS (64bit API) definitions */ #else #ifndef __NR_setresuid @@ -1854,8 +1924,9 @@ struct kernel_statfs { #endif #undef LSS_RETURN - #if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \ - || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__)) + #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \ + || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__) \ + || defined(__e2k__) /* Failing system calls return a negative result in the range of * -1..-4095. These are "errno" values with the sign inverted. */ @@ -1955,7 +2026,7 @@ struct kernel_statfs { LSS_ENTRYPOINT \ "pop %%ebx" \ args \ - : "esp", "memory"); \ + : "memory"); \ LSS_RETURN(type,__res) #undef _syscall0 #define _syscall0(type,name) \ @@ -2012,7 +2083,7 @@ struct kernel_statfs { : "i" (__NR_##name), "ri" ((long)(arg1)), \ "c" ((long)(arg2)), "d" ((long)(arg3)), \ "S" ((long)(arg4)), "D" ((long)(arg5)) \ - : "esp", "memory"); \ + : "memory"); \ LSS_RETURN(type,__res); \ } #undef _syscall6 @@ -2034,7 +2105,7 @@ struct kernel_statfs { : "i" (__NR_##name), "0" ((long)(&__s)), \ "c" ((long)(arg2)), "d" ((long)(arg3)), \ "S" ((long)(arg4)), "D" ((long)(arg5)) \ - : "esp", "memory"); \ + : "memory"); \ LSS_RETURN(type,__res); \ } LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, @@ -2120,7 +2191,7 @@ struct kernel_statfs { : "0"(-EINVAL), "i"(__NR_clone), "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) - : "esp", "memory", "ecx", "edx", "esi", "edi"); + : "memory", "ecx", "edx", "esi", "edi"); LSS_RETURN(int, __res); } @@ -3348,6 +3419,259 @@ struct kernel_statfs { } LSS_RETURN(int, __ret); } + #elif defined(__e2k__) + + #undef _LSS_BODY + #define _LSS_BODY(nr, type, name, ...) \ + register unsigned long long __res; \ + __asm__ __volatile__ \ + ( \ + "{\n\t" \ + " sdisp %%ctpr1, 0x3\n\t" \ + " addd, s 0x0, %[sys_num], %%b[0]\n\t" \ + LSS_BODY_ASM##nr \ + "}\n\t" \ + "{\n\t" \ + " call %%ctpr1, wbs = %#\n\t" \ + "}\n\t" \ + "{\n\t" \ + " addd, s 0x0, %%b[0], %[res]\n\t" \ + "}\n\t" \ + : [res] "=r" (__res) \ + : \ + LSS_BODY_ARG##nr(__VA_ARGS__) \ + [sys_num] "ri" (__NR_##name) \ + : "ctpr1", "ctpr2", "ctpr3", \ + "b[0]", "b[1]", "b[2]", "b[3]", \ + "b[4]", "b[5]", "b[6]", "b[7]" \ + ); \ + LSS_RETURN(type, __res); + + #undef LSS_BODY + #define LSS_BODY(nr, type, name, args...) \ + _LSS_BODY(nr, type, name, ## args) + + #undef LSS_BODY_ASM0 + #undef LSS_BODY_ASM1 + #undef LSS_BODY_ASM2 + #undef LSS_BODY_ASM3 + #undef LSS_BODY_ASM4 + #undef LSS_BODY_ASM5 + #undef LSS_BODY_ASM6 + + #define LSS_BODY_ASM0 + #define LSS_BODY_ASM1 LSS_BODY_ASM0 \ + " addd, s 0x0, %[arg1], %%b[1]\n\t" + #define LSS_BODY_ASM2 LSS_BODY_ASM1 \ + " addd, s 0x0, %[arg2], %%b[2]\n\t" + #define LSS_BODY_ASM3 LSS_BODY_ASM2 \ + " addd, s 0x0, %[arg3], %%b[3]\n\t" + #define LSS_BODY_ASM4 LSS_BODY_ASM3 \ + " addd, s 0x0, %[arg4], %%b[4]\n\t" + #define LSS_BODY_ASM5 LSS_BODY_ASM4 \ + " addd, s 0x0, %[arg5], %%b[5]\n\t" + #define LSS_BODY_ASM6 LSS_BODY_ASM5 \ + "}\n\t" \ + "{\n\t" \ + " addd, s 0x0, %[arg6], %%b[6]\n\t" + + #undef LSS_SYSCALL_ARG + #define LSS_SYSCALL_ARG(a) ((unsigned long long)(uintptr_t)(a)) + + #undef LSS_BODY_ARG0 + #undef LSS_BODY_ARG1 + #undef LSS_BODY_ARG2 + #undef LSS_BODY_ARG3 + #undef LSS_BODY_ARG4 + #undef LSS_BODY_ARG5 + #undef LSS_BODY_ARG6 + + #define LSS_BODY_ARG0() + #define LSS_BODY_ARG1(_arg1) \ + [arg1] "ri" LSS_SYSCALL_ARG(_arg1), + #define LSS_BODY_ARG2(_arg1, _arg2) \ + LSS_BODY_ARG1(_arg1) \ + [arg2] "ri" LSS_SYSCALL_ARG(_arg2), + #define LSS_BODY_ARG3(_arg1, _arg2, _arg3) \ + LSS_BODY_ARG2(_arg1, _arg2) \ + [arg3] "ri" LSS_SYSCALL_ARG(_arg3), + #define LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \ + LSS_BODY_ARG3(_arg1, _arg2, _arg3) \ + [arg4] "ri" LSS_SYSCALL_ARG(_arg4), + #define LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \ + LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \ + [arg5] "ri" LSS_SYSCALL_ARG(_arg5), + #define LSS_BODY_ARG6(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6) \ + LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \ + [arg6] "ri" LSS_SYSCALL_ARG(_arg6), + + #undef _syscall0 + #define _syscall0(type, name) \ + type LSS_NAME(name)(void) { \ + LSS_BODY(0, type, name); \ + } + + #undef _syscall1 + #define _syscall1(type, name, type1, arg1) \ + type LSS_NAME(name)(type1 arg1) { \ + LSS_BODY(1, type, name, arg1) \ + } + + #undef _syscall2 + #define _syscall2(type, name, type1, arg1, type2, arg2) \ + type LSS_NAME(name)(type1 arg1, type2 arg2) { \ + LSS_BODY(2, type, name, arg1, arg2) \ + } + + #undef _syscall3 + #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ + type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ + LSS_BODY(3, type, name, arg1, arg2, arg3) \ + } + + #undef _syscall4 + #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ + type4, arg4) \ + type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + LSS_BODY(4, type, name, arg1, arg2, arg3, arg4) \ + } + + #undef _syscall5 + #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ + type4, arg4, type5, arg5) \ + type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5) { \ + LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5) \ + } + + #undef _syscall6 + #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ + type4, arg4, type5, arg5, type6, arg6) \ + type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5, type6 arg6) { \ + LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) \ + } + + LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, + int flags, void *arg, int *parent_tidptr, + void *newtls, int *child_tidptr) { + unsigned long long __res; + + __asm__ __volatile__ ( + "{\n\t" + " addd,s 0x0, %[nr_clone], %%b[0]\n\t" + " addd,s 0x0, %[flags], %%db[1]\n\t" + " addd,s 0x0, %[child_stack], %%db[2]\n\t" + " addd,s 0x0, %[parent_tidptr], %%db[3]\n\t" + " addd,s 0x0, %[child_tidptr], %%db[4]\n\t" + " addd,s 0x0, %[newtls], %%db[5]\n\t" + "}\n\t" + /* if (fn == NULL) + * return -EINVAL; + */ + + "{\n\t" + " disp %%ctpr1, .L1\n\t" + "}\n\t" + "{\n\t" + " cmpesb,s 0x0, %[fn], %%pred0\n\t" + "}\n\t" + "{\n\t" + " ct %%ctpr1 ? %%pred0\n\t" + "}\n\t" + + /* if (child_stack == NULL) + * return -EINVAL; + */ + "{\n\t" + " cmpesb,s 0x0, %%db[2], %%pred0\n\t" + "}\n\t" + "{\n\t" + " ct %%ctpr1 ? %%pred0\n\t" + "}\n\t" + + /* b[0] = syscall(%b[0] = __NR_clone, + * %db[1] = flags, + * %db[2] = child_stack, + * %db[3] = parent_tidptr, + * %db[4] = child_tidptr, + * %db[5] = newtls) + */ + "{\n\t" + " sdisp %%ctpr1, 0x3\n\t" + "}\n\t" + "{\n\t" + " call %%ctpr1, wbs = %#\n\t" + "}\n\t" + + /* if (%[b0] != 0) + * return %b[0]; + */ + "{\n\t" + " disp %%ctpr1, .L2\n\t" + " cmpesb,s 0x0, %%b[0], %%pred0\n\t" + "}\n\t" + "{\n\t" + " ct %%ctpr1 ? ~%%pred0\n\t" + "}\n\t" + /* In the child, now. Call "fn(arg)". + */ + + "{\n\t" + " movtd,s %[fn], %%ctpr1\n\t" + "}\n\t" + "{\n\t" + " addd,s 0x0, %[arg], %%db[0]\n\t" + "}\n\t" + "{\n\t" + " call %%ctpr1, wbs = %#\n\t" + "}\n\t" + /* Call _exit(%b[0]). + */ + + "{\n\t" + " sdisp %%ctpr1, 0x3\n\t" + " addd,s 0x0, %%b[0], %%b[1]\n\t" + "}\n\t" + "{\n\t" + " addd,s 0x0, %[nr_exit], %%b[0]\n\t" + "}\n\t" + "{\n\t" + " call %%ctpr1, wbs = %#\n\t" + "}\n\t" + "{\n\t" + " disp %%ctpr1, .L2\n\t" + " adds,s 0x0, 0x0, %%b[0]\n\t" + "}\n\t" + "{\n\t" + " ct %%ctpr1\n\t" + "}\n\t" + ".L1:\n\t" + "{\n\t" + " addd,s 0x0, %[einval], %%b[0]\n\t" + "}\n\t" + ".L2:\n\t" + "{\n\t" + " addd,s 0x0, %%b[0], %[res]\n\t" + "}\n\t" + : [res] "=r" LSS_SYSCALL_ARG(__res) + : [nr_clone] "ri" LSS_SYSCALL_ARG(__NR_clone) + [arg] "ri" LSS_SYSCALL_ARG(arg) + [nr_exit] "ri" LSS_SYSCALL_ARG(__NR_exit) + [flags] "ri" LSS_SYSCALL_ARG(flags) + [child_stack] "ri" LSS_SYSCALL_ARG(child_stack) + [parent_tidptr] "ri" + LSS_SYSCALL_ARG(parent_tidptr) + [newtls] "ri" LSS_SYSCALL_ARG(newtls) + [child_tidptr] "ri" + LSS_SYSCALL_ARG(child_tidptr) + [fn] "ri" LSS_SYSCALL_ARG(fn) + [einval] "ri" LSS_SYSCALL_ARG(-EINVAL) + : "ctpr1", "b[0]", "b[1]", "b[2]", "b[3]", + "b[4]", "b[5]", "pred0"); + LSS_RETURN(int, __res); + } + #endif #define __NR__exit __NR_exit #define __NR__gettid __NR_gettid @@ -3391,9 +3715,10 @@ struct kernel_statfs { LSS_INLINE _syscall2(int, ftruncate, int, f, off_t, l) #endif - LSS_INLINE _syscall4(int, futex, int*, a, - int, o, int, v, - struct kernel_timespec*, t) + LSS_INLINE _syscall6(int, futex, int*, u, + int, o, int, v, + struct kernel_timespec*, t, + int*, u2, int, v2) LSS_INLINE _syscall3(int, getdents, int, f, struct kernel_dirent*, d, int, c) LSS_INLINE _syscall3(int, getdents64, int, f, @@ -3538,10 +3863,14 @@ struct kernel_statfs { LSS_INLINE _syscall1(int, sigreturn, unsigned long, u) #endif #if defined(__NR_stat) - // stat is polyfilled below when not available. + // stat and lstat are polyfilled below when not available. LSS_INLINE _syscall2(int, stat, const char*, f, struct kernel_stat*, b) #endif + #if defined(__NR_lstat) + LSS_INLINE _syscall2(int, lstat, const char*, f, + struct kernel_stat*, b) + #endif LSS_INLINE _syscall2(int, statfs, const char*, f, struct kernel_statfs*, b) LSS_INLINE _syscall3(int, tgkill, pid_t, p, @@ -3560,7 +3889,7 @@ struct kernel_statfs { LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, unsigned *, node, void *, unused) #endif - #if defined(__x86_64__) || \ + #if defined(__x86_64__) || defined(__e2k__) || \ (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI32) LSS_INLINE _syscall3(int, recvmsg, int, s, struct kernel_msghdr*, m, int, f) @@ -3650,6 +3979,10 @@ struct kernel_statfs { int, f, int, mode, loff_t, offset, loff_t, len) #endif #endif + #if defined(__NR_getrandom) + LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length, + unsigned int, flags) + #endif #if defined(__NR_newfstatat) LSS_INLINE _syscall4(int, newfstatat, int, d, const char *, p, @@ -3897,7 +4230,7 @@ struct kernel_statfs { defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ defined(__PPC__) || \ - (defined(__s390__) && !defined(__s390x__)) + (defined(__s390__) && !defined(__s390x__)) || defined(__e2k__) #define __NR__sigaction __NR_sigaction #define __NR__sigpending __NR_sigpending #define __NR__sigsuspend __NR_sigsuspend @@ -4462,6 +4795,12 @@ struct kernel_statfs { return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0); } #endif +#if !defined(__NR_lstat) + LSS_INLINE int LSS_NAME(lstat)(const char *pathname, + struct kernel_stat *buf) { + return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, AT_SYMLINK_NOFOLLOW); + } +#endif #if !defined(__NR_waitpid) LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) { @@ -4511,13 +4850,14 @@ struct kernel_statfs { # endif #endif -#ifdef __ANDROID__ - /* These restore the original values of these macros saved by the - * corresponding #pragma push_macro near the top of this file. */ -# pragma pop_macro("stat64") -# pragma pop_macro("fstat64") -# pragma pop_macro("lstat64") -#endif +/* These restore the original values of these macros saved by the + * corresponding #pragma push_macro near the top of this file. */ +#pragma pop_macro("stat64") +#pragma pop_macro("fstat64") +#pragma pop_macro("lstat64") +#pragma pop_macro("pread64") +#pragma pop_macro("pwrite64") +#pragma pop_macro("getdents64") #if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) } diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/fallocate.c b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/fallocate.c index c156e58986..f6589070f7 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/fallocate.c +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/fallocate.c @@ -63,5 +63,7 @@ int main(int argc, char *argv[]) { #endif assert(st.st_size == offset + len); + sys_unlink(filename); + return 0; } diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getrandom.c b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getrandom.c new file mode 100644 index 0000000000..eb1f162284 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/getrandom.c @@ -0,0 +1,59 @@ +/* Copyright 2020, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test_skel.h" + +#define BUFFER_SIZE 256 + +int main(int argc, char *argv[]) { + char buffer[BUFFER_SIZE]; + // Zero it out so we can check later that it's at least not all 0s. + memset(buffer, 0, BUFFER_SIZE); + bool buffer_contains_all_zeros = true; + + // Don't bother passing any flags. (If we're using lss, we might not have the + // right header files with the flags defined anyway, and we'd have to copy + // this in here too, and risk getting out of sync in yet another way.) + const ssize_t r = sys_getrandom(buffer, BUFFER_SIZE, 0); + + // Make sure it either worked, or that it's just not supported. + assert(r == BUFFER_SIZE || errno == ENOSYS); + + if (r == BUFFER_SIZE) { + // If all the bytes are 0, it didn't really work. + for (size_t i = 0; i < BUFFER_SIZE; ++i) { + if (buffer[i] != 0) { + buffer_contains_all_zeros = false; + } + } + assert(!buffer_contains_all_zeros); + } + + return 0; +} diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/lstat.c b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/lstat.c new file mode 100644 index 0000000000..33848a9817 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/lstat.c @@ -0,0 +1,97 @@ +/* Copyright 2021, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test_skel.h" + +int main(int argc, char *argv[]) { + int exit_status = 0; + + // Get two unique paths to play with. + char foo[] = "tempfile.XXXXXX"; + char bar[] = "tempfile.XXXXXX"; + int fd_foo = mkstemp(foo); + int fd_bar = mkstemp(bar); + assert(fd_foo != -1); + assert(fd_bar != -1); + + // Then delete foo. + assert(sys_unlink(foo) == 0); + + // Now make foo a symlink to bar. + assert(symlink(bar, foo) == 0); + + // Make sure sys_stat() and sys_lstat() implementation return different + // information. + + // We need to check our stat syscalls for EOVERFLOW, as sometimes the integer + // types used in the stat structures are too small to fit the actual value. + // E.g. on some systems st_ino is 32-bit, but some filesystems have 64-bit + // inodes. + + struct kernel_stat lstat_info; + int rc = sys_lstat(foo, &lstat_info); + if (rc < 0 && errno == EOVERFLOW) { + // Bail out since we had an overflow in the stat structure. + exit_status = SKIP_TEST_EXIT_STATUS; + goto cleanup; + } + assert(rc == 0); + + struct kernel_stat stat_info; + rc = sys_stat(foo, &stat_info); + if (rc < 0 && errno == EOVERFLOW) { + // Bail out since we had an overflow in the stat structure. + exit_status = SKIP_TEST_EXIT_STATUS; + goto cleanup; + } + assert(rc == 0); + + struct kernel_stat bar_stat_info; + rc = sys_stat(bar, &bar_stat_info); + if (rc < 0 && errno == EOVERFLOW) { + // Bail out since we had an overflow in the stat structure. + exit_status = SKIP_TEST_EXIT_STATUS; + goto cleanup; + } + assert(rc == 0); + + // lstat should produce information about a symlink. + assert((lstat_info.st_mode & S_IFMT) == S_IFLNK); + + // stat-ing foo and bar should produce the same inode. + assert(stat_info.st_ino == bar_stat_info.st_ino); + + // lstat-ing foo should give a different inode than stat-ing foo. + assert(stat_info.st_ino != lstat_info.st_ino); + +cleanup: + sys_unlink(foo); + sys_unlink(bar); + return exit_status; +} diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/sigaction.c b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/sigaction.c new file mode 100644 index 0000000000..f247aca7c8 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/sigaction.c @@ -0,0 +1,54 @@ +/* Copyright 2020, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test_skel.h" + +void test_handler(int sig) {} + +int main(int argc, char *argv[]) { + const size_t kSigsetSize = sizeof(struct kernel_sigset_t); + struct kernel_sigaction action = {}; + // Invalid signal returns EINVAL. + assert(sys_rt_sigaction(SIGKILL, &action, NULL, kSigsetSize) == -1); + assert(errno == EINVAL); + + // Set an action. + action.sa_handler_ = test_handler; + action.sa_flags = SA_SIGINFO; + assert(sys_sigemptyset(&action.sa_mask) == 0); + assert(sys_sigaddset(&action.sa_mask, SIGPIPE) == 0); + assert(sys_rt_sigaction(SIGSEGV, &action, NULL, kSigsetSize) == 0); + + // Retrieve the action. + struct kernel_sigaction old_action = {}; + assert(sys_rt_sigaction(SIGSEGV, NULL, &old_action, kSigsetSize) == 0); + assert(memcmp(&action, &old_action, sizeof(action)) == 0); + + return 0; +} diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/stat.c b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/stat.c new file mode 100644 index 0000000000..48cac620cb --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/stat.c @@ -0,0 +1,67 @@ +/* Copyright 2021, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "test_skel.h" + +int main(int argc, char *argv[]) { + int exit_status = 0; + + // Get two unique paths to play with. + char foo[] = "tempfile.XXXXXX"; + int fd_foo = mkstemp(foo); + assert(fd_foo != -1); + + // Make sure it exists. + assert(access(foo, F_OK) == 0); + + // Make sure sys_stat() and a libc stat() implementation return the same + // information. + struct stat libc_stat; + assert(stat(foo, &libc_stat) == 0); + + struct kernel_stat raw_stat; + // We need to check our stat syscall for EOVERFLOW, as sometimes the integer + // types used in the stat structures are too small to fit the actual value. + // E.g. on some systems st_ino is 32-bit, but some filesystems have 64-bit + // inodes. + int rc = sys_stat(foo, &raw_stat); + if (rc < 0 && errno == EOVERFLOW) { + // Bail out since we had an overflow in the stat structure. + exit_status = SKIP_TEST_EXIT_STATUS; + goto cleanup; + } + assert(rc == 0); + + assert(libc_stat.st_ino == raw_stat.st_ino); + + +cleanup: + sys_unlink(foo); + return exit_status; +} diff --git a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/test_skel.h b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/test_skel.h index 9ff0eb3711..238c48d1db 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/test_skel.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/lss/lss/tests/test_skel.h @@ -44,9 +44,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -57,6 +59,8 @@ #include "linux_syscall_support.h" +#define SKIP_TEST_EXIT_STATUS 77 + void assert_buffers_eq_len(const void *buf1, const void *buf2, size_t len) { const uint8_t *u8_1 = (const uint8_t *)buf1; const uint8_t *u8_2 = (const uint8_t *)buf2; diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/CMakeLists.txt b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/CMakeLists.txt index 342b7aa3d9..4577c1d125 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/CMakeLists.txt +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/CMakeLists.txt @@ -24,7 +24,6 @@ mc_append_sources( files/scoped_file.cc files/scoped_file.h format_macros.h - ignore_result.h logging.cc logging.h memory/free_deleter.h diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/build/chromeos_buildflags.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/build/chromeos_buildflags.h index c54f076845..72714a24ac 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/build/chromeos_buildflags.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/build/chromeos_buildflags.h @@ -7,7 +7,7 @@ #include "build/buildflag.h" -#define BUILDFLAG_INTERNAL_IS_CHROMEOS_LACROS() (0) -#define BUILDFLAG_INTERNAL_IS_CHROMEOS_ASH() (0) +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS_LACROS() (0) +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS_ASH() (0) #endif // MINI_CHROMIUM_BUILD_CHROMEOS_BUILDFLAGS_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/.style.yapf b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/.style.yapf new file mode 100644 index 0000000000..c9970ee73e --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/.style.yapf @@ -0,0 +1,7 @@ +# Copyright 2022 The Crashpad Authors. All rights reserved. +# +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +[style] +based_on_style = google diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/BUILD.gn b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/BUILD.gn index bcd327a8a3..bd36638419 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/BUILD.gn @@ -23,7 +23,6 @@ static_library("base") { "files/scoped_file.cc", "files/scoped_file.h", "format_macros.h", - "ignore_result.h", "logging.cc", "logging.h", "memory/free_deleter.h", diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/atomicops.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/atomicops.h index 422d169175..b6058e550a 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/atomicops.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/atomicops.h @@ -38,7 +38,7 @@ #include "build/build_config.h" -#if defined(OS_WIN) && defined(ARCH_CPU_64_BITS) +#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS) // windows.h #defines this (only on x64). This causes problems because the // public API also uses MemoryBarrier at the public name for this fence. So, on // X64, undef it, and call its documented @@ -54,9 +54,7 @@ typedef int32_t Atomic32; #ifdef ARCH_CPU_64_BITS // We need to be able to go between Atomic64 and AtomicWord implicitly. This // means Atomic64 and AtomicWord should be the same type on 64-bit. -#if defined(__ILP32__) || defined(OS_NACL) -// NaCl's intptr_t is not actually 64-bits on 64-bit! -// http://code.google.com/p/nativeclient/issues/detail?id=1162 +#if defined(__ILP32__) typedef int64_t Atomic64; #else typedef intptr_t Atomic64; @@ -173,7 +171,7 @@ extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures; // On some platforms we need additional declarations to make // AtomicWord compatible with our other Atomic* types. -#if defined(OS_APPLE) || defined(OS_OPENBSD) +#if BUILDFLAG(IS_APPLE) #include "base/atomicops_internals_atomicword_compat.h" #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/compiler_specific.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/compiler_specific.h index 25e65b9549..b1c83c9534 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/compiler_specific.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/compiler_specific.h @@ -7,23 +7,6 @@ #include "build/build_config.h" -// Annotate a variable indicating it's ok if the variable is not used. -// (Typically used to silence a compiler warning when the assignment -// is important for some other reason.) -// Use like: -// int x = ...; -// ALLOW_UNUSED_LOCAL(x); -#define ALLOW_UNUSED_LOCAL(x) false ? (void)x : (void)0 - -// Annotate a typedef or function indicating it's ok if it's not used. -// Use like: -// typedef Foo Bar ALLOW_UNUSED_TYPE; -#if defined(COMPILER_GCC) -#define ALLOW_UNUSED_TYPE __attribute__((unused)) -#else -#define ALLOW_UNUSED_TYPE -#endif - // Specify memory alignment for structs, classes, etc. // Use like: // class ALIGNAS(16) MyClass { ... } @@ -34,12 +17,6 @@ #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) #endif -#if defined(COMPILER_MSVC) -#define WARN_UNUSED_RESULT -#else -#define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#endif - #if defined(COMPILER_MSVC) #define PRINTF_FORMAT(format_param, dots_param) #else @@ -58,7 +35,7 @@ #endif // DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks. -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Windows also needs __declspec(guard(nocf)). #define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") __declspec(guard(nocf)) #else @@ -73,13 +50,4 @@ #define HAS_FEATURE(FEATURE) 0 #endif -// Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional. -#if __cplusplus >= 201703L // C++17 -#define FALLTHROUGH [[fallthrough]] -#elif defined(__clang__) -#define FALLTHROUGH [[clang::fallthrough]] -#else -#define FALLTHROUGH -#endif - #endif // MINI_CHROMIUM_BASE_COMPILER_SPECIFIC_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_path.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_path.h index 0ac91bf873..216c396e8f 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_path.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_path.h @@ -107,17 +107,16 @@ #include #include -#include "base/compiler_specific.h" #include "build/build_config.h" // Windows-style drive letter support and pathname separator characters can be // enabled and disabled independently, to aid testing. These #defines are // here so that the same setting can be used in both the implementation and // in the unit test. -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #define FILE_PATH_USES_DRIVE_LETTERS #define FILE_PATH_USES_WIN_SEPARATORS -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) namespace base { @@ -125,16 +124,16 @@ namespace base { // pathnames on different platforms. class FilePath { public: -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) // On most platforms, native pathnames are char arrays, and the encoding // may or may not be specified. On Mac OS X, native pathnames are encoded // in UTF-8. typedef std::string StringType; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) // On Windows, for Unicode-aware applications, native pathnames are wchar_t // arrays encoded in UTF-16. typedef std::wstring StringType; -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) typedef StringType::value_type CharType; @@ -182,21 +181,21 @@ class FilePath { // only contains one component, returns a FilePath identifying // kCurrentDirectory. If this object already refers to the root directory, // returns a FilePath identifying the root directory. - FilePath DirName() const WARN_UNUSED_RESULT; + [[nodiscard]] FilePath DirName() const; // Returns a FilePath corresponding to the last path component of this // object, either a file or a directory. If this object already refers to // the root directory, returns a FilePath identifying the root directory; // this is the only situation in which BaseName will return an absolute path. - FilePath BaseName() const WARN_UNUSED_RESULT; + [[nodiscard]] FilePath BaseName() const; // Returns the path's file extension. This does not have a special case for // common double extensions, so FinalExtension() of "foo.tar.gz" is simply // ".gz". If there is no extension, "" will be returned. - StringType FinalExtension() const WARN_UNUSED_RESULT; + [[nodiscard]] StringType FinalExtension() const; // Returns a FilePath with FinalExtension() removed. - FilePath RemoveFinalExtension() const WARN_UNUSED_RESULT; + [[nodiscard]] FilePath RemoveFinalExtension() const; // Returns a FilePath by appending a separator and the supplied path // component to this object's path. Append takes care to avoid adding @@ -204,8 +203,8 @@ class FilePath { // If this object's path is kCurrentDirectory, a new FilePath corresponding // only to |component| is returned. |component| must be a relative path; // it is an error to pass an absolute path. - FilePath Append(const StringType& component) const WARN_UNUSED_RESULT; - FilePath Append(const FilePath& component) const WARN_UNUSED_RESULT; + [[nodiscard]] FilePath Append(const StringType& component) const; + [[nodiscard]] FilePath Append(const FilePath& component) const; // Returns true if this FilePath contains an absolute path. On Windows, an // absolute path begins with either a drive letter specification followed by @@ -231,14 +230,14 @@ extern void PrintTo(const base::FilePath& path, std::ostream* out); // Macros for string literal initialization of FilePath::CharType[], and for // using a FilePath::CharType[] in a printf-style format string. -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #define FILE_PATH_LITERAL(x) x #define PRFilePath "s" #define PRFilePathLiteral "%s" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #define FILE_PATH_LITERAL(x) L ## x #define PRFilePath "ls" #define PRFilePathLiteral L"%ls" -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) #endif // MINI_CHROMIUM_BASE_FILES_FILE_PATH_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_util.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_util.h index 312525176b..95906af3da 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_util.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/file_util.h @@ -7,7 +7,7 @@ #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include @@ -17,6 +17,6 @@ bool ReadFromFD(int fd, char* buffer, size_t bytes); } // namespace base -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) #endif // MINI_CHROMIUM_BASE_FILES_FILE_UTIL_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.cc index e7aa07011f..215407d9a6 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.cc @@ -8,7 +8,7 @@ #include "base/logging.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include #include "base/posix/eintr_wrapper.h" #endif @@ -16,11 +16,11 @@ namespace base { namespace internal { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) void ScopedFDCloseTraits::Free(int fd) { PCHECK(IGNORE_EINTR(close(fd)) == 0); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) void ScopedFILECloser::operator()(FILE* file) const { if (file) { diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.h index 462f561386..a0cc882bf4 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/files/scoped_file.h @@ -16,14 +16,14 @@ namespace base { namespace internal { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) struct ScopedFDCloseTraits { static int InvalidValue() { return -1; } static void Free(int fd); }; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) struct ScopedFILECloser { void operator()(FILE* file) const; @@ -31,9 +31,9 @@ struct ScopedFILECloser { } // namespace internal -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) typedef ScopedGeneric ScopedFD; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) typedef std::unique_ptr ScopedFILE; } // namespace base diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/format_macros.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/format_macros.h index 1ceb0dd311..30459f7c71 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/format_macros.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/format_macros.h @@ -23,7 +23,7 @@ #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && !defined(PRId64) #error "inttypes.h has already been included before this header file, but " @@ -50,7 +50,7 @@ // architectures and Apple does not provides standard format macros and // recommends casting. This has many drawbacks, so instead define macros // for formatting those types. -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #if defined(ARCH_CPU_64_BITS) #if !defined(PRIdNS) #define PRIdNS "ld" @@ -72,9 +72,9 @@ #define PRIxNS "x" #endif #endif -#endif // defined(OS_APPLE) +#endif // BUILDFLAG(IS_APPLE) -#else // OS_WIN +#else // BUILDFLAG(IS_WIN) #if !defined(PRId64) #define PRId64 "I64d" diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/ignore_result.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/ignore_result.h deleted file mode 100644 index 3cc2f377ab..0000000000 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/ignore_result.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MINI_CHROMIUM_BASE_IGNORE_RESULT_H_ -#define MINI_CHROMIUM_BASE_IGNORE_RESULT_H_ - -#include -#include - -template -inline void ignore_result(const T&) {} - -#endif // MINI_CHROMIUM_BASE_IGNORE_RESULT_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.cc index 61d62e064e..38c947feb9 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.cc @@ -10,28 +10,28 @@ #include #include -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include #include #include #include #include "base/posix/safe_strerror.h" -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) // In macOS 10.12 and iOS 10.0 and later ASL (Apple System Log) was deprecated // in favor of OS_LOG (Unified Logging). #include -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) #if !defined(__IPHONE_10_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0 #define USE_ASL #endif -#else // !defined(OS_IOS) +#else // !BUILDFLAG(IS_IOS) #if !defined(MAC_OS_X_VERSION_10_12) || \ MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 #define USE_ASL #endif -#endif // defined(OS_IOS) +#endif // BUILDFLAG(IS_IOS) #if defined(USE_ASL) #include @@ -42,15 +42,15 @@ #include #include -#elif defined(OS_LINUX) +#elif BUILDFLAG(IS_LINUX) #include #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) #include -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #include #endif @@ -92,7 +92,7 @@ LogMessageHandlerFunction GetLogMessageHandler() { return g_log_message_handler; } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) std::string SystemErrorCodeToString(unsigned long error_code) { wchar_t msgbuf[256]; DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | @@ -117,7 +117,7 @@ std::string SystemErrorCodeToString(unsigned long error_code) { GetLastError(), error_code); } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) LogMessage::LogMessage(const char* function, const char* file_path, @@ -161,7 +161,7 @@ LogMessage::~LogMessage() { } if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) const bool log_to_system = []() { struct stat stderr_stat; if (fstat(fileno(stderr), &stderr_stat) == -1) { @@ -316,9 +316,9 @@ LogMessage::~LogMessage() { log.get(), os_log_type, "%{public}s", str_newline.c_str()); #endif } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) OutputDebugString(base::UTF8ToWide(str_newline).c_str()); -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) android_LogPriority priority = (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN; switch (severity_) { @@ -337,35 +337,38 @@ LogMessage::~LogMessage() { } // The Android system may truncate the string if it's too long. __android_log_write(priority, "chromium", str_newline.c_str()); -#elif defined(OS_FUCHSIA) - fx_log_severity_t fx_severity; - switch (severity_) { - case LOG_INFO: - fx_severity = FX_LOG_INFO; - break; - case LOG_WARNING: - fx_severity = FX_LOG_WARNING; - break; - case LOG_ERROR: - fx_severity = FX_LOG_ERROR; - break; - case LOG_FATAL: - fx_severity = FX_LOG_FATAL; - break; - default: - fx_severity = FX_LOG_INFO; - break; - } - // Temporarily remove the trailing newline from |str_newline|'s C-string - // representation, since fx_logger will add a newline of its own. - str_newline.pop_back(); - // Ideally the tag would be the same as the caller, but this is not supported - // right now. - fx_logger_log_with_source(fx_log_get_logger(), fx_severity, /*tag=*/nullptr, - file_path_, line_, - str_newline.c_str() + message_start_); - str_newline.push_back('\n'); -#endif // OS_* +#elif BUILDFLAG(IS_FUCHSIA) + fx_log_severity_t fx_severity; + switch (severity_) { + case LOG_INFO: + fx_severity = FX_LOG_INFO; + break; + case LOG_WARNING: + fx_severity = FX_LOG_WARNING; + break; + case LOG_ERROR: + fx_severity = FX_LOG_ERROR; + break; + case LOG_FATAL: + fx_severity = FX_LOG_FATAL; + break; + default: + fx_severity = FX_LOG_INFO; + break; + } + // Temporarily remove the trailing newline from |str_newline|'s C-string + // representation, since fx_logger will add a newline of its own. + str_newline.pop_back(); + // Ideally the tag would be the same as the caller, but this is not + // supported right now. + fx_logger_log_with_source(fx_log_get_logger(), + fx_severity, + /*tag=*/nullptr, + file_path_, + line_, + str_newline.c_str() + message_start_); + str_newline.push_back('\n'); +#endif // BUILDFLAG(IS_*) } if (severity_ == LOG_FATAL) { @@ -392,7 +395,7 @@ LogMessage::~LogMessage() { void LogMessage::Init(const char* function) { std::string file_name(file_path_); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) size_t last_slash = file_name.find_last_of("\\/"); #else size_t last_slash = file_name.find_last_of('/'); @@ -401,26 +404,26 @@ void LogMessage::Init(const char* function) { file_name.assign(file_name.substr(last_slash + 1)); } -#if defined(OS_POSIX) && !defined(OS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FUCHSIA) pid_t pid = getpid(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) DWORD pid = GetCurrentProcessId(); #endif -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) uint64_t thread; pthread_threadid_np(pthread_self(), &thread); -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) pid_t thread = gettid(); -#elif defined(OS_LINUX) +#elif BUILDFLAG(IS_LINUX) pid_t thread = static_cast(syscall(__NR_gettid)); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) DWORD thread = GetCurrentThreadId(); #endif // On Fuchsia, the platform is responsible for adding the process id and // thread id, not the process itself. -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) stream_ << '[' << pid << ':' @@ -431,7 +434,7 @@ void LogMessage::Init(const char* function) { // On Fuchsia, the platform is responsible for adding the log timestamp, // not the process itself. -#if defined(OS_POSIX) && !defined(OS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FUCHSIA) timeval tv; gettimeofday(&tv, nullptr); tm local_time; @@ -446,7 +449,7 @@ void LogMessage::Init(const char* function) { << '.' << std::setw(6) << tv.tv_usec << ':'; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) SYSTEMTIME local_time; GetLocalTime(&local_time); stream_ << std::setw(4) << local_time.wYear @@ -465,7 +468,7 @@ void LogMessage::Init(const char* function) { // number when LOG_TO_SYSTEM_DEBUG_LOG is enabled, but not on // LOG_TO_STDERR so if LOG_TO_STDERR is enabled, print them here with // potentially repetition if LOG_TO_SYSTEM_DEBUG_LOG is also enabled. -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) if ((g_logging_destination & LOG_TO_STDERR)) { #endif if (severity_ >= 0) { @@ -479,14 +482,14 @@ void LogMessage::Init(const char* function) { << ':' << line_ << "] "; -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) } #endif message_start_ = stream_.str().size(); } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) unsigned long GetLastSystemErrorCode() { return GetLastError(); @@ -504,7 +507,7 @@ Win32ErrorLogMessage::~Win32ErrorLogMessage() { stream() << ": " << SystemErrorCodeToString(err_); } -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) ErrnoLogMessage::ErrnoLogMessage(const char* function, const char* file_path, @@ -523,7 +526,7 @@ ErrnoLogMessage::~ErrnoLogMessage() { << ")"; } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } // namespace logging diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.h index d93ef3a354..a123535781 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/logging.h @@ -34,11 +34,11 @@ enum : LoggingDestination { LOG_TO_ALL = LOG_TO_FILE | LOG_TO_SYSTEM_DEBUG_LOG | LOG_TO_STDERR, -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) LOG_DEFAULT = LOG_TO_FILE, -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) LOG_DEFAULT = LOG_TO_SYSTEM_DEBUG_LOG, -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) LOG_DEFAULT = LOG_TO_SYSTEM_DEBUG_LOG | LOG_TO_STDERR, #endif }; @@ -84,12 +84,12 @@ static inline int GetVlogLevel(const char*) { return std::numeric_limits::max(); } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // This is just ::GetLastError, but out-of-line to avoid including windows.h in // such a widely used place. unsigned long GetLastSystemErrorCode(); std::string SystemErrorCodeToString(unsigned long error_code); -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) static inline int GetLastSystemErrorCode() { return errno; } @@ -130,7 +130,7 @@ class LogMessageVoidify { void operator&(const std::ostream&) const {} }; -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) class Win32ErrorLogMessage : public LogMessage { public: Win32ErrorLogMessage(const char* function, @@ -147,7 +147,7 @@ class Win32ErrorLogMessage : public LogMessage { private: unsigned long err_; }; -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) class ErrnoLogMessage : public LogMessage { public: ErrnoLogMessage(const char* function, @@ -206,7 +206,7 @@ class ErrnoLogMessage : public LogMessage { #define COMPACT_GOOGLE_LOG_DFATAL \ COMPACT_GOOGLE_LOG_EX_DFATAL(LogMessage) -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // wingdi.h defines ERROR 0. We don't want to include windows.h here, and we // want to allow "LOG(ERROR)", which will expand to LOG_0. @@ -222,7 +222,7 @@ namespace logging { const LogSeverity LOG_0 = LOG_ERROR; } // namespace logging -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) #define LAZY_STREAM(stream, condition) \ !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream) @@ -237,14 +237,14 @@ const LogSeverity LOG_0 = LOG_ERROR; logging::LogMessage(FUNCTION_SIGNATURE, __FILE__, __LINE__, \ -verbose_level).stream() -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #define PLOG_STREAM(severity) COMPACT_GOOGLE_LOG_EX_ ## severity( \ Win32ErrorLogMessage, ::logging::GetLastSystemErrorCode()).stream() #define VPLOG_STREAM(verbose_level) \ logging::Win32ErrorLogMessage(FUNCTION_SIGNATURE, __FILE__, __LINE__, \ -verbose_level, \ ::logging::GetLastSystemErrorCode()).stream() -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) #define PLOG_STREAM(severity) COMPACT_GOOGLE_LOG_EX_ ## severity( \ ErrnoLogMessage, ::logging::GetLastSystemErrorCode()).stream() #define VPLOG_STREAM(verbose_level) \ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.h index f22cf0ae96..ee9deafbdf 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.h @@ -8,7 +8,7 @@ #include "base/logging.h" #include "build/build_config.h" -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) #include #else #include @@ -134,7 +134,7 @@ CF_CAST_DECL(CGColor); CF_CAST_DECL(CTFont); CF_CAST_DECL(CTRun); -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) CF_CAST_DECL(SecACL); CF_CAST_DECL(SecTrustedApplication); #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.mm b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.mm index 790a25ae66..1e86235efe 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.mm +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/foundation_util.mm @@ -4,7 +4,7 @@ #include "base/mac/foundation_util.h" -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) extern "C" { CFTypeID SecACLGetTypeID(); CFTypeID SecTrustedApplicationGetTypeID(); @@ -105,7 +105,7 @@ CF_CAST_DEFN(CGColor) CF_CAST_DEFN(CTFont) CF_CAST_DEFN(CTRun) -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) CF_CAST_DEFN(SecACL) CF_CAST_DEFN(SecTrustedApplication) #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.cc index 0411e30700..d3008e63f7 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.cc @@ -9,9 +9,9 @@ #include "base/strings/stringprintf.h" -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) #include -#endif // !OS_IOS +#endif // !BUILDFLAG(IS_IOS) namespace { @@ -44,7 +44,7 @@ MachLogMessage::~MachLogMessage() { << FormatMachErrorNumber(mach_err_); } -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) BootstrapLogMessage::BootstrapLogMessage(const char* function, const char* file_path, @@ -84,6 +84,6 @@ BootstrapLogMessage::~BootstrapLogMessage() { } } -#endif // !OS_IOS +#endif // !BUILDFLAG(IS_IOS) } // namespace logging diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.h index 20c2bb988a..94322c4963 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/mach_logging.h @@ -91,7 +91,7 @@ class MachLogMessage : public logging::LogMessage { DCHECK_IS_ON && !(condition)) \ << "Check failed: " # condition << ". " -#if !defined(OS_IOS) +#if !BUILDFLAG(IS_IOS) namespace logging { @@ -158,6 +158,6 @@ class BootstrapLogMessage : public logging::LogMessage { DCHECK_IS_ON && !(condition)) \ << "Check failed: " # condition << ". " -#endif // !OS_IOS +#endif // !BUILDFLAG(IS_IOS) #endif // MINI_CHROMIUM_BASE_MAC_MACH_LOGGING_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_nsautorelease_pool.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_nsautorelease_pool.h index 811d7ff88a..634c2f7dee 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_nsautorelease_pool.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_nsautorelease_pool.h @@ -7,13 +7,13 @@ #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #if defined(__OBJC__) @class NSAutoreleasePool; #else // __OBJC__ class NSAutoreleasePool; #endif // __OBJC__ -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) namespace base { namespace mac { @@ -28,10 +28,10 @@ namespace mac { // ugly #ifdefs. class ScopedNSAutoreleasePool { public: -#if !defined(OS_APPLE) +#if !BUILDFLAG(IS_APPLE) ScopedNSAutoreleasePool() {} void Recycle() { } -#else // OS_APPLE +#else // BUILDFLAG(IS_APPLE) ScopedNSAutoreleasePool(); ScopedNSAutoreleasePool(const ScopedNSAutoreleasePool&) = delete; @@ -46,7 +46,7 @@ class ScopedNSAutoreleasePool { void Recycle(); private: NSAutoreleasePool* autorelease_pool_; -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) }; } // namespace mac diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_typeref.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_typeref.h index 9f00b1a216..1964518396 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_typeref.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/mac/scoped_typeref.h @@ -5,7 +5,6 @@ #ifndef MINI_CHROMIUM_BASE_MAC_SCOPED_TYPEREF_H_ #define MINI_CHROMIUM_BASE_MAC_SCOPED_TYPEREF_H_ -#include "base/compiler_specific.h" #include "base/logging.h" #include "base/memory/scoped_policy.h" @@ -42,7 +41,7 @@ class ScopedTypeRef { return *this; } - T* InitializeInto() WARN_UNUSED_RESULT { + [[nodiscard]] T* InitializeInto() { DCHECK(!object_); return &object_; } @@ -71,7 +70,7 @@ class ScopedTypeRef { object_ = temp; } - T release() WARN_UNUSED_RESULT { + [[nodiscard]] T release() { T temp = object_; object_ = Traits::InvalidValue(); return temp; diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/numerics/checked_math.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/numerics/checked_math.h index 6b918c4277..9eefced226 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/numerics/checked_math.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/numerics/checked_math.h @@ -61,13 +61,7 @@ class CheckedNumeric { // and is within the range supported by the destination type. Returns true if // successful and false otherwise. template -#if defined(__clang__) || defined(__GNUC__) - __attribute__((warn_unused_result)) -#elif defined(_MSC_VER) - _Check_return_ -#endif - constexpr bool - AssignIfValid(Dst* result) const { + [[nodiscard]] constexpr bool AssignIfValid(Dst* result) const { return BASE_NUMERICS_LIKELY(IsValid()) ? ((*result = static_cast(state_.value())), true) : false; diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/eintr_wrapper.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/eintr_wrapper.h index 3b1d6d3f66..e6e19f6b3b 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/eintr_wrapper.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/eintr_wrapper.h @@ -13,7 +13,7 @@ #include "build/build_config.h" // On Fuchsia, these wrapper macros do nothing because there are no signals. -#if defined(OS_POSIX) && !defined(OS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FUCHSIA) #include @@ -41,6 +41,6 @@ #define HANDLE_EINTR(x) (x) #define IGNORE_EINTR(x) (x) -#endif // OS_POSIX && !OS_FUCHSIA +#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FUCHSIA) #endif // MINI_CHROMIUM_BASE_POSIX_EINTR_WRAPPER_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/safe_strerror.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/safe_strerror.cc index f39495c638..012966c59e 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/safe_strerror.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/posix/safe_strerror.cc @@ -11,7 +11,7 @@ #include "base/cxx17_backports.h" #include "build/build_config.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif @@ -19,7 +19,7 @@ namespace base { void safe_strerror_r(int err, char* buf, size_t len) { #if defined(__GLIBC__) || \ - (defined(OS_ANDROID) && defined(_GNU_SOURCE) && __ANDROID_API__ >= 23) + (BUILDFLAG(IS_ANDROID) && defined(_GNU_SOURCE) && __ANDROID_API__ >= 23) char* ret = strerror_r(err, buf, len); if (ret != buf) { snprintf(buf, len, "%s", ret); diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/process/memory.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/process/memory.h index fca87456c9..88799af0b9 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/process/memory.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/process/memory.h @@ -7,15 +7,12 @@ #include -#include "base/compiler_specific.h" - namespace base { // Special allocator function for callers that want to check for OOM. // On success, *result will contain a pointer that should be dallocated with // free(). -WARN_UNUSED_RESULT bool UncheckedMalloc(size_t size, - void** result); +[[nodiscard]] bool UncheckedMalloc(size_t size, void** result); } // namespace base diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/rand_util.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/rand_util.cc index ae5cdbfb19..9f4196d161 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/rand_util.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/rand_util.cc @@ -15,12 +15,12 @@ #include "base/logging.h" #include "build/build_config.h" -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) #include #include "base/fuchsia/fuchsia_logging.h" -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) #include "base/posix/eintr_wrapper.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include // #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the @@ -30,9 +30,9 @@ #include #undef SystemFunction036 -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) -#if defined(OS_POSIX) && !defined(OS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FUCHSIA) namespace { @@ -49,7 +49,7 @@ int GetUrandomFD() { } // namespace -#endif // OS_POSIX && !OS_FUCHSIA +#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_FUCHSIA) namespace base { @@ -109,13 +109,13 @@ void RandBytes(void* output, size_t output_length) { return; } -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) zx_cprng_draw(output, output_length); -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) int fd = GetUrandomFD(); bool success = ReadFromFD(fd, static_cast(output), output_length); CHECK(success); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) char* output_ptr = static_cast(output); while (output_length > 0) { const ULONG output_bytes_this_pass = static_cast(std::min( diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_clear_last_error.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_clear_last_error.h index acc256844f..85f59df750 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_clear_last_error.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_clear_last_error.h @@ -24,7 +24,7 @@ class ScopedClearLastErrorBase { const int last_errno_; }; -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) class ScopedClearLastError : public ScopedClearLastErrorBase { public: @@ -39,11 +39,11 @@ class ScopedClearLastError : public ScopedClearLastErrorBase { const unsigned long last_system_error_; }; -#elif defined(OS_POSIX) || defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) using ScopedClearLastError = ScopedClearLastErrorBase; -#endif // defined(OS_WIN) +#endif // BUILDFLAG(IS_WIN) } // namespace base diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_generic.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_generic.h index 062ae1b47e..d3a6dfd134 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_generic.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/scoped_generic.h @@ -9,8 +9,6 @@ #include -#include "base/compiler_specific.h" - namespace base { template @@ -63,7 +61,7 @@ class ScopedGeneric { swap(data_.generic, other.data_.generic); } - element_type release() WARN_UNUSED_RESULT { + [[nodiscard]] element_type release() { element_type old_generic = data_.generic; data_.generic = traits_type::InvalidValue(); return old_generic; diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/string_util.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/string_util.h index 80dd87964f..bfb02acd06 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/string_util.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/string_util.h @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "base/logging.h" +#include "build/build_config.h" namespace base { @@ -18,9 +19,9 @@ size_t wcslcpy(wchar_t* dst, const wchar_t* src, size_t dst_size); } // namespace base -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include "base/strings/string_util_win.h" -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) #include "base/strings/string_util_posix.h" #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/stringprintf.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/stringprintf.cc index 627ccb5272..684f3e7ab1 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/stringprintf.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/stringprintf.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/scoped_clear_last_error.h" #include "base/strings/string_util.h" +#include "build/build_config.h" namespace base { @@ -46,7 +47,7 @@ static void StringAppendVT(StringType* dst, size_t mem_length = size(stack_buf); while (true) { if (result < 0) { -#if !defined(OS_WIN) +#if !BUILDFLAG(IS_WIN) // On Windows, vsnprintfT always returns the number of characters in a // fully-formatted string, so if we reach this point, something else is // wrong and no amount of buffer-doubling is going to fix it. @@ -56,7 +57,7 @@ static void StringAppendVT(StringType* dst, DLOG(WARNING) << "Unable to printf the requested string due to error."; return; } -#if !defined(OS_WIN) +#if !BUILDFLAG(IS_WIN) // Try doubling the buffer size. mem_length *= 2; #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/sys_string_conversions.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/sys_string_conversions.h index 154f224a88..c8c84c523d 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/sys_string_conversions.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/strings/sys_string_conversions.h @@ -7,7 +7,7 @@ #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include @@ -28,6 +28,6 @@ NSString* SysUTF8ToNSString(const std::string& utf8); } // namespace base -#endif // defined(OS_APPLE) +#endif // BUILDFLAG(IS_APPLE) #endif // MINI_CHROMIUM_BASE_STRINGS_SYS_STRING_CONVERSIONS_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.cc index e94e637991..e7c0d8c3fb 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.cc @@ -17,9 +17,9 @@ namespace base { namespace { ThreadRefType GetCurrentThreadRef() { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) return GetCurrentThreadId(); -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) return pthread_self(); #endif } diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.h index 89f2558c5a..66e74f3586 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock.h @@ -7,9 +7,9 @@ #include "build/build_config.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) #include #endif @@ -17,9 +17,9 @@ namespace base { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) typedef DWORD ThreadRefType; -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) typedef pthread_t ThreadRefType; #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock_impl.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock_impl.h index cfd9dcad7a..b82df6adb5 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock_impl.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/synchronization/lock_impl.h @@ -7,9 +7,9 @@ #include "build/build_config.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) #include #endif @@ -22,9 +22,9 @@ namespace internal { // should instead use Lock. class LockImpl { public: -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) typedef CRITICAL_SECTION NativeHandle; -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) typedef pthread_mutex_t NativeHandle; #endif diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/sys_byteorder.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/sys_byteorder.h index 0e18e5a9c1..dba8fb5b85 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/sys_byteorder.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/sys_byteorder.h @@ -7,9 +7,9 @@ #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #else #include @@ -18,9 +18,9 @@ namespace base { inline uint16_t ByteSwap(uint16_t x) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) return OSSwapInt16(x); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return _byteswap_ushort(x); #else return bswap_16(x); @@ -28,9 +28,9 @@ inline uint16_t ByteSwap(uint16_t x) { } inline uint32_t ByteSwap(uint32_t x) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) return OSSwapInt32(x); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return _byteswap_ulong(x); #else return bswap_32(x); @@ -38,9 +38,9 @@ inline uint32_t ByteSwap(uint32_t x) { } inline uint64_t ByteSwap(uint64_t x) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) return OSSwapInt64(x); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return _byteswap_uint64(x); #else return bswap_64(x); diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.cc b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.cc index 470896ca1e..e3eab3d4f4 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.cc +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.cc @@ -175,7 +175,7 @@ namespace base { namespace internal { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) void PlatformThreadLocalStorage::OnThreadExit() { PlatformThreadLocalStorage::TLSKey key = base::subtle::NoBarrier_Load(&g_native_tls_key); @@ -187,11 +187,11 @@ void PlatformThreadLocalStorage::OnThreadExit() { return; OnThreadExitInternal(tls_data); } -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) void PlatformThreadLocalStorage::OnThreadExit(void* value) { OnThreadExitInternal(value); } -#endif // defined(OS_WIN) +#endif // BUILDFLAG(IS_WIN) } // namespace internal diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.h index ec5b191005..01a212a10e 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/base/threading/thread_local_storage.h @@ -7,9 +7,9 @@ #include "build/build_config.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) #include #endif @@ -22,11 +22,10 @@ namespace internal { // interface, you should instead be using ThreadLocalStorage::StaticSlot/Slot. class PlatformThreadLocalStorage { public: - -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) typedef unsigned long TLSKey; enum { TLS_KEY_OUT_OF_INDEXES = TLS_OUT_OF_INDEXES }; -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) typedef pthread_key_t TLSKey; // The following is a "reserved key" which is used in our generic Chromium // ThreadLocalStorage implementation. We expect that an OS will not return @@ -58,11 +57,11 @@ class PlatformThreadLocalStorage { // Destructors may end up being called multiple times on a terminating // thread, as other destructors may re-set slots that were previously // destroyed. -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Since Windows which doesn't support TLS destructor, the implementation // should use GetTLSValue() to retrieve the value of TLS slot. static void OnThreadExit(); -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) // |Value| is the data stored in TLS slot, The implementation can't use // GetTLSValue() to retrieve the value of slot as it has already been reset // in Posix. diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/BUILD.gn b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/BUILD.gn index 561a4bccf8..ed507eea59 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/BUILD.gn @@ -12,13 +12,14 @@ import("./platform.gni") config("mini_chromium_config") { include_dirs = [ "..", - root_gen_dir + root_gen_dir, ] } source_set("build") { sources = [ "build_config.h" ] public_configs = [ ":mini_chromium_config" ] + public_deps = [ ":buildflag_header_h" ] } source_set("buildflag_header_h") { diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/build_config.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/build_config.h index 3d670a90c9..113500063f 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/build_config.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/build_config.h @@ -5,34 +5,73 @@ #ifndef MINI_CHROMIUM_BUILD_BUILD_CONFIG_H_ #define MINI_CHROMIUM_BUILD_BUILD_CONFIG_H_ +#include "build/buildflag.h" + #if defined(__APPLE__) -#define OS_APPLE 1 +#include +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_APPLE() 1 +#if defined(TARGET_OS_OSX) && TARGET_OS_OSX +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_MAC() 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_IOS() 0 +#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_MAC() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_IOS() 1 +#endif // TARGET_OS_* +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_ANDROID() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_LINUX() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_WIN() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_FUCHSIA() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_POSIX() 1 #elif defined(__ANDROID__) -#define OS_ANDROID 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_APPLE() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_MAC() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_IOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_ANDROID() 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_LINUX() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_WIN() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_FUCHSIA() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_POSIX() 1 #elif defined(__linux__) -#define OS_LINUX 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_APPLE() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_MAC() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_IOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_ANDROID() 0 +#if !defined(OS_CHROMEOS) +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_LINUX() 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS() 0 +#else +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_LINUX() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS() 1 +#endif +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_WIN() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_FUCHSIA() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_POSIX() 1 #elif defined(_WIN32) -#define OS_WIN 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_APPLE() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_MAC() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_IOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_ANDROID() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_LINUX() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_WIN() 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_FUCHSIA() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_POSIX() 0 #elif defined(__Fuchsia__) -#define OS_FUCHSIA 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_APPLE() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_MAC() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_IOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_ANDROID() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_LINUX() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_CHROMEOS() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_WIN() 0 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_FUCHSIA() 1 +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_IS_POSIX() 1 #else #error Please add support for your platform in build/build_config.h #endif -#if defined(OS_APPLE) -#include -#if defined(TARGET_OS_OSX) && TARGET_OS_OSX -#define OS_MAC 1 -#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE -#define OS_IOS 1 -#endif // TARGET_OS_* -#endif // defined(OS_APPLE) - -#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_ANDROID) || \ - defined(OS_FUCHSIA) -#define OS_POSIX 1 -#endif - // Compiler detection. #if defined(__GNUC__) #define COMPILER_GCC 1 @@ -88,11 +127,10 @@ #endif #endif -#if defined(OS_POSIX) && defined(COMPILER_GCC) && \ - defined(__WCHAR_MAX__) && \ +#if BUILDFLAG(IS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \ (__WCHAR_MAX__ == 0x7fffffff || __WCHAR_MAX__ == 0xffffffff) #define WCHAR_T_IS_UTF32 -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #define WCHAR_T_IS_UTF16 #else #error Please add support for your compiler in build/build_config.h diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/buildflag.h b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/buildflag.h index ca057979c3..62222a8926 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/buildflag.h +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/buildflag.h @@ -5,9 +5,12 @@ #ifndef BUILD_BUILDFLAG_H_ #define BUILD_BUILDFLAG_H_ -#define BUILDFLAG_CAT_INDIRECT(a, b) a ## b -#define BUILDFLAG_CAT(a, b) BUILDFLAG_CAT_INDIRECT(a, b) +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_CAT_INDIRECT(a, b) a##b +#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_CAT(a, b) \ + MINI_CHROMIUM_INTERNAL_BUILDFLAG_CAT_INDIRECT(a, b) -#define BUILDFLAG(flag) (BUILDFLAG_CAT(BUILDFLAG_INTERNAL_, flag)()) +#define BUILDFLAG(flag) \ + (MINI_CHROMIUM_INTERNAL_BUILDFLAG_CAT( \ + MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_, flag)()) #endif // BUILD_BUILDFLAG_H_ diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/config/BUILD.gn b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/config/BUILD.gn index d6171efad9..e32e40de14 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/config/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/config/BUILD.gn @@ -153,7 +153,7 @@ config("default") { ] cflags_c = [ "-std=c11" ] - cflags_cc = [ "-std=c++14" ] + cflags_cc = [ "-std=c++17" ] cflags_objc = cflags_c cflags_objcc = cflags_cc @@ -225,10 +225,10 @@ config("default") { if (mini_chromium_is_ios) { if (ios_deployment_target != "") { - if (current_cpu == "x64") { + if (target_environment == "simulator") { common_flags += [ "-mios-simulator-version-min=" + ios_deployment_target ] - } else if (current_cpu == "arm64") { + } else if (target_environment == "device") { common_flags += [ "-mios-version-min=" + ios_deployment_target ] } } @@ -255,6 +255,11 @@ config("default") { "/wd4996", # 'X' was declared deprecated. ] + cflags_cc = [ + "/std:c++17", + "/Zc:__cplusplus", + ] + ldflags += [ "/DEBUG" ] libs = [ "kernel32.lib" ] @@ -665,7 +670,7 @@ if (mini_chromium_is_win) { tool("cxx") { depfile = "{{output}}.d" pdbname = "{{target_out_dir}}/{{label_name}}_cc.pdb" - command = "ninja -t msvc -e $env -- $cxx /nologo /showIncludes {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}${extra_cflags}${extra_cflags_cc} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" + command = "ninja -t msvc -e $env -- $cxx /nologo /showIncludes {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cflags}${extra_cflags_cc} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" depsformat = "msvc" description = "CXX {{output}}" outputs = diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/XCTRunnerAddition+Info.plist b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/XCTRunnerAddition+Info.plist index c171601c2b..040d76c372 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/XCTRunnerAddition+Info.plist +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/XCTRunnerAddition+Info.plist @@ -5,7 +5,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.apple.test.${EXECUTABLE_NAME} + ${BUNDLE_IDENTIFIER} CFBundleName ${PRODUCT_NAME} diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/codesign.py b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/codesign.py index e812978388..c93c46af15 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/codesign.py +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/codesign.py @@ -1,14 +1,15 @@ -#!/usr/bin/env python - # Copyright 2016 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function + import argparse import codecs import datetime import fnmatch import glob +import json import os import plistlib import shutil @@ -16,6 +17,11 @@ import subprocess import sys import tempfile +if sys.version_info.major < 3: + basestring_compat = basestring +else: + basestring_compat = str + def GetProvisioningProfilesDir(): """Returns the location of the installed mobile provisioning profiles. @@ -28,6 +34,21 @@ def GetProvisioningProfilesDir(): os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles') +def ReadPlistFromString(plist_bytes): + """Parse property list from given |plist_bytes|. + + Args: + plist_bytes: contents of property list to load. Must be bytes in python 3. + + Returns: + The contents of property list as a python object. + """ + if sys.version_info.major == 2: + return plistlib.readPlistFromString(plist_bytes) + else: + return plistlib.loads(plist_bytes) + + def LoadPlistFile(plist_path): """Loads property list file at |plist_path|. @@ -37,29 +58,94 @@ def LoadPlistFile(plist_path): Returns: The content of the property list file as a python object. """ - return plistlib.readPlistFromString(subprocess.check_output([ - 'xcrun', 'plutil', '-convert', 'xml1', '-o', '-', plist_path])) + if sys.version_info.major == 2: + return plistlib.readPlistFromString( + subprocess.check_output( + ['xcrun', 'plutil', '-convert', 'xml1', '-o', '-', plist_path])) + else: + with open(plist_path, 'rb') as fp: + return plistlib.load(fp) + + +def CreateSymlink(value, location): + """Creates symlink with value at location if the target exists.""" + target = os.path.join(os.path.dirname(location), value) + if os.path.exists(location): + os.unlink(location) + os.symlink(value, location) class Bundle(object): """Wraps a bundle.""" - def __init__(self, bundle_path): + def __init__(self, bundle_path, platform): """Initializes the Bundle object with data from bundle Info.plist file.""" self._path = bundle_path - self._data = LoadPlistFile(os.path.join(self._path, 'Info.plist')) + self._kind = Bundle.Kind(platform, os.path.splitext(bundle_path)[-1]) + self._data = None + + def Load(self): + self._data = LoadPlistFile(self.info_plist_path) + + @staticmethod + def Kind(platform, extension): + if platform == 'iphonesimulator' or platform == 'iphoneos': + return 'ios' + if platform == 'macosx': + if extension == '.framework': + return 'mac_framework' + return 'mac' + raise ValueError('unknown bundle type %s for %s' % (extension, platform)) + + @property + def kind(self): + return self._kind @property def path(self): return self._path + @property + def contents_dir(self): + if self._kind == 'mac': + return os.path.join(self.path, 'Contents') + if self._kind == 'mac_framework': + return os.path.join(self.path, 'Versions/A') + return self.path + + @property + def executable_dir(self): + if self._kind == 'mac': + return os.path.join(self.contents_dir, 'MacOS') + return self.contents_dir + + @property + def resources_dir(self): + if self._kind == 'mac' or self._kind == 'mac_framework': + return os.path.join(self.contents_dir, 'Resources') + return self.path + + @property + def info_plist_path(self): + if self._kind == 'mac_framework': + return os.path.join(self.resources_dir, 'Info.plist') + return os.path.join(self.contents_dir, 'Info.plist') + + @property + def signature_dir(self): + return os.path.join(self.contents_dir, '_CodeSignature') + @property def identifier(self): return self._data['CFBundleIdentifier'] + @property + def binary_name(self): + return self._data['CFBundleExecutable'] + @property def binary_path(self): - return os.path.join(self._path, self._data['CFBundleExecutable']) + return os.path.join(self.executable_dir, self.binary_name) def Validate(self, expected_mappings): """Checks that keys in the bundle have the expected value. @@ -75,7 +161,7 @@ class Bundle(object): error message. The dictionary will be empty if there are no errors. """ errors = {} - for key, expected_value in expected_mappings.iteritems(): + for key, expected_value in expected_mappings.items(): if key in self._data: value = self._data[key] if value != expected_value: @@ -89,21 +175,31 @@ class ProvisioningProfile(object): def __init__(self, provisioning_profile_path): """Initializes the ProvisioningProfile with data from profile file.""" self._path = provisioning_profile_path - self._data = plistlib.readPlistFromString(subprocess.check_output([ - 'xcrun', 'security', 'cms', '-D', '-u', 'certUsageAnyCA', - '-i', provisioning_profile_path])) + self._data = ReadPlistFromString( + subprocess.check_output([ + 'xcrun', 'security', 'cms', '-D', '-u', 'certUsageAnyCA', '-i', + provisioning_profile_path + ])) @property def path(self): return self._path + @property + def team_identifier(self): + return self._data.get('TeamIdentifier', [''])[0] + + @property + def name(self): + return self._data.get('Name', '') + @property def application_identifier_pattern(self): return self._data.get('Entitlements', {}).get('application-identifier', '') @property - def team_identifier(self): - return self._data.get('TeamIdentifier', [''])[0] + def application_identifier_prefix(self): + return self._data.get('ApplicationIdentifierPrefix', [''])[0] @property def entitlements(self): @@ -124,7 +220,7 @@ class ProvisioningProfile(object): with the corresponding bundle_identifier, False otherwise. """ return fnmatch.fnmatch( - '%s.%s' % (self.team_identifier, bundle_identifier), + '%s.%s' % (self.application_identifier_prefix, bundle_identifier), self.application_identifier_pattern) def Install(self, installation_path): @@ -148,13 +244,13 @@ class Entitlements(object): self._data = self._ExpandVariables(self._data, substitutions) def _ExpandVariables(self, data, substitutions): - if isinstance(data, str): - for key, substitution in substitutions.iteritems(): + if isinstance(data, basestring_compat): + for key, substitution in substitutions.items(): data = data.replace('$(%s)' % (key,), substitution) return data if isinstance(data, dict): - for key, value in data.iteritems(): + for key, value in data.items(): data[key] = self._ExpandVariables(value, substitutions) return data @@ -165,12 +261,16 @@ class Entitlements(object): return data def LoadDefaults(self, defaults): - for key, value in defaults.iteritems(): + for key, value in defaults.items(): if key not in self._data: self._data[key] = value def WriteTo(self, target_path): - plistlib.writePlist(self._data, target_path) + with open(target_path, 'wb') as fp: + if sys.version_info.major == 2: + plistlib.writePlist(self._data, fp) + else: + plistlib.dump(self._data, fp) def FindProvisioningProfile(bundle_identifier, required): @@ -225,9 +325,11 @@ def FindProvisioningProfile(bundle_identifier, required): def CodeSignBundle(bundle_path, identity, extra_args): - process = subprocess.Popen(['xcrun', 'codesign', '--force', '--sign', - identity, '--timestamp=none'] + list(extra_args) + [bundle_path], - stderr=subprocess.PIPE) + process = subprocess.Popen( + ['xcrun', 'codesign', '--force', '--sign', identity, '--timestamp=none'] + + list(extra_args) + [bundle_path], + stderr=subprocess.PIPE, + universal_newlines=True) _, stderr = process.communicate() if process.returncode: sys.stderr.write(stderr) @@ -268,7 +370,8 @@ def GenerateEntitlements(path, provisioning_profile, bundle_identifier): entitlements = Entitlements(path) if provisioning_profile: entitlements.LoadDefaults(provisioning_profile.entitlements) - app_identifier_prefix = provisioning_profile.team_identifier + '.' + app_identifier_prefix = \ + provisioning_profile.application_identifier_prefix + '.' else: app_identifier_prefix = '*.' entitlements.ExpandVariables({ @@ -278,19 +381,18 @@ def GenerateEntitlements(path, provisioning_profile, bundle_identifier): return entitlements -def GenerateBundleInfoPlist(bundle_path, plist_compiler, partial_plist): +def GenerateBundleInfoPlist(bundle, plist_compiler, partial_plist): """Generates the bundle Info.plist for a list of partial .plist files. Args: - bundle_path: path to the bundle + bundle: a Bundle instance plist_compiler: string, path to the Info.plist compiler partial_plist: list of path to partial .plist files to merge """ # Filter empty partial .plist files (this happens if an application - # does not include need to compile any asset catalog, in which case - # the partial .plist file from the asset catalog compilation step is - # just a stamp file). + # does not compile any asset catalog, in which case the partial .plist + # file from the asset catalog compilation step is just a stamp file). filtered_partial_plist = [] for plist in partial_plist: plist_size = os.stat(plist).st_size @@ -299,8 +401,13 @@ def GenerateBundleInfoPlist(bundle_path, plist_compiler, partial_plist): # Invoke the plist_compiler script. It needs to be a python script. subprocess.check_call([ - 'python', plist_compiler, 'merge', '-f', 'binary1', - '-o', os.path.join(bundle_path, 'Info.plist'), + 'python3', + plist_compiler, + 'merge', + '-f', + 'binary1', + '-o', + bundle.info_plist_path, ] + filtered_partial_plist) @@ -359,13 +466,16 @@ class CodeSignBundleAction(Action): if not args.identity: args.identity = '-' - if args.partial_info_plist: - GenerateBundleInfoPlist( - args.path, - args.plist_compiler_path, - args.partial_info_plist) + bundle = Bundle(args.path, args.platform) - bundle = Bundle(args.path) + if args.partial_info_plist: + GenerateBundleInfoPlist(bundle, args.plist_compiler_path, + args.partial_info_plist) + + # The bundle Info.plist may have been updated by GenerateBundleInfoPlist() + # above. Load the bundle information from Info.plist after the modification + # have been written to disk. + bundle.Load() # According to Apple documentation, the application binary must be the same # as the bundle name without the .app suffix. See crbug.com/740476 for more @@ -402,19 +512,37 @@ class CodeSignBundleAction(Action): os.unlink(embedded_provisioning_profile) # Delete existing code signature. - signature_file = os.path.join(args.path, '_CodeSignature', 'CodeResources') - if os.path.isfile(signature_file): - shutil.rmtree(os.path.dirname(signature_file)) + if os.path.exists(bundle.signature_dir): + shutil.rmtree(bundle.signature_dir) # Install system frameworks if requested. for framework_path in args.frameworks: InstallSystemFramework(framework_path, args.path, args) # Copy main binary into bundle. - if os.path.isfile(bundle.binary_path): - os.unlink(bundle.binary_path) + if not os.path.isdir(bundle.executable_dir): + os.makedirs(bundle.executable_dir) shutil.copy(args.binary, bundle.binary_path) + if bundle.kind == 'mac_framework': + # Create Versions/Current -> Versions/A symlink + CreateSymlink('A', os.path.join(bundle.path, 'Versions/Current')) + + # Create $binary_name -> Versions/Current/$binary_name symlink + CreateSymlink(os.path.join('Versions/Current', bundle.binary_name), + os.path.join(bundle.path, bundle.binary_name)) + + # Create optional symlinks. + for name in ('Headers', 'Resources', 'Modules'): + target = os.path.join(bundle.path, 'Versions/A', name) + if os.path.exists(target): + CreateSymlink(os.path.join('Versions/Current', name), + os.path.join(bundle.path, name)) + else: + obsolete_path = os.path.join(bundle.path, name) + if os.path.exists(obsolete_path): + os.unlink(obsolete_path) + if args.no_signature: return @@ -512,6 +640,31 @@ class GenerateEntitlementsAction(Action): entitlements.WriteTo(args.path) +class FindProvisioningProfileAction(Action): + """Class implementing the find-codesign-identity action.""" + + name = 'find-provisioning-profile' + help = 'find provisioning profile for use by Xcode project generator' + + @staticmethod + def _Register(parser): + parser.add_argument('--bundle-id', + '-b', + required=True, + help='bundle identifier') + + @staticmethod + def _Execute(args): + provisioning_profile_info = {} + provisioning_profile = FindProvisioningProfile(args.bundle_id, False) + for key in ('team_identifier', 'name'): + if provisioning_profile: + provisioning_profile_info[key] = getattr(provisioning_profile, key) + else: + provisioning_profile_info[key] = '' + print(json.dumps(provisioning_profile_info)) + + def Main(): # Cache this codec so that plistlib can find it. See # https://crbug.com/999461#c12 for more details. @@ -524,6 +677,7 @@ def Main(): CodeSignBundleAction, CodeSignFileAction, GenerateEntitlementsAction, + FindProvisioningProfileAction, ] for action in actions: diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/find_signing_identity.py b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/find_signing_identity.py index 985281b504..f6c2342aa6 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/find_signing_identity.py +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/find_signing_identity.py @@ -1,6 +1,4 @@ -#!/usr/bin/env python - -# Copyright 2015 The Chromium Authors. All rights reserved. +# Copyright (c) 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -12,35 +10,80 @@ import subprocess import sys import re + +def Redact(value, from_nth_char=5): + """Redact value past the N-th character.""" + return value[:from_nth_char] + '*' * (len(value) - from_nth_char) + + +class Identity(object): + """Represents a valid identity.""" + + def __init__(self, identifier, name, team): + self.identifier = identifier + self.name = name + self.team = team + + def redacted(self): + return Identity(Redact(self.identifier), self.name, Redact(self.team)) + + def format(self): + return '%s: "%s (%s)"' % (self.identifier, self.name, self.team) + + def ListIdentities(): return subprocess.check_output([ - 'xcrun', - 'security', - 'find-identity', - '-v', - '-p', - 'codesigning', - ]) + 'xcrun', + 'security', + 'find-identity', + '-v', + '-p', + 'codesigning', + ]).decode('utf8') -def FindValidIdentity(identity_description): - lines = list(map(str.strip, ListIdentities().splitlines())) +def FindValidIdentity(pattern): + """Find all identities matching the pattern.""" + lines = list(l.strip() for l in ListIdentities().splitlines()) # Look for something like "2) XYZ "iPhone Developer: Name (ABC)"" - exp = re.compile('[0-9]+\) ([A-F0-9]+) "([^"]*)"') + regex = re.compile('[0-9]+\) ([A-F0-9]+) "([^"(]*) \(([^)"]*)\)"') + + result = [] for line in lines: - res = exp.match(line) + res = regex.match(line) if res is None: continue - if identity_description in res.group(2): - yield res.group(1) + if pattern is None or pattern in res.group(2): + result.append(Identity(*res.groups())) + return result + + +def Main(args): + parser = argparse.ArgumentParser('codesign iOS bundles') + parser.add_argument( + '--identity-description', required=True, dest='pattern', + help='Text description used to select the code signing identity.') + parsed = parser.parse_args(args) + + identities = FindValidIdentity(parsed.pattern) + if len(identities) == 1: + print(identities[0].identifier, end='') + return 0 + + all_identities = FindValidIdentity(None) + + print('Automatic code signing identity selection was enabled but could not') + print('find exactly one codesigning identity matching "%s".' % parsed.pattern) + print('') + print('Check that the keychain is accessible and that there is exactly one') + print('valid codesigning identity matching the pattern. Here is the parsed') + print('output of `xcrun security find-identity -v -p codesigning`:') + print() + for i, identity in enumerate(all_identities): + print(' %d) %s' % (i + 1, identity.redacted().format())) + print(' %d valid identities found' % (len(all_identities))) + return 1 if __name__ == '__main__': - parser = argparse.ArgumentParser('codesign iOS bundles') - parser.add_argument( - '--identity-description', required=True, - help='Text description used to select the code signing identity.') - args = parser.parse_args() - - for identity in FindValidIdentity(args.identity_description): - print(identity) + sys.exit(Main(sys.argv[1:])) diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/ios_sdk.gni b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/ios_sdk.gni index 1aacf49997..8a01f6f975 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/ios_sdk.gni +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/ios_sdk.gni @@ -6,7 +6,7 @@ declare_args() { # The minimum runtime iOS version that built products are expected to run # on. If empty, the toolchain will choose its own default, typically the # most recent OS version. - ios_deployment_target = "12.0" + ios_deployment_target = "14.0" # SDK path to use. When empty this will use the default SDK based on the # value of use_ios_simulator. @@ -21,9 +21,24 @@ declare_args() { ios_enable_code_signing = true ios_code_signing_identity = "" ios_code_signing_identity_description = "Apple Development" + + # Configure the environment for which to build. Could be either "device", + # "simulator" or "catalyst". If unspecified, then it will be assumed to be + # "simulator" if the target_cpu is "x68" or "x64", "device" otherwise. The + # default is only there for compatibility reasons and will be removed (see + # crbug.com/1138425 for more details). + target_environment = "" } -use_ios_simulator = current_cpu == "x86" || current_cpu == "x64" +if (target_environment == "") { + if (current_cpu == "x86" || current_cpu == "x64") { + target_environment = "simulator" + } else { + target_environment = "device" + } +} + +use_ios_simulator = target_environment == "simulator" if (ios_sdk_path == "") { # Compute default target. diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/plist_util.py b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/plist_util.py index f908835538..54cf46176b 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/plist_util.py +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/plist_util.py @@ -1,10 +1,9 @@ -#!/usr/bin/env python - # Copyright 2016 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse +import codecs import plistlib import os import re @@ -13,6 +12,10 @@ import sys import tempfile import shlex +if sys.version_info.major < 3: + basestring_compat = basestring +else: + basestring_compat = str # Xcode substitutes variables like ${PRODUCT_NAME} or $(PRODUCT_NAME) when # compiling Info.plist. It also supports supports modifiers like :identifier @@ -48,6 +51,7 @@ def InterpolateString(value, substitutions): value in |substitutions|. Raises SubstitutionError if a variable has no substitution. """ + def repl(match): variable = match.group('id') if variable not in substitutions: @@ -63,6 +67,7 @@ def InterpolateString(value, substitutions): return INVALID_CHARACTER_REGEXP.sub('-', substitutions[variable]) else: return substitutions[variable] + for substitution_regexp in SUBSTITUTION_REGEXP_LIST: value = substitution_regexp.sub(repl, value) return value @@ -81,40 +86,49 @@ def Interpolate(value, substitutions): substitution. """ if isinstance(value, dict): - return {k: Interpolate(v, substitutions) for k, v in value.iteritems()} + return {k: Interpolate(v, substitutions) for k, v in value.items()} if isinstance(value, list): return [Interpolate(v, substitutions) for v in value] - if isinstance(value, str): + if isinstance(value, basestring_compat): return InterpolateString(value, substitutions) return value def LoadPList(path): """Loads Plist at |path| and returns it as a dictionary.""" - fd, name = tempfile.mkstemp() - try: - subprocess.check_call(['plutil', '-convert', 'xml1', '-o', name, path]) - with os.fdopen(fd, 'r') as f: - return plistlib.readPlist(f) - finally: - os.unlink(name) + if sys.version_info.major == 2: + fd, name = tempfile.mkstemp() + try: + subprocess.check_call(['plutil', '-convert', 'xml1', '-o', name, path]) + with os.fdopen(fd, 'rb') as f: + return plistlib.readPlist(f) + finally: + os.unlink(name) + else: + with open(path, 'rb') as f: + return plistlib.load(f) def SavePList(path, format, data): """Saves |data| as a Plist to |path| in the specified |format|.""" - fd, name = tempfile.mkstemp() - try: - # "plutil" does not replace the destination file but update it in place, - # so if more than one hardlink points to destination all of them will be - # modified. This is not what is expected, so delete destination file if - # it does exist. - if os.path.exists(path): - os.unlink(path) - with os.fdopen(fd, 'w') as f: - plistlib.writePlist(data, f) - subprocess.check_call(['plutil', '-convert', format, '-o', path, name]) - finally: - os.unlink(name) + # The below does not replace the destination file but update it in place, + # so if more than one hardlink points to destination all of them will be + # modified. This is not what is expected, so delete destination file if + # it does exist. + if os.path.exists(path): + os.unlink(path) + if sys.version_info.major == 2: + fd, name = tempfile.mkstemp() + try: + with os.fdopen(fd, 'wb') as f: + plistlib.writePlist(data, f) + subprocess.check_call(['plutil', '-convert', format, '-o', path, name]) + finally: + os.unlink(name) + else: + with open(path, 'wb') as f: + plist_format = {'binary1': plistlib.FMT_BINARY, 'xml1': plistlib.FMT_XML} + plistlib.dump(data, f, fmt=plist_format[format]) def MergePList(plist1, plist2): @@ -135,7 +149,7 @@ def MergePList(plist1, plist2): are concatenated. """ result = plist1.copy() - for key, value in plist2.iteritems(): + for key, value in plist2.items(): if isinstance(value, dict): old_value = result.get(key) if isinstance(old_value, dict): @@ -164,15 +178,20 @@ class MergeAction(Action): @staticmethod def _Register(parser): + parser.add_argument('-o', + '--output', + required=True, + help='path to the output plist file') + parser.add_argument('-f', + '--format', + required=True, + choices=('xml1', 'binary1'), + help='format of the plist file to generate') parser.add_argument( - '-o', '--output', required=True, - help='path to the output plist file') - parser.add_argument( - '-f', '--format', required=True, choices=('xml1', 'binary1', 'json'), - help='format of the plist file to generate') - parser.add_argument( - 'path', nargs="+", - help='path to plist files to merge') + '-x', + '--xcode-version', + help='version of Xcode, ignored (can be used to force rebuild)') + parser.add_argument('path', nargs="+", help='path to plist files to merge') @staticmethod def _Execute(args): @@ -190,18 +209,28 @@ class SubstituteAction(Action): @staticmethod def _Register(parser): + parser.add_argument('-o', + '--output', + required=True, + help='path to the output plist file') + parser.add_argument('-t', + '--template', + required=True, + help='path to the template file') + parser.add_argument('-s', + '--substitution', + action='append', + default=[], + help='substitution rule in the format key=value') + parser.add_argument('-f', + '--format', + required=True, + choices=('xml1', 'binary1'), + help='format of the plist file to generate') parser.add_argument( - '-o', '--output', required=True, - help='path to the output plist file') - parser.add_argument( - '-t', '--template', required=True, - help='path to the template file') - parser.add_argument( - '-s', '--substitution', action='append', default=[], - help='substitution rule in the format key=value') - parser.add_argument( - '-f', '--format', required=True, choices=('xml1', 'binary1', 'json'), - help='format of the plist file to generate') + '-x', + '--xcode-version', + help='version of Xcode, ignored (can be used to force rebuild)') @staticmethod def _Execute(args): @@ -214,6 +243,10 @@ class SubstituteAction(Action): def Main(): + # Cache this codec so that plistlib can find it. See + # https://crbug.com/1005190#c2 for more details. + codecs.lookup('utf-8') + parser = argparse.ArgumentParser(description='manipulate plist files') subparsers = parser.add_subparsers() @@ -225,4 +258,8 @@ def Main(): if __name__ == '__main__': + # TODO(https://crbug.com/941669): Temporary workaround until all scripts use + # python3 by default. + if sys.version_info[0] < 3: + os.execvp('python3', ['python3'] + sys.argv) sys.exit(Main()) diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/rules.gni b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/rules.gni index 2fd17154c8..7a3b7bd14e 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/rules.gni +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/rules.gni @@ -109,10 +109,20 @@ template("create_signed_bundle") { "_", "-") + _ios_provisioning_profile_info = + exec_script(code_signing_script, + [ + "find-provisioning-profile", + "-b=" + _xcode_product_bundle_id, + ], + "json") + xcode_extra_attributes = { IPHONEOS_DEPLOYMENT_TARGET = ios_deployment_target + CODE_SIGN_IDENTITY = "iPhone Developer" + DEVELOPMENT_TEAM = _ios_provisioning_profile_info.team_identifier + PROVISIONING_PROFILE_SPECIFIER = _ios_provisioning_profile_info.name CODE_SIGN_STYLE = "Manual" - CODE_SIGN_IDENTITY = "" PRODUCT_BUNDLE_IDENTIFIER = _xcode_product_bundle_id if (defined(invoker.xcode_extra_attributes)) { @@ -548,6 +558,10 @@ template("ios_xcuitest_test_runner_bundle") { ] } + # Bundle identifier should respect rfc1034, so replace "_" with "-". + _bundle_identifier = "$ios_app_bundle_id_prefix.chrome." + + string_replace(_output_name, "_", "-") + _info_plist_target = _target_name + "_info_plist" _info_plist_bundle = _target_name + "_info_plist_bundle" info_plist(_info_plist_target) { @@ -563,6 +577,7 @@ template("ios_xcuitest_test_runner_bundle") { # "CFBundleName". "//third_party/mini_chromium/mini_chromium/build/ios/XCTRunnerAddition+Info.plist", ] + extra_substitutions = [ "BUNDLE_IDENTIFIER=$_bundle_identifier" ] } bundle_data(_info_plist_bundle) { @@ -604,6 +619,15 @@ template("ios_xcuitest_test_runner_bundle") { "$ios_sdk_platform_path/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework", ] + if (xcode_version_int >= 1300) { + extra_system_frameworks += [ + "$ios_sdk_platform_path/Developer/Library/PrivateFrameworks/XCTestCore.framework", + "$ios_sdk_platform_path/Developer/Library/PrivateFrameworks/XCUIAutomation.framework", + "$ios_sdk_platform_path/Developer/Library/PrivateFrameworks/XCUnit.framework", + "$ios_sdk_platform_path/Developer/usr/lib/libXCTestSwiftSupport.dylib", + ] + } + bundle_deps = [] if (defined(invoker.bundle_deps)) { bundle_deps += invoker.bundle_deps diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/sdk_info.py b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/sdk_info.py index 26ac8da1a2..9f662edce0 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/sdk_info.py +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/sdk_info.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -11,13 +9,34 @@ import doctest import itertools import os import plistlib +import re import subprocess import sys +if sys.version_info.major < 3: + basestring_compat = basestring +else: + basestring_compat = str + +# src directory +ROOT_SRC_DIR = os.path.dirname( + os.path.dirname(os.path.dirname(os.path.dirname( + os.path.realpath(__file__))))) + # This script prints information about the build system, the operating # system and the iOS or Mac SDK (depending on the platform "iphonesimulator", # "iphoneos" or "macosx" generally). + +def LoadPList(path): + """Loads Plist at |path| and returns it as a dictionary.""" + # Cloned from //build/apple/plist_util.py. + if sys.version_info.major == 2: + return plistlib.readPlist(path) + with open(path, 'rb') as f: + return plistlib.load(f) + + def SplitVersion(version): """Splits the Xcode version to 3 values. @@ -31,6 +50,7 @@ def SplitVersion(version): version = version.split('.') return itertools.islice(itertools.chain(version, itertools.repeat('0')), 0, 3) + def FormatVersion(version): """Converts Xcode version to a format required for DTXcode in Info.plist @@ -44,19 +64,21 @@ def FormatVersion(version): major, minor, patch = SplitVersion(version) return ('%2s%s%s' % (major, minor, patch)).replace(' ', '0') + def FillXcodeVersion(settings, developer_dir): """Fills the Xcode version and build number into |settings|.""" if developer_dir: - xcode_version_plist_path = os.path.join( - developer_dir, 'Contents/version.plist') - version_plist = plistlib.readPlist(xcode_version_plist_path) + xcode_version_plist_path = os.path.join(developer_dir, + 'Contents/version.plist') + version_plist = LoadPList(xcode_version_plist_path) settings['xcode_version'] = FormatVersion( version_plist['CFBundleShortVersionString']) settings['xcode_version_int'] = int(settings['xcode_version'], 10) settings['xcode_build'] = version_plist['ProductBuildVersion'] return - lines = subprocess.check_output(['xcodebuild', '-version']).splitlines() + lines = subprocess.check_output(['xcodebuild', + '-version']).decode('UTF-8').splitlines() settings['xcode_version'] = FormatVersion(lines[0].split()[-1]) settings['xcode_version_int'] = int(settings['xcode_version'], 10) settings['xcode_build'] = lines[-1].split()[-1] @@ -64,43 +86,79 @@ def FillXcodeVersion(settings, developer_dir): def FillMachineOSBuild(settings): """Fills OS build number into |settings|.""" - settings['machine_os_build'] = subprocess.check_output( - ['sw_vers', '-buildVersion']).strip() + machine_os_build = subprocess.check_output(['sw_vers', '-buildVersion' + ]).decode('UTF-8').strip() + settings['machine_os_build'] = machine_os_build def FillSDKPathAndVersion(settings, platform, xcode_version): """Fills the SDK path and version for |platform| into |settings|.""" - settings['sdk_path'] = subprocess.check_output([ - 'xcrun', '-sdk', platform, '--show-sdk-path']).strip() - settings['sdk_version'] = subprocess.check_output([ - 'xcrun', '-sdk', platform, '--show-sdk-version']).strip() - settings['sdk_platform_path'] = subprocess.check_output([ - 'xcrun', '-sdk', platform, '--show-sdk-platform-path']).strip() - # TODO: unconditionally use --show-sdk-build-version once Xcode 7.2 or - # higher is required to build Chrome for iOS or OS X. - if xcode_version >= '0720': - settings['sdk_build'] = subprocess.check_output([ - 'xcrun', '-sdk', platform, '--show-sdk-build-version']).strip() - else: - settings['sdk_build'] = settings['sdk_version'] + settings['sdk_path'] = subprocess.check_output( + ['xcrun', '-sdk', platform, '--show-sdk-path']).decode('UTF-8').strip() + settings['sdk_version'] = subprocess.check_output( + ['xcrun', '-sdk', platform, + '--show-sdk-version']).decode('UTF-8').strip() + settings['sdk_platform_path'] = subprocess.check_output( + ['xcrun', '-sdk', platform, + '--show-sdk-platform-path']).decode('UTF-8').strip() + settings['sdk_build'] = subprocess.check_output( + ['xcrun', '-sdk', platform, + '--show-sdk-build-version']).decode('UTF-8').strip() + settings['toolchains_path'] = os.path.join( + subprocess.check_output(['xcode-select', + '-print-path']).decode('UTF-8').strip(), + 'Toolchains/XcodeDefault.xctoolchain') + + +def CreateXcodeSymlinkAt(src, dst): + """Create symlink to Xcode directory at target location.""" + + if not os.path.isdir(dst): + os.makedirs(dst) + + dst = os.path.join(dst, os.path.basename(src)) + updated_value = '//' + os.path.relpath(dst, ROOT_SRC_DIR) + + # Update the symlink only if it is different from the current destination. + if os.path.islink(dst): + current_src = os.readlink(dst) + if current_src == src: + return updated_value + os.unlink(dst) + sys.stderr.write('existing symlink %s points %s; want %s. Removed.' % + (dst, current_src, src)) + os.symlink(src, dst) + return updated_value if __name__ == '__main__': doctest.testmod() parser = argparse.ArgumentParser() - parser.add_argument("--developer_dir", required=False) + parser.add_argument("--developer_dir", dest="developer_dir", required=False) parser.add_argument("--get_sdk_info", - action="store_true", dest="get_sdk_info", default=False, - help="Returns SDK info in addition to xcode/machine info.") + action="store_true", + dest="get_sdk_info", + default=False, + help="Returns SDK info in addition to xcode info.") + parser.add_argument("--get_machine_info", + action="store_true", + dest="get_machine_info", + default=False, + help="Returns machine info in addition to xcode info.") + parser.add_argument("--create_symlink_at", + action="store", + dest="create_symlink_at", + help="Create symlink of SDK at given location and " + "returns the symlinked paths as SDK info instead " + "of the original location.") args, unknownargs = parser.parse_known_args() if args.developer_dir: os.environ['DEVELOPER_DIR'] = args.developer_dir if len(unknownargs) != 1: - sys.stderr.write( - 'usage: %s [iphoneos|iphonesimulator|macosx]\n' % - os.path.basename(sys.argv[0])) + sys.stderr.write('usage: %s [iphoneos|iphonesimulator|macosx]\n' % + os.path.basename(sys.argv[0])) sys.exit(1) settings = {} @@ -111,6 +169,8 @@ if __name__ == '__main__': for key in sorted(settings): value = settings[key] - if isinstance(value, str): + if args.create_symlink_at and '_path' in key: + value = CreateXcodeSymlinkAt(value, args.create_symlink_at) + if isinstance(value, basestring_compat): value = '"%s"' % value print('%s=%s' % (key, value)) diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/strip_arm64e.py b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/strip_arm64e.py index 667cd08a57..005d1f8531 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/strip_arm64e.py +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/ios/strip_arm64e.py @@ -1,9 +1,6 @@ -#!/usr/bin/env python - # Copyright 2020 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. - """Strip arm64e architecture from a binary if present.""" import argparse @@ -21,9 +18,9 @@ def check_output(command): if process.returncode: sys.stderr.write('error: command failed with retcode %d: %s\n\n' % (process.returncode, ' '.join(map(repr, command)))) - sys.stderr.write(errs) + sys.stderr.write(errs.decode('UTF-8', errors='ignore')) sys.exit(process.returncode) - return outs + return outs.decode('UTF-8') def check_call(command): diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/win_helper.py b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/win_helper.py index a5e1fdd4c4..223716da84 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/win_helper.py +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/win_helper.py @@ -1,10 +1,8 @@ -#!/usr/bin/env python - # Copyright 2017 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import _winreg +import winreg import os import re import subprocess @@ -12,7 +10,7 @@ import sys def _RegistryGetValue(key, value): - """Use the _winreg module to obtain the value of a registry key. + """Use the winreg module to obtain the value of a registry key. Args: key: The registry key. @@ -23,8 +21,8 @@ def _RegistryGetValue(key, value): try: root, subkey = key.split('\\', 1) assert root == 'HKLM' # Only need HKLM for now. - with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: - return _winreg.QueryValueEx(hkey, value)[0] + with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, subkey) as hkey: + return winreg.QueryValueEx(hkey, value)[0] except WindowsError: return None @@ -44,6 +42,7 @@ def _ExtractImportantEnvironment(output_of_set): ) env = {} for line in output_of_set.splitlines(): + line = line.decode("utf-8") for envvar in envvars_to_save: if re.match(envvar + '=', line.lower()): var, setting = line.split('=', 1) @@ -62,7 +61,7 @@ def _FormatAsEnvironmentBlock(envvar_dict): CreateProcess() documentation for more details.""" block = '' nul = '\0' - for key, value in envvar_dict.iteritems(): + for key, value in envvar_dict.items(): block += key + '=' + value + nul block += nul return block @@ -99,7 +98,7 @@ def _GenerateEnvironmentFiles(install_dir, out_dir, script_path): env_block = _FormatAsEnvironmentBlock(env) basename = 'environment.' + arch with open(os.path.join(out_dir, basename), 'wb') as f: - f.write(env_block) + f.write(env_block.encode()) result.append(basename) return result @@ -139,10 +138,11 @@ class WinTool(object): link = subprocess.Popen(args, env=env, shell=True, stdout=subprocess.PIPE) out, _ = link.communicate() for line in out.splitlines(): + line = line.decode("utf-8") if (not line.startswith(' Creating library ') and not line.startswith('Generating code') and not line.startswith('Finished generating code')): - print line + print(line) return link.returncode def ExecAsmWrapper(self, arch, *args): @@ -152,24 +152,32 @@ class WinTool(object): stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = popen.communicate() for line in out.splitlines(): + line = line.decode("utf-8") if (not line.startswith('Copyright (C) Microsoft Corporation') and not line.startswith('Microsoft (R) Macro Assembler') and not line.startswith(' Assembling: ') and line): - print line + print(line) return popen.returncode def ExecGetVisualStudioData(self, outdir, toolchain_path): - setenv_path = os.path.join('win_sdk', 'bin', 'SetEnv.cmd') + setenv_paths = [ + # cipd packaged SDKs from 10.0.19041.0 onwards. + os.path.join('Windows Kits', '10', 'bin', 'SetEnv.cmd'), + # cipd packaged SDKs prior to 10.0.19041.0. + os.path.join('win_sdk', 'bin', 'SetEnv.cmd'), + ] def explicit(): - if os.path.exists(os.path.join(toolchain_path, setenv_path)): - return toolchain_path, setenv_path + for setenv_path in setenv_paths: + if os.path.exists(os.path.join(toolchain_path, setenv_path)): + return toolchain_path, setenv_path def env(): from_env = os.environ.get('VSINSTALLDIR') - if from_env and os.path.exists(os.path.join(from_env, setenv_path)): - return from_env, setenv_path + for setenv_path in setenv_paths: + if from_env and os.path.exists(os.path.join(from_env, setenv_path)): + return from_env, setenv_path def autodetect(): # Try vswhere, which will find VS2017.2+. Note that earlier VS2017s will @@ -180,7 +188,7 @@ class WinTool(object): installation_path = subprocess.check_output( [vswhere_path, '-latest', '-property', 'installationPath']).strip() if installation_path: - return (installation_path, + return (installation_path.decode("utf-8"), os.path.join('VC', 'Auxiliary', 'Build', 'vcvarsall.bat')) # Otherwise, try VS2015. @@ -203,11 +211,13 @@ class WinTool(object): x86_file, x64_file, arm64_file = _GenerateEnvironmentFiles( install_dir, outdir, script_path) + # gn is unhappy with trailing backslashes. + install_dir = install_dir.rstrip('\\') result = '''install_dir = "%s" x86_environment_file = "%s" x64_environment_file = "%s" arm64_environment_file = "%s"''' % (install_dir, x86_file, x64_file, arm64_file) - print result + print(result) return 0 def ExecStamp(self, path): diff --git a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/write_buildflag_header.py b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/write_buildflag_header.py index f45af6c0d8..719022ddde 100644 --- a/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/write_buildflag_header.py +++ b/thirdparty/sentry-native/external/crashpad/third_party/mini_chromium/mini_chromium/build/write_buildflag_header.py @@ -1,4 +1,5 @@ #!/usr/bin/env python + # Copyright 2015 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -20,79 +21,84 @@ import sys class Options: - def __init__(self, output, rulename, header_guard, flags): - self.output = output - self.rulename = rulename - self.header_guard = header_guard - self.flags = flags + + def __init__(self, output, rulename, header_guard, flags): + self.output = output + self.rulename = rulename + self.header_guard = header_guard + self.flags = flags def GetOptions(): - parser = optparse.OptionParser() - parser.add_option('--output', help="Output header name inside --gen-dir.") - parser.add_option('--rulename', - help="Helpful name of build rule for including in the " + - "comment at the top of the file.") - parser.add_option('--gen-dir', - help="Path to root of generated file directory tree.") - parser.add_option('--definitions', - help="Name of the response file containing the flags.") - cmdline_options, cmdline_flags = parser.parse_args() + parser = optparse.OptionParser() + parser.add_option('--output', help="Output header name inside --gen-dir.") + parser.add_option('--rulename', + help="Helpful name of build rule for including in the " + + "comment at the top of the file.") + parser.add_option('--gen-dir', + help="Path to root of generated file directory tree.") + parser.add_option('--definitions', + help="Name of the response file containing the flags.") + cmdline_options, cmdline_flags = parser.parse_args() - # Compute header guard by replacing some chars with _ and upper-casing. - header_guard = cmdline_options.output.upper() - header_guard = \ - header_guard.replace('/', '_').replace('\\', '_').replace('.', '_') - header_guard += '_' + # Compute header guard by replacing some chars with _ and upper-casing. + header_guard = cmdline_options.output.upper() + header_guard = \ + header_guard.replace('/', '_').replace('\\', '_').replace('.', '_') + header_guard += '_' - # The actual output file is inside the gen dir. - output = os.path.join(cmdline_options.gen_dir, cmdline_options.output) + # The actual output file is inside the gen dir. + output = os.path.join(cmdline_options.gen_dir, cmdline_options.output) - # Definition file in GYP is newline separated, in GN they are shell formatted. - # shlex can parse both of these. - with open(cmdline_options.definitions, 'r') as def_file: - defs = shlex.split(def_file.read()) - flags_index = defs.index('--flags') + # Definition file in GYP is newline separated, in GN they are shell formatted. + # shlex can parse both of these. + with open(cmdline_options.definitions, 'r') as def_file: + defs = shlex.split(def_file.read()) + flags_index = defs.index('--flags') - # Everything after --flags are flags. true/false are remapped to 1/0, - # everything else is passed through. - flags = [] - for flag in defs[flags_index + 1 :]: - equals_index = flag.index('=') - key = flag[:equals_index] - value = flag[equals_index + 1:] + # Everything after --flags are flags. true/false are remapped to 1/0, + # everything else is passed through. + flags = [] + for flag in defs[flags_index + 1:]: + equals_index = flag.index('=') + key = flag[:equals_index] + value = flag[equals_index + 1:] - # Canonicalize and validate the value. - if value == 'true': - value = '1' - elif value == 'false': - value = '0' - flags.append((key, str(value))) + # Canonicalize and validate the value. + if value == 'true': + value = '1' + elif value == 'false': + value = '0' + flags.append((key, str(value))) - return Options(output=output, - rulename=cmdline_options.rulename, - header_guard=header_guard, - flags=flags) + return Options(output=output, + rulename=cmdline_options.rulename, + header_guard=header_guard, + flags=flags) def WriteHeader(options): - with open(options.output, 'w') as output_file: - output_file.write("// Generated by build/write_buildflag_header.py\n") - if options.rulename: - output_file.write('// From "' + options.rulename + '"\n') + with open(options.output, 'w') as output_file: + output_file.write("// Generated by build/write_buildflag_header.py\n") + if options.rulename: + output_file.write('// From "' + options.rulename + '"\n') - output_file.write('\n#ifndef %s\n' % options.header_guard) - output_file.write('#define %s\n\n' % options.header_guard) - output_file.write('#include "build/buildflag.h"\n\n') + output_file.write('\n#ifndef %s\n' % options.header_guard) + output_file.write('#define %s\n\n' % options.header_guard) + output_file.write('#include "build/buildflag.h"\n\n') - for pair in options.flags: - output_file.write('#define BUILDFLAG_INTERNAL_%s() (%s)\n' % pair) + for pair in options.flags: + output_file.write( + '#define MINI_CHROMIUM_INTERNAL_BUILDFLAG_VALUE_%s() (%s)\n' % + pair) + + output_file.write('\n#endif // %s\n' % options.header_guard) - output_file.write('\n#endif // %s\n' % options.header_guard) def main(): - options = GetOptions() - WriteHeader(options) + options = GetOptions() + WriteHeader(options) + if __name__ == "__main__": - sys.exit(main()) + sys.exit(main()) diff --git a/thirdparty/sentry-native/external/crashpad/tools/base94_encoder.cc b/thirdparty/sentry-native/external/crashpad/tools/base94_encoder.cc index 1b184e9fb8..b0f7e0e328 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/base94_encoder.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/base94_encoder.cc @@ -24,6 +24,7 @@ namespace crashpad { namespace { void Usage(const base::FilePath& me) { + // clang-format off fprintf(stderr, "Usage: %" PRFilePath " [options] \n" "Encode/Decode the given file\n" @@ -34,6 +35,7 @@ void Usage(const base::FilePath& me) { " --help display this help and exit\n" " --version output version information and exit\n", me.value().c_str()); + // clang-format on ToolSupport::UsageTail(me); } @@ -117,12 +119,12 @@ int Base94EncoderMain(int argc, char* argv[]) { } // namespace } // namespace crashpad -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int main(int argc, char* argv[]) { return crashpad::Base94EncoderMain(argc, argv); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) int wmain(int argc, wchar_t* argv[]) { return crashpad::ToolSupport::Wmain(argc, argv, crashpad::Base94EncoderMain); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) diff --git a/thirdparty/sentry-native/external/crashpad/tools/crashpad_database_util.cc b/thirdparty/sentry-native/external/crashpad/tools/crashpad_database_util.cc index e9927bd40c..d55937772e 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/crashpad_database_util.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/crashpad_database_util.cc @@ -21,13 +21,13 @@ #include #include +#include #include #include #include #include #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/files/file_path.h" #include "base/numerics/safe_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -44,6 +44,7 @@ namespace crashpad { namespace { void Usage(const base::FilePath& me) { + // clang-format off fprintf(stderr, "Usage: %" PRFilePath " [OPTION]... PID\n" "Operate on Crashpad crash report databases.\n" @@ -66,6 +67,7 @@ void Usage(const base::FilePath& me) { " --help display this help and exit\n" " --version output version information and exit\n", me.value().c_str()); + // clang-format on ToolSupport::UsageTail(me); } @@ -109,14 +111,14 @@ bool StringToBool(const char* string, bool* boolean) { "set", }; - for (size_t index = 0; index < base::size(kFalseWords); ++index) { + for (size_t index = 0; index < std::size(kFalseWords); ++index) { if (strcasecmp(string, kFalseWords[index]) == 0) { *boolean = false; return true; } } - for (size_t index = 0; index < base::size(kTrueWords); ++index) { + for (size_t index = 0; index < std::size(kTrueWords); ++index) { if (strcasecmp(string, kTrueWords[index]) == 0) { *boolean = true; return true; @@ -159,7 +161,7 @@ bool StringToTime(const char* string, time_t* out_time, bool utc) { "%+", }; - for (size_t index = 0; index < base::size(kFormats); ++index) { + for (size_t index = 0; index < std::size(kFormats); ++index) { tm time_tm; const char* strptime_result = strptime(string, kFormats[index], &time_tm); if (strptime_result == end) { @@ -214,7 +216,7 @@ std::string TimeToString(time_t out_time, bool utc) { char string[64]; CHECK_NE( - strftime(string, base::size(string), "%Y-%m-%d %H:%M:%S %Z", &time_tm), + strftime(string, std::size(string), "%Y-%m-%d %H:%M:%S %Z", &time_tm), 0u); return std::string(string); @@ -619,12 +621,12 @@ int DatabaseUtilMain(int argc, char* argv[]) { } // namespace } // namespace crashpad -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int main(int argc, char* argv[]) { return crashpad::DatabaseUtilMain(argc, argv); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) int wmain(int argc, wchar_t* argv[]) { return crashpad::ToolSupport::Wmain(argc, argv, crashpad::DatabaseUtilMain); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) diff --git a/thirdparty/sentry-native/external/crashpad/tools/crashpad_http_upload.cc b/thirdparty/sentry-native/external/crashpad/tools/crashpad_http_upload.cc index 624aaa715e..1470b410eb 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/crashpad_http_upload.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/crashpad_http_upload.cc @@ -22,6 +22,7 @@ #include #include "base/files/file_path.h" +#include "build/build_config.h" #include "tools/tool_support.h" #include "util/file/file_reader.h" #include "util/file/file_writer.h" @@ -34,6 +35,7 @@ namespace crashpad { namespace { void Usage(const base::FilePath& me) { + // clang-format off fprintf(stderr, "Usage: %" PRFilePath " [OPTION]...\n" "Send an HTTP POST request.\n" @@ -45,6 +47,7 @@ void Usage(const base::FilePath& me) { " --help display this help and exit\n" " --version output version information and exit\n", me.value().c_str()); + // clang-format on ToolSupport::UsageTail(me); } @@ -205,12 +208,12 @@ int HTTPUploadMain(int argc, char* argv[]) { } // namespace } // namespace crashpad -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int main(int argc, char* argv[]) { return crashpad::HTTPUploadMain(argc, argv); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) int wmain(int argc, wchar_t* argv[]) { return crashpad::ToolSupport::Wmain(argc, argv, crashpad::HTTPUploadMain); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) diff --git a/thirdparty/sentry-native/external/crashpad/tools/generate_dump.cc b/thirdparty/sentry-native/external/crashpad/tools/generate_dump.cc index ab027b8795..ba561a583a 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/generate_dump.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/generate_dump.cc @@ -29,33 +29,34 @@ #include "util/process/process_id.h" #include "util/stdlib/string_number_conversion.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include #include "util/posix/drop_privileges.h" #endif -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include #include "base/mac/scoped_mach_port.h" #include "snapshot/mac/process_snapshot_mac.h" #include "util/mach/scoped_task_suspend.h" #include "util/mach/task_for_pid.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include "base/strings/utf_string_conversions.h" #include "snapshot/win/process_snapshot_win.h" #include "util/win/scoped_process_suspend.h" #include "util/win/xp_compat.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "snapshot/linux/process_snapshot_linux.h" #include "util/linux/direct_ptrace_connection.h" -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) namespace crashpad { namespace { void Usage(const base::FilePath& me) { + // clang-format off fprintf(stderr, "Usage: %" PRFilePath " [OPTION]... PID\n" "Generate a minidump file containing a snapshot of a running process.\n" @@ -65,6 +66,7 @@ void Usage(const base::FilePath& me) { " --help display this help and exit\n" " --version output version information and exit\n", me.value().c_str()); + // clang-format on ToolSupport::UsageTail(me); } @@ -137,7 +139,7 @@ int GenerateDumpMain(int argc, char* argv[]) { return EXIT_FAILURE; } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) task_t task = TaskForPID(options.pid); if (task == TASK_NULL) { return EXIT_FAILURE; @@ -155,14 +157,14 @@ int GenerateDumpMain(int argc, char* argv[]) { } LOG(WARNING) << "operating on myself"; } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) ScopedKernelHANDLE process( OpenProcess(kXPProcessAllAccess, false, options.pid)); if (!process.is_valid()) { PLOG(ERROR) << "could not open process " << options.pid; return EXIT_FAILURE; } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) if (options.dump_path.empty()) { options.dump_path = base::StringPrintf("minidump.%" PRI_PROCESS_ID, @@ -170,24 +172,24 @@ int GenerateDumpMain(int argc, char* argv[]) { } { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) std::unique_ptr suspend; if (options.suspend) { suspend.reset(new ScopedTaskSuspend(task)); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) std::unique_ptr suspend; if (options.suspend) { suspend.reset(new ScopedProcessSuspend(process.get())); } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) ProcessSnapshotMac process_snapshot; if (!process_snapshot.Initialize(task)) { return EXIT_FAILURE; } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) ProcessSnapshotWin process_snapshot; if (!process_snapshot.Initialize(process.get(), options.suspend @@ -197,7 +199,7 @@ int GenerateDumpMain(int argc, char* argv[]) { 0)) { return EXIT_FAILURE; } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // TODO(jperaza): https://crashpad.chromium.org/bug/30. DirectPtraceConnection task; if (!task.Initialize(options.pid)) { @@ -207,7 +209,7 @@ int GenerateDumpMain(int argc, char* argv[]) { if (!process_snapshot.Initialize(&task)) { return EXIT_FAILURE; } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) FileWriter file_writer; base::FilePath dump_path( @@ -236,12 +238,12 @@ int GenerateDumpMain(int argc, char* argv[]) { } // namespace } // namespace crashpad -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int main(int argc, char* argv[]) { return crashpad::GenerateDumpMain(argc, argv); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) int wmain(int argc, wchar_t* argv[]) { return crashpad::ToolSupport::Wmain(argc, argv, crashpad::GenerateDumpMain); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) diff --git a/thirdparty/sentry-native/external/crashpad/tools/mac/catch_exception_tool.cc b/thirdparty/sentry-native/external/crashpad/tools/mac/catch_exception_tool.cc index 06fda23d4e..568672d781 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/mac/catch_exception_tool.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/mac/catch_exception_tool.cc @@ -181,6 +181,7 @@ class ExceptionServer final : public UniversalMachExcServer::Interface { }; void Usage(const std::string& me) { + // clang-format off fprintf(stderr, "Usage: %s -m SERVICE [OPTION]...\n" "Catch Mach exceptions and display information about them.\n" @@ -192,6 +193,7 @@ void Usage(const std::string& me) { " --help display this help and exit\n" " --version output version information and exit\n", me.c_str()); + // clang-format on ToolSupport::UsageTail(me); } diff --git a/thirdparty/sentry-native/external/crashpad/tools/mac/exception_port_tool.cc b/thirdparty/sentry-native/external/crashpad/tools/mac/exception_port_tool.cc index 2fdc580018..60d841445d 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/mac/exception_port_tool.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/mac/exception_port_tool.cc @@ -311,6 +311,7 @@ bool SetExceptionPort(const ExceptionHandlerDescription* description, } void Usage(const std::string& me) { + // clang-format off fprintf(stderr, "Usage: %s [OPTION]... [COMMAND [ARG]...]\n" "View and change Mach exception ports, and run COMMAND if supplied.\n" @@ -343,6 +344,7 @@ void Usage(const std::string& me) { "The default DESCRIPTION is\n" " target=task,mask=CRASH,behavior=DEFAULT|MACH,flavor=NONE,handler=NULL\n", me.c_str()); + // clang-format on ToolSupport::UsageTail(me); } diff --git a/thirdparty/sentry-native/external/crashpad/tools/mac/on_demand_service_tool.mm b/thirdparty/sentry-native/external/crashpad/tools/mac/on_demand_service_tool.mm index 7b3e104169..ffb7920c8f 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/mac/on_demand_service_tool.mm +++ b/thirdparty/sentry-native/external/crashpad/tools/mac/on_demand_service_tool.mm @@ -34,6 +34,7 @@ namespace crashpad { namespace { void Usage(const std::string& me) { + // clang-format off fprintf(stderr, "Usage: %s -L -l LABEL [OPTION]... COMMAND [ARG]...\n" " %s -U -l LABEL\n" @@ -48,6 +49,7 @@ void Usage(const std::string& me) { " --version output version information and exit\n", me.c_str(), me.c_str()); + // clang-format on ToolSupport::UsageTail(me); } diff --git a/thirdparty/sentry-native/external/crashpad/tools/run_with_crashpad.cc b/thirdparty/sentry-native/external/crashpad/tools/run_with_crashpad.cc index 5ef0edb685..487f378fa5 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/run_with_crashpad.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/run_with_crashpad.cc @@ -31,7 +31,7 @@ #include "util/stdlib/map_insert.h" #include "util/string/split_string.h" -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) #include #include #include @@ -43,16 +43,23 @@ namespace crashpad { namespace { void Usage(const std::string& me) { + // clang-format off fprintf(stderr, "Usage: %s [OPTION]... COMMAND [ARG]...\n" "Start a Crashpad handler and have it handle crashes from COMMAND.\n" "\n" -#if defined(OS_FUCHSIA) + // clang-format on +#if BUILDFLAG(IS_FUCHSIA) + // clang-format off "COMMAND is run via fdio_spawn, so must be a qualified path to the subprocess to\n" "be executed.\n" + // clang-format on #else + // clang-format off "COMMAND is run via execvp() so the PATH will be searched.\n" + // clang-format on #endif + // clang-format off "\n" " -h, --handler=HANDLER invoke HANDLER instead of crashpad_handler\n" " --annotation=KEY=VALUE passed to the handler as an --annotation argument\n" @@ -62,6 +69,7 @@ void Usage(const std::string& me) { " --help display this help and exit\n" " --version output version information and exit\n", me.c_str()); + // clang-format on ToolSupport::UsageTail(me); } @@ -189,7 +197,7 @@ int RunWithCrashpadMain(int argc, char* argv[]) { return kExitFailure; } -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) // Fuchsia doesn't implement execvp(), launch with fdio_spawn here. zx_handle_t child = ZX_HANDLE_INVALID; zx_status_t status = fdio_spawn( diff --git a/thirdparty/sentry-native/external/crashpad/tools/tool_support.cc b/thirdparty/sentry-native/external/crashpad/tools/tool_support.cc index b453f6e87b..aa6a2d9e4e 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/tool_support.cc +++ b/thirdparty/sentry-native/external/crashpad/tools/tool_support.cc @@ -21,6 +21,7 @@ #include "base/strings/string_piece.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "package.h" namespace crashpad { @@ -55,7 +56,7 @@ void ToolSupport::UsageHint(const base::FilePath& me, const char* hint) { me.value().c_str()); } -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) // static void ToolSupport::Version(const std::string& me) { Version(base::FilePath(me)); @@ -70,9 +71,9 @@ void ToolSupport::UsageTail(const std::string& me) { void ToolSupport::UsageHint(const std::string& me, const char* hint) { UsageHint(base::FilePath(me), hint); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // static int ToolSupport::Wmain(int argc, wchar_t* argv[], int (*entry)(int, char* [])) { @@ -87,26 +88,26 @@ int ToolSupport::Wmain(int argc, wchar_t* argv[], int (*entry)(int, char* [])) { return entry(argc, argv_as_utf8.get()); } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) // static base::FilePath::StringType ToolSupport::CommandLineArgumentToFilePathStringType( const base::StringPiece& path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) return std::string(path.data(), path.size()); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return base::UTF8ToWide(path); -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } // static std::string ToolSupport::FilePathToCommandLineArgument( const base::FilePath& file_path) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) return file_path.value(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return base::WideToUTF8(file_path.value()); -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/tools/tool_support.h b/thirdparty/sentry-native/external/crashpad/tools/tool_support.h index fd4955e432..87db24dbb5 100644 --- a/thirdparty/sentry-native/external/crashpad/tools/tool_support.h +++ b/thirdparty/sentry-native/external/crashpad/tools/tool_support.h @@ -48,7 +48,7 @@ class ToolSupport { //! Optional, may be `nullptr`, in which case no hint will be presented. static void UsageHint(const base::FilePath& me, const char* hint); -#if defined(OS_POSIX) || DOXYGEN +#if BUILDFLAG(IS_POSIX) || DOXYGEN //! \copydoc Version static void Version(const std::string& me); @@ -57,15 +57,15 @@ class ToolSupport { //! \copydoc UsageHint static void UsageHint(const std::string& me, const char* hint); -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) -#if defined(OS_WIN) || DOXYGEN +#if BUILDFLAG(IS_WIN) || DOXYGEN //! \brief Converts \a argv `wchar_t` UTF-16 to UTF-8, and passes onwards to a //! UTF-8 entry point. //! //! \return The return value of \a entry. static int Wmain(int argc, wchar_t* argv[], int (*entry)(int, char*[])); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) //! \brief Converts a command line argument to the string type suitable for //! base::FilePath. diff --git a/thirdparty/sentry-native/external/crashpad/util/BUILD.gn b/thirdparty/sentry-native/external/crashpad/util/BUILD.gn index 7b70440887..c372ff49b3 100644 --- a/thirdparty/sentry-native/external/crashpad/util/BUILD.gn +++ b/thirdparty/sentry-native/external/crashpad/util/BUILD.gn @@ -385,6 +385,8 @@ crashpad_static_library("util") { "ios/ios_system_data_collector.mm", "ios/raw_logging.cc", "ios/raw_logging.h", + "ios/scoped_background_task.h", + "ios/scoped_background_task.mm", "ios/scoped_vm_read.cc", "ios/scoped_vm_read.h", ] @@ -466,6 +468,7 @@ crashpad_static_library("util") { "win/context_wrappers.h", "win/critical_section_with_debug_info.cc", "win/critical_section_with_debug_info.h", + "win/exception_codes.h", "win/exception_handler_server.cc", "win/exception_handler_server.h", "win/get_function.cc", @@ -578,10 +581,14 @@ crashpad_static_library("util") { ] if (crashpad_is_mac || crashpad_is_ios) { - include_dirs += [ "$root_build_dir/gen" ] + include_dirs += [ "$root_gen_dir" ] deps += [ ":mig_output" ] } + if (crashpad_is_ios) { + deps += [ "../build:ios_enable_arc" ] + } + if (crashpad_is_mac && !crashpad_is_in_fuchsia) { libs = [ "bsm" ] frameworks = [ @@ -655,7 +662,7 @@ crashpad_static_library("net") { if (crashpad_http_transport_impl == "socket") { sources += [ "net/http_transport_socket.cc" ] if (crashpad_use_boringssl_for_http_transport_socket) { - defines += [ "CRASHPAD_USE_BORINGSSL" ] + defines = [ "CRASHPAD_USE_BORINGSSL" ] if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) { deps += [ "//third_party/boringssl" ] diff --git a/thirdparty/sentry-native/external/crashpad/util/CMakeLists.txt b/thirdparty/sentry-native/external/crashpad/util/CMakeLists.txt index 2b42bd9f51..e37bfb155e 100644 --- a/thirdparty/sentry-native/external/crashpad/util/CMakeLists.txt +++ b/thirdparty/sentry-native/external/crashpad/util/CMakeLists.txt @@ -221,9 +221,19 @@ if(APPLE) ios/ios_system_data_collector.mm ios/raw_logging.cc ios/raw_logging.h + ios/scoped_background_task.h + ios/scoped_background_task.mm ios/scoped_vm_read.cc ios/scoped_vm_read.h - ) + ) + # This specific file requires ARC support, while other parts do not + # build when ARC is enabled. + set_source_files_properties( + ios/scoped_background_task.mm + PROPERTIES + COMPILE_FLAGS + "-fobjc-arc" + ) endif() endif() @@ -303,6 +313,7 @@ if(WIN32) win/context_wrappers.h win/critical_section_with_debug_info.cc win/critical_section_with_debug_info.h + win/exception_codes.h win/exception_handler_server.cc win/exception_handler_server.h win/get_function.cc @@ -376,7 +387,7 @@ if(APPLE) list(APPEND input_files "${full_path}") endforeach() - find_package(PythonInterp 2.7 REQUIRED) + find_package(Python COMPONENTS Interpreter REQUIRED) set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/util/mach") file(MAKE_DIRECTORY "${output_dir}") @@ -428,7 +439,7 @@ if(APPLE) OUTPUT ${output_files} COMMAND - "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mach/mig.py" ${archs} ${sdk} ${includes} "${input}" ${output_files} + "${Python_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mach/mig.py" ${archs} ${sdk} ${includes} "${input}" ${output_files} DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/mach/mig.py" "${input}" ) diff --git a/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader.cc b/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader.cc index f899dbf340..015a09dc50 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader.cc @@ -17,10 +17,10 @@ #include #include +#include #include #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/numerics/safe_conversions.h" namespace crashpad { @@ -76,7 +76,7 @@ DelimitedFileReader::Result DelimitedFileReader::GetDelim(char delimiter, return Result::kEndOfFile; } - DCHECK_LE(static_cast(read_result), base::size(buf_)); + DCHECK_LE(static_cast(read_result), std::size(buf_)); DCHECK( base::IsValueInRangeForNumericType(read_result)); buf_len_ = static_cast(read_result); diff --git a/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader_test.cc b/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader_test.cc index 05e610119d..5cc1f0fc7f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/delimited_file_reader_test.cc @@ -14,9 +14,9 @@ #include "util/file/delimited_file_reader.h" +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -260,7 +260,7 @@ TEST(DelimitedFileReader, ReallyLongMultiLineFile) { TEST(DelimitedFileReader, EmbeddedNUL) { static constexpr char kString[] = "embedded\0NUL\n"; StringFile string_file; - string_file.SetString(std::string(kString, base::size(kString) - 1)); + string_file.SetString(std::string(kString, std::size(kString) - 1)); DelimitedFileReader delimited_file_reader(&string_file); std::string line; @@ -278,7 +278,7 @@ TEST(DelimitedFileReader, EmbeddedNUL) { TEST(DelimitedFileReader, NULDelimiter) { static constexpr char kString[] = "aa\0b\0ccc\0"; StringFile string_file; - string_file.SetString(std::string(kString, base::size(kString) - 1)); + string_file.SetString(std::string(kString, std::size(kString) - 1)); DelimitedFileReader delimited_file_reader(&string_file); std::string field; @@ -302,7 +302,7 @@ TEST(DelimitedFileReader, NULDelimiter) { TEST(DelimitedFileReader, EdgeCases) { static constexpr size_t kSizes[] = {4094, 4095, 4096, 4097, 8190, 8191, 8192, 8193}; - for (size_t index = 0; index < base::size(kSizes); ++index) { + for (size_t index = 0; index < std::size(kSizes); ++index) { size_t size = kSizes[index]; SCOPED_TRACE( base::StringPrintf("index %" PRIuS ", size %" PRIuS, index, size)); diff --git a/thirdparty/sentry-native/external/crashpad/util/file/directory_reader.h b/thirdparty/sentry-native/external/crashpad/util/file/directory_reader.h index 096d120d63..ccde8b7173 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/directory_reader.h +++ b/thirdparty/sentry-native/external/crashpad/util/file/directory_reader.h @@ -18,13 +18,13 @@ #include "base/files/file_path.h" #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include "util/posix/scoped_dir.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include "util/win/scoped_handle.h" -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) namespace crashpad { @@ -67,20 +67,20 @@ class DirectoryReader { //! logged. Result NextFile(base::FilePath* filename); -#if defined(OS_POSIX) || DOXYGEN +#if BUILDFLAG(IS_POSIX) || DOXYGEN //! \brief Returns the file descriptor associated with this reader, logging a //! message and returning -1 on error. int DirectoryFD(); #endif private: -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) ScopedDIR dir_; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) WIN32_FIND_DATA find_data_; ScopedSearchHANDLE handle_; bool first_entry_; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) }; } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/file/directory_reader_test.cc b/thirdparty/sentry-native/external/crashpad/util/file/directory_reader_test.cc index 5d09c6fb3d..e1dcee2fa6 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/directory_reader_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/directory_reader_test.cc @@ -19,6 +19,7 @@ #include "base/files/file_path.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "gtest/gtest.h" #include "test/filesystem.h" #include "test/scoped_temp_dir.h" @@ -42,7 +43,7 @@ TEST(DirectoryReader, BadPaths) { reader.Open(temp_dir.path().Append(FILE_PATH_LITERAL("doesntexist")))); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(DirectoryReader, BadPaths_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -63,7 +64,7 @@ TEST(DirectoryReader, BadPaths_SymbolicLinks) { EXPECT_FALSE(reader.Open(link)); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(DirectoryReader, EmptyDirectory) { ScopedTempDir temp_dir; @@ -103,7 +104,7 @@ void TestFilesAndDirectories(bool symbolic_links) { ASSERT_TRUE( CreateFile(temp_dir.path().Append(directory).Append(nested_file))); -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) if (symbolic_links) { base::FilePath link(FILE_PATH_LITERAL("link")); @@ -118,7 +119,7 @@ void TestFilesAndDirectories(bool symbolic_links) { EXPECT_TRUE(expected_files.insert(dangling).second); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) std::set files; DirectoryReader reader; @@ -138,7 +139,7 @@ TEST(DirectoryReader, FilesAndDirectories) { TestFilesAndDirectories(false); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(DirectoryReader, FilesAndDirectories_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -148,7 +149,7 @@ TEST(DirectoryReader, FilesAndDirectories_SymbolicLinks) { TestFilesAndDirectories(true); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) } // namespace } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/util/file/file_io.h b/thirdparty/sentry-native/external/crashpad/util/file/file_io.h index 526debddae..6a6a58653a 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/file_io.h +++ b/thirdparty/sentry-native/external/crashpad/util/file/file_io.h @@ -21,9 +21,9 @@ #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include "base/files/scoped_file.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include "util/win/scoped_handle.h" #endif @@ -34,7 +34,7 @@ class FilePath; namespace crashpad { -#if defined(OS_POSIX) || DOXYGEN +#if BUILDFLAG(IS_POSIX) || DOXYGEN //! \brief Platform-specific alias for a low-level file handle. using FileHandle = int; @@ -51,7 +51,7 @@ using FileOperationResult = ssize_t; //! \brief A value that can never be a valid FileHandle. const FileHandle kInvalidFileHandle = -1; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) using FileHandle = HANDLE; using FileOffset = LONGLONG; @@ -132,7 +132,7 @@ enum class StdioStream { namespace internal { -#if defined(OS_POSIX) || DOXYGEN +#if BUILDFLAG(IS_POSIX) || DOXYGEN //! \brief The name of the native read function used by ReadFile(). //! @@ -148,7 +148,7 @@ constexpr char kNativeReadFunctionName[] = "read"; //! \sa kNativeReadFunctionName constexpr char kNativeWriteFunctionName[] = "write"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) constexpr char kNativeReadFunctionName[] = "ReadFile"; constexpr char kNativeWriteFunctionName[] = "WriteFile"; @@ -422,7 +422,7 @@ FileHandle LoggingOpenFileForWrite(const base::FilePath& path, FileWriteMode mode, FilePermissions permissions); -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) //! \brief Opens an in-memory file for input and output. //! //! This function first attempts to open the file with `memfd_create()`. If @@ -444,7 +444,7 @@ FileHandle LoggingOpenFileForWrite(const base::FilePath& path, //! \sa LoggingOpenFileForWrite //! \sa LoggingOpenFileForReadAndWrite FileHandle LoggingOpenMemoryFileForReadAndWrite(const base::FilePath& name); -#endif // OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) //! \brief Wraps OpenFileForReadAndWrite(), logging an error if the operation //! fails. @@ -461,7 +461,7 @@ FileHandle LoggingOpenFileForReadAndWrite(const base::FilePath& path, // Fuchsia does not currently support any sort of file locking. See // https://crashpad.chromium.org/bug/196 and // https://crashpad.chromium.org/bug/217. -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) //! \brief Locks the given \a file using `flock()` on POSIX or `LockFileEx()` on //! Windows. @@ -500,7 +500,7 @@ FileLockingResult LoggingLockFile(FileHandle file, //! \return `true` on success, or `false` and a message will be logged. bool LoggingUnlockFile(FileHandle file); -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) //! \brief Wraps `lseek()` or `SetFilePointerEx()`. Logs an error if the //! operation fails. diff --git a/thirdparty/sentry-native/external/crashpad/util/file/file_io_posix.cc b/thirdparty/sentry-native/external/crashpad/util/file/file_io_posix.cc index 119a2fcf67..5276b36dac 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/file_io_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/file_io_posix.cc @@ -72,7 +72,7 @@ FileHandle OpenFileForOutput(int rdwr_or_wronly, const base::FilePath& path, FileWriteMode mode, FilePermissions permissions) { -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) // O_NOCTTY is invalid on Fuchsia, and O_CLOEXEC isn't necessary. int flags = 0; #else @@ -120,7 +120,7 @@ FileOperationResult ReadFile(FileHandle file, void* buffer, size_t size) { FileHandle OpenFileForRead(const base::FilePath& path) { int flags = O_RDONLY; -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) // O_NOCTTY is invalid on Fuchsia, and O_CLOEXEC isn't necessary. flags |= O_NOCTTY | O_CLOEXEC; #endif @@ -153,7 +153,7 @@ FileHandle LoggingOpenFileForWrite(const base::FilePath& path, return fd; } -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FileHandle LoggingOpenMemoryFileForReadAndWrite(const base::FilePath& name) { DCHECK(name.value().find('/') == std::string::npos); @@ -208,7 +208,7 @@ FileHandle LoggingOpenFileForReadAndWrite(const base::FilePath& path, return fd; } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) FileLockingResult LoggingLockFile(FileHandle file, FileLocking locking, @@ -234,7 +234,7 @@ bool LoggingUnlockFile(FileHandle file) { return rv == 0; } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) FileOffset LoggingSeekFile(FileHandle file, FileOffset offset, int whence) { off_t rv = lseek(file, offset, whence); diff --git a/thirdparty/sentry-native/external/crashpad/util/file/file_io_test.cc b/thirdparty/sentry-native/external/crashpad/util/file/file_io_test.cc index abfef12916..2d45cfb6c5 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/file_io_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/file_io_test.cc @@ -16,12 +16,13 @@ #include +#include #include #include #include "base/atomicops.h" -#include "base/cxx17_backports.h" #include "base/files/file_path.h" +#include "build/build_config.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "test/errors.h" @@ -474,7 +475,7 @@ TEST(FileIO, LoggingOpenFileForReadAndWrite) { TestOpenFileForWrite(LoggingOpenFileForReadAndWrite); } -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) TEST(FileIO, LoggingOpenMemoryFileForReadAndWrite) { ScopedFileHandle handle( LoggingOpenMemoryFileForReadAndWrite(base::FilePath("memfile"))); @@ -489,7 +490,7 @@ TEST(FileIO, LoggingOpenMemoryFileForReadAndWrite) { ASSERT_TRUE(LoggingReadFileExactly(handle.get(), buffer, sizeof(buffer))); EXPECT_EQ(memcmp(buffer, kTestData, sizeof(buffer)), 0); } -#endif // OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) enum class ReadOrWrite : bool { kRead, @@ -545,7 +546,7 @@ TEST(FileIO, FileShareMode_Write_Write) { // Fuchsia does not currently support any sort of file locking. See // https://crashpad.chromium.org/bug/196 and // https://crashpad.chromium.org/bug/217. -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(FileIO, MultipleSharedLocks) { ScopedTempDir temp_dir; @@ -642,7 +643,7 @@ void LockingTest(FileLocking main_lock, FileLocking other_locks) { LockingTestThread threads[20]; int expected_iterations = 0; - for (size_t index = 0; index < base::size(threads); ++index) { + for (size_t index = 0; index < std::size(threads); ++index) { int iterations_for_this_thread = static_cast(index * 10); threads[index].Init( (other_locks == FileLocking::kShared) @@ -720,7 +721,7 @@ TEST(FileIO, ExclusiveVsExclusivesNonBlocking) { EXPECT_TRUE(LoggingUnlockFile(handle2.get())); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(FileIO, FileSizeByHandle) { EXPECT_EQ(LoggingFileSizeByHandle(kInvalidFileHandle), -1); @@ -742,9 +743,9 @@ TEST(FileIO, FileSizeByHandle) { FileHandle FileHandleForFILE(FILE* file) { int fd = fileno(file); -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) return fd; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return reinterpret_cast(_get_osfhandle(fd)); #else #error Port diff --git a/thirdparty/sentry-native/external/crashpad/util/file/file_writer.cc b/thirdparty/sentry-native/external/crashpad/util/file/file_writer.cc index 73fe708796..b6f50eb78f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/file_writer.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/file_writer.cc @@ -25,22 +25,22 @@ #include "build/build_config.h" #include "util/misc/implicit_cast.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include #include #include "base/posix/eintr_wrapper.h" -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) namespace crashpad { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) // Ensure type compatibility between WritableIoVec and iovec. static_assert(sizeof(WritableIoVec) == sizeof(iovec), "WritableIoVec size"); static_assert(offsetof(WritableIoVec, iov_base) == offsetof(iovec, iov_base), "WritableIoVec base offset"); static_assert(offsetof(WritableIoVec, iov_len) == offsetof(iovec, iov_len), "WritableIoVec len offset"); -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) WeakFileHandleFileWriter::WeakFileHandleFileWriter(FileHandle file_handle) : file_handle_(file_handle) { @@ -62,7 +62,7 @@ bool WeakFileHandleFileWriter::WriteIoVec(std::vector* iovecs) { return false; } -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) ssize_t size = 0; for (const WritableIoVec& iov : *iovecs) { @@ -79,7 +79,7 @@ bool WeakFileHandleFileWriter::WriteIoVec(std::vector* iovecs) { iovec* iov = reinterpret_cast(&(*iovecs)[0]); size_t remaining_iovecs = iovecs->size(); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // Android does not expose the IOV_MAX macro, but makes its value available // via sysconf(). See Android 7.0.0 bionic/libc/bionic/sysconf.cpp sysconf(). // Bionic defines IOV_MAX at bionic/libc/include/limits.h, but does not ship @@ -127,14 +127,14 @@ bool WeakFileHandleFileWriter::WriteIoVec(std::vector* iovecs) { DCHECK_EQ(remaining_iovecs, 0u); -#else // !OS_POSIX +#else // !BUILDFLAG(IS_POSIX) for (const WritableIoVec& iov : *iovecs) { if (!Write(iov.iov_base, iov.iov_len)) return false; } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) #ifndef NDEBUG // The interface says that |iovecs| is not sacred, so scramble it to make sure @@ -171,7 +171,7 @@ bool FileWriter::Open(const base::FilePath& path, return true; } -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) bool FileWriter::OpenMemfd(const base::FilePath& path) { CHECK(!file_.is_valid()); file_.reset(LoggingOpenMemoryFileForReadAndWrite(path)); diff --git a/thirdparty/sentry-native/external/crashpad/util/file/file_writer.h b/thirdparty/sentry-native/external/crashpad/util/file/file_writer.h index 4ba7a43868..8d82d1473c 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/file_writer.h +++ b/thirdparty/sentry-native/external/crashpad/util/file/file_writer.h @@ -20,6 +20,7 @@ #include #include "base/files/file_path.h" +#include "build/build_config.h" #include "util/file/file_io.h" #include "util/file/file_seeker.h" @@ -136,7 +137,7 @@ class FileWriter : public FileWriterInterface { FileWriteMode write_mode, FilePermissions permissions); -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) //! \brief Wraps LoggingOpenMemoryFileForWrite(). //! //! \return `true` if the operation succeeded, `false` if it failed, with an diff --git a/thirdparty/sentry-native/external/crashpad/util/file/filesystem_posix.cc b/thirdparty/sentry-native/external/crashpad/util/file/filesystem_posix.cc index c413397447..8853b9f67e 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/filesystem_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/filesystem_posix.cc @@ -33,9 +33,9 @@ bool FileModificationTime(const base::FilePath& path, timespec* mtime) { return false; } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) *mtime = st.st_mtimespec; -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) // This is needed to compile with traditional NDK headers. mtime->tv_sec = st.st_mtime; mtime->tv_nsec = st.st_mtime_nsec; diff --git a/thirdparty/sentry-native/external/crashpad/util/file/filesystem_test.cc b/thirdparty/sentry-native/external/crashpad/util/file/filesystem_test.cc index 9338cdcc12..cc683b3a07 100644 --- a/thirdparty/sentry-native/external/crashpad/util/file/filesystem_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/file/filesystem_test.cc @@ -31,7 +31,7 @@ namespace { constexpr char kTestFileContent[] = "file_content"; bool CurrentTime(timespec* now) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) timeval now_tv; int res = gettimeofday(&now_tv, nullptr); if (res != 0) { @@ -40,7 +40,7 @@ bool CurrentTime(timespec* now) { } TimevalToTimespec(now_tv, now); return true; -#elif defined(OS_POSIX) +#elif BUILDFLAG(IS_POSIX) int res = clock_gettime(CLOCK_REALTIME, now); if (res != 0) { EXPECT_EQ(res, 0) << ErrnoMessage("clock_gettime"); @@ -90,7 +90,7 @@ TEST(Filesystem, FileModificationTime) { temp_dir.path().Append(FILE_PATH_LITERAL("notafile")), &mtime)); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, FileModificationTime_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -140,7 +140,7 @@ TEST(Filesystem, FileModificationTime_SymbolicLinks) { EXPECT_LE(mtime.tv_sec, expected_time_end.tv_sec + 2); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, CreateDirectory) { ScopedTempDir temp_dir; @@ -221,7 +221,7 @@ TEST(Filesystem, MoveFileOrDirectory) { EXPECT_TRUE(IsRegularFile(file)); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, MoveFileOrDirectory_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -284,7 +284,7 @@ TEST(Filesystem, MoveFileOrDirectory_SymbolicLinks) { EXPECT_FALSE(PathExists(link2)); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, IsRegularFile) { EXPECT_FALSE(IsRegularFile(base::FilePath())); @@ -299,7 +299,7 @@ TEST(Filesystem, IsRegularFile) { EXPECT_TRUE(IsRegularFile(file)); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, IsRegularFile_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -323,7 +323,7 @@ TEST(Filesystem, IsRegularFile_SymbolicLinks) { EXPECT_FALSE(IsRegularFile(dir_link)); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, IsDirectory) { EXPECT_FALSE(IsDirectory(base::FilePath(), false)); @@ -341,7 +341,7 @@ TEST(Filesystem, IsDirectory) { EXPECT_FALSE(IsDirectory(file, true)); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, IsDirectory_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -368,7 +368,7 @@ TEST(Filesystem, IsDirectory_SymbolicLinks) { EXPECT_TRUE(IsDirectory(dir_link, true)); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, RemoveFile) { EXPECT_FALSE(LoggingRemoveFile(base::FilePath())); @@ -390,7 +390,7 @@ TEST(Filesystem, RemoveFile) { EXPECT_FALSE(LoggingRemoveFile(file)); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, RemoveFile_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -417,7 +417,7 @@ TEST(Filesystem, RemoveFile_SymbolicLinks) { EXPECT_TRUE(PathExists(dir)); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, RemoveDirectory) { EXPECT_FALSE(LoggingRemoveDirectory(base::FilePath())); @@ -432,7 +432,7 @@ TEST(Filesystem, RemoveDirectory) { EXPECT_FALSE(LoggingRemoveDirectory(file)); ASSERT_TRUE(CreateFile(file)); -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) // The current implementation of Fuchsia's rmdir() simply calls unlink(), and // unlink() works on all FS objects. This is incorrect as // http://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html says @@ -447,7 +447,7 @@ TEST(Filesystem, RemoveDirectory) { EXPECT_TRUE(LoggingRemoveDirectory(dir)); } -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, RemoveDirectory_SymbolicLinks) { if (!CanCreateSymbolicLinks()) { @@ -472,7 +472,7 @@ TEST(Filesystem, RemoveDirectory_SymbolicLinks) { EXPECT_TRUE(LoggingRemoveFile(link)); } -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) TEST(Filesystem, GetFileSize) { ScopedTempDir temp_dir; @@ -486,13 +486,13 @@ TEST(Filesystem, GetFileSize) { uint64_t filesize = GetFileSize(filepath); EXPECT_EQ(filesize, sizeof(kTestFileContent)); -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) // Create a link to a file. base::FilePath link(temp_dir.path().Append(FILE_PATH_LITERAL("link"))); ASSERT_TRUE(CreateSymbolicLink(filepath, link)); uint64_t filesize_link = GetFileSize(link); EXPECT_EQ(filesize_link, 0u); -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) } TEST(Filesystem, GetDirectorySize) { @@ -516,7 +516,7 @@ TEST(Filesystem, GetDirectorySize) { writer2.Write(kTestFileContent, sizeof(kTestFileContent)); writer2.Close(); -#if !defined(OS_FUCHSIA) +#if !BUILDFLAG(IS_FUCHSIA) // Create a link to a file. base::FilePath link(dir.Append(FILE_PATH_LITERAL("link"))); ASSERT_TRUE(CreateSymbolicLink(filepath2, link)); @@ -524,7 +524,7 @@ TEST(Filesystem, GetDirectorySize) { // Create a link to a dir. base::FilePath linkdir(temp_dir.path().Append(FILE_PATH_LITERAL("link"))); ASSERT_TRUE(CreateSymbolicLink(dir, linkdir)); -#endif // !OS_FUCHSIA +#endif // !BUILDFLAG(IS_FUCHSIA) uint64_t filesize = GetDirectorySize(temp_dir.path()); EXPECT_EQ(filesize, 2 * sizeof(kTestFileContent)); diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_format.h b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_format.h index 5e36862e8d..ea206430dd 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_format.h +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_format.h @@ -99,6 +99,7 @@ namespace internal { TD(kThreadContextMemoryRegions, 6011) \ TD(kThreadContextMemoryRegionAddress, 6012) \ TD(kThreadContextMemoryRegionData, 6013) \ + TD(kThreadName, 6014) \ TD(kMaxValue, 65535) \ // clang-format on diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader.cc b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader.cc index 022133bce7..d9610f656f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader.cc @@ -70,6 +70,12 @@ bool IOSIntermediateDumpReader::Parse(FileReaderInterface* reader, } while (reader->ReadExactly(&command, sizeof(Command))) { + constexpr int kMaxStackDepth = 10; + if (stack.size() > kMaxStackDepth) { + LOG(ERROR) << "Unexpected depth of intermediate dump data."; + return false; + } + IOSIntermediateDumpObject* parent = stack.top(); switch (command) { case Command::kMapStart: { diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader_test.cc b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader_test.cc index a66d6c3d46..7dfecdf9a6 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_reader_test.cc @@ -53,6 +53,7 @@ class IOSIntermediateDumpReaderTest : public testing::Test { } void TearDown() override { + ASSERT_TRUE(writer_->Close()); fd_.reset(); writer_.reset(); EXPECT_FALSE(IsRegularFile(path_)); diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.cc b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.cc index cd4d99d252..0fd3851697 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.cc +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.cc @@ -17,6 +17,9 @@ #include #include +#include + +#include "base/check.h" #include "base/posix/eintr_wrapper.h" #include "build/build_config.h" #include "util/ios/raw_logging.h" @@ -50,6 +53,10 @@ bool RawLoggingCloseFile(int fd) { return rv == 0; } +IOSIntermediateDumpWriter::~IOSIntermediateDumpWriter() { + DCHECK_EQ(fd_, -1) << "Call Close() before this object is destroyed."; +} + bool IOSIntermediateDumpWriter::Open(const base::FilePath& path) { // Set data protection class D (No protection). A file with this type of // protection can be read from or written to at any time. @@ -71,7 +78,12 @@ bool IOSIntermediateDumpWriter::Open(const base::FilePath& path) { } bool IOSIntermediateDumpWriter::Close() { - return RawLoggingCloseFile(fd_); + if (fd_ < 0) { + return true; + } + int fd = fd_; + fd_ = -1; + return RawLoggingCloseFile(fd); } bool IOSIntermediateDumpWriter::ArrayMapStart() { diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.h b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.h index 836fbe7ac6..d4f7a7b770 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.h +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer.h @@ -39,12 +39,14 @@ namespace internal { //! Note: All methods are `RUNS-DURING-CRASH`. class IOSIntermediateDumpWriter final { public: - IOSIntermediateDumpWriter() = default; + IOSIntermediateDumpWriter() : fd_(-1) { } IOSIntermediateDumpWriter(const IOSIntermediateDumpWriter&) = delete; IOSIntermediateDumpWriter& operator=(const IOSIntermediateDumpWriter&) = delete; + ~IOSIntermediateDumpWriter(); + //! \brief Command instructions for the intermediate dump reader. enum class CommandType : uint8_t { //! \brief Indicates a new map, followed by associated key. @@ -73,6 +75,8 @@ class IOSIntermediateDumpWriter final { //! \brief Open and lock an intermediate dump file. This is the only method //! in the writer class that is generally run outside of a crash. //! + //! The client must invoke `Close()` before this object is destroyed. + //! //! \param[in] path The path to the intermediate dump. //! //! \return On success, returns `true`, otherwise returns `false`. diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer_test.cc b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer_test.cc index 24f56efd23..055ae70cca 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_intermediate_dump_writer_test.cc @@ -41,6 +41,7 @@ class IOSIntermediateDumpWriterTest : public testing::Test { } void TearDown() override { + EXPECT_TRUE(writer_->Close()); writer_.reset(); EXPECT_EQ(unlink(path_.value().c_str()), 0) << ErrnoMessage("unlink"); } diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.h b/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.h index 035f9d81e7..916a674560 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.h +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.h @@ -17,6 +17,7 @@ #import +#include #include namespace crashpad { @@ -41,28 +42,25 @@ class IOSSystemDataCollector { int DaylightOffsetSeconds() const { return daylight_offset_seconds_; } const std::string& StandardName() const { return standard_name_; } const std::string& DaylightName() const { return daylight_name_; } + bool IsApplicationActive() const { return active_; } // Currently unused by minidump. int Orientation() const { return orientation_; } - private: - // Notification handlers. - void InstallHandlers(); - static void SystemTimeZoneDidChangeNotificationHandler( - CFNotificationCenterRef center, - void* observer, - CFStringRef name, - const void* object, - CFDictionaryRef userInfo); - void SystemTimeZoneDidChangeNotification(); + // A completion callback that takes a bool indicating that the application has + // become active or inactive. + using ActiveApplicationCallback = std::function; - static void OrientationDidChangeNotificationHandler( - CFNotificationCenterRef center, - void* observer, - CFStringRef name, - const void* object, - CFDictionaryRef userInfo); + void SetActiveApplicationCallback(ActiveApplicationCallback callback) { + active_application_callback_ = callback; + } + + private: + // Notification handlers for time zone, orientation and active state. + void InstallHandlers(); + void SystemTimeZoneDidChangeNotification(); void OrientationDidChangeNotification(); + void ApplicationDidChangeActiveNotification(); int major_version_; int minor_version_; @@ -72,6 +70,7 @@ class IOSSystemDataCollector { bool is_extension_; std::string machine_description_; int orientation_; + bool active_; int processor_count_; std::string cpu_vendor_; bool has_next_daylight_saving_time_; @@ -80,6 +79,7 @@ class IOSSystemDataCollector { int daylight_offset_seconds_; std::string standard_name_; std::string daylight_name_; + ActiveApplicationCallback active_application_callback_; }; } // namespace internal diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.mm b/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.mm index 366be46481..6d39b6d2d4 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.mm +++ b/thirdparty/sentry-native/external/crashpad/util/ios/ios_system_data_collector.mm @@ -49,6 +49,24 @@ std::string ReadStringSysctlByName(const char* name) { return value; } +template +void AddObserver(CFStringRef notification_name, T* observer) { + CFNotificationCenterAddObserver( + CFNotificationCenterGetLocalCenter(), + observer, + [](CFNotificationCenterRef center, + void* observer_vp, + CFNotificationName name, + const void* object, + CFDictionaryRef userInfo) { + T* observer = reinterpret_cast(observer_vp); + (observer->*M)(); + }, + notification_name, + nullptr, + CFNotificationSuspensionBehaviorDeliverImmediately); +} + } // namespace namespace crashpad { @@ -131,35 +149,30 @@ void IOSSystemDataCollector::OSVersion(int* major, void IOSSystemDataCollector::InstallHandlers() { // Timezone. - CFNotificationCenterAddObserver( - CFNotificationCenterGetLocalCenter(), - this, - IOSSystemDataCollector::SystemTimeZoneDidChangeNotificationHandler, - reinterpret_cast(NSSystemTimeZoneDidChangeNotification), - nullptr, - CFNotificationSuspensionBehaviorDeliverImmediately); + AddObserver( + (__bridge CFStringRef)NSSystemTimeZoneDidChangeNotification, this); SystemTimeZoneDidChangeNotification(); // Orientation. - CFNotificationCenterAddObserver( - CFNotificationCenterGetLocalCenter(), - this, - IOSSystemDataCollector::OrientationDidChangeNotificationHandler, - reinterpret_cast(UIDeviceOrientationDidChangeNotification), - nullptr, - CFNotificationSuspensionBehaviorDeliverImmediately); + AddObserver( + (__bridge CFStringRef)UIDeviceOrientationDidChangeNotification, this); OrientationDidChangeNotification(); -} -// static -void IOSSystemDataCollector::SystemTimeZoneDidChangeNotificationHandler( - CFNotificationCenterRef center, - void* observer, - CFStringRef name, - const void* object, - CFDictionaryRef userInfo) { - static_cast(observer) - ->SystemTimeZoneDidChangeNotification(); + // Foreground/Background. Extensions shouldn't use UIApplication*. + if (!is_extension_) { + AddObserver< + IOSSystemDataCollector, + &IOSSystemDataCollector::ApplicationDidChangeActiveNotification>( + (__bridge CFStringRef)UIApplicationDidBecomeActiveNotification, this); + AddObserver< + IOSSystemDataCollector, + &IOSSystemDataCollector::ApplicationDidChangeActiveNotification>( + (__bridge CFStringRef)UIApplicationDidEnterBackgroundNotification, + this); + ApplicationDidChangeActiveNotification(); + } } void IOSSystemDataCollector::SystemTimeZoneDidChangeNotification() { @@ -197,21 +210,20 @@ void IOSSystemDataCollector::SystemTimeZoneDidChangeNotification() { } } -// static -void IOSSystemDataCollector::OrientationDidChangeNotificationHandler( - CFNotificationCenterRef center, - void* observer, - CFStringRef name, - const void* object, - CFDictionaryRef userInfo) { - static_cast(observer) - ->OrientationDidChangeNotification(); -} - void IOSSystemDataCollector::OrientationDidChangeNotification() { orientation_ = base::saturated_cast([[UIDevice currentDevice] orientation]); } +void IOSSystemDataCollector::ApplicationDidChangeActiveNotification() { + dispatch_assert_queue_debug(dispatch_get_main_queue()); + bool old_active = active_; + active_ = [UIApplication sharedApplication].applicationState == + UIApplicationStateActive; + if (active_ != old_active && active_application_callback_) { + active_application_callback_(active_); + } +} + } // namespace internal } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.cc b/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.cc index f037c45289..821348e5b8 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.cc +++ b/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.cc @@ -14,6 +14,8 @@ #include "util/ios/raw_logging.h" +#include + #include #include #include @@ -23,12 +25,22 @@ namespace crashpad { namespace internal { +namespace { +static_assert(std::atomic::is_always_lock_free, + "std::atomic may not be signal-safe"); +std::atomic g_file_handle = STDERR_FILENO; +} // namespace + +void SetFileHandleForTesting(FileHandle file_handle) { + g_file_handle = file_handle; +} + void RawLogString(const char* message) { const size_t message_len = strlen(message); size_t bytes_written = 0; while (bytes_written < message_len) { int rv = HANDLE_EINTR(write( - STDERR_FILENO, message + bytes_written, message_len - bytes_written)); + g_file_handle, message + bytes_written, message_len - bytes_written)); if (rv < 0) { // Give up, nothing we can do now. break; @@ -51,15 +63,15 @@ void RawLogInt(unsigned int number) { // Prints `path:linenum message:error` (with optional `:error`). void RawLog(const char* file, int line, const char* message, int error) { RawLogString(file); - HANDLE_EINTR(write(STDERR_FILENO, ":", 1)); + HANDLE_EINTR(write(g_file_handle, ":", 1)); RawLogInt(line); - HANDLE_EINTR(write(STDERR_FILENO, " ", 1)); + HANDLE_EINTR(write(g_file_handle, " ", 1)); RawLogString(message); if (error) { RawLogString(": "); RawLogInt(error); } - HANDLE_EINTR(write(STDERR_FILENO, "\n", 1)); + HANDLE_EINTR(write(g_file_handle, "\n", 1)); } } // namespace internal diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.h b/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.h index 6075281713..16f08d601d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.h +++ b/thirdparty/sentry-native/external/crashpad/util/ios/raw_logging.h @@ -15,6 +15,8 @@ #ifndef CRASHPAD_UTIL_IOS_EXCEPTION_LOGGING_H_ #define CRASHPAD_UTIL_IOS_EXCEPTION_LOGGING_H_ +#include "util/file/file_io.h" + namespace crashpad { namespace internal { @@ -25,6 +27,11 @@ namespace internal { //! Note: RUNS-DURING-CRASH. void RawLog(const char* file, int line, const char* message, int error); +//! \brief Direct RawLog to log to \a file_handle instead of stderr, so tests +//! can confirm certain error conditions during in-process crashes. Call +//! before before any Crashpad is run. +void SetFileHandleForTesting(FileHandle file_handle); + } // namespace internal } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.h b/thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.h new file mode 100644 index 0000000000..909915b757 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.h @@ -0,0 +1,40 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_UTIL_IOS_SCOPED_BACKGROUND_TASK_H_ +#define CRASHPAD_UTIL_IOS_SCOPED_BACKGROUND_TASK_H_ + +#include + +namespace crashpad { +namespace internal { + +//! \brief Marks the start of a task that should continue if the application +//! enters the background. +class ScopedBackgroundTask { + public: + //! \param[in] task_name A string used in debugging to indicate the reason the + //! activity began. This parameter must not be nullptr or an empty string. + ScopedBackgroundTask(const char* task_name); + + ScopedBackgroundTask(const ScopedBackgroundTask&) = delete; + ScopedBackgroundTask& operator=(const ScopedBackgroundTask&) = delete; + ~ScopedBackgroundTask(); + + private: + dispatch_semaphore_t task_complete_semaphore_; +}; + +} // namespace internal +} // namespace crashpad + +#endif // CRASHPAD_UTIL_IOS_SCOPED_BACKGROUND_TASK_H_ diff --git a/thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.mm b/thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.mm new file mode 100644 index 0000000000..fdf2640e2e --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/util/ios/scoped_background_task.mm @@ -0,0 +1,58 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "util/ios/scoped_background_task.h" + +#import + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace crashpad { +namespace internal { + +ScopedBackgroundTask::ScopedBackgroundTask(const char* task_name) + : task_complete_semaphore_(dispatch_semaphore_create(0)) { + __weak dispatch_semaphore_t weak_task_complete_semaphore = + task_complete_semaphore_; + NSString* name = [NSString stringWithUTF8String:task_name]; + [[NSProcessInfo processInfo] + performExpiringActivityWithReason:name + usingBlock:^(BOOL expired) { + if (expired) { + // TODO(crbug.com/crashpad/400): Notify the + // BG task creator that time's up -- this will + // be useful for BackgroundTasks and + // NSURLSessions. + return; + } + __strong dispatch_semaphore_t + strong_task_complete_semaphore = + weak_task_complete_semaphore; + if (!strong_task_complete_semaphore) { + return; + } + dispatch_semaphore_wait( + strong_task_complete_semaphore, + DISPATCH_TIME_FOREVER); + }]; +} + +ScopedBackgroundTask::~ScopedBackgroundTask() { + dispatch_semaphore_signal(task_complete_semaphore_); +} + +} // namespace internal +} // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/auxiliary_vector_test.cc b/thirdparty/sentry-native/external/crashpad/util/linux/auxiliary_vector_test.cc index 75c20d1a09..a230de6f1a 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/auxiliary_vector_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/auxiliary_vector_test.cc @@ -33,7 +33,7 @@ #include "util/numeric/int128.h" #include "util/process/process_memory_linux.h" -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) // TODO(jperaza): This symbol isn't defined when building in chromium for // Android. There may be another symbol to use. extern "C" { @@ -72,7 +72,7 @@ void TestAgainstCloneOrSelf(pid_t pid) { ASSERT_TRUE(aux.GetValue(AT_BASE, &interp_base)); EXPECT_TRUE(mappings.FindMapping(interp_base)); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) LinuxVMAddress entry_addr; ASSERT_TRUE(aux.GetValue(AT_ENTRY, &entry_addr)); EXPECT_EQ(entry_addr, FromPointerCast(START_SYMBOL)); diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_client.cc b/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_client.cc index 608a199c0d..ed1c9fbb25 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_client.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_client.cc @@ -30,7 +30,7 @@ #include "util/misc/from_pointer_cast.h" #include "util/posix/signals.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.cc b/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.cc index 27f180c6e1..a5530f738d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.cc @@ -14,15 +14,19 @@ #include "util/linux/exception_handler_protocol.h" +#include "build/build_config.h" + namespace crashpad { ExceptionHandlerProtocol::ClientInformation::ClientInformation() : exception_information_address(0), sanitization_information_address(0) -#if defined(OS_LINUX) || defined(OS_CHROMEOS) - , crash_loop_before_time(0) -#endif // OS_LINUX || OS_CHROMEOS -{} +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + , + crash_loop_before_time(0) +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +{ +} ExceptionHandlerProtocol::ClientToServerMessage::ClientToServerMessage() : version(kVersion), diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.h b/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.h index cbd24418a6..6a38acd54f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.h +++ b/thirdparty/sentry-native/external/crashpad/util/linux/exception_handler_protocol.h @@ -51,7 +51,7 @@ class ExceptionHandlerProtocol { //! SanitizationInformation struct, or 0 if there is no such struct. VMAddress sanitization_information_address; -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) //! \brief Indicates that the client is likely in a crash loop if a crash //! occurs before this timestamp. This value is only used by ChromeOS's //! `/sbin/crash_reporter`. diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/memory_map.cc b/thirdparty/sentry-native/external/crashpad/util/linux/memory_map.cc index 47eec973f2..3e845c4c6f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/memory_map.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/memory_map.cc @@ -398,7 +398,7 @@ std::unique_ptr MemoryMap::FindFilePossibleMmapStarts( return std::make_unique(); } -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) // The Android Chromium linker uses ashmem to share RELRO segments between // processes. The original RELRO segment has been unmapped and replaced with a // mapping named "/dev/ashmem/RELRO:" where is the base @@ -427,17 +427,17 @@ std::unique_ptr MemoryMap::FindFilePossibleMmapStarts( } } } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) for (const auto& candidate : mappings_) { if (candidate.device == mapping.device && candidate.inode == mapping.inode -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) // Libraries on Android may be mapped from zipfiles (APKs), in which // case the offset is not 0. && candidate.offset == 0 -#endif // !defined(OS_ANDROID) - ) { +#endif // !BUILDFLAG(IS_ANDROID) + ) { possible_starts.push_back(&candidate); } if (mapping.Equals(candidate)) { diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/memory_map_test.cc b/thirdparty/sentry-native/external/crashpad/util/linux/memory_map_test.cc index 4ab7b05c43..d77dd0da5d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/memory_map_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/memory_map_test.cc @@ -101,7 +101,7 @@ TEST(MemoryMap, SelfBasic) { ASSERT_TRUE(mapping); EXPECT_GE(code_address, mapping->range.Base()); EXPECT_LT(code_address, mapping->range.End()); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) // Android Q+ supports execute only memory. EXPECT_TRUE(mapping->readable); #endif @@ -174,7 +174,7 @@ class MapChildTest : public Multiprocess { ASSERT_TRUE(mapping); EXPECT_GE(code_address, mapping->range.Base()); EXPECT_LT(code_address, mapping->range.End()); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) // Android Q+ supports execute only memory. EXPECT_TRUE(mapping->readable); #endif @@ -426,7 +426,7 @@ void ExpectFindFilePossibleMmapStarts(LinuxVMAddress mapping_start, EXPECT_EQ(mappings->Next(), mapping2); mappings = map.FindFilePossibleMmapStarts(*mapping3); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_EQ(mappings->Count(), 2u); #else ASSERT_EQ(mappings->Count(), 1u); @@ -474,7 +474,7 @@ TEST(MemoryMap, FindFilePossibleMmapStarts) { ASSERT_NE(mapping1, mapping2); ASSERT_NE(mapping2, mapping3); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) auto mappings = map.FindFilePossibleMmapStarts(*mapping1); EXPECT_EQ(mappings->Count(), 1u); EXPECT_EQ(mappings->Next(), mapping1); @@ -622,7 +622,7 @@ TEST(MemoryMap, FindFilePossibleMmapStarts_MultipleStarts) { auto mapping = map.FindMapping(file_mapping0.addr_as()); ASSERT_TRUE(mapping); auto possible_starts = map.FindFilePossibleMmapStarts(*mapping); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_EQ(possible_starts->Count(), 1u); #else EXPECT_EQ(possible_starts->Count(), 0u); @@ -631,7 +631,7 @@ TEST(MemoryMap, FindFilePossibleMmapStarts_MultipleStarts) { mapping = map.FindMapping(file_mapping1.addr_as()); ASSERT_TRUE(mapping); possible_starts = map.FindFilePossibleMmapStarts(*mapping); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_EQ(possible_starts->Count(), 2u); #else EXPECT_EQ(possible_starts->Count(), 1u); @@ -640,7 +640,7 @@ TEST(MemoryMap, FindFilePossibleMmapStarts_MultipleStarts) { mapping = map.FindMapping(file_mapping2.addr_as()); ASSERT_TRUE(mapping); possible_starts = map.FindFilePossibleMmapStarts(*mapping); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_EQ(possible_starts->Count(), 3u); #else EXPECT_EQ(possible_starts->Count(), 2u); @@ -649,7 +649,7 @@ TEST(MemoryMap, FindFilePossibleMmapStarts_MultipleStarts) { mapping = map.FindMapping(file_mapping3.addr_as()); ASSERT_TRUE(mapping); possible_starts = map.FindFilePossibleMmapStarts(*mapping); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_EQ(possible_starts->Count(), 4u); #else EXPECT_EQ(possible_starts->Count(), 3u); @@ -658,7 +658,7 @@ TEST(MemoryMap, FindFilePossibleMmapStarts_MultipleStarts) { mapping = map.FindMapping(file_mapping4.addr_as()); ASSERT_TRUE(mapping); possible_starts = map.FindFilePossibleMmapStarts(*mapping); -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) EXPECT_EQ(possible_starts->Count(), 5u); #else EXPECT_EQ(possible_starts->Count(), 4u); diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/proc_stat_reader.cc b/thirdparty/sentry-native/external/crashpad/util/linux/proc_stat_reader.cc index 878103d9dc..04d47f5e41 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/proc_stat_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/proc_stat_reader.cc @@ -18,7 +18,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/files/file_path.h" #include "base/logging.h" #include "util/file/file_io.h" @@ -48,7 +49,7 @@ bool ProcStatReader::Initialize(PtraceConnection* connection, pid_t tid) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); char path[32]; - snprintf(path, base::size(path), "/proc/%d/stat", tid); + snprintf(path, std::size(path), "/proc/%d/stat", tid); if (!connection->ReadFileContents(base::FilePath(path), &contents_)) { return false; } diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/proc_task_reader.cc b/thirdparty/sentry-native/external/crashpad/util/linux/proc_task_reader.cc index ca62db2712..0d2fb90b1b 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/proc_task_reader.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/proc_task_reader.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/files/file_path.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" @@ -29,7 +30,7 @@ bool ReadThreadIDs(pid_t pid, std::vector* tids) { DCHECK(tids->empty()); char path[32]; - snprintf(path, base::size(path), "/proc/%d/task", pid); + snprintf(path, std::size(path), "/proc/%d/task", pid); DirectoryReader reader; if (!reader.Open(base::FilePath(path))) { return false; diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/ptrace_client.cc b/thirdparty/sentry-native/external/crashpad/util/linux/ptrace_client.cc index 9a34722ae2..1863841f73 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/ptrace_client.cc +++ b/thirdparty/sentry-native/external/crashpad/util/linux/ptrace_client.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "util/file/file_io.h" @@ -265,7 +265,7 @@ bool PtraceClient::Threads(std::vector* threads) { threads->push_back(pid_); char path[32]; - snprintf(path, base::size(path), "/proc/%d/task", pid_); + snprintf(path, std::size(path), "/proc/%d/task", pid_); PtraceBroker::Request request = {}; request.type = PtraceBroker::Request::kTypeListDirectory; diff --git a/thirdparty/sentry-native/external/crashpad/util/linux/thread_info.h b/thirdparty/sentry-native/external/crashpad/util/linux/thread_info.h index 5b55c24a76..d3f3b2c695 100644 --- a/thirdparty/sentry-native/external/crashpad/util/linux/thread_info.h +++ b/thirdparty/sentry-native/external/crashpad/util/linux/thread_info.h @@ -24,7 +24,7 @@ #include "util/linux/address_types.h" #include "util/numeric/int128.h" -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) #include #endif @@ -261,11 +261,12 @@ union FloatContext { // __ANDROID_API_N__ is a proxy for determining whether unified headers are in // use. It’s only defined by unified headers. Unified headers call this // structure user_fpxregs_struct regardless of API level. -#if defined(OS_ANDROID) && __ANDROID_API__ <= 19 && !defined(__ANDROID_API_N__) +#if BUILDFLAG(IS_ANDROID) && __ANDROID_API__ <= 19 && \ + !defined(__ANDROID_API_N__) using NativeFpxregs = user_fxsr_struct; #else using NativeFpxregs = user_fpxregs_struct; -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) static_assert(sizeof(f32_t::fxsave) == sizeof(NativeFpxregs), "Size mismatch"); #elif defined(ARCH_CPU_X86_64) diff --git a/thirdparty/sentry-native/external/crashpad/util/mac/checked_mach_address_range_test.cc b/thirdparty/sentry-native/external/crashpad/util/mac/checked_mach_address_range_test.cc index 4ef26fd923..7f26d25596 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mac/checked_mach_address_range_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mac/checked_mach_address_range_test.cc @@ -17,9 +17,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gtest/gtest.h" @@ -116,7 +116,7 @@ TEST(CheckedMachAddressRange, IsValid) { {0xffffffffffffffff, 1, kInvalid}, }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf("index %zu, base 0x%llx, size 0x%llx", index, @@ -166,7 +166,7 @@ TEST(CheckedMachAddressRange, ContainsValue) { CheckedMachAddressRange parent_range_32(false, 0x2000, 0x1000); ASSERT_TRUE(parent_range_32.IsValid()); - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE( base::StringPrintf("index %zu, value 0x%llx", index, testcase.value)); @@ -223,7 +223,7 @@ TEST(CheckedMachAddressRange, ContainsRange) { CheckedMachAddressRange parent_range_32(false, 0x2000, 0x1000); ASSERT_TRUE(parent_range_32.IsValid()); - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf("index %zu, base 0x%llx, size 0x%llx", index, diff --git a/thirdparty/sentry-native/external/crashpad/util/mac/launchd_test.mm b/thirdparty/sentry-native/external/crashpad/util/mac/launchd_test.mm index 2e49ee665b..21920598ff 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mac/launchd_test.mm +++ b/thirdparty/sentry-native/external/crashpad/util/mac/launchd_test.mm @@ -20,9 +20,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/mac/scoped_launch_data.h" #include "gtest/gtest.h" #include "util/stdlib/objc.h" @@ -58,7 +58,7 @@ TEST(Launchd, CFPropertyToLaunchData_Integer) { @0xfedcba9876543210, }; - for (size_t index = 0; index < base::size(integer_nses); ++index) { + for (size_t index = 0; index < std::size(integer_nses); ++index) { NSNumber* integer_ns = integer_nses[index]; launch_data.reset(CFPropertyToLaunchData(integer_ns)); ASSERT_TRUE(launch_data.get()); @@ -88,7 +88,7 @@ TEST(Launchd, CFPropertyToLaunchData_FloatingPoint) { @(std::numeric_limits::signaling_NaN()), }; - for (size_t index = 0; index < base::size(double_nses); ++index) { + for (size_t index = 0; index < std::size(double_nses); ++index) { NSNumber* double_ns = double_nses[index]; launch_data.reset(CFPropertyToLaunchData(double_ns)); ASSERT_TRUE(launch_data.get()); @@ -114,7 +114,7 @@ TEST(Launchd, CFPropertyToLaunchData_Boolean) { @YES, }; - for (size_t index = 0; index < base::size(bool_nses); ++index) { + for (size_t index = 0; index < std::size(bool_nses); ++index) { NSNumber* bool_ns = bool_nses[index]; launch_data.reset(CFPropertyToLaunchData(bool_ns)); ASSERT_TRUE(launch_data.get()); @@ -138,7 +138,7 @@ TEST(Launchd, CFPropertyToLaunchData_String) { @"Üñîçø∂é", }; - for (size_t index = 0; index < base::size(string_nses); ++index) { + for (size_t index = 0; index < std::size(string_nses); ++index) { NSString* string_ns = string_nses[index]; launch_data.reset(CFPropertyToLaunchData(string_ns)); ASSERT_TRUE(launch_data.get()); diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.cc b/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.cc index 28fdbae6db..d0e58030ff 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.cc @@ -24,10 +24,10 @@ #include #include +#include #include #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/mac/mach_logging.h" #include "base/mac/scoped_mach_port.h" @@ -167,8 +167,8 @@ mach_port_t ChildPortHandshakeServer::RunServer( 0, 0, nullptr); - int rv = HANDLE_EINTR(kevent( - kq.get(), changelist, base::size(changelist), nullptr, 0, nullptr)); + int rv = HANDLE_EINTR( + kevent(kq.get(), changelist, std::size(changelist), nullptr, 0, nullptr)); PCHECK(rv != -1) << "kevent"; ChildPortServer child_port_server(this); diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.h b/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.h index c61f734ed0..54168691bd 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.h +++ b/thirdparty/sentry-native/external/crashpad/util/mach/child_port_handshake.h @@ -18,9 +18,9 @@ #include #include +#include #include "base/files/scoped_file.h" -#include "base/ignore_result.h" #include "util/mach/child_port_types.h" namespace crashpad { @@ -124,7 +124,7 @@ class ChildPortHandshakeTest; //! // for use in the parent process. //! if (child_port_handshake.RunClient(receive_right.get(), //! MACH_MSG_TYPE_MOVE_RECEIVE)) { -//! ignore_result(receive_right.release()); +//! std::ignore = receive_right.release(); //! } //! \endcode //! diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/child_port_server.cc b/thirdparty/sentry-native/external/crashpad/util/mach/child_port_server.cc index 927342942f..9323723c37 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/child_port_server.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/child_port_server.cc @@ -14,7 +14,8 @@ #include "util/mach/child_port_server.h" -#include "base/cxx17_backports.h" +#include + #include "util/mach/child_portServer.h" #include "util/mach/mach_message.h" @@ -90,7 +91,7 @@ std::set ChildPortServer::MachMessageServerRequestIDs() { static constexpr mach_msg_id_t request_ids[] = {kMachMessageIDChildPortCheckIn}; return std::set(&request_ids[0], - &request_ids[base::size(request_ids)]); + &request_ids[std::size(request_ids)]); } mach_msg_size_t ChildPortServer::MachMessageServerRequestSize() { diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/composite_mach_message_server_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/composite_mach_message_server_test.cc index 91a3851f2e..36fd6ac08e 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/composite_mach_message_server_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/composite_mach_message_server_test.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "gtest/gtest.h" #include "test/gtest_death.h" @@ -198,7 +199,7 @@ TEST(CompositeMachMessageServer, ThreeHandlers) { TestMachMessageHandler handlers[3]; std::set expect_request_ids; - for (size_t index = 0; index < base::size(kRequestIDs0); ++index) { + for (size_t index = 0; index < std::size(kRequestIDs0); ++index) { const mach_msg_id_t request_id = kRequestIDs0[index]; handlers[0].AddRequestID(request_id); expect_request_ids.insert(request_id); @@ -207,7 +208,7 @@ TEST(CompositeMachMessageServer, ThreeHandlers) { handlers[0].SetReplySize(sizeof(mig_reply_error_t)); handlers[0].SetReturnCodes(true, kReturnCode0, false); - for (size_t index = 0; index < base::size(kRequestIDs1); ++index) { + for (size_t index = 0; index < std::size(kRequestIDs1); ++index) { const mach_msg_id_t request_id = kRequestIDs1[index]; handlers[1].AddRequestID(request_id); expect_request_ids.insert(request_id); @@ -216,7 +217,7 @@ TEST(CompositeMachMessageServer, ThreeHandlers) { handlers[1].SetReplySize(200); handlers[1].SetReturnCodes(false, kReturnCode1, true); - for (size_t index = 0; index < base::size(kRequestIDs2); ++index) { + for (size_t index = 0; index < std::size(kRequestIDs2); ++index) { const mach_msg_id_t request_id = kRequestIDs2[index]; handlers[2].AddRequestID(request_id); expect_request_ids.insert(request_id); @@ -254,7 +255,7 @@ TEST(CompositeMachMessageServer, ThreeHandlers) { // Send messages with known request IDs. - for (size_t index = 0; index < base::size(kRequestIDs0); ++index) { + for (size_t index = 0; index < std::size(kRequestIDs0); ++index) { request.header.msgh_id = kRequestIDs0[index]; SCOPED_TRACE(base::StringPrintf( "handler 0, index %zu, id %d", index, request.header.msgh_id)); @@ -265,7 +266,7 @@ TEST(CompositeMachMessageServer, ThreeHandlers) { EXPECT_FALSE(destroy_complex_request); } - for (size_t index = 0; index < base::size(kRequestIDs1); ++index) { + for (size_t index = 0; index < std::size(kRequestIDs1); ++index) { request.header.msgh_id = kRequestIDs1[index]; SCOPED_TRACE(base::StringPrintf( "handler 1, index %zu, id %d", index, request.header.msgh_id)); @@ -276,7 +277,7 @@ TEST(CompositeMachMessageServer, ThreeHandlers) { EXPECT_TRUE(destroy_complex_request); } - for (size_t index = 0; index < base::size(kRequestIDs2); ++index) { + for (size_t index = 0; index < std::size(kRequestIDs2); ++index) { request.header.msgh_id = kRequestIDs2[index]; SCOPED_TRACE(base::StringPrintf( "handler 2, index %zu, id %d", index, request.header.msgh_id)); diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/exc_client_variants_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/exc_client_variants_test.cc index aba72052fb..700eb5f8df 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/exc_client_variants_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/exc_client_variants_test.cc @@ -19,7 +19,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "gtest/gtest.h" #include "test/mac/mach_errors.h" @@ -184,11 +185,11 @@ class TestExcClientVariants : public MachMultiprocess, // These aren’t real flavors, it’s just for testing. flavor = exception_ + 10; flavor_p = &flavor; - for (size_t index = 0; index < base::size(old_state); ++index) { + for (size_t index = 0; index < std::size(old_state); ++index) { old_state[index] = index; } old_state_p = reinterpret_cast(&old_state); - old_state_count = base::size(old_state); + old_state_count = std::size(old_state); // new_state and new_state_count are out parameters that the server should // never see or use, so set them to bogus values. The call to the server @@ -205,7 +206,7 @@ class TestExcClientVariants : public MachMultiprocess, task, exception, code, - base::size(code), + std::size(code), flavor_p, old_state_p, old_state_count, @@ -274,7 +275,7 @@ TEST(ExcClientVariants, UniversalExceptionRaise) { kMachExceptionCodes | EXCEPTION_STATE_IDENTITY, }; - for (size_t index = 0; index < base::size(kBehaviors); ++index) { + for (size_t index = 0; index < std::size(kBehaviors); ++index) { exception_behavior_t behavior = kBehaviors[index]; SCOPED_TRACE(base::StringPrintf("index %zu, behavior %d", index, behavior)); diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants.cc b/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants.cc index b9357a7802..2941cb29e9 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "build/build_config.h" #include "util/mac/mac_util.h" #include "util/mach/composite_mach_message_server.h" @@ -246,7 +246,7 @@ class ExcServer : public MachMessageServer::Interface { Traits::kMachMessageIDExceptionRaiseStateIdentity, }; return std::set(&request_ids[0], - &request_ids[base::size(request_ids)]); + &request_ids[std::size(request_ids)]); } mach_msg_size_t MachMessageServerRequestSize() override { @@ -321,7 +321,7 @@ bool ExcServer::MachMessageServerFunction( using Reply = typename Traits::ExceptionRaiseStateReply; Reply* out_reply = reinterpret_cast(out_header); out_reply->flavor = in_request_1->flavor; - out_reply->new_stateCnt = base::size(out_reply->new_state); + out_reply->new_stateCnt = std::size(out_reply->new_state); out_reply->RetCode = interface_->CatchExceptionRaiseState(in_header->msgh_local_port, in_request->exception, @@ -364,7 +364,7 @@ bool ExcServer::MachMessageServerFunction( using Reply = typename Traits::ExceptionRaiseStateIdentityReply; Reply* out_reply = reinterpret_cast(out_header); out_reply->flavor = in_request_1->flavor; - out_reply->new_stateCnt = base::size(out_reply->new_state); + out_reply->new_stateCnt = std::size(out_reply->new_state); out_reply->RetCode = interface_->CatchExceptionRaiseStateIdentity( in_header->msgh_local_port, in_request->thread.name, @@ -686,10 +686,10 @@ kern_return_t ExcServerSuccessfulReturnValue(exception_type_t exception, exception_behavior_t behavior, bool set_thread_state) { if (exception == EXC_CRASH -#if defined(OS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_11 +#if BUILDFLAG(IS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_11 && MacOSVersionNumber() >= 10'11'00 #endif - ) { + ) { return KERN_SUCCESS; } diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants_test.cc index d74cbc5915..b0fcef092c 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/exc_server_variants_test.cc @@ -19,7 +19,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gmock/gmock.h" @@ -31,9 +32,9 @@ #include "util/mach/mach_message.h" #include "util/misc/implicit_cast.h" -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) #include "test/mac/mach_multiprocess.h" -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) namespace crashpad { namespace test { @@ -232,7 +233,7 @@ struct __attribute__((packed, aligned(4))) ExceptionRaiseStateReply { EXPECT_EQ(memcmp(&NDR, &NDR_record, sizeof(NDR)), 0); EXPECT_EQ(RetCode, KERN_SUCCESS); EXPECT_EQ(flavor, kThreadStateFlavor); - EXPECT_EQ(new_stateCnt, base::size(new_state)); + EXPECT_EQ(new_stateCnt, std::size(new_state)); } mach_msg_header_t Head; @@ -664,7 +665,7 @@ TEST(ExcServerVariants, MockExceptionRaiseState) { AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), Pointee(Eq(kThreadStateFlavor)), IsThreadStateAndCount(kThreadStateFlavorCount), - IsThreadStateAndCount(base::size(reply.new_state)), + IsThreadStateAndCount(std::size(reply.new_state)), Eq(request.Trailer()))) .WillOnce(Return(KERN_SUCCESS)) .RetiresOnSaturation(); @@ -713,7 +714,7 @@ TEST(ExcServerVariants, MockExceptionRaiseStateIdentity) { AreExceptionCodes(kTestExceptonCodes[0], kTestExceptonCodes[1]), Pointee(Eq(kThreadStateFlavor)), IsThreadStateAndCount(kThreadStateFlavorCount), - IsThreadStateAndCount(base::size(reply.new_state)), + IsThreadStateAndCount(std::size(reply.new_state)), Eq(request.Trailer()))) .WillOnce(Return(KERN_SUCCESS)) .RetiresOnSaturation(); @@ -807,7 +808,7 @@ TEST(ExcServerVariants, MockMachExceptionRaiseState) { kTestMachExceptionCodes[1]), Pointee(Eq(kThreadStateFlavor)), IsThreadStateAndCount(kThreadStateFlavorCount), - IsThreadStateAndCount(base::size(reply.new_state)), + IsThreadStateAndCount(std::size(reply.new_state)), Eq(request.Trailer()))) .WillOnce(Return(KERN_SUCCESS)) .RetiresOnSaturation(); @@ -857,7 +858,7 @@ TEST(ExcServerVariants, MockMachExceptionRaiseStateIdentity) { kTestMachExceptionCodes[1]), Pointee(Eq(kThreadStateFlavor)), IsThreadStateAndCount(kThreadStateFlavorCount), - IsThreadStateAndCount(base::size(reply.new_state)), + IsThreadStateAndCount(std::size(reply.new_state)), Eq(request.Trailer()))) .WillOnce(Return(KERN_SUCCESS)) .RetiresOnSaturation(); @@ -911,7 +912,7 @@ TEST(ExcServerVariants, MockUnknownID) { 2508, }; - for (size_t index = 0; index < base::size(unknown_ids); ++index) { + for (size_t index = 0; index < std::size(unknown_ids); ++index) { mach_msg_id_t id = unknown_ids[index]; SCOPED_TRACE(base::StringPrintf("unknown id %d", id)); @@ -962,7 +963,7 @@ TEST(ExcServerVariants, MachMessageServerRequestIDs) { expect_request_ids); } -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) class TestExcServerVariants : public MachMultiprocess, public UniversalMachExcServer::Interface { @@ -1190,7 +1191,7 @@ TEST(ExcServerVariants, ThreadStates) { #endif }; - for (size_t index = 0; index < base::size(test_data); ++index) { + for (size_t index = 0; index < std::size(test_data); ++index) { const auto& test = test_data[index]; SCOPED_TRACE( base::StringPrintf("index %zu, flavor %d", index, test.flavor)); @@ -1203,10 +1204,10 @@ TEST(ExcServerVariants, ThreadStates) { } } -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) TEST(ExcServerVariants, ExcServerSuccessfulReturnValue) { -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) // iOS 9 ≅ OS X 10.11. const kern_return_t prefer_not_set_thread_state = KERN_SUCCESS; #else @@ -1270,7 +1271,7 @@ TEST(ExcServerVariants, ExcServerSuccessfulReturnValue) { KERN_SUCCESS}, }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& test_data = kTestData[index]; SCOPED_TRACE( base::StringPrintf("index %zu, behavior %d, set_thread_state %s", @@ -1289,8 +1290,8 @@ TEST(ExcServerVariants, ExcServerCopyState) { static constexpr natural_t old_state[] = {1, 2, 3, 4, 5}; natural_t new_state[10] = {}; - constexpr mach_msg_type_number_t old_state_count = base::size(old_state); - mach_msg_type_number_t new_state_count = base::size(new_state); + constexpr mach_msg_type_number_t old_state_count = std::size(old_state); + mach_msg_type_number_t new_state_count = std::size(new_state); // EXCEPTION_DEFAULT (with or without MACH_EXCEPTION_CODES) is not // state-carrying. new_state and new_state_count should be untouched. @@ -1299,8 +1300,8 @@ TEST(ExcServerVariants, ExcServerCopyState) { old_state_count, new_state, &new_state_count); - EXPECT_EQ(new_state_count, base::size(new_state)); - for (size_t i = 0; i < base::size(new_state); ++i) { + EXPECT_EQ(new_state_count, std::size(new_state)); + for (size_t i = 0; i < std::size(new_state); ++i) { EXPECT_EQ(new_state[i], 0u) << "i " << i; } @@ -1309,8 +1310,8 @@ TEST(ExcServerVariants, ExcServerCopyState) { old_state_count, new_state, &new_state_count); - EXPECT_EQ(new_state_count, base::size(new_state)); - for (size_t i = 0; i < base::size(new_state); ++i) { + EXPECT_EQ(new_state_count, std::size(new_state)); + for (size_t i = 0; i < std::size(new_state); ++i) { EXPECT_EQ(new_state[i], 0u) << "i " << i; } @@ -1322,7 +1323,7 @@ TEST(ExcServerVariants, ExcServerCopyState) { for (size_t i = 0; i < copy_limit; ++i) { EXPECT_EQ(new_state[i], old_state[i]) << "i " << i; } - for (size_t i = copy_limit; i < base::size(new_state); ++i) { + for (size_t i = copy_limit; i < std::size(new_state); ++i) { EXPECT_EQ(new_state[i], 0u) << "i " << i; } @@ -1338,23 +1339,23 @@ TEST(ExcServerVariants, ExcServerCopyState) { for (size_t i = 0; i < copy_limit; ++i) { EXPECT_EQ(new_state[i], old_state[i]) << "i " << i; } - for (size_t i = copy_limit; i < base::size(new_state); ++i) { + for (size_t i = copy_limit; i < std::size(new_state); ++i) { EXPECT_EQ(new_state[i], 0u) << "i " << i; } // This is a state-carrying exception where all of old_state is copied to // new_state, which is large enough to receive it and then some. - new_state_count = base::size(new_state); + new_state_count = std::size(new_state); ExcServerCopyState(MACH_EXCEPTION_CODES | EXCEPTION_STATE_IDENTITY, old_state, old_state_count, new_state, &new_state_count); EXPECT_EQ(new_state_count, old_state_count); - for (size_t i = 0; i < base::size(old_state); ++i) { + for (size_t i = 0; i < std::size(old_state); ++i) { EXPECT_EQ(new_state[i], old_state[i]) << "i " << i; } - for (size_t i = base::size(old_state); i < base::size(new_state); ++i) { + for (size_t i = std::size(old_state); i < std::size(new_state); ++i) { EXPECT_EQ(new_state[i], 0u) << "i " << i; } } diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/exception_behaviors_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/exception_behaviors_test.cc index e6abd25fbc..8e3d0f4b79 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/exception_behaviors_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/exception_behaviors_test.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "gtest/gtest.h" #include "util/mach/mach_extensions.h" @@ -53,7 +54,7 @@ TEST(ExceptionBehaviors, ExceptionBehaviors) { EXCEPTION_STATE_IDENTITY}, }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& test_data = kTestData[index]; SCOPED_TRACE(base::StringPrintf( "index %zu, behavior %d", index, test_data.behavior)); diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/exception_types_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/exception_types_test.cc index 3e777ef246..fb095fab0e 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/exception_types_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/exception_types_test.cc @@ -20,7 +20,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gtest/gtest.h" @@ -71,7 +72,7 @@ TEST(ExceptionTypes, ExcCrashRecoverOriginalException) { // TODO(macos_arm64): Add arm64 test data. }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& test_data = kTestData[index]; SCOPED_TRACE(base::StringPrintf( "index %zu, code_0 0x%llx", index, test_data.code_0)); @@ -88,7 +89,7 @@ TEST(ExceptionTypes, ExcCrashRecoverOriginalException) { // Now make sure that ExcCrashRecoverOriginalException() properly ignores // optional arguments. - static_assert(base::size(kTestData) >= 1, "must have something to test"); + static_assert(std::size(kTestData) >= 1, "must have something to test"); const auto& test_data = kTestData[0]; EXPECT_EQ( ExcCrashRecoverOriginalException(test_data.code_0, nullptr, nullptr), @@ -248,7 +249,7 @@ TEST(ExceptionTypes, ExceptionCodeForMetrics) { {0x00010000, 0x00010000, static_cast(0xffffffff)}, }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& test_data = kTestData[index]; SCOPED_TRACE(base::StringPrintf("index %zu, exception 0x%x, code_0 0x%llx", index, diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions.cc b/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions.cc index 7f80693888..dcff5c2a89 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions.cc @@ -44,12 +44,12 @@ exception_mask_t ExcMaskAll() { // 10.9.4 xnu-2422.110.17/osfmk/mach/ipc_host.c and // xnu-2422.110.17/osfmk/mach/ipc_tt.c. -#if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 +#if BUILDFLAG(IS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 // iOS 7 ≅ OS X 10.9. #error This code was not ported to iOS versions older than 7 #endif -#if defined(OS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 +#if BUILDFLAG(IS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 const int macos_version_number = MacOSVersionNumber(); #endif @@ -66,7 +66,7 @@ exception_mask_t ExcMaskAll() { EXC_MASK_MACH_SYSCALL | EXC_MASK_RPC_ALERT | EXC_MASK_MACHINE; -#if defined(OS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8 +#if BUILDFLAG(IS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8 if (macos_version_number < 10'08'00) { return kExcMaskAll_10_6; } @@ -76,7 +76,7 @@ exception_mask_t ExcMaskAll() { // xnu-2050.48.11/osfmk/mach/exception_types.h. constexpr exception_mask_t kExcMaskAll_10_8 = kExcMaskAll_10_6 | EXC_MASK_RESOURCE; -#if defined(OS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 +#if BUILDFLAG(IS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 if (macos_version_number < 10'09'00) { return kExcMaskAll_10_8; } @@ -91,12 +91,12 @@ exception_mask_t ExcMaskAll() { exception_mask_t ExcMaskValid() { const exception_mask_t kExcMaskValid_10_6 = ExcMaskAll() | EXC_MASK_CRASH; -#if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 +#if BUILDFLAG(IS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 // iOS 9 ≅ OS X 10.11. #error This code was not ported to iOS versions older than 9 #endif -#if defined(OS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_11 +#if BUILDFLAG(IS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_11 if (MacOSVersionNumber() < 10'11'00) { return kExcMaskValid_10_6; } diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions_test.cc index 4ff53d9422..57e03ad153 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mach_extensions_test.cc @@ -80,11 +80,11 @@ TEST(MachExtensions, ExcMaskAll) { EXPECT_FALSE(exc_mask_all & EXC_MASK_CRASH); EXPECT_FALSE(exc_mask_all & EXC_MASK_CORPSE_NOTIFY); -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) // Assume at least iOS 7 (≅ OS X 10.9). EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE); EXPECT_TRUE(exc_mask_all & EXC_MASK_GUARD); -#else // OS_IOS +#else // BUILDFLAG(IS_IOS) const int macos_version_number = MacOSVersionNumber(); if (macos_version_number >= 10'08'00) { EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE); @@ -97,7 +97,7 @@ TEST(MachExtensions, ExcMaskAll) { } else { EXPECT_FALSE(exc_mask_all & EXC_MASK_GUARD); } -#endif // OS_IOS +#endif // BUILDFLAG(IS_IOS) // Bit 0 should not be set. EXPECT_FALSE(ExcMaskAll() & 1); @@ -112,12 +112,12 @@ TEST(MachExtensions, ExcMaskValid) { EXPECT_TRUE(exc_mask_valid & EXC_MASK_CRASH); -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) // Assume at least iOS 9 (≅ OS X 10.11). EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE); EXPECT_TRUE(exc_mask_valid & EXC_MASK_GUARD); EXPECT_TRUE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY); -#else // OS_IOS +#else // BUILDFLAG(IS_IOS) const int macos_version_number = MacOSVersionNumber(); if (macos_version_number >= 10'08'00) { EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE); @@ -136,7 +136,7 @@ TEST(MachExtensions, ExcMaskValid) { } else { EXPECT_FALSE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY); } -#endif // OS_IOS +#endif // BUILDFLAG(IS_IOS) // Bit 0 should not be set. EXPECT_FALSE(ExcMaskValid() & 1); diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.cc b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.cc index 00fe116f88..ac76a53864 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.cc @@ -20,12 +20,13 @@ #include "base/logging.h" #include "base/mac/mach_logging.h" +#include "build/build_config.h" #include "util/misc/clock.h" #include "util/misc/implicit_cast.h" -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) #include -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) namespace crashpad { @@ -253,7 +254,7 @@ bool MachMessageDestroyReceivedPort(mach_port_t port, } } -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer) { if (trailer->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0) { @@ -287,6 +288,6 @@ pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer) { return audit_pid; } -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.h b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.h index c58b6d05fa..e670a13e7d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.h +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message.h @@ -183,7 +183,7 @@ const mach_msg_trailer_t* MachMessageTrailerFromHeader( bool MachMessageDestroyReceivedPort(mach_port_t port, mach_msg_type_name_t port_right_type); -#if defined(OS_MAC) || DOXYGEN +#if BUILDFLAG(IS_MAC) || DOXYGEN //! \brief Returns the process ID of a Mach message’s sender from its audit //! trailer. @@ -201,7 +201,7 @@ bool MachMessageDestroyReceivedPort(mach_port_t port, //! audit information. pid_t AuditPIDFromMachMessageTrailer(const mach_msg_trailer_t* trailer); -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_server_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_server_test.cc index 6785827b98..51a0b4cab9 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_server_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_server_test.cc @@ -19,9 +19,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/mac/scoped_mach_port.h" #include "gtest/gtest.h" #include "test/mac/mach_errors.h" @@ -284,7 +284,7 @@ class TestMachMessageServer : public MachMessageServer::Interface, std::set MachMessageServerRequestIDs() override { static constexpr mach_msg_id_t request_ids[] = {kRequestMessageID}; return std::set(&request_ids[0], - &request_ids[base::size(request_ids)]); + &request_ids[std::size(request_ids)]); } mach_msg_size_t MachMessageServerRequestSize() override { diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_test.cc index 0bee04b335..587061ff71 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mach_message_test.cc @@ -16,8 +16,10 @@ #include -#include "base/ignore_result.h" +#include + #include "base/mac/scoped_mach_port.h" +#include "build/build_config.h" #include "gtest/gtest.h" #include "test/mac/mach_errors.h" #include "util/mach/mach_extensions.h" @@ -154,11 +156,11 @@ TEST(MachMessage, MachMessageDestroyReceivedPort) { ASSERT_EQ(right_type, implicit_cast(MACH_MSG_TYPE_PORT_SEND)); EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_RECEIVE)); - ignore_result(receive.release()); + std::ignore = receive.release(); EXPECT_TRUE(MachMessageDestroyReceivedPort(port, MACH_MSG_TYPE_PORT_SEND)); } -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) TEST(MachMessage, AuditPIDFromMachMessageTrailer) { base::mac::ScopedMachReceiveRight port(NewMachPort(MACH_PORT_RIGHT_RECEIVE)); @@ -200,7 +202,7 @@ TEST(MachMessage, AuditPIDFromMachMessageTrailer) { EXPECT_EQ(AuditPIDFromMachMessageTrailer(&receive.trailer), getpid()); } -#endif // OS_MAC +#endif // BUILDFLAG(IS_MAC) } // namespace } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mig.py b/thirdparty/sentry-native/external/crashpad/util/mach/mig.py index 53a7a5bd1d..c7a1543520 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mig.py +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mig.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2019 The Crashpad Authors. All rights reserved. # diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mig_fix.py b/thirdparty/sentry-native/external/crashpad/util/mach/mig_fix.py index 037746fac3..974c58df79 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mig_fix.py +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mig_fix.py @@ -1,5 +1,4 @@ -#!/usr/bin/env python -# coding: utf-8 +#!/usr/bin/env python3 # Copyright 2019 The Crashpad Authors. All rights reserved. # @@ -23,6 +22,33 @@ import sys from mig_gen import MigInterface +def _make_generated_comments_deterministic(contents): + """Replaces generated code comments with determenistic ones. + + This is what is generated by mig (only in .c files): + /* + * IDENTIFICATION: + * stub generated Mon Jan 17 15:28:03 2022 + * with a MiG generated by bootstrap_cmds-122 + * OPTIONS: + */ + + We look for two specific lines and replace them like so: + /* + * IDENTIFICATION: + * stub generated + * with a MiG generated by + * OPTIONS: + */ + """ + + return re.sub(r'^( \* (?:stub generated|with a MiG generated by) ).+$', + r'\1', + contents, + count=2, + flags=re.MULTILINE) + + def _fix_user_implementation(implementation, fixed_implementation, header, fixed_header): """Rewrites a MIG-generated user implementation (.c) file. @@ -33,7 +59,8 @@ def _fix_user_implementation(implementation, fixed_implementation, header, unused in the user implementation file, and this will trigger a -Wunused-local-typedefs warning in gcc unless removed or marked with the “unused” attribute. Also changes header references to point to the new - header filename, if changed. + header filename, if changed. Replaces generated code comments with + deterministic ones. If |fixed_implementation| is None, overwrites the original; otherwise, puts the result in the file at |fixed_implementation|. @@ -50,6 +77,9 @@ def _fix_user_implementation(implementation, fixed_implementation, header, '#include "%s"' % os.path.basename(header), '#include "%s"' % os.path.basename(fixed_header)) + # Replace generated code comments with determenistic ones. + contents = _make_generated_comments_deterministic(contents) + if fixed_implementation is None: file.seek(0) file.truncate() @@ -71,6 +101,7 @@ def _fix_server_implementation(implementation, fixed_implementation, header, added to a header file, so that other files that include that header file will have access to these declarations from a compilation perspective. Also changes header references to point to the new header filename, if changed. + Replaces generated code comments with deterministic ones. If |fixed_implementation| is None or not provided, overwrites the original; otherwise, puts the result in the file at |fixed_implementation|. @@ -117,6 +148,9 @@ extern '#include "%s"' % os.path.basename(header), '#include "%s"' % os.path.basename(fixed_header)) + # Replace generated code comments with determenistic ones. + contents = _make_generated_comments_deterministic(contents) + if fixed_implementation is None: file.seek(0) file.truncate() diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/mig_gen.py b/thirdparty/sentry-native/external/crashpad/util/mach/mig_gen.py index b3ef614e7a..87d02725f5 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/mig_gen.py +++ b/thirdparty/sentry-native/external/crashpad/util/mach/mig_gen.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2019 The Crashpad Authors. All rights reserved. # diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/notify_server.cc b/thirdparty/sentry-native/external/crashpad/util/mach/notify_server.cc index e625419e93..b16c6fb3e7 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/notify_server.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/notify_server.cc @@ -14,7 +14,8 @@ #include "util/mach/notify_server.h" -#include "base/cxx17_backports.h" +#include + #include "util/mach/mach_message.h" #include "util/mach/notifyServer.h" @@ -227,7 +228,7 @@ std::set NotifyServer::MachMessageServerRequestIDs() { MACH_NOTIFY_DEAD_NAME, }; return std::set(&request_ids[0], - &request_ids[base::size(request_ids)]); + &request_ids[std::size(request_ids)]); } mach_msg_size_t NotifyServer::MachMessageServerRequestSize() { diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach.cc b/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach.cc index 47090086e4..457a0ca2b7 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach.cc @@ -17,7 +17,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "util/mach/exception_behaviors.h" #include "util/mach/mach_extensions.h" @@ -45,7 +46,7 @@ constexpr const char* kExceptionNames[] = { "GUARD", "CORPSE_NOTIFY", }; -static_assert(base::size(kExceptionNames) == EXC_TYPES_COUNT, +static_assert(std::size(kExceptionNames) == EXC_TYPES_COUNT, "kExceptionNames length"); constexpr char kExcPrefix[] = "EXC_"; @@ -170,7 +171,7 @@ std::string ThreadStateFlavorFullToShort(const base::StringPiece& flavor) { {"_STATE32", "32"}, {"_STATE64", "64"}, }; - for (size_t suffix_index = 0; suffix_index < base::size(kStateSuffixes); + for (size_t suffix_index = 0; suffix_index < std::size(kStateSuffixes); ++suffix_index) { const char* suffix = kStateSuffixes[suffix_index].orig; size_t suffix_len = strlen(suffix); @@ -194,7 +195,7 @@ namespace crashpad { std::string ExceptionToString(exception_type_t exception, SymbolicConstantToStringOptions options) { const char* exception_name = - implicit_cast(exception) < base::size(kExceptionNames) + implicit_cast(exception) < std::size(kExceptionNames) ? kExceptionNames[exception] : nullptr; if (!exception_name) { @@ -220,7 +221,7 @@ bool StringToException(const base::StringPiece& string, base::StringPiece short_string = can_match_full ? string.substr(strlen(kExcPrefix)) : string; for (exception_type_t index = 0; - index < implicit_cast(base::size(kExceptionNames)); + index < implicit_cast(std::size(kExceptionNames)); ++index) { const char* exception_name = kExceptionNames[index]; if (!exception_name) { @@ -250,7 +251,7 @@ std::string ExceptionMaskToString(exception_mask_t exception_mask, exception_mask_t local_exception_mask = exception_mask; std::string mask_string; bool has_forbidden_or = false; - for (size_t exception = 0; exception < base::size(kExceptionNames); + for (size_t exception = 0; exception < std::size(kExceptionNames); ++exception) { const char* exception_name = kExceptionNames[exception]; exception_mask_t exception_mask_value = 1 << exception; @@ -324,7 +325,7 @@ bool StringToExceptionMask(const base::StringPiece& string, base::StringPiece short_string = can_match_full ? string.substr(strlen(kExcMaskPrefix)) : string; for (exception_type_t index = 0; - index < implicit_cast(base::size(kExceptionNames)); + index < implicit_cast(std::size(kExceptionNames)); ++index) { const char* exception_name = kExceptionNames[index]; if (!exception_name) { @@ -363,7 +364,7 @@ std::string ExceptionBehaviorToString(exception_behavior_t behavior, const exception_behavior_t basic_behavior = ExceptionBehaviorBasic(behavior); const char* behavior_name = - implicit_cast(basic_behavior) < base::size(kBehaviorNames) + implicit_cast(basic_behavior) < std::size(kBehaviorNames) ? kBehaviorNames[basic_behavior] : nullptr; if (!behavior_name) { @@ -430,8 +431,7 @@ bool StringToExceptionBehavior(const base::StringPiece& string, base::StringPiece short_string = can_match_full ? sp.substr(strlen(kBehaviorPrefix)) : sp; for (exception_behavior_t index = 0; - index < - implicit_cast(base::size(kBehaviorNames)); + index < implicit_cast(std::size(kBehaviorNames)); ++index) { const char* behavior_name = kBehaviorNames[index]; if (!behavior_name) { @@ -467,13 +467,13 @@ bool StringToExceptionBehavior(const base::StringPiece& string, std::string ThreadStateFlavorToString(thread_state_flavor_t flavor, SymbolicConstantToStringOptions options) { const char* flavor_name = - implicit_cast(flavor) < base::size(kFlavorNames) + implicit_cast(flavor) < std::size(kFlavorNames) ? kFlavorNames[flavor] : nullptr; if (!flavor_name) { for (size_t generic_flavor_index = 0; - generic_flavor_index < base::size(kGenericFlavorNames); + generic_flavor_index < std::size(kGenericFlavorNames); ++generic_flavor_index) { if (flavor == kGenericFlavorNames[generic_flavor_index].flavor) { flavor_name = kGenericFlavorNames[generic_flavor_index].name; @@ -500,7 +500,7 @@ bool StringToThreadStateFlavor(const base::StringPiece& string, thread_state_flavor_t* flavor) { if ((options & kAllowFullName) || (options & kAllowShortName)) { for (thread_state_flavor_t index = 0; - index < implicit_cast(base::size(kFlavorNames)); + index < implicit_cast(std::size(kFlavorNames)); ++index) { const char* flavor_name = kFlavorNames[index]; if (!flavor_name) { @@ -520,7 +520,7 @@ bool StringToThreadStateFlavor(const base::StringPiece& string, } for (size_t generic_flavor_index = 0; - generic_flavor_index < base::size(kGenericFlavorNames); + generic_flavor_index < std::size(kGenericFlavorNames); ++generic_flavor_index) { const char* flavor_name = kGenericFlavorNames[generic_flavor_index].name; thread_state_flavor_t flavor_number = diff --git a/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach_test.cc b/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach_test.cc index 20c60a0ead..614a45b580 100644 --- a/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/mach/symbolic_constants_mach_test.cc @@ -18,7 +18,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -26,7 +27,7 @@ #include "util/misc/implicit_cast.h" #define NUL_TEST_DATA(string) \ - { string, base::size(string) - 1 } + { string, std::size(string) - 1 } namespace crashpad { namespace test { @@ -160,7 +161,7 @@ void TestExceptionToString(exception_type_t value, } TEST(SymbolicConstantsMach, ExceptionToString) { - for (size_t index = 0; index < base::size(kExceptionTestData); ++index) { + for (size_t index = 0; index < std::size(kExceptionTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestExceptionToString(kExceptionTestData[index].exception, kExceptionTestData[index].full_name, @@ -188,11 +189,11 @@ void TestStringToException(const base::StringPiece& string, } TEST(SymbolicConstantsMach, StringToException) { - for (size_t option_index = 0; option_index < base::size(kNormalOptions); + for (size_t option_index = 0; option_index < std::size(kNormalOptions); ++option_index) { SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index)); StringToSymbolicConstantOptions options = kNormalOptions[option_index]; - for (size_t index = 0; index < base::size(kExceptionTestData); ++index) { + for (size_t index = 0; index < std::size(kExceptionTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); exception_type_t exception = kExceptionTestData[index].exception; { @@ -230,7 +231,7 @@ TEST(SymbolicConstantsMach, StringToException) { "", }; - for (size_t index = 0; index < base::size(kNegativeTestData); ++index) { + for (size_t index = 0; index < std::size(kNegativeTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestStringToException(kNegativeTestData[index], options, false, 0); } @@ -251,7 +252,7 @@ TEST(SymbolicConstantsMach, StringToException) { NUL_TEST_DATA("1\0002"), }; - for (size_t index = 0; index < base::size(kNULTestData); ++index) { + for (size_t index = 0; index < std::size(kNULTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); base::StringPiece string(kNULTestData[index].string, kNULTestData[index].length); @@ -334,7 +335,7 @@ void TestExceptionMaskToString(exception_mask_t value, } TEST(SymbolicConstantsMach, ExceptionMaskToString) { - for (size_t index = 0; index < base::size(kExceptionMaskTestData); ++index) { + for (size_t index = 0; index < std::size(kExceptionMaskTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestExceptionMaskToString(kExceptionMaskTestData[index].exception_mask, kExceptionMaskTestData[index].full_name, @@ -389,12 +390,11 @@ TEST(SymbolicConstantsMach, StringToExceptionMask) { kAllowFullName | kAllowShortName | kAllowNumber | kAllowOr, }; - for (size_t option_index = 0; option_index < base::size(kOptions); + for (size_t option_index = 0; option_index < std::size(kOptions); ++option_index) { SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index)); StringToSymbolicConstantOptions options = kOptions[option_index]; - for (size_t index = 0; index < base::size(kExceptionMaskTestData); - ++index) { + for (size_t index = 0; index < std::size(kExceptionMaskTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); exception_mask_t exception_mask = kExceptionMaskTestData[index].exception_mask; @@ -445,7 +445,7 @@ TEST(SymbolicConstantsMach, StringToExceptionMask) { "", }; - for (size_t index = 0; index < base::size(kNegativeTestData); ++index) { + for (size_t index = 0; index < std::size(kNegativeTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestStringToExceptionMask(kNegativeTestData[index], options, false, 0); } @@ -471,7 +471,7 @@ TEST(SymbolicConstantsMach, StringToExceptionMask) { NUL_TEST_DATA("ARITHMETIC|\0EMULATION"), }; - for (size_t index = 0; index < base::size(kNULTestData); ++index) { + for (size_t index = 0; index < std::size(kNULTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); base::StringPiece string(kNULTestData[index].string, kNULTestData[index].length); @@ -506,7 +506,7 @@ TEST(SymbolicConstantsMach, StringToExceptionMask) { EXC_MASK_SYSCALL | 0x100}, }; - for (size_t index = 0; index < base::size(kNonCanonicalTestData); ++index) { + for (size_t index = 0; index < std::size(kNonCanonicalTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestStringToExceptionMask(kNonCanonicalTestData[index].string, kNonCanonicalTestData[index].options, @@ -577,7 +577,7 @@ void TestExceptionBehaviorToString(exception_behavior_t value, } TEST(SymbolicConstantsMach, ExceptionBehaviorToString) { - for (size_t index = 0; index < base::size(kExceptionBehaviorTestData); + for (size_t index = 0; index < std::size(kExceptionBehaviorTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestExceptionBehaviorToString(kExceptionBehaviorTestData[index].behavior, @@ -607,11 +607,11 @@ void TestStringToExceptionBehavior(const base::StringPiece& string, } TEST(SymbolicConstantsMach, StringToExceptionBehavior) { - for (size_t option_index = 0; option_index < base::size(kNormalOptions); + for (size_t option_index = 0; option_index < std::size(kNormalOptions); ++option_index) { SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index)); StringToSymbolicConstantOptions options = kNormalOptions[option_index]; - for (size_t index = 0; index < base::size(kExceptionBehaviorTestData); + for (size_t index = 0; index < std::size(kExceptionBehaviorTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); exception_behavior_t behavior = @@ -657,7 +657,7 @@ TEST(SymbolicConstantsMach, StringToExceptionBehavior) { "", }; - for (size_t index = 0; index < base::size(kNegativeTestData); ++index) { + for (size_t index = 0; index < std::size(kNegativeTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestStringToExceptionBehavior( kNegativeTestData[index], options, false, 0); @@ -683,7 +683,7 @@ TEST(SymbolicConstantsMach, StringToExceptionBehavior) { NUL_TEST_DATA("STATE_IDENTITY|\0MACH"), }; - for (size_t index = 0; index < base::size(kNULTestData); ++index) { + for (size_t index = 0; index < std::size(kNULTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); base::StringPiece string(kNULTestData[index].string, kNULTestData[index].length); @@ -720,7 +720,7 @@ TEST(SymbolicConstantsMach, StringToExceptionBehavior) { implicit_cast(MACH_EXCEPTION_CODES | 0x2)}, }; - for (size_t index = 0; index < base::size(kNonCanonicalTestData); ++index) { + for (size_t index = 0; index < std::size(kNonCanonicalTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestStringToExceptionBehavior(kNonCanonicalTestData[index].string, kNonCanonicalTestData[index].options, @@ -837,7 +837,7 @@ void TestThreadStateFlavorToString(exception_type_t value, } TEST(SymbolicConstantsMach, ThreadStateFlavorToString) { - for (size_t index = 0; index < base::size(kThreadStateFlavorTestData); + for (size_t index = 0; index < std::size(kThreadStateFlavorTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestThreadStateFlavorToString(kThreadStateFlavorTestData[index].flavor, @@ -879,11 +879,11 @@ void TestStringToThreadStateFlavor(const base::StringPiece& string, } TEST(SymbolicConstantsMach, StringToThreadStateFlavor) { - for (size_t option_index = 0; option_index < base::size(kNormalOptions); + for (size_t option_index = 0; option_index < std::size(kNormalOptions); ++option_index) { SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index)); StringToSymbolicConstantOptions options = kNormalOptions[option_index]; - for (size_t index = 0; index < base::size(kThreadStateFlavorTestData); + for (size_t index = 0; index < std::size(kThreadStateFlavorTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); thread_state_flavor_t flavor = kThreadStateFlavorTestData[index].flavor; @@ -953,7 +953,7 @@ TEST(SymbolicConstantsMach, StringToThreadStateFlavor) { #endif }; - for (size_t index = 0; index < base::size(kNegativeTestData); ++index) { + for (size_t index = 0; index < std::size(kNegativeTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestStringToThreadStateFlavor( kNegativeTestData[index], options, false, 0); @@ -1019,7 +1019,7 @@ TEST(SymbolicConstantsMach, StringToThreadStateFlavor) { #endif }; - for (size_t index = 0; index < base::size(kNULTestData); ++index) { + for (size_t index = 0; index < std::size(kNULTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); base::StringPiece string(kNULTestData[index].string, kNULTestData[index].length); diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/address_types.h b/thirdparty/sentry-native/external/crashpad/util/misc/address_types.h index 14942bd8ea..8902efb6cd 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/address_types.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/address_types.h @@ -21,13 +21,13 @@ #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include "util/win/address_types.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "util/linux/address_types.h" -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #include #else #error "Unhandled OS type" @@ -45,22 +45,22 @@ using VMAddress = uint64_t; //! VMAddress), potentially across bitness. using VMSize = uint64_t; -#elif defined(OS_APPLE) +#elif BUILDFLAG(IS_APPLE) using VMAddress = mach_vm_address_t; using VMSize = mach_vm_size_t; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) using VMAddress = WinVMAddress; using VMSize = WinVMSize; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) using VMAddress = LinuxVMAddress; using VMSize = LinuxVMSize; -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) using VMAddress = zx_vaddr_t; using VMSize = size_t; diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/arm64_bti_note.S b/thirdparty/sentry-native/external/crashpad/util/misc/arm64_pac_bti.S similarity index 63% rename from thirdparty/sentry-native/external/crashpad/util/misc/arm64_bti_note.S rename to thirdparty/sentry-native/external/crashpad/util/misc/arm64_pac_bti.S index 987493be81..ac90f2abec 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/arm64_bti_note.S +++ b/thirdparty/sentry-native/external/crashpad/util/misc/arm64_pac_bti.S @@ -12,16 +12,40 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef CRASHPAD_UTIL_MISC_ARM64_BTI_NOTE_S -#define CRASHPAD_UTIL_MISC_ARM64_BTI_NOTE_S +#ifndef CRASHPAD_UTIL_MISC_ARM64_PAC_BTI_S +#define CRASHPAD_UTIL_MISC_ARM64_PAC_BTI_S -/* Support macros for the Armv8.5-A Branch Target Identification feature which - * requires emitting a .note.gnu.property section with the appropriate +/* Support macros for the Armv8.5-A Branch Target Identification and + * Armv8.3-A Pointer Authentication features which require emitting + * a .note.gnu.property section with the appropriate * architecture-dependent feature bits set. * Read more: "ELF for the Arm® 64-bit Architecture" */ #if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT == 1) -#define GNU_PROPERTY_AARCH64_BTI (1 << 0) // Has BTI +#define GNU_PROPERTY_AARCH64_BTI 1 // Has BTI +#define CRASHPAD_AARCH64_VALID_JUMP_CALL_TARGET bti jc +#define CRASHPAD_AARCH64_VALID_CALL_TARGET bti c +#define CRASHPAD_AARCH64_VALID_JUMP_TARGET bti j +#else +#define GNU_PROPERTY_AARCH64_BTI 0 // No BTI +#define CRASHPAD_AARCH64_VALID_JUMP_CALL_TARGET +#define CRASHPAD_AARCH64_VALID_CALL_TARGET +#define CRASHPAD_AARCH64_VALID_JUMP_TARGET +#endif + +#if defined(__ARM_FEATURE_PAC_DEFAULT) +#if ((__ARM_FEATURE_PAC_DEFAULT & ((1<<0)|(1<<2))) == 0) +#error Pointer authentication defines no valid key! +#endif +#define GNU_PROPERTY_AARCH64_PAC 1 // Has PAC +#else +#define GNU_PROPERTY_AARCH64_PAC 0 // No PAC +#endif + +/** + * Emit a proper .note.gnu.property section in case of PAC or BTI being enabled. + */ +#if (GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_PAC != 0) .pushsection .note.gnu.property, "a" .balign 4 .long 0x4 /* size of field "GNU" */ @@ -30,17 +54,12 @@ .asciz "GNU" .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ .long 0x4 - .long GNU_PROPERTY_AARCH64_BTI + .long ((GNU_PROPERTY_AARCH64_BTI<<0)|(GNU_PROPERTY_AARCH64_PAC<<1)) .long 0x0 .popsection -#define CRASHPAD_AARCH64_VALID_JUMP_CALL_TARGET bti jc -#define CRASHPAD_AARCH64_VALID_CALL_TARGET bti c -#define CRASHPAD_AARCH64_VALID_JUMP_TARGET bti j -#undef GNU_PROPERTY_AARCH64_BTI -#else -#define CRASHPAD_AARCH64_VALID_JUMP_CALL_TARGET -#define CRASHPAD_AARCH64_VALID_CALL_TARGET -#define CRASHPAD_AARCH64_VALID_JUMP_TARGET #endif -#endif /* CRASHPAD_UTIL_MISC_ARM64_BTI_NOTE_S */ +#undef GNU_PROPERTY_AARCH64_BTI +#undef GNU_PROPERTY_AARCH64_PAC + +#endif /* CRASHPAD_UTIL_MISC_ARM64_PAC_BTI_S */ diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/arraysize.h b/thirdparty/sentry-native/external/crashpad/util/misc/arraysize.h index 93a63882e4..63f49768c0 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/arraysize.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/arraysize.h @@ -35,9 +35,9 @@ constexpr size_t ArraySizeHelper() noexcept { //! \brief A way of computing an array’s size. //! -//! Use this only where `base::size()` or `std::size()` won’t work, such as in -//! constant expressions (including `static_assert` expressions) that consider -//! the sizes of non-static data members. +//! Use this only where `std::size()` won’t work, such as in constant +//! expressions (including `static_assert` expressions) that consider the +//! sizes of non-static data members. #define ArraySize(array) crashpad::internal::ArraySizeHelper() #endif // CRASHPAD_UTIL_MISC_ARRAYSIZE_H_ diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/arraysize_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/arraysize_test.cc index ad8da0970a..5a2106a092 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/arraysize_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/arraysize_test.cc @@ -14,7 +14,6 @@ #include "util/misc/arraysize.h" -#include "base/compiler_specific.h" #include "gtest/gtest.h" namespace crashpad { @@ -22,37 +21,29 @@ namespace test { namespace { TEST(ArraySize, ArraySize) { - char c1[1]; + [[maybe_unused]] char c1[1]; static_assert(ArraySize(c1) == 1, "c1"); - ALLOW_UNUSED_LOCAL(c1); - char c2[2]; + [[maybe_unused]] char c2[2]; static_assert(ArraySize(c2) == 2, "c2"); - ALLOW_UNUSED_LOCAL(c2); - char c4[4]; + [[maybe_unused]] char c4[4]; static_assert(ArraySize(c4) == 4, "c4"); - ALLOW_UNUSED_LOCAL(c4); - int i1[1]; + [[maybe_unused]] int i1[1]; static_assert(ArraySize(i1) == 1, "i1"); - ALLOW_UNUSED_LOCAL(i1); - int i2[2]; + [[maybe_unused]] int i2[2]; static_assert(ArraySize(i2) == 2, "i2"); - ALLOW_UNUSED_LOCAL(i2); - int i4[4]; + [[maybe_unused]] int i4[4]; static_assert(ArraySize(i4) == 4, "i4"); - ALLOW_UNUSED_LOCAL(i4); - long l8[8]; + [[maybe_unused]] long l8[8]; static_assert(ArraySize(l8) == 8, "l8"); - ALLOW_UNUSED_LOCAL(l8); - int l9[9]; + [[maybe_unused]] int l9[9]; static_assert(ArraySize(l9) == 9, "l9"); - ALLOW_UNUSED_LOCAL(l9); struct S { char c; @@ -61,13 +52,11 @@ TEST(ArraySize, ArraySize) { bool b; }; - S s1[1]; + [[maybe_unused]] S s1[1]; static_assert(ArraySize(s1) == 1, "s1"); - ALLOW_UNUSED_LOCAL(s1); - S s10[10]; + [[maybe_unused]] S s10[10]; static_assert(ArraySize(s10) == 10, "s10"); - ALLOW_UNUSED_LOCAL(s10); } } // namespace diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context.h b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context.h index d21a24f19f..37ed40021d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context.h @@ -17,30 +17,30 @@ #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #include -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) namespace crashpad { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #if defined(ARCH_CPU_X86_FAMILY) using NativeCPUContext = x86_thread_state; #elif defined(ARCH_CPU_ARM64) using NativeCPUContext = arm_unified_thread_state; #endif -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) using NativeCPUContext = CONTEXT; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || \ - defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) using NativeCPUContext = ucontext_t; -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) //! \brief Saves the CPU context. //! diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_linux.S b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_linux.S index 0ee561f534..96e030d902 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_linux.S +++ b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_linux.S @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "util/misc/arm64_bti_note.S" +#include "util/misc/arm64_pac_bti.S" // namespace crashpad { // void CaptureContext(ucontext_t* context); @@ -316,14 +316,15 @@ CAPTURECONTEXT_SYMBOL2: stp x26, x27, [x0, #0x188] stp x28, x29, [x0, #0x198] - // The original LR can't be recovered. + // The original LR can't be recovered, therefore no need to sign x30 with PAC. str x30, [x0, #0x1a8] // Use x1 as a scratch register. mov x1, SP str x1, [x0, #0x1b0] // context->uc_mcontext.sp - // The link register holds the return address for this function. + // The link register holds the return address for this function and won't be + // recovered, therefore no need to sign x30 with PAC. str x30, [x0, #0x1b8] // context->uc_mcontext.pc // pstate should hold SPSR but NZCV are the only bits we know about. diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test.cc index cf23c2deff..a24ea15045 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test.cc @@ -28,14 +28,14 @@ namespace crashpad { namespace test { namespace { -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) // Fuchsia uses -fsanitize=safe-stack by default, which splits local variables // and the call stack into separate regions (see // https://clang.llvm.org/docs/SafeStack.html). Because this test would like to // find an approximately valid stack pointer by comparing locals to the // captured one, disable safe-stack for this function. __attribute__((no_sanitize("safe-stack"))) -#endif // defined(OS_FUCHSIA) +#endif // BUILDFLAG(IS_FUCHSIA) #if defined(MEMORY_SANITIZER) // CaptureContext() calls inline assembly and is incompatible with MSan. diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test_util_win.cc b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test_util_win.cc index d1221956d8..dd9d9a6834 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test_util_win.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/capture_context_test_util_win.cc @@ -13,10 +13,11 @@ // limitations under the License. #include "util/misc/capture_context_test_util.h" -#include "util/win/context_wrappers.h" -#include "base/cxx17_backports.h" +#include + #include "gtest/gtest.h" +#include "util/win/context_wrappers.h" namespace crashpad { namespace test { @@ -59,7 +60,7 @@ void SanityCheckContext(const NativeCPUContext& context) { #if defined(ARCH_CPU_X86) // fxsave doesn’t write these bytes. - for (size_t i = 464; i < base::size(context.ExtendedRegisters); ++i) { + for (size_t i = 464; i < std::size(context.ExtendedRegisters); ++i) { SCOPED_TRACE(i); EXPECT_EQ(context.ExtendedRegisters[i], 0); } @@ -69,7 +70,7 @@ void SanityCheckContext(const NativeCPUContext& context) { EXPECT_EQ(context.FltSave.MxCsr, context.MxCsr); // fxsave doesn’t write these bytes. - for (size_t i = 0; i < base::size(context.FltSave.Reserved4); ++i) { + for (size_t i = 0; i < std::size(context.FltSave.Reserved4); ++i) { SCOPED_TRACE(i); EXPECT_EQ(context.FltSave.Reserved4[i], 0); } @@ -81,7 +82,7 @@ void SanityCheckContext(const NativeCPUContext& context) { EXPECT_EQ(context.P4Home, 0u); EXPECT_EQ(context.P5Home, 0u); EXPECT_EQ(context.P6Home, 0u); - for (size_t i = 0; i < base::size(context.VectorRegister); ++i) { + for (size_t i = 0; i < std::size(context.VectorRegister); ++i) { SCOPED_TRACE(i); EXPECT_EQ(context.VectorRegister[i].Low, 0u); EXPECT_EQ(context.VectorRegister[i].High, 0u); diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/clock_posix.cc b/thirdparty/sentry-native/external/crashpad/util/misc/clock_posix.cc index a9fe8e5856..448f843102 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/clock_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/clock_posix.cc @@ -30,7 +30,7 @@ constexpr uint64_t kNanosecondsPerSecond = 1E9; namespace crashpad { -#if !defined(OS_APPLE) +#if !BUILDFLAG(IS_APPLE) uint64_t ClockMonotonicNanoseconds() { timespec now; diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/clock_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/clock_test.cc index 443d496b05..8c43d02b5e 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/clock_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/clock_test.cc @@ -17,10 +17,11 @@ #include #include +#include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" +#include "build/build_config.h" #include "gtest/gtest.h" namespace crashpad { @@ -41,17 +42,17 @@ TEST(Clock, ClockMonotonicNanoseconds) { EXPECT_GE(now, last); } -#if !defined(OS_WIN) // No SleepNanoseconds implemented on Windows. +#if !BUILDFLAG(IS_WIN) // No SleepNanoseconds implemented on Windows. // SleepNanoseconds() should sleep for at least the value of the clock’s // resolution, so the clock’s value should definitely increase after a sleep. // EXPECT_GT can be used instead of EXPECT_GE after the sleep. SleepNanoseconds(1); now = ClockMonotonicNanoseconds(); EXPECT_GT(now, start); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } -#if !defined(OS_WIN) // No SleepNanoseconds implemented on Windows. +#if !BUILDFLAG(IS_WIN) // No SleepNanoseconds implemented on Windows. void TestSleepNanoseconds(uint64_t nanoseconds) { uint64_t start = ClockMonotonicNanoseconds(); @@ -82,7 +83,7 @@ TEST(Clock, SleepNanoseconds) { static_cast(5E7), // 50 milliseconds }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const uint64_t nanoseconds = kTestData[index]; SCOPED_TRACE(base::StringPrintf( "index %zu, nanoseconds %" PRIu64, index, nanoseconds)); @@ -91,7 +92,7 @@ TEST(Clock, SleepNanoseconds) { } } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } // namespace } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/initialization_state_dcheck.h b/thirdparty/sentry-native/external/crashpad/util/misc/initialization_state_dcheck.h index e04ff234c3..659eaa8457 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/initialization_state_dcheck.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/initialization_state_dcheck.h @@ -17,8 +17,9 @@ //! \file +#include + #include "base/check_op.h" -#include "base/compiler_specific.h" #include "build/build_config.h" #include "util/misc/initialization_state.h" @@ -175,11 +176,17 @@ using InitializationStateDcheck = bool[0]; // Avoid triggering warnings by repurposing these macros when DCHECKs are // disabled. #define INITIALIZATION_STATE_SET_INITIALIZING(initialization_state_dcheck) \ - ALLOW_UNUSED_LOCAL(initialization_state_dcheck) + do { \ + std::ignore = initialization_state_dcheck; \ + } while (false) #define INITIALIZATION_STATE_SET_VALID(initialization_state_dcheck) \ - ALLOW_UNUSED_LOCAL(initialization_state_dcheck) + do { \ + std::ignore = initialization_state_dcheck; \ + } while (false) #define INITIALIZATION_STATE_DCHECK_VALID(initialization_state_dcheck) \ - ALLOW_UNUSED_LOCAL(initialization_state_dcheck) + do { \ + std::ignore = initialization_state_dcheck; \ + } while (false) #endif diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/metrics.cc b/thirdparty/sentry-native/external/crashpad/util/misc/metrics.cc index 47c9f26f31..2e8459c71d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/metrics.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/metrics.cc @@ -19,15 +19,15 @@ #include "base/numerics/safe_conversions.h" #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #define METRICS_OS_NAME "Mac" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #define METRICS_OS_NAME "Win" -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) #define METRICS_OS_NAME "Android" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #define METRICS_OS_NAME "Linux" -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #define METRICS_OS_NAME "Fuchsia" #endif @@ -115,7 +115,7 @@ void Metrics::HandlerCrashed(uint32_t exception_code) { "Crashpad.HandlerCrash.ExceptionCode." METRICS_OS_NAME, exception_code); } -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) // static void Metrics::MissingIntermediateDumpKey( const internal::IntermediateDumpKey& key) { diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/metrics.h b/thirdparty/sentry-native/external/crashpad/util/misc/metrics.h index dcd37a6aaa..c870b3a22a 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/metrics.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/metrics.h @@ -20,7 +20,7 @@ #include "build/build_config.h" #include "util/file/file_io.h" -#if defined(OS_IOS) +#if BUILDFLAG(IS_IOS) #include "util/ios/ios_intermediate_dump_format.h" #endif @@ -207,7 +207,7 @@ class Metrics { //! This is currently only reported on Windows. static void HandlerCrashed(uint32_t exception_code); -#if defined(OS_IOS) || DOXYGEN +#if BUILDFLAG(IS_IOS) || DOXYGEN //! \brief Records a missing key from an intermediate dump. static void MissingIntermediateDumpKey( const internal::IntermediateDumpKey& key); diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall.h b/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall.h index 80e584ebd5..1a5ddc68a7 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall.h @@ -20,9 +20,9 @@ #include "build/build_config.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) namespace crashpad { @@ -39,7 +39,7 @@ namespace { #endif // DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks. -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Windows also needs __declspec(guard(nocf)). #define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") __declspec(guard(nocf)) #else @@ -65,7 +65,7 @@ struct FunctorTraits { } }; -#if defined(OS_WIN) && defined(ARCH_CPU_X86) +#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_X86) template struct FunctorTraits { template @@ -74,7 +74,7 @@ struct FunctorTraits { return function(std::forward(args)...); } }; -#endif // OS_WIN && ARCH_CPU_X86 +#endif // BUILDFLAG(IS_WIN) && ARCH_CPU_X86 #if __cplusplus >= 201703L // These specializations match functions which are not explicitly declared @@ -97,7 +97,7 @@ struct FunctorTraits { } }; -#if defined(OS_WIN) && defined(ARCH_CPU_X86) +#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_X86) template struct FunctorTraits { template @@ -106,7 +106,7 @@ struct FunctorTraits { return function(std::forward(args)...); } }; -#endif // OS_WIN && ARCH_CPU_X86 +#endif // BUILDFLAG(IS_WIN) && ARCH_CPU_X86 #endif // __cplusplus >= 201703L @@ -146,14 +146,14 @@ class NoCfiIcall { explicit NoCfiIcall(PointerType function) : function_(reinterpret_cast(function)) {} -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) //! \see NoCfiIcall template ::type, FARPROC>::value>> explicit NoCfiIcall(FARPROC function) : function_(reinterpret_cast(function)) {} -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) ~NoCfiIcall() = default; diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall_test.cc index 5654a2f4a4..56a2cacfda 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/no_cfi_icall_test.cc @@ -19,7 +19,7 @@ #include "build/build_config.h" #include "gtest/gtest.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include #include "util/win/get_function.h" @@ -49,7 +49,7 @@ TEST(NoCfiIcall, SameDSOICall) { } TEST(NoCfiIcall, CrossDSOICall) { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) static const NoCfiIcall call( GET_FUNCTION_REQUIRED(L"kernel32.dll", GetCurrentProcessId)); ASSERT_TRUE(call); @@ -62,7 +62,7 @@ TEST(NoCfiIcall, CrossDSOICall) { } TEST(NoCfiIcall, Args) { -#if !defined(OS_WIN) +#if !BUILDFLAG(IS_WIN) static const NoCfiIcall call( dlsym(RTLD_NEXT, "snprintf")); ASSERT_TRUE(call); diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/paths_win.cc b/thirdparty/sentry-native/external/crashpad/util/misc/paths_win.cc index 8510ccf932..9261718c00 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/paths_win.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/paths_win.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" namespace crashpad { @@ -24,14 +25,12 @@ namespace crashpad { // static bool Paths::Executable(base::FilePath* path) { wchar_t executable_path[_MAX_PATH]; - unsigned int len = - GetModuleFileName(nullptr, - executable_path, - static_cast(base::size(executable_path))); + unsigned int len = GetModuleFileName( + nullptr, executable_path, static_cast(std::size(executable_path))); if (len == 0) { PLOG(ERROR) << "GetModuleFileName"; return false; - } else if (len >= base::size(executable_path)) { + } else if (len >= std::size(executable_path)) { LOG(ERROR) << "GetModuleFileName"; return false; } diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/random_string_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/random_string_test.cc index fac830f358..15b3a4140e 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/random_string_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/random_string_test.cc @@ -16,9 +16,9 @@ #include +#include #include -#include "base/cxx17_backports.h" #include "gtest/gtest.h" namespace crashpad { @@ -33,7 +33,7 @@ TEST(RandomString, RandomString) { const std::string allowed_characters("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); size_t character_counts[26] = {}; - ASSERT_EQ(allowed_characters.size(), base::size(character_counts)); + ASSERT_EQ(allowed_characters.size(), std::size(character_counts)); std::set strings; @@ -61,7 +61,7 @@ TEST(RandomString, RandomString) { // Make sure every character appears at least once. It is possible, but // extremely unlikely, for a character to not appear at all. for (size_t character_index = 0; - character_index < base::size(character_counts); + character_index < std::size(character_counts); ++character_index) { EXPECT_GT(character_counts[character_index], 0u) << allowed_characters[character_index]; diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/scoped_forbid_return_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/scoped_forbid_return_test.cc index 06cb5494b4..b728cf4dc7 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/scoped_forbid_return_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/scoped_forbid_return_test.cc @@ -14,7 +14,6 @@ #include "util/misc/scoped_forbid_return.h" -#include "base/compiler_specific.h" #include "gtest/gtest.h" #include "test/gtest_death.h" @@ -43,13 +42,12 @@ void ScopedForbidReturnHelper(ForbidReturnType type) { } } -constexpr char kForbiddenMessage[] = "attempt to exit scope forbidden"; +// kForbiddenMessage may appear to be unused if ASSERT_DEATH_CHECK() throws it +// away. +[[maybe_unused]] constexpr char kForbiddenMessage[] = + "attempt to exit scope forbidden"; TEST(ScopedForbidReturnDeathTest, Default) { - // kForbiddenMessage may appear to be unused if ASSERT_DEATH_CHECK() throws it - // away. - ALLOW_UNUSED_LOCAL(kForbiddenMessage); - ASSERT_DEATH_CHECK(ScopedForbidReturnHelper(kForbidReturnDefault), kForbiddenMessage); } diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/time.h b/thirdparty/sentry-native/external/crashpad/util/misc/time.h index dc992bdcce..d695f77d28 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/time.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/time.h @@ -21,7 +21,7 @@ #include "build/build_config.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include #endif @@ -45,7 +45,7 @@ bool TimespecToTimeval(const timespec& ts, timeval* tv); //! \brief Convert the timeval \a tv to a timespec \a ts. void TimevalToTimespec(const timeval& tv, timespec* ts); -#if defined(OS_WIN) || DOXYGEN +#if BUILDFLAG(IS_WIN) || DOXYGEN //! \brief Convert a `timespec` to a Windows `FILETIME`, converting from POSIX //! epoch to Windows epoch. @@ -67,15 +67,17 @@ timeval FiletimeToTimevalInterval(const FILETIME& filetime); //! UTC. void GetTimeOfDay(timeval* tv); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || DOXYGEN +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ + DOXYGEN //! \brief Get the kernel boot time. Subsequent calls to this function may //! return different results due to the system clock being changed or //! imprecision in measuring the boot time. //! \return `true` on success. Otherwise, `false` with a message logged. bool GetBootTime(timespec* ts); -#endif // OS_LINUX || OS_CHROMEOS || OS_ANDROID || DOXYGEN +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) || DOXYGEN } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/time_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/time_test.cc index 87e28faae3..d3ae956639 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/time_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/time_test.cc @@ -16,6 +16,7 @@ #include +#include "build/build_config.h" #include "gtest/gtest.h" namespace crashpad { @@ -71,7 +72,7 @@ TEST(Time, TimeConversions) { EXPECT_TRUE(TimespecToTimeval(kEndOfTime, &end_of_timeval)); } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) constexpr uint64_t kBirthdateFiletimeIntervals = 130512285140000324; FILETIME filetime_birthdate; filetime_birthdate.dwLowDateTime = 0xffffffff & kBirthdateFiletimeIntervals; @@ -112,10 +113,10 @@ TEST(Time, TimeConversions) { elapsed_timeval = FiletimeToTimevalInterval(elapsed_filetime); EXPECT_EQ(elapsed_timeval.tv_sec, 429); EXPECT_EQ(elapsed_timeval.tv_usec, 496729); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) TEST(Time, GetTimeOfDay) { timeval t; @@ -125,7 +126,7 @@ TEST(Time, GetTimeOfDay) { EXPECT_LT(approx_now - 100, t.tv_sec); } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } // namespace } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/uuid.cc b/thirdparty/sentry-native/external/crashpad/util/misc/uuid.cc index 4ed3831175..6ad7e67277 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/uuid.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/uuid.cc @@ -29,10 +29,11 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/sys_byteorder.h" +#include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) namespace crashpad { @@ -87,20 +88,20 @@ bool UUID::InitializeFromString(const base::StringPiece& string) { return true; } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) bool UUID::InitializeFromString(const base::WStringPiece& string) { return InitializeFromString(WideToUTF8(string)); } #endif bool UUID::InitializeWithNew() { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) uuid_t uuid; uuid_generate(uuid); InitializeFromBytes(uuid); return true; -#elif defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ - defined(OS_ANDROID) || defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) // Linux, Android, and Fuchsia do not provide a UUID generator in a // widely-available system library. On Linux and Android, uuid_generate() // from libuuid is not available everywhere. @@ -115,10 +116,10 @@ bool UUID::InitializeWithNew() { return true; #else #error Port. -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) void UUID::InitializeFromSystemUUID(const ::UUID* system_uuid) { static_assert(sizeof(::UUID) == sizeof(UUID), "unexpected system uuid size"); @@ -126,7 +127,7 @@ void UUID::InitializeFromSystemUUID(const ::UUID* system_uuid) { "unexpected system uuid layout"); memcpy(this, system_uuid, sizeof(*this)); } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) std::string UUID::ToString() const { return base::StringPrintf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", @@ -143,10 +144,10 @@ std::string UUID::ToString() const { data_5[5]); } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) std::wstring UUID::ToWString() const { return base::UTF8ToWide(ToString()); } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/uuid.h b/thirdparty/sentry-native/external/crashpad/util/misc/uuid.h index 7e504a2253..574f01dc20 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/uuid.h +++ b/thirdparty/sentry-native/external/crashpad/util/misc/uuid.h @@ -22,7 +22,7 @@ #include "base/strings/string_piece.h" #include "build/build_config.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include #endif @@ -63,9 +63,9 @@ struct UUID { //! been initialized with the data. `false` if the string could not be //! parsed, with the object state untouched. bool InitializeFromString(const base::StringPiece& string); -#if defined(OS_WIN) || DOXYGEN +#if BUILDFLAG(IS_WIN) || DOXYGEN bool InitializeFromString(const base::WStringPiece& string); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) //! \brief Initializes the %UUID using a standard system facility to generate //! the value. @@ -74,22 +74,22 @@ struct UUID { //! with a message logged. bool InitializeWithNew(); -#if defined(OS_WIN) || DOXYGEN +#if BUILDFLAG(IS_WIN) || DOXYGEN //! \brief Initializes the %UUID from a system `UUID` or `GUID` structure. //! //! \param[in] system_uuid A system `UUID` or `GUID` structure. void InitializeFromSystemUUID(const ::UUID* system_uuid); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) //! \brief Formats the %UUID per RFC 4122 §3. //! //! \return A string of the form `"00112233-4455-6677-8899-aabbccddeeff"`. std::string ToString() const; -#if defined(OS_WIN) || DOXYGEN +#if BUILDFLAG(IS_WIN) || DOXYGEN //! \brief The same as ToString, but returned as a wstring. std::wstring ToWString() const; -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) // These fields are laid out according to RFC 4122 §4.1.2. uint32_t data_1; diff --git a/thirdparty/sentry-native/external/crashpad/util/misc/uuid_test.cc b/thirdparty/sentry-native/external/crashpad/util/misc/uuid_test.cc index 28d7ce4bd6..6c036633d7 100644 --- a/thirdparty/sentry-native/external/crashpad/util/misc/uuid_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/misc/uuid_test.cc @@ -17,12 +17,13 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/scoped_generic.h" #include "base/strings/stringprintf.h" +#include "build/build_config.h" #include "gtest/gtest.h" namespace crashpad { @@ -109,13 +110,13 @@ TEST(UUID, UUID) { EXPECT_NE(uuid, uuid_2); EXPECT_LT(uuid_2, uuid); --uuid.data_3; - for (size_t index = 0; index < base::size(uuid.data_4); ++index) { + for (size_t index = 0; index < std::size(uuid.data_4); ++index) { ++uuid.data_4[index]; EXPECT_NE(uuid, uuid_2); EXPECT_LT(uuid_2, uuid); --uuid.data_4[index]; } - for (size_t index = 0; index < base::size(uuid.data_5); ++index) { + for (size_t index = 0; index < std::size(uuid.data_5); ++index) { ++uuid.data_5[index]; EXPECT_NE(uuid, uuid_2); EXPECT_LT(uuid_2, uuid); @@ -206,7 +207,7 @@ TEST(UUID, FromString) { uuid_zero.InitializeToZero(); const std::string empty_uuid = uuid_zero.ToString(); - for (size_t index = 0; index < base::size(kCases); ++index) { + for (size_t index = 0; index < std::size(kCases); ++index) { const TestCase& test_case = kCases[index]; SCOPED_TRACE(base::StringPrintf( "index %" PRIuS ": %s", index, test_case.uuid_string)); @@ -231,7 +232,7 @@ TEST(UUID, FromString) { uuid.InitializeFromString("5762C15D-50b5-4171-a2e9-7429C9EC6CAB"); EXPECT_EQ(uuid.ToString(), "5762c15d-50b5-4171-a2e9-7429c9ec6cab"); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Test accepting a StringPiece16 via L"" literals on Windows. EXPECT_TRUE( uuid.InitializeFromString(L"F32E5BDC-2681-4C73-A4E6-444FFD44B444")); @@ -240,10 +241,10 @@ TEST(UUID, FromString) { EXPECT_TRUE( uuid.InitializeFromString(L"5762C15D-50b5-4171-a2e9-5555C5EC5CAB")); EXPECT_EQ(uuid.ToString(), "5762c15d-50b5-4171-a2e9-5555c5ec5cab"); -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) TEST(UUID, FromSystem) { ::GUID system_uuid; @@ -268,7 +269,7 @@ TEST(UUID, FromSystem) { EXPECT_EQ(uuid.ToWString(), reinterpret_cast(system_string)); } -#endif // OS_WIN +#endif // BUILDFLAG(IS_WIN) } // namespace } // namespace test diff --git a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_socket.cc b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_socket.cc index a9654942ae..069c44cad2 100644 --- a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_socket.cc +++ b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_socket.cc @@ -12,23 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "util/net/http_transport.h" - #include #include #include #include #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/posix/eintr_wrapper.h" #include "base/scoped_generic.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" +#include "build/build_config.h" #include "util/file/file_io.h" #include "util/net/http_body.h" +#include "util/net/http_transport.h" #include "util/net/url.h" #include "util/stdlib/string_number_conversion.h" #include "util/string/split_string.h" @@ -127,13 +128,13 @@ class SSLStream : public Stream { return false; } } else { -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) if (SSL_CTX_load_verify_locations( ctx_.get(), nullptr, "/etc/ssl/certs") <= 0) { LOG(ERROR) << "SSL_CTX_load_verify_locations"; return false; } -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) if (SSL_CTX_load_verify_locations( ctx_.get(), "/config/ssl/cert.pem", nullptr) <= 0) { LOG(ERROR) << "SSL_CTX_load_verify_locations"; @@ -374,7 +375,7 @@ bool WriteRequest(Stream* stream, FileOperationResult data_bytes; do { - constexpr size_t kCRLFSize = base::size(kCRLFTerminator) - 1; + constexpr size_t kCRLFSize = std::size(kCRLFTerminator) - 1; struct __attribute__((packed)) { char size[8]; char crlf[2]; diff --git a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test.cc b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test.cc index cf53450ee4..6c13bfad0f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test.cc @@ -41,7 +41,7 @@ namespace crashpad { namespace test { namespace { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) std::string ToUTF8IfWin(const std::wstring& x) { return base::WideToUTF8(x); } @@ -70,7 +70,7 @@ class HTTPTransportTestFixture : public MultiprocessExec { scheme_and_host_() { base::FilePath server_path = TestPaths::Executable().DirName().Append( FILE_PATH_LITERAL("http_transport_test_server") -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) FILE_PATH_LITERAL(".exe") #endif ); @@ -361,7 +361,7 @@ TEST_P(HTTPTransport, Upload33k_LengthUnknown) { } // This should be on for Fuchsia, but DX-382. Debug and re-enabled. -#if defined(CRASHPAD_USE_BORINGSSL) && !defined(OS_FUCHSIA) +#if defined(CRASHPAD_USE_BORINGSSL) && !BUILDFLAG(IS_FUCHSIA) // The test server requires BoringSSL or OpenSSL, so https in tests can only be // enabled where that's readily available. Additionally on Linux, the bots fail // lacking libcrypto.so.1.1, so disabled there for now. On Mac, they could also diff --git a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test_server.cc b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test_server.cc index a3bcc6a5ab..4e30cbdc86 100644 --- a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test_server.cc +++ b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_test_server.cc @@ -122,13 +122,13 @@ int HttpTransportTestServerMain(int argc, char* argv[]) { } // namespace } // namespace crashpad -#if defined(OS_POSIX) || defined(OS_FUCHSIA) +#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) int main(int argc, char* argv[]) { return crashpad::HttpTransportTestServerMain(argc, argv); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) int wmain(int argc, wchar_t* argv[]) { return crashpad::ToolSupport::Wmain( argc, argv, crashpad::HttpTransportTestServerMain); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) diff --git a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_win.cc b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_win.cc index cb04c2e930..117b82696c 100644 --- a/thirdparty/sentry-native/external/crashpad/util/net/http_transport_win.cc +++ b/thirdparty/sentry-native/external/crashpad/util/net/http_transport_win.cc @@ -22,7 +22,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/scoped_generic.h" @@ -96,7 +97,7 @@ std::string WinHttpMessage(const char* extra) { error_code, 0, msgbuf, - static_cast(base::size(msgbuf)), + static_cast(std::size(msgbuf)), nullptr); if (!len) { return base::StringPrintf("%s: error 0x%lx while retrieving error 0x%lx", diff --git a/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range.cc b/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range.cc index 4ba7ff3900..1f5abc27e9 100644 --- a/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range.cc +++ b/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range.cc @@ -17,16 +17,17 @@ #include "base/check_op.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" +#include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include "util/win/address_types.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "util/linux/address_types.h" -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #include -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) namespace crashpad { namespace internal { @@ -126,15 +127,15 @@ std::string CheckedAddressRangeGeneric::AsString() const { } // Explicit instantiations for the cases we use. -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) template class CheckedAddressRangeGeneric; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) template class CheckedAddressRangeGeneric; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) template class CheckedAddressRangeGeneric; -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) template class CheckedAddressRangeGeneric; -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) } // namespace internal } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range_test.cc b/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range_test.cc index aa700e0a0d..1a4d93f7a6 100644 --- a/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/numeric/checked_address_range_test.cc @@ -16,9 +16,9 @@ #include +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" @@ -119,7 +119,7 @@ TEST(CheckedAddressRange, IsValid) { {0xffffffffffffffff, 1, kInvalid}, }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf("index %" PRIuS ", base 0x%" PRIx64 ", size 0x%" PRIx64, @@ -170,7 +170,7 @@ TEST(CheckedAddressRange, ContainsValue) { CheckedAddressRange parent_range_32(false, 0x2000, 0x1000); ASSERT_TRUE(parent_range_32.IsValid()); - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf( "index %" PRIuS ", value 0x%" PRIx64, index, testcase.value)); @@ -227,7 +227,7 @@ TEST(CheckedAddressRange, ContainsRange) { CheckedAddressRange parent_range_32(false, 0x2000, 0x1000); ASSERT_TRUE(parent_range_32.IsValid()); - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf("index %" PRIuS ", base 0x%" PRIx64 ", size 0x%" PRIx64, diff --git a/thirdparty/sentry-native/external/crashpad/util/numeric/checked_range_test.cc b/thirdparty/sentry-native/external/crashpad/util/numeric/checked_range_test.cc index ad734ba342..b4e0426163 100644 --- a/thirdparty/sentry-native/external/crashpad/util/numeric/checked_range_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/numeric/checked_range_test.cc @@ -17,9 +17,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -78,7 +78,7 @@ TEST(CheckedRange, IsValid) { {0xffffffff, 0xffffffff, false}, }; - for (size_t index = 0; index < base::size(kUnsignedTestData); ++index) { + for (size_t index = 0; index < std::size(kUnsignedTestData); ++index) { const auto& testcase = kUnsignedTestData[index]; SCOPED_TRACE(base::StringPrintf("unsigned index %" PRIuS ", base 0x%x, size 0x%x", @@ -140,7 +140,7 @@ TEST(CheckedRange, IsValid) { {-1, 0xffffffff, false}, }; - for (size_t index = 0; index < base::size(kSignedTestData); ++index) { + for (size_t index = 0; index < std::size(kSignedTestData); ++index) { const auto& testcase = kSignedTestData[index]; SCOPED_TRACE(base::StringPrintf("signed index %" PRIuS ", base 0x%x, size 0x%x", @@ -186,7 +186,7 @@ TEST(CheckedRange, ContainsValue) { CheckedRange parent_range(0x2000, 0x1000); ASSERT_TRUE(parent_range.IsValid()); - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf( "index %" PRIuS ", value 0x%x", index, testcase.value)); @@ -234,7 +234,7 @@ TEST(CheckedRange, ContainsRange) { CheckedRange parent_range(0x2000, 0x1000); ASSERT_TRUE(parent_range.IsValid()); - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf("index %" PRIuS ", base 0x%x, size 0x%x", index, @@ -287,7 +287,7 @@ TEST(CheckedRange, OverlapsRange) { CheckedRange first_range(0x2000, 0x1000); ASSERT_TRUE(first_range.IsValid()); - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto& testcase = kTestData[index]; SCOPED_TRACE(base::StringPrintf("index %" PRIuS ", base 0x%x, size 0x%x", index, diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/close_multiple.cc b/thirdparty/sentry-native/external/crashpad/util/posix/close_multiple.cc index 2e0ad1056e..4bafd474b8 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/close_multiple.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/close_multiple.cc @@ -21,8 +21,8 @@ #include #include +#include -#include "base/cxx17_backports.h" #include "base/files/scoped_file.h" #include "base/logging.h" #include "base/posix/eintr_wrapper.h" @@ -31,7 +31,7 @@ #include "util/file/directory_reader.h" #include "util/misc/implicit_cast.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include #endif @@ -51,7 +51,7 @@ namespace { void CloseNowOrOnExec(int fd, bool ebadf_ok) { int rv; -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) // Try to set close-on-exec, to avoid attempting to close a guarded FD with // a close guard set. rv = fcntl(fd, F_SETFD, FD_CLOEXEC); @@ -72,9 +72,9 @@ void CloseNowOrOnExec(int fd, bool ebadf_ok) { // This is an advantage over looping over all possible file descriptors, because // no attempt needs to be made to close file descriptors that are not open. bool CloseMultipleNowOrOnExecUsingFDDir(int min_fd, int preserve_fd) { -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) static constexpr char kFDDir[] = "/dev/fd"; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) static constexpr char kFDDir[] = "/proc/self/fd"; #endif @@ -128,14 +128,15 @@ void CloseMultipleNowOrOnExec(int fd, int preserve_fd) { // bionic/libc/bionic/ndk_cruft.cpp getdtablesize(). int max_fd = implicit_cast(sysconf(_SC_OPEN_MAX)); -#if !defined(OS_ANDROID) +#if !BUILDFLAG(IS_ANDROID) // getdtablesize() was removed effective Android 5.0.0 (API 21). Since it // returns the same thing as the sysconf() above, just skip it. See // https://android.googlesource.com/platform/bionic/+/462abab12b074c62c0999859e65d5a32ebb41951. max_fd = std::max(max_fd, getdtablesize()); #endif -#if !(defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)) || \ +#if !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_ANDROID)) || \ defined(OPEN_MAX) // Linux does not provide OPEN_MAX. See // https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/include/linux/limits.h?id=77293034696e3e0b6c8b8fc1f96be091104b3d2b. @@ -147,14 +148,14 @@ void CloseMultipleNowOrOnExec(int fd, int preserve_fd) { // while the system is running, but it’s still a better upper bound than the // current RLIMIT_NOFILE value. -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) // See 10.11.6 xnu-3248.60.10/bsd/kern/kern_resource.c maxfilesperproc, // referenced by dosetrlimit(). int oid[] = {CTL_KERN, KERN_MAXFILESPERPROC}; int maxfilesperproc; size_t maxfilesperproc_size = sizeof(maxfilesperproc); if (sysctl(oid, - base::size(oid), + std::size(oid), &maxfilesperproc, &maxfilesperproc_size, nullptr, @@ -163,7 +164,7 @@ void CloseMultipleNowOrOnExec(int fd, int preserve_fd) { } else { PLOG(WARNING) << "sysctl"; } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // See linux-4.4.27/fs/file.c sysctl_nr_open, referenced by kernel/sys.c // do_prlimit() and kernel/sysctl.c fs_table. Inability to open this file is // not considered an error, because /proc may not be available or usable. diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/close_stdio.cc b/thirdparty/sentry-native/external/crashpad/util/posix/close_stdio.cc index a8efc81c19..37c40a4a0a 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/close_stdio.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/close_stdio.cc @@ -18,9 +18,10 @@ #include #include +#include + #include "base/check.h" #include "base/files/scoped_file.h" -#include "base/ignore_result.h" #include "base/posix/eintr_wrapper.h" namespace crashpad { @@ -32,7 +33,7 @@ void CloseStdioStream(int desired_fd, int oflag) { HANDLE_EINTR(open(_PATH_DEVNULL, oflag | O_NOCTTY | O_CLOEXEC))); if (fd == desired_fd) { // Weird, but play along. - ignore_result(fd.release()); + std::ignore = fd.release(); } else { PCHECK(fd.get() >= 0) << "open"; PCHECK(HANDLE_EINTR(dup2(fd.get(), desired_fd)) != -1) << "dup2"; diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/drop_privileges.cc b/thirdparty/sentry-native/external/crashpad/util/posix/drop_privileges.cc index 75650d5a68..82aa1eba1d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/drop_privileges.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/drop_privileges.cc @@ -25,7 +25,7 @@ void DropPrivileges() { gid_t gid = getgid(); uid_t uid = getuid(); -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) // Based on the POSIX.1-2008 2013 edition documentation for setreuid() and // setregid(), setreuid() and setregid() alone should be sufficient to drop // privileges. The standard specifies that the saved ID should be set to the @@ -73,7 +73,7 @@ void DropPrivileges() { CHECK_EQ(setegid(egid), -1); } } -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) PCHECK(setresgid(gid, gid, gid) == 0) << "setresgid"; PCHECK(setresuid(uid, uid, uid) == 0) << "setresuid"; diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/process_info.h b/thirdparty/sentry-native/external/crashpad/util/posix/process_info.h index 7a58788dfa..d3f1c992fc 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/process_info.h +++ b/thirdparty/sentry-native/external/crashpad/util/posix/process_info.h @@ -27,12 +27,12 @@ #include "util/misc/initialization_state.h" #include "util/misc/initialization_state_dcheck.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include #include #endif -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "util/linux/ptrace_connection.h" #endif @@ -47,7 +47,8 @@ class ProcessInfo { ~ProcessInfo(); -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || DOXYGEN +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ + DOXYGEN //! \brief Initializes this object with information about the process whose ID //! is \a pid using a PtraceConnection \a connection. //! @@ -62,9 +63,10 @@ class ProcessInfo { //! //! \return `true` on success, `false` on failure with a message logged. bool InitializeWithPtrace(PtraceConnection* connection); -#endif // OS_LINUX || OS_CHROMEOS || OS_ANDROID || DOXYGEN +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) || DOXYGEN -#if defined(OS_APPLE) || DOXYGEN +#if BUILDFLAG(IS_APPLE) || DOXYGEN //! \brief Initializes this object with information about the process whose ID //! is \a pid. //! @@ -169,9 +171,9 @@ class ProcessInfo { bool Arguments(std::vector* argv) const; private: -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) kinfo_proc kern_proc_info_; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // Some members are marked mutable so that they can be lazily initialized by // const methods. These are always InitializationState-protected so that // multiple successive calls will always produce the same return value and out diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/process_info_mac.cc b/thirdparty/sentry-native/external/crashpad/util/posix/process_info_mac.cc index 47d0ff4ae1..de056dd5ae 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/process_info_mac.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/process_info_mac.cc @@ -16,7 +16,8 @@ #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "base/mac/mach_logging.h" @@ -33,7 +34,7 @@ bool ProcessInfo::InitializeWithPid(pid_t pid) { int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; size_t len = sizeof(kern_proc_info_); - if (sysctl(mib, base::size(mib), &kern_proc_info_, &len, nullptr, 0) != 0) { + if (sysctl(mib, std::size(mib), &kern_proc_info_, &len, nullptr, 0) != 0) { PLOG(ERROR) << "sysctl for pid " << pid; return false; } @@ -112,7 +113,7 @@ std::set ProcessInfo::SupplementaryGroups() const { const short ngroups = kern_proc_info_.kp_eproc.e_ucred.cr_ngroups; DCHECK_GE(ngroups, 0); DCHECK_LE(static_cast(ngroups), - base::size(kern_proc_info_.kp_eproc.e_ucred.cr_groups)); + std::size(kern_proc_info_.kp_eproc.e_ucred.cr_groups)); const gid_t* groups = kern_proc_info_.kp_eproc.e_ucred.cr_groups; return std::set(&groups[0], &groups[ngroups]); @@ -169,7 +170,7 @@ bool ProcessInfo::Arguments(std::vector* argv) const { do { int mib[] = {CTL_KERN, KERN_PROCARGS2, pid}; int rv = - sysctl(mib, base::size(mib), nullptr, &args_size_estimate, nullptr, 0); + sysctl(mib, std::size(mib), nullptr, &args_size_estimate, nullptr, 0); if (rv != 0) { PLOG(ERROR) << "sysctl (size) for pid " << pid; return false; @@ -184,7 +185,7 @@ bool ProcessInfo::Arguments(std::vector* argv) const { // for the reasons described above.) args_size = args_size_estimate + 32; args.resize(args_size); - rv = sysctl(mib, base::size(mib), &args[0], &args_size, nullptr, 0); + rv = sysctl(mib, std::size(mib), &args[0], &args_size, nullptr, 0); if (rv != 0) { PLOG(ERROR) << "sysctl (data) for pid " << pid; return false; diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/process_info_test.cc b/thirdparty/sentry-native/external/crashpad/util/posix/process_info_test.cc index 1d9b065743..8456b72c49 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/process_info_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/process_info_test.cc @@ -33,7 +33,7 @@ #include "util/misc/implicit_cast.h" #include "util/string/split_string.h" -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "util/linux/direct_ptrace_connection.h" #include "test/linux/fake_ptrace_connection.h" #endif @@ -98,7 +98,7 @@ void TestProcessSelfOrClone(const ProcessInfo& process_info) { const std::vector& expect_argv = GetMainArguments(); -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) // Prior to Linux 4.2, the kernel only allowed reading a single page from // /proc//cmdline, causing any further arguments to be truncated. Disable // testing arguments in this case. @@ -124,7 +124,8 @@ void TestProcessSelfOrClone(const ProcessInfo& process_info) { argv_size > static_cast(getpagesize())) { return; } -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) std::vector argv; ASSERT_TRUE(process_info.Arguments(&argv)); @@ -161,18 +162,19 @@ void TestSelfProcess(const ProcessInfo& process_info) { TEST(ProcessInfo, Self) { ProcessInfo process_info; -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(getpid())); ASSERT_TRUE(process_info.InitializeWithPtrace(&connection)); #else ASSERT_TRUE(process_info.InitializeWithPid(getpid())); -#endif // OS_LINUX || OS_ANDROID || OS_CHROMEOS +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_CHROMEOS) TestSelfProcess(process_info); } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) TEST(ProcessInfo, SelfTask) { ProcessInfo process_info; ASSERT_TRUE(process_info.InitializeWithTask(mach_task_self())); @@ -184,7 +186,7 @@ TEST(ProcessInfo, Pid1) { // PID 1 is expected to be init or the system’s equivalent. This tests reading // information about another process. ProcessInfo process_info; -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(1)); ASSERT_TRUE(process_info.InitializeWithPtrace(&connection)); @@ -216,7 +218,7 @@ class ProcessInfoForkedTest : public Multiprocess { void MultiprocessParent() override { const pid_t pid = ChildPID(); -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) DirectPtraceConnection connection; ASSERT_TRUE(connection.Initialize(pid)); @@ -225,7 +227,8 @@ class ProcessInfoForkedTest : public Multiprocess { #else ProcessInfo process_info; ASSERT_TRUE(process_info.InitializeWithPid(pid)); -#endif // OS_LINUX || OS_CHROMEOS || OS_ANDROID +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || + // BUILDFLAG(IS_ANDROID) EXPECT_EQ(process_info.ProcessID(), pid); EXPECT_EQ(process_info.ParentProcessID(), getpid()); diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap.cc b/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap.cc index 4438393173..1d28581e38 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap.cc @@ -28,7 +28,7 @@ // TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is // complete. -#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) #include "third_party/lss/lss.h" #endif @@ -36,7 +36,7 @@ namespace { // TODO(crbug.com/1052397): Revisit once build flag switch of lacros-chrome is // complete. -#if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) void* CallMmap(void* addr, size_t len, int prot, diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap_test.cc b/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap_test.cc index f8307cc698..c171b81d0a 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/scoped_mmap_test.cc @@ -18,7 +18,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/numerics/safe_conversions.h" #include "base/rand_util.h" #include "base/strings/stringprintf.h" @@ -152,7 +153,7 @@ TEST(ScopedMmapDeathTest, ResetAddrLen_Shrink) { EXPECT_EQ(mapping.len(), 3 * kPageSize); TestCookie cookies[3]; - for (size_t index = 0; index < base::size(cookies); ++index) { + for (size_t index = 0; index < std::size(cookies); ++index) { cookies[index].SetUp(reinterpret_cast( mapping.addr_as() + index * kPageSize)); } @@ -187,7 +188,7 @@ TEST(ScopedMmap, ResetAddrLen_Grow) { EXPECT_EQ(mapping.len(), kPageSize); TestCookie cookies[3]; - for (size_t index = 0; index < base::size(cookies); ++index) { + for (size_t index = 0; index < std::size(cookies); ++index) { cookies[index].SetUp(reinterpret_cast( reinterpret_cast(pages) + index * kPageSize)); } @@ -198,7 +199,7 @@ TEST(ScopedMmap, ResetAddrLen_Grow) { EXPECT_EQ(mapping.addr(), pages); EXPECT_EQ(mapping.len(), 3 * kPageSize); - for (size_t index = 0; index < base::size(cookies); ++index) { + for (size_t index = 0; index < std::size(cookies); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); EXPECT_EQ(cookies[index].Observed(), cookies[index].Expected()); } @@ -219,7 +220,7 @@ TEST(ScopedMmapDeathTest, ResetAddrLen_MoveDownAndGrow) { EXPECT_EQ(mapping.len(), kPageSize); TestCookie cookies[3]; - for (size_t index = 0; index < base::size(cookies); ++index) { + for (size_t index = 0; index < std::size(cookies); ++index) { cookies[index].SetUp(reinterpret_cast( reinterpret_cast(pages) + index * kPageSize)); } @@ -250,7 +251,7 @@ TEST(ScopedMmapDeathTest, ResetAddrLen_MoveUpAndShrink) { EXPECT_EQ(mapping.len(), 2 * kPageSize); TestCookie cookies[3]; - for (size_t index = 0; index < base::size(cookies); ++index) { + for (size_t index = 0; index < std::size(cookies); ++index) { cookies[index].SetUp(reinterpret_cast( reinterpret_cast(pages) + index * kPageSize)); } @@ -348,7 +349,7 @@ TEST(ScopedMmapDeathTest, NotIntegralNumberOfPages) { EXPECT_EQ(mapping.len(), 2 * kPageSize); TestCookie two_cookies[2]; - for (size_t index = 0; index < base::size(two_cookies); ++index) { + for (size_t index = 0; index < std::size(two_cookies); ++index) { two_cookies[index].SetUp(reinterpret_cast( mapping.addr_as() + index * kPageSize)); } @@ -368,7 +369,7 @@ TEST(ScopedMmapDeathTest, NotIntegralNumberOfPages) { EXPECT_NE(mapping.addr(), MAP_FAILED); EXPECT_EQ(mapping.len(), 2 * kPageSize); - for (size_t index = 0; index < base::size(two_cookies); ++index) { + for (size_t index = 0; index < std::size(two_cookies); ++index) { two_cookies[index].SetUp(reinterpret_cast( mapping.addr_as() + index * kPageSize)); } diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/signals.cc b/thirdparty/sentry-native/external/crashpad/util/posix/signals.cc index cd8b87d868..f53ceb2a2f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/signals.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/signals.cc @@ -16,13 +16,14 @@ #include +#include #include #include "base/check_op.h" -#include "base/cxx17_backports.h" #include "base/logging.h" +#include "build/build_config.h" -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) #include #endif @@ -50,10 +51,10 @@ constexpr int kCrashSignals[] = { #if defined(SIGEMT) SIGEMT, #endif // defined(SIGEMT) -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) SIGXCPU, SIGXFSZ, -#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) }; // These are the non-core-generating but terminating signals. @@ -86,13 +87,13 @@ constexpr int kTerminateSignals[] = { #if defined(SIGSTKFLT) SIGSTKFLT, #endif // defined(SIGSTKFLT) -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) SIGXCPU, SIGXFSZ, -#endif // defined(OS_APPLE) -#if defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) SIGIO, -#endif // defined(OS_LINUX) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) }; bool InstallHandlers(const std::vector& signals, @@ -129,7 +130,7 @@ bool IsSignalInSet(int sig, const int* set, size_t set_size) { struct sigaction* Signals::OldActions::ActionForSignal(int sig) { DCHECK_GT(sig, 0); const size_t slot = sig - 1; - DCHECK_LT(slot, base::size(actions_)); + DCHECK_LT(slot, std::size(actions_)); return &actions_[slot]; } @@ -164,8 +165,7 @@ bool Signals::InstallCrashHandlers(Handler handler, OldActions* old_actions, const std::set* unhandled_signals) { return InstallHandlers( - std::vector(kCrashSignals, - kCrashSignals + base::size(kCrashSignals)), + std::vector(kCrashSignals, kCrashSignals + std::size(kCrashSignals)), handler, flags, old_actions, @@ -178,7 +178,7 @@ bool Signals::InstallTerminateHandlers(Handler handler, OldActions* old_actions) { return InstallHandlers( std::vector(kTerminateSignals, - kTerminateSignals + base::size(kTerminateSignals)), + kTerminateSignals + std::size(kTerminateSignals)), handler, flags, old_actions, @@ -289,7 +289,7 @@ void Signals::RestoreHandlerAndReraiseSignalOnReturn( // signals that do not re-raise autonomously), such as signals delivered via // kill() and asynchronous hardware faults such as SEGV_MTEAERR, which would // otherwise be lost when re-raising the signal via raise(). -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) int retval = syscall(SYS_rt_tgsigqueueinfo, getpid(), syscall(SYS_gettid), @@ -307,7 +307,8 @@ void Signals::RestoreHandlerAndReraiseSignalOnReturn( if (errno != EPERM) { _exit(kFailureExitCode); } -#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_CHROMEOS) // Explicitly re-raise the signal if it will not re-raise itself. Because // signal handlers normally execute with their signal blocked, this raise() @@ -322,12 +323,12 @@ void Signals::RestoreHandlerAndReraiseSignalOnReturn( // static bool Signals::IsCrashSignal(int sig) { - return IsSignalInSet(sig, kCrashSignals, base::size(kCrashSignals)); + return IsSignalInSet(sig, kCrashSignals, std::size(kCrashSignals)); } // static bool Signals::IsTerminateSignal(int sig) { - return IsSignalInSet(sig, kTerminateSignals, base::size(kTerminateSignals)); + return IsSignalInSet(sig, kTerminateSignals, std::size(kTerminateSignals)); } } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/signals_test.cc b/thirdparty/sentry-native/external/crashpad/util/posix/signals_test.cc index cb29ff50b3..9ccd4c5926 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/signals_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/signals_test.cc @@ -20,10 +20,9 @@ #include #include +#include #include -#include "base/compiler_specific.h" -#include "base/cxx17_backports.h" #include "base/files/scoped_file.h" #include "base/logging.h" #include "base/strings/stringprintf.h" @@ -34,7 +33,7 @@ #include "test/scoped_temp_dir.h" #include "util/posix/scoped_mmap.h" -#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS) #include #include @@ -58,7 +57,8 @@ #define PR_MTE_TCF_ASYNC (1UL << 2) #endif #endif // defined(ARCH_CPU_ARM64) -#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_CHROMEOS) namespace crashpad { namespace test { @@ -90,15 +90,16 @@ std::vector TestableSignals() { #endif // defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARMEL) signals.push_back({SIGPIPE, 0}); signals.push_back({SIGSEGV, 0}); -#if (defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)) && \ +#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_CHROMEOS)) && \ defined(ARCH_CPU_ARM64) if (getauxval(AT_HWCAP2) & HWCAP2_MTE) { signals.push_back({SIGSEGV, SEGV_MTEAERR}); } #endif -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) signals.push_back({SIGSYS, 0}); -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM64) signals.push_back({SIGTRAP, 0}); #endif // defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM64) @@ -163,10 +164,9 @@ void CauseSignal(int sig, int code) { * Arm architecture. */ #if defined(ARCH_CPU_X86_FAMILY) - volatile int a = 42; + [[maybe_unused]] volatile int a = 42; volatile int b = 0; - a /= b; - ALLOW_UNUSED_LOCAL(a); + a = a / b; #endif break; } @@ -209,7 +209,8 @@ void CauseSignal(int sig, int code) { *i = 0; break; } -#if (defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)) && \ +#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || \ + BUILDFLAG(IS_CHROMEOS)) && \ defined(ARCH_CPU_ARM64) case SEGV_MTEAERR: { ScopedMmap mapping; @@ -231,13 +232,13 @@ void CauseSignal(int sig, int code) { mapping.addr_as()[1ULL << 56] = 0; break; } -#endif // (defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)) && - // defined(ARCH_CPU_ARM64) +#endif // (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) || + // BUILDFLAG(IS_CHROMEOS)) && defined(ARCH_CPU_ARM64) } break; } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) case SIGSYS: { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -249,7 +250,7 @@ void CauseSignal(int sig, int code) { } break; } -#endif // OS_APPLE +#endif // BUILDFLAG(IS_APPLE) #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM64) case SIGTRAP: { @@ -409,7 +410,7 @@ TEST(Signals, WillSignalReraiseAutonomously) { {SIGHUP, SEGV_MAPERR, false}, {SIGINT, SI_USER, false}, }; - for (size_t index = 0; index < base::size(kTestData); ++index) { + for (size_t index = 0; index < std::size(kTestData); ++index) { const auto test_data = kTestData[index]; SCOPED_TRACE(base::StringPrintf( "index %zu, sig %d, code %d", index, test_data.sig, test_data.code)); @@ -522,7 +523,7 @@ TEST(Signals, Raise_HandlerReraisesToDefault) { continue; } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) if (sig == SIGBUS #if defined(ARCH_CPU_ARM64) || sig == SIGILL || sig == SIGSEGV @@ -535,7 +536,7 @@ TEST(Signals, Raise_HandlerReraisesToDefault) { // test must be skipped. continue; } -#endif // defined(OS_APPLE) +#endif // BUILDFLAG(IS_APPLE) SignalsTest test(SignalsTest::TestType::kHandlerReraisesToDefault, SignalsTest::SignalSource::kRaise, @@ -554,7 +555,7 @@ TEST(Signals, Raise_HandlerReraisesToPrevious) { continue; } -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) if (sig == SIGBUS #if defined(ARCH_CPU_ARM64) || sig == SIGILL || sig == SIGSEGV @@ -567,7 +568,7 @@ TEST(Signals, Raise_HandlerReraisesToPrevious) { // test must be skipped. continue; } -#endif // defined(OS_APPLE) +#endif // BUILDFLAG(IS_APPLE) SignalsTest test(SignalsTest::TestType::kHandlerReraisesToPrevious, SignalsTest::SignalSource::kRaise, diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix.cc b/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix.cc index 671d963403..686de578c3 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix.cc @@ -18,7 +18,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "util/misc/implicit_cast.h" @@ -29,8 +30,10 @@ namespace { constexpr const char* kSignalNames[] = { nullptr, -#if defined(OS_APPLE) - // sed -Ene 's/^#define[[:space:]]SIG([[:alnum:]]+)[[:space:]]+[[:digit:]]{1,2}([[:space:]]|$).*/ "\1",/p' +#if BUILDFLAG(IS_APPLE) + // sed -Ene + // 's/^#define[[:space:]]SIG([[:alnum:]]+)[[:space:]]+[[:digit:]]{1,2}([[:space:]]|$).*/ + // "\1",/p' // /usr/include/sys/signal.h // and fix up by removing the entry for SIGPOLL. "HUP", @@ -64,7 +67,7 @@ constexpr const char* kSignalNames[] = { "INFO", "USR1", "USR2", -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #if defined(ARCH_CPU_MIPS_FAMILY) "HUP", "INT", @@ -135,11 +138,11 @@ constexpr const char* kSignalNames[] = { #endif // defined(ARCH_CPU_MIPS_FAMILY) #endif }; -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // NSIG is 64 to account for real-time signals. -static_assert(base::size(kSignalNames) == 32, "kSignalNames length"); +static_assert(std::size(kSignalNames) == 32, "kSignalNames length"); #else -static_assert(base::size(kSignalNames) == NSIG, "kSignalNames length"); +static_assert(std::size(kSignalNames) == NSIG, "kSignalNames length"); #endif constexpr char kSigPrefix[] = "SIG"; @@ -151,7 +154,7 @@ namespace crashpad { std::string SignalToString(int signal, SymbolicConstantToStringOptions options) { const char* signal_name = - implicit_cast(signal) < base::size(kSignalNames) + implicit_cast(signal) < std::size(kSignalNames) ? kSignalNames[signal] : nullptr; if (!signal_name) { @@ -176,7 +179,7 @@ bool StringToSignal(const base::StringPiece& string, string.substr(0, strlen(kSigPrefix)).compare(kSigPrefix) == 0; base::StringPiece short_string = can_match_full ? string.substr(strlen(kSigPrefix)) : string; - for (int index = 0; index < implicit_cast(base::size(kSignalNames)); + for (int index = 0; index < implicit_cast(std::size(kSignalNames)); ++index) { const char* signal_name = kSignalNames[index]; if (!signal_name) { diff --git a/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix_test.cc b/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix_test.cc index 61d75e28a8..532f7fd2e4 100644 --- a/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/posix/symbolic_constants_posix_test.cc @@ -17,14 +17,15 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "gtest/gtest.h" #define NUL_TEST_DATA(string) \ - { string, base::size(string) - 1 } + { string, std::size(string) - 1 } namespace crashpad { namespace test { @@ -35,38 +36,23 @@ constexpr struct { const char* full_name; const char* short_name; } kSignalTestData[] = { - {SIGABRT, "SIGABRT", "ABRT"}, - {SIGALRM, "SIGALRM", "ALRM"}, - {SIGBUS, "SIGBUS", "BUS"}, - {SIGCHLD, "SIGCHLD", "CHLD"}, - {SIGCONT, "SIGCONT", "CONT"}, - {SIGFPE, "SIGFPE", "FPE"}, - {SIGHUP, "SIGHUP", "HUP"}, - {SIGILL, "SIGILL", "ILL"}, - {SIGINT, "SIGINT", "INT"}, - {SIGIO, "SIGIO", "IO"}, - {SIGKILL, "SIGKILL", "KILL"}, - {SIGPIPE, "SIGPIPE", "PIPE"}, - {SIGPROF, "SIGPROF", "PROF"}, - {SIGQUIT, "SIGQUIT", "QUIT"}, - {SIGSEGV, "SIGSEGV", "SEGV"}, - {SIGSTOP, "SIGSTOP", "STOP"}, - {SIGSYS, "SIGSYS", "SYS"}, - {SIGTERM, "SIGTERM", "TERM"}, - {SIGTRAP, "SIGTRAP", "TRAP"}, - {SIGTSTP, "SIGTSTP", "TSTP"}, - {SIGTTIN, "SIGTTIN", "TTIN"}, - {SIGTTOU, "SIGTTOU", "TTOU"}, - {SIGURG, "SIGURG", "URG"}, - {SIGUSR1, "SIGUSR1", "USR1"}, - {SIGUSR2, "SIGUSR2", "USR2"}, - {SIGVTALRM, "SIGVTALRM", "VTALRM"}, - {SIGWINCH, "SIGWINCH", "WINCH"}, - {SIGXCPU, "SIGXCPU", "XCPU"}, -#if defined(OS_APPLE) - {SIGEMT, "SIGEMT", "EMT"}, - {SIGINFO, "SIGINFO", "INFO"}, -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) + {SIGABRT, "SIGABRT", "ABRT"}, {SIGALRM, "SIGALRM", "ALRM"}, + {SIGBUS, "SIGBUS", "BUS"}, {SIGCHLD, "SIGCHLD", "CHLD"}, + {SIGCONT, "SIGCONT", "CONT"}, {SIGFPE, "SIGFPE", "FPE"}, + {SIGHUP, "SIGHUP", "HUP"}, {SIGILL, "SIGILL", "ILL"}, + {SIGINT, "SIGINT", "INT"}, {SIGIO, "SIGIO", "IO"}, + {SIGKILL, "SIGKILL", "KILL"}, {SIGPIPE, "SIGPIPE", "PIPE"}, + {SIGPROF, "SIGPROF", "PROF"}, {SIGQUIT, "SIGQUIT", "QUIT"}, + {SIGSEGV, "SIGSEGV", "SEGV"}, {SIGSTOP, "SIGSTOP", "STOP"}, + {SIGSYS, "SIGSYS", "SYS"}, {SIGTERM, "SIGTERM", "TERM"}, + {SIGTRAP, "SIGTRAP", "TRAP"}, {SIGTSTP, "SIGTSTP", "TSTP"}, + {SIGTTIN, "SIGTTIN", "TTIN"}, {SIGTTOU, "SIGTTOU", "TTOU"}, + {SIGURG, "SIGURG", "URG"}, {SIGUSR1, "SIGUSR1", "USR1"}, + {SIGUSR2, "SIGUSR2", "USR2"}, {SIGVTALRM, "SIGVTALRM", "VTALRM"}, + {SIGWINCH, "SIGWINCH", "WINCH"}, {SIGXCPU, "SIGXCPU", "XCPU"}, +#if BUILDFLAG(IS_APPLE) + {SIGEMT, "SIGEMT", "EMT"}, {SIGINFO, "SIGINFO", "INFO"}, +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) {SIGPWR, "SIGPWR", "PWR"}, #if !defined(ARCH_CPU_MIPS_FAMILY) {SIGSTKFLT, "SIGSTKFLT", "STKFLT"}, @@ -116,14 +102,14 @@ void TestSignalToString(int value, } TEST(SymbolicConstantsPOSIX, SignalToString) { - for (size_t index = 0; index < base::size(kSignalTestData); ++index) { + for (size_t index = 0; index < std::size(kSignalTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestSignalToString(kSignalTestData[index].signal, kSignalTestData[index].full_name, kSignalTestData[index].short_name); } -#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) // NSIG is 64 to account for real-time signals. constexpr int kSignalCount = 32; #else @@ -171,11 +157,11 @@ TEST(SymbolicConstantsPOSIX, StringToSignal) { kAllowFullName | kAllowShortName | kAllowNumber, }; - for (size_t option_index = 0; option_index < base::size(kOptions); + for (size_t option_index = 0; option_index < std::size(kOptions); ++option_index) { SCOPED_TRACE(base::StringPrintf("option_index %zu", option_index)); StringToSymbolicConstantOptions options = kOptions[option_index]; - for (size_t index = 0; index < base::size(kSignalTestData); ++index) { + for (size_t index = 0; index < std::size(kSignalTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); int signal = kSignalTestData[index].signal; { @@ -213,7 +199,7 @@ TEST(SymbolicConstantsPOSIX, StringToSignal) { "", }; - for (size_t index = 0; index < base::size(kNegativeTestData); ++index) { + for (size_t index = 0; index < std::size(kNegativeTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); TestStringToSignal(kNegativeTestData[index], options, false, 0); } @@ -234,7 +220,7 @@ TEST(SymbolicConstantsPOSIX, StringToSignal) { NUL_TEST_DATA("1\0002"), }; - for (size_t index = 0; index < base::size(kNULTestData); ++index) { + for (size_t index = 0; index < std::size(kNULTestData); ++index) { SCOPED_TRACE(base::StringPrintf("index %zu", index)); base::StringPiece string(kNULTestData[index].string, kNULTestData[index].length); diff --git a/thirdparty/sentry-native/external/crashpad/util/process/process_id.h b/thirdparty/sentry-native/external/crashpad/util/process/process_id.h index 113f6fc638..0d8273cc79 100644 --- a/thirdparty/sentry-native/external/crashpad/util/process/process_id.h +++ b/thirdparty/sentry-native/external/crashpad/util/process/process_id.h @@ -20,27 +20,27 @@ #include "base/format_macros.h" #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) #include #endif namespace crashpad { -#if defined(OS_POSIX) || DOXYGEN +#if BUILDFLAG(IS_POSIX) || DOXYGEN //! \brief Alias for platform-specific type to represent a process. using ProcessID = pid_t; constexpr ProcessID kInvalidProcessID = -1; static_assert(std::is_same::value, "Port."); #define PRI_PROCESS_ID "d" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) using ProcessID = DWORD; constexpr ProcessID kInvalidProcessID = 0; #define PRI_PROCESS_ID "lu" -#elif defined(OS_FUCHSIA) +#elif BUILDFLAG(IS_FUCHSIA) using ProcessID = zx_koid_t; constexpr ProcessID kInvalidProcessID = ZX_KOID_INVALID; static_assert(std::is_same::value, "Port."); diff --git a/thirdparty/sentry-native/external/crashpad/util/process/process_memory.h b/thirdparty/sentry-native/external/crashpad/util/process/process_memory.h index eeb78e97ee..d7e65437d1 100644 --- a/thirdparty/sentry-native/external/crashpad/util/process/process_memory.h +++ b/thirdparty/sentry-native/external/crashpad/util/process/process_memory.h @@ -22,10 +22,10 @@ #include "build/build_config.h" #include "util/misc/address_types.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include typedef SSIZE_T ssize_t; -#endif // defined(OS_WIN) +#endif // BUILDFLAG(IS_WIN) namespace crashpad { diff --git a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_native.h b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_native.h index 5a792d76e2..c3b94e826a 100644 --- a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_native.h +++ b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_native.h @@ -14,26 +14,26 @@ #include "build/build_config.h" -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) #include "util/process/process_memory_fuchsia.h" -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) #include "util/process/process_memory_linux.h" -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include "util/process/process_memory_win.h" -#elif defined(OS_APPLE) +#elif BUILDFLAG(IS_APPLE) #include "util/process/process_memory_mac.h" #endif namespace crashpad { -#if defined(OS_FUCHSIA) || DOXYGEN +#if BUILDFLAG(IS_FUCHSIA) || DOXYGEN //! \brief Alias for platform-specific native implementation of ProcessMemory. using ProcessMemoryNative = ProcessMemoryFuchsia; -#elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) using ProcessMemoryNative = ProcessMemoryLinux; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) using ProcessMemoryNative = ProcessMemoryWin; -#elif defined(OS_APPLE) +#elif BUILDFLAG(IS_APPLE) using ProcessMemoryNative = ProcessMemoryMac; #else #error Port. diff --git a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_range_test.cc b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_range_test.cc index 2e34665fec..381eb04338 100644 --- a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_range_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_range_test.cc @@ -14,16 +14,16 @@ #include "util/process/process_memory_range.h" +#include #include -#include "base/cxx17_backports.h" #include "build/build_config.h" #include "gtest/gtest.h" #include "test/process_type.h" #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "test/linux/fake_ptrace_connection.h" #endif @@ -43,14 +43,15 @@ TEST(ProcessMemoryRange, Basic) { constexpr bool is_64_bit = false; #endif // ARCH_CPU_64_BITS -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(GetSelfProcess())); ProcessMemoryLinux memory(&connection); #else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(GetSelfProcess())); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) ProcessMemoryRange range; ASSERT_TRUE(range.Initialize(&memory, is_64_bit)); @@ -68,28 +69,28 @@ TEST(ProcessMemoryRange, Basic) { auto string1_addr = FromPointerCast(kTestObject.string1); auto string2_addr = FromPointerCast(kTestObject.string2); ASSERT_TRUE(range.ReadCStringSizeLimited( - string1_addr, base::size(kTestObject.string1), &string)); + string1_addr, std::size(kTestObject.string1), &string)); EXPECT_STREQ(string.c_str(), kTestObject.string1); ASSERT_TRUE(range.ReadCStringSizeLimited( - string2_addr, base::size(kTestObject.string2), &string)); + string2_addr, std::size(kTestObject.string2), &string)); EXPECT_STREQ(string.c_str(), kTestObject.string2); // Limit the range to remove access to string2. ProcessMemoryRange range2; ASSERT_TRUE(range2.Initialize(range)); ASSERT_TRUE( - range2.RestrictRange(string1_addr, base::size(kTestObject.string1))); + range2.RestrictRange(string1_addr, std::size(kTestObject.string1))); EXPECT_TRUE(range2.ReadCStringSizeLimited( - string1_addr, base::size(kTestObject.string1), &string)); + string1_addr, std::size(kTestObject.string1), &string)); EXPECT_FALSE(range2.ReadCStringSizeLimited( - string2_addr, base::size(kTestObject.string2), &string)); + string2_addr, std::size(kTestObject.string2), &string)); EXPECT_FALSE(range2.Read(object_addr, sizeof(object), &object)); // String reads fail if the NUL terminator is outside the range. ASSERT_TRUE(range2.RestrictRange(string1_addr, strlen(kTestObject.string1))); EXPECT_FALSE(range2.ReadCStringSizeLimited( - string1_addr, base::size(kTestObject.string1), &string)); + string1_addr, std::size(kTestObject.string1), &string)); // New range outside the old range. EXPECT_FALSE(range2.RestrictRange(string1_addr - 1, 1)); diff --git a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_sanitized_test.cc b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_sanitized_test.cc index b88eab132d..03eee91928 100644 --- a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_sanitized_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_sanitized_test.cc @@ -14,12 +14,13 @@ #include "util/process/process_memory_sanitized.h" +#include "build/build_config.h" #include "gtest/gtest.h" #include "test/process_type.h" #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "test/linux/fake_ptrace_connection.h" #endif @@ -28,14 +29,15 @@ namespace test { namespace { TEST(ProcessMemorySanitized, DenyDisallowedMemory) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(GetSelfProcess())); ProcessMemoryLinux memory(&connection); #else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(GetSelfProcess())); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) char c = 42; char out; @@ -51,14 +53,15 @@ TEST(ProcessMemorySanitized, DenyDisallowedMemory) { } TEST(ProcessMemorySanitized, AllowedMemory) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(GetSelfProcess())); ProcessMemoryLinux memory(&connection); #else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(GetSelfProcess())); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) char str[4] = "ABC"; char out[4]; diff --git a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_test.cc b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_test.cc index fe9971bcc7..17df85deda 100644 --- a/thirdparty/sentry-native/external/crashpad/util/process/process_memory_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/process/process_memory_test.cc @@ -30,14 +30,15 @@ #include "util/misc/from_pointer_cast.h" #include "util/process/process_memory_native.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include "test/mac/mach_multiprocess.h" -#endif // defined(OS_APPLE) +#endif // BUILDFLAG(IS_APPLE) -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "test/linux/fake_ptrace_connection.h" #include "util/linux/direct_ptrace_connection.h" -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) namespace crashpad { namespace test { @@ -47,7 +48,7 @@ namespace { // port which requires root or a code signing entitlement. To account for this // we implement an adaptor class that wraps MachMultiprocess on macOS, because // it shares the child's task port, and makes it behave like MultiprocessExec. -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) class MultiprocessAdaptor : public MachMultiprocess { public: void SetChildTestMainFunction(const std::string& function_name) { @@ -102,7 +103,7 @@ class MultiprocessAdaptor : public MultiprocessExec { void MultiprocessParent() override { Parent(); } }; -#endif // defined(OS_APPLE) +#endif // BUILDFLAG(IS_APPLE) void DoChildReadTestSetup(size_t* region_size, std::unique_ptr* region) { @@ -156,14 +157,15 @@ class ReadTest : public MultiprocessAdaptor { } void DoTest(ProcessType process, size_t region_size, VMAddress address) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); #else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) std::unique_ptr result(new char[region_size]); @@ -343,14 +345,15 @@ class ReadCStringTest : public MultiprocessAdaptor { VMAddress local_empty_address, VMAddress local_short_address, VMAddress long_string_address) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) FakePtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); #else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) Compare(memory, const_empty_address, kConstCharEmpty); Compare(memory, const_short_address, kConstCharShort); @@ -421,14 +424,15 @@ class ReadUnmappedTest : public MultiprocessAdaptor { } void DoTest(ProcessType process, VMAddress address) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) DirectPtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); #else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) VMAddress page_addr1 = address; VMAddress page_addr2 = page_addr1 + base::GetPageSize(); @@ -554,14 +558,15 @@ class ReadCStringUnmappedTest : public MultiprocessAdaptor { void DoTest(ProcessType process, const std::vector& strings) { -#if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) DirectPtraceConnection connection; ASSERT_TRUE(connection.Initialize(process)); ProcessMemoryLinux memory(&connection); #else ProcessMemoryNative memory; ASSERT_TRUE(memory.Initialize(process)); -#endif // OS_ANDROID || OS_LINUX || OS_CHROMEOS +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) std::string result; result.reserve(kChildProcessStringLength + 1); diff --git a/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator.cc b/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator.cc index 1cbf7d2a5f..7e1c1abc92 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator.cc @@ -18,12 +18,12 @@ #include "build/build_config.h" -#if defined(OS_POSIX) || defined(_LIBCPP_STD_VER) || defined(__MINGW32__) +#if BUILDFLAG(IS_POSIX) || defined(_LIBCPP_STD_VER) || defined(__MINGW32__) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include #include -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) namespace { @@ -31,12 +31,12 @@ namespace { // library to do so. This works even if C++ exceptions are disabled, causing // program termination if uncaught. void ThrowBadAlloc() { -#if defined(OS_POSIX) || defined(_LIBCPP_STD_VER) || defined(__MINGW32__) +#if BUILDFLAG(IS_POSIX) || defined(_LIBCPP_STD_VER) || defined(__MINGW32__) // This works with both libc++ and libstdc++. std::__throw_bad_alloc(); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) std::_Xbad_alloc(); -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } } // namespace @@ -44,7 +44,7 @@ void ThrowBadAlloc() { namespace crashpad { void* AlignedAllocate(size_t alignment, size_t size) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) // posix_memalign() requires that alignment be at least sizeof(void*), so the // power-of-2 check needs to happen before potentially changing the alignment. if (alignment == 0 || alignment & (alignment - 1)) { @@ -55,22 +55,22 @@ void* AlignedAllocate(size_t alignment, size_t size) { if (posix_memalign(&pointer, std::max(alignment, sizeof(void*)), size) != 0) { ThrowBadAlloc(); } -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) void* pointer = _aligned_malloc(size, alignment); if (pointer == nullptr) { ThrowBadAlloc(); } -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) return pointer; } void AlignedFree(void* pointer) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) free(pointer); -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) _aligned_free(pointer); -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator_test.cc b/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator_test.cc index 1c16dcc5e0..ed58d2b951 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stdlib/aligned_allocator_test.cc @@ -16,11 +16,11 @@ #include -#include "base/compiler_specific.h" +#include "build/build_config.h" #include "gtest/gtest.h" #include "test/gtest_death.h" -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) #include #endif @@ -91,21 +91,19 @@ TEST(AlignedAllocator, AlignedVector) { } void BadAlignmentTest() { -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) // Suppress the assertion MessageBox() normally displayed by the CRT in debug - // mode. - int previous = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); - - // In release mode, _CrtSetReportMode() is #defined to ((int)0), so |previous| - // would appear unused. - ALLOW_UNUSED_LOCAL(previous); + // mode. In release mode, _CrtSetReportMode() is #defined to ((int)0), so + // |previous| would appear unused, thus the [[maybe_unused]]. + [[maybe_unused]] int previous = + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); #endif // Alignment constraints must be powers of 2. 7 is not valid. AlignedVector bad_aligned_vector; bad_aligned_vector.push_back(0); -#if defined(OS_WIN) +#if BUILDFLAG(IS_WIN) _CrtSetReportMode(_CRT_ASSERT, previous); #endif } diff --git a/thirdparty/sentry-native/external/crashpad/util/stdlib/string_number_conversion_test.cc b/thirdparty/sentry-native/external/crashpad/util/stdlib/string_number_conversion_test.cc index 90b67757f4..9f4dcbeb08 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stdlib/string_number_conversion_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stdlib/string_number_conversion_test.cc @@ -17,10 +17,10 @@ #include #include +#include #include #include -#include "base/cxx17_backports.h" #include "gtest/gtest.h" #define STRINGIFY(a) STR(a) @@ -277,7 +277,7 @@ TEST(StringNumberConversion, StringToInt) { // "decimal digit terminates octal escape sequence". int output; std::string kEmbeddedNullInput(kEmbeddedNullInputRaw, - base::size(kEmbeddedNullInputRaw) - 1); + std::size(kEmbeddedNullInputRaw) - 1); EXPECT_FALSE(StringToNumber(kEmbeddedNullInput, &output)); } @@ -307,7 +307,7 @@ TEST(StringNumberConversion, StringToUnsignedInt) { // "decimal digit terminates octal escape sequence". unsigned int output; std::string kEmbeddedNullInput(kEmbeddedNullInputRaw, - base::size(kEmbeddedNullInputRaw) - 1); + std::size(kEmbeddedNullInputRaw) - 1); EXPECT_FALSE(StringToNumber(kEmbeddedNullInput, &output)); } diff --git a/thirdparty/sentry-native/external/crashpad/util/stdlib/strlcpy_test.cc b/thirdparty/sentry-native/external/crashpad/util/stdlib/strlcpy_test.cc index b729c24247..4cb933694d 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stdlib/strlcpy_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stdlib/strlcpy_test.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/format_macros.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -53,7 +53,7 @@ TEST(strlcpy, c16lcpy) { static constexpr char16_t test_characters[] = { 0x4d, 0xe9, 0x100, 0x151, 0x1e18}; - for (size_t index = 0; index < base::size(test_characters); ++index) { + for (size_t index = 0; index < std::size(test_characters); ++index) { char16_t test_character = test_characters[index]; SCOPED_TRACE(base::StringPrintf( "character index %" PRIuS ", character 0x%x", index, test_character)); @@ -67,13 +67,13 @@ TEST(strlcpy, c16lcpy) { EXPECT_EQ(c16lcpy(destination.data, test_string.c_str(), - base::size(destination.data)), + std::size(destination.data)), length); // Make sure that the destination buffer is NUL-terminated, and that as // much of the test string was copied as could fit. size_t expected_destination_length = - std::min(length, base::size(destination.data) - 1); + std::min(length, std::size(destination.data) - 1); EXPECT_EQ(destination.data[expected_destination_length], '\0'); EXPECT_EQ(C16Len(destination.data), expected_destination_length); @@ -86,15 +86,15 @@ TEST(strlcpy, c16lcpy) { // of the buffer passed to c16lcpy. EXPECT_TRUE(C16Memcmp(expected_untouched.lead_guard, destination.lead_guard, - base::size(destination.lead_guard)) == 0); + std::size(destination.lead_guard)) == 0); size_t expected_untouched_length = - base::size(destination.data) - expected_destination_length - 1; + std::size(destination.data) - expected_destination_length - 1; EXPECT_TRUE(C16Memcmp(expected_untouched.data, &destination.data[expected_destination_length + 1], expected_untouched_length) == 0); EXPECT_TRUE(C16Memcmp(expected_untouched.trail_guard, destination.trail_guard, - base::size(destination.trail_guard)) == 0); + std::size(destination.trail_guard)) == 0); } } } diff --git a/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.cc b/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.cc index 872c0eb472..296b13106f 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.cc @@ -14,7 +14,9 @@ #include "util/stdlib/strnlen.h" -#if defined(OS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 +#include "build/build_config.h" + +#if BUILDFLAG(IS_MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_7 // Redeclare a method only available on Mac OS X 10.7 and later to suppress a diff --git a/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.h b/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.h index 59253b7517..9fa447c222 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.h +++ b/thirdparty/sentry-native/external/crashpad/util/stdlib/strnlen.h @@ -20,7 +20,7 @@ #include "build/build_config.h" -#if defined(OS_MAC) +#if BUILDFLAG(IS_MAC) #include #endif @@ -38,7 +38,7 @@ namespace crashpad { //! and not all systems’ standard libraries provide an implementation. size_t strnlen(const char* string, size_t max_length); -#if !defined(OS_MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_7 +#if !BUILDFLAG(IS_MAC) || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_7 inline size_t strnlen(const char* string, size_t max_length) { return ::strnlen(string, max_length); } diff --git a/thirdparty/sentry-native/external/crashpad/util/stdlib/thread_safe_vector_test.cc b/thirdparty/sentry-native/external/crashpad/util/stdlib/thread_safe_vector_test.cc index 8962430411..6558fc15ab 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stdlib/thread_safe_vector_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stdlib/thread_safe_vector_test.cc @@ -14,7 +14,8 @@ #include "util/stdlib/thread_safe_vector.h" -#include "base/cxx17_backports.h" +#include + #include "gtest/gtest.h" #include "util/thread/thread.h" @@ -57,12 +58,12 @@ TEST(ThreadSafeVector, ThreadSafeVector) { EXPECT_TRUE(vector.empty()); ThreadSafeVectorTestThread threads[100]; - for (size_t index = 0; index < base::size(threads); ++index) { + for (size_t index = 0; index < std::size(threads); ++index) { threads[index].SetTestParameters( &thread_safe_vector, static_cast(index * kElementsPerThread)); } - for (size_t index = 0; index < base::size(threads); ++index) { + for (size_t index = 0; index < std::size(threads); ++index) { threads[index].Start(); if (index % 10 == 0) { @@ -79,8 +80,8 @@ TEST(ThreadSafeVector, ThreadSafeVector) { std::vector drained = thread_safe_vector.Drain(); vector.insert(vector.end(), drained.begin(), drained.end()); - bool found[base::size(threads) * kElementsPerThread] = {}; - EXPECT_EQ(vector.size(), base::size(found)); + bool found[std::size(threads) * kElementsPerThread] = {}; + EXPECT_EQ(vector.size(), std::size(found)); for (int element : vector) { EXPECT_FALSE(found[element]) << element; found[element] = true; diff --git a/thirdparty/sentry-native/external/crashpad/util/stream/base94_output_stream_test.cc b/thirdparty/sentry-native/external/crashpad/util/stream/base94_output_stream_test.cc index d0a2985576..34c1b434cc 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stream/base94_output_stream_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stream/base94_output_stream_test.cc @@ -17,9 +17,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/rand_util.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -237,7 +237,7 @@ TEST_F(Base94OutputStreamTest, WriteDeterministicLongDataMultipleTimes) { 4, 96, 40, kLongDataLength - 4 - 96 - 40}; size_t offset = 0; - for (size_t index = 0; index < base::size(kWriteLengths); ++index) { + for (size_t index = 0; index < std::size(kWriteLengths); ++index) { const size_t write_length = kWriteLengths[index]; SCOPED_TRACE(base::StringPrintf( "offset %zu, write_length %zu", offset, write_length)); diff --git a/thirdparty/sentry-native/external/crashpad/util/stream/file_encoder.cc b/thirdparty/sentry-native/external/crashpad/util/stream/file_encoder.cc index 5cebbfcc52..d39b5b09a5 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stream/file_encoder.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stream/file_encoder.cc @@ -15,8 +15,8 @@ #include "util/stream/file_encoder.h" #include +#include -#include "base/ignore_result.h" #include "util/file/file_io.h" #include "util/file/file_reader.h" #include "util/file/scoped_remove_file.h" @@ -77,7 +77,7 @@ bool FileEncoder::Process() { if (!output->Flush()) return false; - ignore_result(file_remover.release()); + std::ignore = file_remover.release(); return true; } diff --git a/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream.cc b/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream.cc index 3ae7d91296..153adbe0f7 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream.cc @@ -14,8 +14,9 @@ #include "util/stream/zlib_output_stream.h" +#include + #include "base/check.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "util/misc/zlib.h" @@ -65,7 +66,7 @@ bool ZlibOutputStream::Write(const uint8_t* data, size_t size) { } } zlib_stream_.next_out = buffer_; - zlib_stream_.avail_out = base::saturated_cast(base::size(buffer_)); + zlib_stream_.avail_out = base::saturated_cast(std::size(buffer_)); initialized_.set_valid(); } @@ -127,12 +128,12 @@ bool ZlibOutputStream::Flush() { } bool ZlibOutputStream::WriteOutputStream() { - auto valid_size = base::size(buffer_) - zlib_stream_.avail_out; + auto valid_size = std::size(buffer_) - zlib_stream_.avail_out; if (valid_size > 0 && !output_stream_->Write(buffer_, valid_size)) return false; zlib_stream_.next_out = buffer_; - zlib_stream_.avail_out = base::saturated_cast(base::size(buffer_)); + zlib_stream_.avail_out = base::saturated_cast(std::size(buffer_)); return true; } diff --git a/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream_test.cc b/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream_test.cc index 306a61b1e5..528800e386 100644 --- a/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/stream/zlib_output_stream_test.cc @@ -17,8 +17,8 @@ #include #include +#include -#include "base/cxx17_backports.h" #include "base/rand_util.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -102,7 +102,7 @@ TEST_F(ZlibOutputStreamTest, WriteDeterministicLongDataMultipleTimes) { 4, 96, 40, kLongDataLength - 4 - 96 - 40}; size_t offset = 0; - for (size_t index = 0; index < base::size(kWriteLengths); ++index) { + for (size_t index = 0; index < std::size(kWriteLengths); ++index) { const size_t write_length = kWriteLengths[index]; SCOPED_TRACE(base::StringPrintf( "offset %zu, write_length %zu", offset, write_length)); diff --git a/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore.h b/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore.h index 308b29b034..1bb9e2184b 100644 --- a/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore.h +++ b/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore.h @@ -19,11 +19,11 @@ #include "build/build_config.h" -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) #include -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) #include -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) #include #include #else @@ -76,11 +76,11 @@ class Semaphore { void Signal(); private: -#if defined(OS_APPLE) +#if BUILDFLAG(IS_APPLE) dispatch_semaphore_t semaphore_; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) HANDLE semaphore_; -#elif defined(OS_ANDROID) +#elif BUILDFLAG(IS_ANDROID) std::condition_variable cv_; std::mutex mutex_; int value_; diff --git a/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_posix.cc b/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_posix.cc index ebe62a4f42..9e55ede720 100644 --- a/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_posix.cc @@ -23,11 +23,12 @@ #include "base/check_op.h" #include "base/logging.h" #include "base/posix/eintr_wrapper.h" +#include "build/build_config.h" #include "util/misc/time.h" namespace crashpad { -#if defined(OS_ANDROID) +#if BUILDFLAG(IS_ANDROID) Semaphore::Semaphore(int value) : cv_(), mutex_(), value_(value) {} @@ -63,7 +64,7 @@ void Semaphore::Signal() { cv_.notify_one(); } -#elif !defined(OS_APPLE) +#elif !BUILDFLAG(IS_APPLE) Semaphore::Semaphore(int value) { PCHECK(sem_init(&semaphore_, 0, value) == 0) << "sem_init"; @@ -104,6 +105,6 @@ void Semaphore::Signal() { PCHECK(sem_post(&semaphore_) == 0) << "sem_post"; } -#endif // OS_ANDROID +#endif // BUILDFLAG(IS_ANDROID) } // namespace crashpad diff --git a/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_test.cc b/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_test.cc index 5cb91e489f..9a6b6dec3b 100644 --- a/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/synchronization/semaphore_test.cc @@ -16,12 +16,14 @@ #include -#include "base/cxx17_backports.h" +#include + +#include "build/build_config.h" #include "gtest/gtest.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) namespace crashpad { namespace test { @@ -60,50 +62,50 @@ TEST(Semaphore, TimedWaitInfinite_1) { } struct ThreadMainInfo { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) pthread_t pthread; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) HANDLE thread; #endif Semaphore* semaphore; size_t iterations; }; -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) void* -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) DWORD WINAPI -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) ThreadMain(void* argument) { ThreadMainInfo* info = reinterpret_cast(argument); for (size_t iteration = 0; iteration < info->iterations; ++iteration) { info->semaphore->Wait(); } -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) return nullptr; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) return 0; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } void StartThread(ThreadMainInfo* info) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int rv = pthread_create(&info->pthread, nullptr, ThreadMain, info); ASSERT_EQ(rv, 0) << "pthread_create"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) info->thread = CreateThread(nullptr, 0, ThreadMain, info, 0, nullptr); ASSERT_NE(info->thread, nullptr) << "CreateThread"; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } void JoinThread(ThreadMainInfo* info) { -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) int rv = pthread_join(info->pthread, nullptr); EXPECT_EQ(rv, 0) << "pthread_join"; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) DWORD result = WaitForSingleObject(info->thread, INFINITE); EXPECT_EQ(result, WAIT_OBJECT_0) << "WaitForSingleObject"; -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) } TEST(Semaphore, Threaded) { @@ -126,7 +128,7 @@ TEST(Semaphore, TenThreaded) { Semaphore semaphore(5); ThreadMainInfo info[10]; size_t iterations = 0; - for (size_t index = 0; index < base::size(info); ++index) { + for (size_t index = 0; index < std::size(info); ++index) { info[index].semaphore = &semaphore; info[index].iterations = index; iterations += info[index].iterations; @@ -138,7 +140,7 @@ TEST(Semaphore, TenThreaded) { semaphore.Signal(); } - for (size_t index = 0; index < base::size(info); ++index) { + for (size_t index = 0; index < std::size(info); ++index) { JoinThread(&info[index]); } } diff --git a/thirdparty/sentry-native/external/crashpad/util/thread/thread.h b/thirdparty/sentry-native/external/crashpad/util/thread/thread.h index e06ca3c9db..6f93ed0961 100644 --- a/thirdparty/sentry-native/external/crashpad/util/thread/thread.h +++ b/thirdparty/sentry-native/external/crashpad/util/thread/thread.h @@ -17,11 +17,14 @@ #include "build/build_config.h" -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) #include -#elif defined(OS_WIN) +#include +#elif BUILDFLAG(IS_WIN) #include -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) + +#include "build/build_config.h" namespace crashpad { @@ -44,21 +47,26 @@ class Thread { //! Must paired with a call to Start(). void Join(); +#if BUILDFLAG(IS_APPLE) + //! \brief Returns the thread id of the Thread pthread_t. + uint64_t GetThreadIdForTesting(); +#endif // BUILDFLAG(IS_APPLE) + private: //! \brief The thread entry point to be implemented by the subclass. virtual void ThreadMain() = 0; static -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) void* -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) DWORD WINAPI -#endif // OS_POSIX +#endif // BUILDFLAG(IS_POSIX) ThreadEntryThunk(void* argument); -#if defined(OS_POSIX) +#if BUILDFLAG(IS_POSIX) pthread_t platform_thread_; -#elif defined(OS_WIN) +#elif BUILDFLAG(IS_WIN) HANDLE platform_thread_; #endif }; diff --git a/thirdparty/sentry-native/external/crashpad/util/thread/thread_log_messages_test.cc b/thirdparty/sentry-native/external/crashpad/util/thread/thread_log_messages_test.cc index f3dc1a6659..efd6b53a5c 100644 --- a/thirdparty/sentry-native/external/crashpad/util/thread/thread_log_messages_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/thread/thread_log_messages_test.cc @@ -17,7 +17,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" @@ -65,8 +66,8 @@ TEST(ThreadLogMessages, Basic) { const std::vector& log_messages = thread_log_messages.log_messages(); - EXPECT_EQ(log_messages.size(), base::size(kMessages)); - for (size_t index = 0; index < base::size(kMessages); ++index) { + EXPECT_EQ(log_messages.size(), std::size(kMessages)); + for (size_t index = 0; index < std::size(kMessages); ++index) { ASSERT_NO_FATAL_FAILURE( ExpectLogMessage(log_messages[index], kMessages[index])) << "index " << index; @@ -149,7 +150,7 @@ TEST(ThreadLogMessages, Multithreaded) { LoggingTestThread threads[20]; int start = 0; - for (size_t index = 0; index < base::size(threads); ++index) { + for (size_t index = 0; index < std::size(threads); ++index) { threads[index].Initialize( index, static_cast(start), static_cast(index)); start += static_cast(index); diff --git a/thirdparty/sentry-native/external/crashpad/util/thread/thread_posix.cc b/thirdparty/sentry-native/external/crashpad/util/thread/thread_posix.cc index fe50050c7f..8e00c210c3 100644 --- a/thirdparty/sentry-native/external/crashpad/util/thread/thread_posix.cc +++ b/thirdparty/sentry-native/external/crashpad/util/thread/thread_posix.cc @@ -19,6 +19,7 @@ #include #include "base/check.h" +#include "build/build_config.h" namespace crashpad { @@ -35,6 +36,15 @@ void Thread::Join() { platform_thread_ = 0; } +#if BUILDFLAG(IS_APPLE) +uint64_t Thread::GetThreadIdForTesting() { + uint64_t thread_self; + errno = pthread_threadid_np(pthread_self(), &thread_self); + PCHECK(errno == 0) << "pthread_threadid_np"; + return thread_self; +} +#endif // BUILDFLAG(IS_APPLE) + // static void* Thread::ThreadEntryThunk(void* argument) { Thread* self = reinterpret_cast(argument); diff --git a/thirdparty/sentry-native/external/crashpad/util/thread/worker_thread_test.cc b/thirdparty/sentry-native/external/crashpad/util/thread/worker_thread_test.cc index 811d09c375..86f8474273 100644 --- a/thirdparty/sentry-native/external/crashpad/util/thread/worker_thread_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/thread/worker_thread_test.cc @@ -14,6 +14,7 @@ #include "util/thread/worker_thread.h" +#include "build/build_config.h" #include "gtest/gtest.h" #include "util/misc/clock.h" #include "util/synchronization/semaphore.h" @@ -78,7 +79,7 @@ TEST(WorkerThread, DoWork) { // also somewhat useful. The expected time "should" be ~40-50ms with a work // interval of 0.05s, but on Fuchsia, 1200ms was observed. So, on Fuchsia, use a // much larger timeout. See https://crashpad.chromium.org/bug/231. -#if defined(OS_FUCHSIA) +#if BUILDFLAG(IS_FUCHSIA) constexpr uint64_t kUpperBoundTime = 10; #else constexpr uint64_t kUpperBoundTime = 1; diff --git a/thirdparty/sentry-native/external/crashpad/util/win/command_line_test.cc b/thirdparty/sentry-native/external/crashpad/util/win/command_line_test.cc index 28b9504182..6fd4b31bed 100644 --- a/thirdparty/sentry-native/external/crashpad/util/win/command_line_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/win/command_line_test.cc @@ -18,7 +18,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/scoped_generic.h" #include "gtest/gtest.h" #include "test/errors.h" @@ -64,7 +65,7 @@ TEST(CommandLine, AppendCommandLineArgument) { L"argument 1", L"argument 2", }; - AppendCommandLineArgumentTest(base::size(kArguments), kArguments); + AppendCommandLineArgumentTest(std::size(kArguments), kArguments); } { @@ -76,7 +77,7 @@ TEST(CommandLine, AppendCommandLineArgument) { L"argument 2", L"\\some\\path with\\spaces", }; - AppendCommandLineArgumentTest(base::size(kArguments), kArguments); + AppendCommandLineArgumentTest(std::size(kArguments), kArguments); } { @@ -88,7 +89,7 @@ TEST(CommandLine, AppendCommandLineArgument) { L"she said, \"you had me at hello\"", L"\\some\\path with\\spaces", }; - AppendCommandLineArgumentTest(base::size(kArguments), kArguments); + AppendCommandLineArgumentTest(std::size(kArguments), kArguments); } { @@ -101,7 +102,7 @@ TEST(CommandLine, AppendCommandLineArgument) { L"argument3", L"argument4", }; - AppendCommandLineArgumentTest(base::size(kArguments), kArguments); + AppendCommandLineArgumentTest(std::size(kArguments), kArguments); } { @@ -112,7 +113,7 @@ TEST(CommandLine, AppendCommandLineArgument) { L"\\some\\directory with\\spaces\\", L"argument2", }; - AppendCommandLineArgumentTest(base::size(kArguments), kArguments); + AppendCommandLineArgumentTest(std::size(kArguments), kArguments); } { @@ -123,7 +124,7 @@ TEST(CommandLine, AppendCommandLineArgument) { L"", L"argument2", }; - AppendCommandLineArgumentTest(base::size(kArguments), kArguments); + AppendCommandLineArgumentTest(std::size(kArguments), kArguments); } { @@ -158,7 +159,7 @@ TEST(CommandLine, AppendCommandLineArgument) { L"\"\"", L" \t\n\v\"", }; - AppendCommandLineArgumentTest(base::size(kArguments), kArguments); + AppendCommandLineArgumentTest(std::size(kArguments), kArguments); } } diff --git a/thirdparty/sentry-native/external/crashpad/util/win/exception_codes.h b/thirdparty/sentry-native/external/crashpad/util/win/exception_codes.h new file mode 100644 index 0000000000..eca940c3a3 --- /dev/null +++ b/thirdparty/sentry-native/external/crashpad/util/win/exception_codes.h @@ -0,0 +1,37 @@ +// Copyright 2022 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_UTIL_WIN_EXCEPTION_CODES_H_ +#define CRASHPAD_UTIL_WIN_EXCEPTION_CODES_H_ + +#include + +namespace crashpad { + +//! \brief Crashpad-specific exception codes that are used as arguments to +//! `RaiseException()` in unusual circumstances. +enum ExceptionCodes : uint32_t { + //! \brief The exception code (roughly "Client called") used when + //! DumpAndCrashTargetProcess() triggers an exception in a target + //! process. + //! + //! \note This value does not have any bits of the top nibble set, to avoid + //! confusion with real exception codes which tend to have those bits + //! set. + kTriggeredExceptionCode = 0xcca11ed, +}; + +} // namespace crashpad + +#endif // CRASHPAD_UTIL_WIN_EXCEPTION_CODES_H_ diff --git a/thirdparty/sentry-native/external/crashpad/util/win/exception_handler_server.cc b/thirdparty/sentry-native/external/crashpad/util/win/exception_handler_server.cc index 92d5c5d47c..6890a01cc4 100644 --- a/thirdparty/sentry-native/external/crashpad/util/win/exception_handler_server.cc +++ b/thirdparty/sentry-native/external/crashpad/util/win/exception_handler_server.cc @@ -18,9 +18,9 @@ #include #include +#include #include -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" #include "base/rand_util.h" @@ -306,7 +306,7 @@ void ExceptionHandlerServer::InitializeWithInheritedDataForInitialClient( void ExceptionHandlerServer::Run(Delegate* delegate) { uint64_t shutdown_token = base::RandUint64(); ScopedKernelHANDLE thread_handles[kPipeInstances]; - for (size_t i = 0; i < base::size(thread_handles); ++i) { + for (size_t i = 0; i < std::size(thread_handles); ++i) { HANDLE pipe; if (first_pipe_instance_.is_valid()) { pipe = first_pipe_instance_.release(); @@ -358,7 +358,7 @@ void ExceptionHandlerServer::Run(Delegate* delegate) { } // Signal to the named pipe instances that they should terminate. - for (size_t i = 0; i < base::size(thread_handles); ++i) { + for (size_t i = 0; i < std::size(thread_handles); ++i) { ClientToServerMessage message; memset(&message, 0, sizeof(message)); message.type = ClientToServerMessage::kShutdown; diff --git a/thirdparty/sentry-native/external/crashpad/util/win/ntstatus_logging.cc b/thirdparty/sentry-native/external/crashpad/util/win/ntstatus_logging.cc index 7a1341952b..9c2630c940 100644 --- a/thirdparty/sentry-native/external/crashpad/util/win/ntstatus_logging.cc +++ b/thirdparty/sentry-native/external/crashpad/util/win/ntstatus_logging.cc @@ -14,9 +14,9 @@ #include "util/win/ntstatus_logging.h" +#include #include -#include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" namespace { @@ -30,7 +30,7 @@ std::string FormatNtstatus(DWORD ntstatus) { ntstatus, 0, msgbuf, - static_cast(base::size(msgbuf)), + static_cast(std::size(msgbuf)), nullptr); if (len) { // Most system messages end in a period and a space. Remove the space if diff --git a/thirdparty/sentry-native/external/crashpad/util/win/registration_protocol_win.cc b/thirdparty/sentry-native/external/crashpad/util/win/registration_protocol_win.cc index e3d55c6650..61dbd3d99e 100644 --- a/thirdparty/sentry-native/external/crashpad/util/win/registration_protocol_win.cc +++ b/thirdparty/sentry-native/external/crashpad/util/win/registration_protocol_win.cc @@ -19,7 +19,8 @@ #include #include -#include "base/cxx17_backports.h" +#include + #include "base/logging.h" #include "util/win/exception_handler_server.h" #include "util/win/loader_lock.h" @@ -209,8 +210,7 @@ const void* GetFallbackSecurityDescriptorForNamedPipeInstance(size_t* size) { ACL_REVISION, // AclRevision. 0, // Sbz1. sizeof(kSecDescBlob.sacl), // AclSize. - static_cast( - base::size(kSecDescBlob.sacl.ace)), // AceCount. + static_cast(std::size(kSecDescBlob.sacl.ace)), // AceCount. 0, // Sbz2. }, @@ -231,8 +231,8 @@ const void* GetFallbackSecurityDescriptorForNamedPipeInstance(size_t* size) { { SID_REVISION, // Revision. // SubAuthorityCount. - static_cast(base::size( - kSecDescBlob.sacl.ace[0].sid.SubAuthority)), + static_cast( + std::size(kSecDescBlob.sacl.ace[0].sid.SubAuthority)), // IdentifierAuthority. {SECURITY_MANDATORY_LABEL_AUTHORITY}, {SECURITY_MANDATORY_UNTRUSTED_RID}, // SubAuthority. diff --git a/thirdparty/sentry-native/external/crashpad/util/win/safe_terminate_process_test.cc b/thirdparty/sentry-native/external/crashpad/util/win/safe_terminate_process_test.cc index 6ca5aa6d3f..30a9a32da5 100644 --- a/thirdparty/sentry-native/external/crashpad/util/win/safe_terminate_process_test.cc +++ b/thirdparty/sentry-native/external/crashpad/util/win/safe_terminate_process_test.cc @@ -16,11 +16,11 @@ #include -#include +#include #include +#include #include "base/check.h" -#include "base/cxx17_backports.h" #include "base/files/file_path.h" #include "build/build_config.h" #include "gtest/gtest.h" @@ -150,7 +150,7 @@ TEST(SafeTerminateProcess, PatchBadly) { }; void* target = reinterpret_cast(TerminateProcess); - ScopedExecutablePatch executable_patch(target, patch, base::size(patch)); + ScopedExecutablePatch executable_patch(target, patch, std::size(patch)); // Make sure that SafeTerminateProcess() can be called. Since it’s been // patched with a no-op stub, GetLastError() shouldn’t be modified. diff --git a/thirdparty/sentry-native/include/sentry.h b/thirdparty/sentry-native/include/sentry.h index 307b782f2d..44a0f878f9 100644 --- a/thirdparty/sentry-native/include/sentry.h +++ b/thirdparty/sentry-native/include/sentry.h @@ -23,8 +23,14 @@ extern "C" { #endif /* SDK Version */ -#define SENTRY_SDK_NAME "sentry.native" -#define SENTRY_SDK_VERSION "0.4.15" +#ifndef SENTRY_SDK_NAME +# ifdef __ANDROID__ +# define SENTRY_SDK_NAME "sentry.native.android" +# else +# define SENTRY_SDK_NAME "sentry.native" +# endif +#endif +#define SENTRY_SDK_VERSION "0.5.0" #define SENTRY_SDK_USER_AGENT SENTRY_SDK_NAME "/" SENTRY_SDK_VERSION /* common platform detection */ @@ -403,8 +409,8 @@ SENTRY_EXPERIMENTAL_API sentry_value_t sentry_value_new_thread( * * See https://develop.sentry.dev/sdk/event-payloads/stacktrace/ * - * The returned object needs to be attached to either an exception - * event, or a thread object. + * The returned object must be attached to either an exception or thread + * object. * * If `ips` is NULL the current stack trace is captured, otherwise `len` * stack trace instruction pointers are attached to the event. @@ -412,6 +418,17 @@ SENTRY_EXPERIMENTAL_API sentry_value_t sentry_value_new_thread( SENTRY_EXPERIMENTAL_API sentry_value_t sentry_value_new_stacktrace( void **ips, size_t len); +/** + * Sets the Stack Trace conforming to the Stack Trace Interface in a value. + * + * The value argument must be either an exception or thread object. + * + * If `ips` is NULL the current stack trace is captured, otherwise `len` stack + * trace instruction pointers are attached to the event. + */ +SENTRY_EXPERIMENTAL_API void sentry_value_set_stacktrace( + sentry_value_t value, void **ips, size_t len); + /** * Adds an Exception to an Event value. * @@ -561,7 +578,6 @@ SENTRY_API void sentry_envelope_free(sentry_envelope_t *envelope); SENTRY_API sentry_value_t sentry_envelope_get_event( const sentry_envelope_t *envelope); -#ifdef SENTRY_PERFORMANCE_MONITORING /** * Given an Envelope, returns the embedded Transaction if there is one. * @@ -569,7 +585,6 @@ SENTRY_API sentry_value_t sentry_envelope_get_event( */ SENTRY_EXPERIMENTAL_API sentry_value_t sentry_envelope_get_transaction( const sentry_envelope_t *envelope); -#endif /** * Serializes the envelope. @@ -705,6 +720,20 @@ SENTRY_API void sentry_transport_free(sentry_transport_t *transport); SENTRY_API sentry_transport_t *sentry_new_function_transport( void (*func)(const sentry_envelope_t *envelope, void *data), void *data); +/** + * This represents an interface for user-defined backends. + * + * Backends are responsible to handle crashes. They are maintained at runtime + * via various life-cycle hooks from the sentry-core. + * + * At this point none of those interfaces are exposed in the API including + * creation and destruction. The main use-case of the backend in the API at this + * point is to disable it via `sentry_options_set_backend` at runtime before it + * is initialized. + */ +struct sentry_backend_s; +typedef struct sentry_backend_s sentry_backend_t; + /* -- Options APIs -- */ /** @@ -741,11 +770,23 @@ SENTRY_API void sentry_options_set_transport( * call `sentry_value_decref` on the provided event, and return a * `sentry_value_new_null()` instead. * + * If you have set an `on_crash` callback (independent of whether it discards or + * retains the event), `before_send` will no longer be invoked for crash-events, + * which allows you to better distinguish between crashes and all other events + * in client-side pre-processing. + * * This function may be invoked inside of a signal handler and must be safe for * that purpose, see https://man7.org/linux/man-pages/man7/signal-safety.7.html. * On Windows, it may be called from inside of a `UnhandledExceptionFilter`, see * the documentation on SEH (structured exception handling) for more information * https://docs.microsoft.com/en-us/windows/win32/debug/structured-exception-handling + * + * Up to version 0.4.18 the `before_send` callback wasn't invoked in case the + * event sampling discarded an event. In the current implementation the + * `before_send` callback is invoked even if the event sampling discards the + * event, following the cross-SDK session filter order: + * + * https://develop.sentry.dev/sdk/sessions/#filter-order */ typedef sentry_value_t (*sentry_event_function_t)( sentry_value_t event, void *hint, void *closure); @@ -758,6 +799,60 @@ typedef sentry_value_t (*sentry_event_function_t)( SENTRY_API void sentry_options_set_before_send( sentry_options_t *opts, sentry_event_function_t func, void *data); +/** + * Type of the `on_crash` callback. + * + * The `on_crash` callback replaces the `before_send` callback for crash events. + * The interface is analogous to `before_send` in that the callback takes + * ownership of the `event`, and should usually return that same event. In case + * the event should be discarded, the callback needs to call + * `sentry_value_decref` on the provided event, and return a + * `sentry_value_new_null()` instead. + * + * Only the `inproc` backend currently fills the passed-in event with useful + * data and processes any modifications to the return value. Since both + * `breakpad` and `crashpad` use minidumps to capture the crash state, the + * passed-in event is empty when using these backends, and they ignore any + * changes to the return value. + * + * If you set this callback in the options, it prevents a concurrently enabled + * `before_send` callback from being invoked in the crash case. This allows for + * better differentiation between crashes and other events and gradual migration + * from existing `before_send` implementations: + * + * - if you have a `before_send` implementation and do not define an `on_crash` + * callback your application will receive both normal and crash events as + * before + * - if you have a `before_send` implementation but only want to handle normal + * events with it, then you can define an `on_crash` callback that returns + * the passed-in event and does nothing else + * - if you are not interested in normal events, but only want to act on + * crashes (within the limits mentioned below), then only define an + * `on_crash` callback with the option to filter (on all backends) or enrich + * (only inproc) the crash event + * + * This function may be invoked inside of a signal handler and must be safe for + * that purpose, see https://man7.org/linux/man-pages/man7/signal-safety.7.html. + * On Windows, it may be called from inside of a `UnhandledExceptionFilter`, see + * the documentation on SEH (structured exception handling) for more information + * https://docs.microsoft.com/en-us/windows/win32/debug/structured-exception-handling + * + * Platform-specific behavior: + * + * - does not work with crashpad on macOS. + * - for breakpad on Linux the `uctx` parameter is always NULL. + */ +typedef sentry_value_t (*sentry_crash_function_t)( + const sentry_ucontext_t *uctx, sentry_value_t event, void *closure); + +/** + * Sets the `on_crash` callback. + * + * See the `sentry_crash_function_t` typedef above for more information. + */ +SENTRY_API void sentry_options_set_on_crash( + sentry_options_t *opts, sentry_crash_function_t func, void *data); + /** * Sets the DSN. */ @@ -772,6 +867,19 @@ SENTRY_API const char *sentry_options_get_dsn(const sentry_options_t *opts); * Sets the sample rate, which should be a double between `0.0` and `1.0`. * Sentry will randomly discard any event that is captured using * `sentry_capture_event` when a sample rate < 1 is set. + * + * The sampling happens at the end of the event processing according to the + * following order: + * + * https://develop.sentry.dev/sdk/sessions/#filter-order + * + * Only items 3. to 6. are currently applicable to sentry-native. This means + * each processing step is executed even if the sampling discards the event + * before sending it to the backend. This is particularly relevant to users of + * the `before_send` callback. + * + * The above is in contrast to versions up to 0.4.18 where the sampling happened + * at the beginning of the processing/filter sequence. */ SENTRY_API void sentry_options_set_sample_rate( sentry_options_t *opts, double sample_rate); @@ -1046,6 +1154,16 @@ SENTRY_API void sentry_options_set_shutdown_timeout( */ SENTRY_API uint64_t sentry_options_get_shutdown_timeout(sentry_options_t *opts); +/** + * Sets a user-defined backend. + * + * Since creation and destruction of backends is not exposed in the API, this + * can only be used to set the backend to `NULL`, which disables the backend in + * the initialization. + */ +SENTRY_API void sentry_options_set_backend( + sentry_options_t *opts, sentry_backend_t *backend); + /* -- Global APIs -- */ /** @@ -1137,9 +1255,9 @@ SENTRY_API sentry_user_consent_t sentry_user_consent_get(void); /** * Sends a sentry event. * - * If SENTRY_PERFORMANCE_MONITORING is enabled, returns a nil UUID if the event - * being passed in is a transaction, and the transaction will not be sent nor - * consumed. `sentry_transaction_finish` should be used to send transactions. + * If returns a nil UUID if the event being passed in is a transaction, and the + * transaction will not be sent nor consumed. `sentry_transaction_finish` should + * be used to send transactions. */ SENTRY_API sentry_uuid_t sentry_capture_event(sentry_value_t event); @@ -1229,7 +1347,6 @@ SENTRY_API void sentry_start_session(void); */ SENTRY_API void sentry_end_session(void); -#ifdef SENTRY_PERFORMANCE_MONITORING /** * Sets the maximum number of spans that can be attached to a * transaction. @@ -1708,7 +1825,48 @@ SENTRY_EXPERIMENTAL_API void sentry_transaction_iter_headers( sentry_transaction_t *tx, sentry_iter_headers_function_t callback, void *userdata); -#endif +/** + * Returns whether the application has crashed on the last run. + * + * Notes: + * * The underlying value is set by sentry_init() - it must be called first. + * * Call sentry_clear_crashed_last_run() to reset for the next app run. + * + * Possible return values: + * 1 = the last run was a crash + * 0 = no crash recognized + * -1 = sentry_init() hasn't been called yet + */ +SENTRY_EXPERIMENTAL_API int sentry_get_crashed_last_run(); + +/** + * Clear the status of the "crashed-last-run". You should explicitly call + * this after sentry_init() if you're using sentry_get_crashed_last_run(). + * Otherwise, the same information is reported on any subsequent runs. + * + * Notes: + * * This doesn't change the value of sentry_get_crashed_last_run() yet. + * However, if sentry_init() is called again, the value will change. + * * This may only be called after sentry_init() and before sentry_close(). + * + * Returns 0 on success, 1 on error. + */ +SENTRY_EXPERIMENTAL_API int sentry_clear_crashed_last_run(); + +/** + * Sentry SDK version. + */ +SENTRY_EXPERIMENTAL_API const char *sentry_sdk_version(); + +/** + * Sentry SDK name. + */ +SENTRY_EXPERIMENTAL_API const char *sentry_sdk_name(); + +/** + * Sentry SDK User-Agent. + */ +SENTRY_EXPERIMENTAL_API const char *sentry_sdk_user_agent(); #ifdef __cplusplus } diff --git a/thirdparty/sentry-native/src/CMakeLists.txt b/thirdparty/sentry-native/src/CMakeLists.txt index 22fa09f227..1a7ba59490 100644 --- a/thirdparty/sentry-native/src/CMakeLists.txt +++ b/thirdparty/sentry-native/src/CMakeLists.txt @@ -10,6 +10,7 @@ sentry_target_sources_cwd(sentry sentry_database.h sentry_envelope.c sentry_envelope.h + sentry_info.c sentry_json.c sentry_json.h sentry_logger.c @@ -42,6 +43,8 @@ sentry_target_sources_cwd(sentry sentry_uuid.h sentry_value.c sentry_value.h + sentry_tracing.c + sentry_tracing.h path/sentry_path.c transports/sentry_disk_transport.c transports/sentry_disk_transport.h @@ -151,11 +154,3 @@ if(SENTRY_INTEGRATION_QT) integrations/sentry_integration_qt.h ) endif() - -if(SENTRY_BUILD_EXAMPLES) - target_compile_definitions(sentry PRIVATE SENTRY_PERFORMANCE_MONITORING) - sentry_target_sources_cwd(sentry - sentry_tracing.c - sentry_tracing.h - ) -endif() diff --git a/thirdparty/sentry-native/src/backends/sentry_backend_breakpad.cpp b/thirdparty/sentry-native/src/backends/sentry_backend_breakpad.cpp index eaf596d17c..1c22e43e95 100644 --- a/thirdparty/sentry-native/src/backends/sentry_backend_breakpad.cpp +++ b/thirdparty/sentry-native/src/backends/sentry_backend_breakpad.cpp @@ -40,7 +40,7 @@ extern "C" { static bool sentry__breakpad_backend_callback(const wchar_t *breakpad_dump_path, const wchar_t *minidump_id, void *UNUSED(context), - EXCEPTION_POINTERS *UNUSED(exinfo), MDRawAssertionInfo *UNUSED(assertion), + EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *UNUSED(assertion), bool succeeded) #elif defined(SENTRY_PLATFORM_DARWIN) static bool @@ -91,46 +91,70 @@ sentry__breakpad_backend_callback( #else dump_path = sentry__path_new(descriptor.path()); #endif + sentry_value_t event = sentry_value_new_event(); SENTRY_WITH_OPTIONS (options) { sentry__write_crash_marker(options); - sentry_value_t event = sentry_value_new_event(); - sentry_envelope_t *envelope - = sentry__prepare_event(options, event, NULL); - // the event we just prepared is empty, so no error is recorded for it - sentry__record_errors_on_current_session(1); - sentry_session_t *session = sentry__end_current_session_with_status( - SENTRY_SESSION_STATUS_CRASHED); - sentry__envelope_add_session(envelope, session); + bool should_handle = true; - // the minidump is added as an attachment, with type `event.minidump` - sentry_envelope_item_t *item - = sentry__envelope_add_from_path(envelope, dump_path, "attachment"); - if (item) { - sentry__envelope_item_set_header(item, "attachment_type", - sentry_value_new_string("event.minidump")); + if (options->on_crash_func) { + sentry_ucontext_t *uctx = nullptr; - sentry__envelope_item_set_header(item, "filename", #ifdef SENTRY_PLATFORM_WINDOWS - sentry__value_new_string_from_wstr( -#else - sentry_value_new_string( + sentry_ucontext_t uctx_data; + uctx_data.exception_ptrs = *exinfo; + uctx = &uctx_data; #endif - sentry__path_filename(dump_path))); + + SENTRY_TRACE("invoking `on_crash` hook"); + sentry_value_t result + = options->on_crash_func(uctx, event, options->on_crash_data); + should_handle = !sentry_value_is_null(result); } - // capture the envelope with the disk transport - sentry_transport_t *disk_transport - = sentry_new_disk_transport(options->run); - sentry__capture_envelope(disk_transport, envelope); - sentry__transport_dump_queue(disk_transport, options->run); - sentry_transport_free(disk_transport); + if (should_handle) { + sentry_envelope_t *envelope = sentry__prepare_event( + options, event, nullptr, !options->on_crash_func); + // the event we just prepared is empty, + // so no error is recorded for it + sentry__record_errors_on_current_session(1); + sentry_session_t *session = sentry__end_current_session_with_status( + SENTRY_SESSION_STATUS_CRASHED); + sentry__envelope_add_session(envelope, session); - // now that the envelope was written, we can remove the temporary - // minidump file - sentry__path_remove(dump_path); - sentry__path_free(dump_path); + // the minidump is added as an attachment, + // with type `event.minidump` + sentry_envelope_item_t *item = sentry__envelope_add_from_path( + envelope, dump_path, "attachment"); + if (item) { + sentry__envelope_item_set_header(item, "attachment_type", + sentry_value_new_string("event.minidump")); + + sentry__envelope_item_set_header(item, "filename", +#ifdef SENTRY_PLATFORM_WINDOWS + sentry__value_new_string_from_wstr( +#else + sentry_value_new_string( +#endif + sentry__path_filename(dump_path))); + } + + // capture the envelope with the disk transport + sentry_transport_t *disk_transport + = sentry_new_disk_transport(options->run); + sentry__capture_envelope(disk_transport, envelope); + sentry__transport_dump_queue(disk_transport, options->run); + sentry_transport_free(disk_transport); + + // now that the envelope was written, we can remove the temporary + // minidump file + sentry__path_remove(dump_path); + sentry__path_free(dump_path); + } else { + SENTRY_TRACE("event was discarded by the `on_crash` hook"); + sentry_value_decref(event); + } // after capturing the crash event, try to dump all the in-flight // data of the previous transports diff --git a/thirdparty/sentry-native/src/backends/sentry_backend_crashpad.cpp b/thirdparty/sentry-native/src/backends/sentry_backend_crashpad.cpp index dcebd9c7e5..09002543a7 100644 --- a/thirdparty/sentry-native/src/backends/sentry_backend_crashpad.cpp +++ b/thirdparty/sentry-native/src/backends/sentry_backend_crashpad.cpp @@ -31,7 +31,11 @@ extern "C" { #include "client/crash_report_database.h" #include "client/crashpad_client.h" #include "client/crashpad_info.h" +#include "client/prune_crash_reports.h" #include "client/settings.h" +#if defined(_MSC_VER) +# include "util/win/termination_codes.h" +#endif #if defined(__GNUC__) # pragma GCC diagnostic pop @@ -42,6 +46,7 @@ extern "C" { extern "C" { #ifdef SENTRY_PLATFORM_LINUX +# include # define SIGNAL_STACK_SIZE 65536 static stack_t g_signal_stack; @@ -121,44 +126,63 @@ sentry__crashpad_backend_flush_scope( #if defined(SENTRY_PLATFORM_LINUX) || defined(SENTRY_PLATFORM_WINDOWS) # ifdef SENTRY_PLATFORM_WINDOWS static bool -sentry__crashpad_handler(EXCEPTION_POINTERS *UNUSED(ExceptionInfo)) +sentry__crashpad_handler(EXCEPTION_POINTERS *ExceptionInfo) { # else static bool -sentry__crashpad_handler(int UNUSED(signum), siginfo_t *UNUSED(info), - ucontext_t *UNUSED(user_context)) +sentry__crashpad_handler(int signum, siginfo_t *info, ucontext_t *user_context) { sentry__page_allocator_enable(); sentry__enter_signal_handler(); # endif SENTRY_DEBUG("flushing session and queue before crashpad handler"); - SENTRY_WITH_OPTIONS (options) { - sentry__write_crash_marker(options); + bool should_dump = true; + sentry_value_t event = sentry_value_new_event(); - sentry_value_t event = sentry_value_new_event(); - if (options->before_send_func) { + SENTRY_WITH_OPTIONS (options) { + + if (options->on_crash_func) { + sentry_ucontext_t uctx; +# ifdef SENTRY_PLATFORM_WINDOWS + uctx.exception_ptrs = *ExceptionInfo; +# else + uctx.signum = signum; + uctx.siginfo = info; + uctx.user_context = user_context; +# endif + + SENTRY_TRACE("invoking `on_crash` hook"); + event + = options->on_crash_func(&uctx, event, options->on_crash_data); + } else if (options->before_send_func) { SENTRY_TRACE("invoking `before_send` hook"); event = options->before_send_func( - event, NULL, options->before_send_data); + event, nullptr, options->before_send_data); } + should_dump = !sentry_value_is_null(event); sentry_value_decref(event); - sentry__record_errors_on_current_session(1); - sentry_session_t *session = sentry__end_current_session_with_status( - SENTRY_SESSION_STATUS_CRASHED); - if (session) { - sentry_envelope_t *envelope = sentry__envelope_new(); - sentry__envelope_add_session(envelope, session); + if (should_dump) { + sentry__write_crash_marker(options); - // capture the envelope with the disk transport - sentry_transport_t *disk_transport - = sentry_new_disk_transport(options->run); - sentry__capture_envelope(disk_transport, envelope); - sentry__transport_dump_queue(disk_transport, options->run); - sentry_transport_free(disk_transport); + sentry__record_errors_on_current_session(1); + sentry_session_t *session = sentry__end_current_session_with_status( + SENTRY_SESSION_STATUS_CRASHED); + if (session) { + sentry_envelope_t *envelope = sentry__envelope_new(); + sentry__envelope_add_session(envelope, session); + + // capture the envelope with the disk transport + sentry_transport_t *disk_transport + = sentry_new_disk_transport(options->run); + sentry__capture_envelope(disk_transport, envelope); + sentry__transport_dump_queue(disk_transport, options->run); + sentry_transport_free(disk_transport); + } + } else { + SENTRY_TRACE("event was discarded"); } - sentry__transport_dump_queue(options->transport, options->run); } @@ -166,6 +190,41 @@ sentry__crashpad_handler(int UNUSED(signum), siginfo_t *UNUSED(info), # ifndef SENTRY_PLATFORM_WINDOWS sentry__leave_signal_handler(); # endif + + // If we __don't__ want a minidump produced by crashpad we need to either + // exit or longjmp at this point. The crashpad client handler which calls + // back here (SetFirstChanceExceptionHandler) does the same if the + // application is not shutdown via the crashpad_handler process. + // + // If we would return `true` here without changing any of the global signal- + // handling state or rectifying the cause of the signal, this would turn + // into a signal-handler/exception-filter loop, because some + // signals/exceptions (like SIGSEGV) are unrecoverable. + // + // Ideally the SetFirstChanceExceptionHandler would accept more than a + // boolean to differentiate between: + // + // * we accept our fate and want a minidump (currently returning `false`) + // * we accept our fate and don't want a minidump (currently not available) + // * we rectified the situation, so crashpads signal-handler can simply + // return, thereby letting the not-rectified signal-cause trigger a + // signal-handler/exception-filter again, which probably leads to us + // (currently returning `true`) + // + // TODO(supervacuus): + // * we need integration tests for more signal/exception types not only + // for unmapped memory access (which is the current crash in example.c). + // * we should adapt the SetFirstChanceExceptionHandler interface in + // crashpad + if (!should_dump) { +# ifdef SENTRY_PLATFORM_WINDOWS + TerminateProcess(GetCurrentProcess(), + crashpad::TerminationCodes::kTerminationCodeCrashNoDump); +# else + _exit(EXIT_FAILURE); +# endif + } + // we did not "handle" the signal, so crashpad should do that. return false; } @@ -408,14 +467,6 @@ sentry__crashpad_backend_last_crash(sentry_backend_t *backend) uint64_t crash_time = 0; std::vector reports; - if (data->db->GetPendingReports(&reports) - == crashpad::CrashReportDatabase::kNoError) { - for (const crashpad::CrashReportDatabase::Report &report : reports) { - report_crash_time(&crash_time, report); - } - } - - reports.clear(); if (data->db->GetCompletedReports(&reports) == crashpad::CrashReportDatabase::kNoError) { for (const crashpad::CrashReportDatabase::Report &report : reports) { @@ -426,6 +477,22 @@ sentry__crashpad_backend_last_crash(sentry_backend_t *backend) return crash_time; } +static void +sentry__crashpad_backend_prune_database(sentry_backend_t *backend) +{ + crashpad_state_t *data = (crashpad_state_t *)backend->data; + + // We want to eagerly clean up reports older than 2 days, and limit the + // complete database to a maximum of 8M. That might still be a lot for + // an embedded use-case, but minidumps on desktop can sometimes be quite + // large. + data->db->CleanDatabase(60 * 60 * 24 * 2); + crashpad::BinaryPruneCondition condition(crashpad::BinaryPruneCondition::OR, + new crashpad::DatabaseSizePruneCondition(1024 * 8), + new crashpad::AgePruneCondition(2)); + crashpad::PruneCrashReportDatabase(data->db, &condition); +} + sentry_backend_t * sentry__backend_new(void) { @@ -451,6 +518,7 @@ sentry__backend_new(void) backend->user_consent_changed_func = sentry__crashpad_backend_user_consent_changed; backend->get_last_crash_func = sentry__crashpad_backend_last_crash; + backend->prune_database_func = sentry__crashpad_backend_prune_database; backend->data = data; backend->can_capture_after_shutdown = true; diff --git a/thirdparty/sentry-native/src/backends/sentry_backend_inproc.c b/thirdparty/sentry-native/src/backends/sentry_backend_inproc.c index 2318e27746..32887a0334 100644 --- a/thirdparty/sentry-native/src/backends/sentry_backend_inproc.c +++ b/thirdparty/sentry-native/src/backends/sentry_backend_inproc.c @@ -114,7 +114,8 @@ shutdown_inproc_backend(sentry_backend_t *UNUSED(backend)) reset_signal_handlers(); } -#elif defined SENTRY_PLATFORM_WINDOWS +#elif defined(SENTRY_PLATFORM_WINDOWS) + struct signal_slot { DWORD signum; const char *signame; @@ -168,8 +169,273 @@ shutdown_inproc_backend(sentry_backend_t *UNUSED(backend)) SetUnhandledExceptionFilter(current_handler); } } + #endif +sentry_value_t +sentry__registers_from_uctx(const sentry_ucontext_t *uctx) +{ + sentry_value_t registers = sentry_value_new_object(); + +#if defined(SENTRY_PLATFORM_LINUX) + + // just assume the ctx is a bunch of uintpr_t, and index that directly + uintptr_t *ctx = (uintptr_t *)&uctx->user_context->uc_mcontext; + +# define SET_REG(name, num) \ + sentry_value_set_by_key(registers, name, \ + sentry__value_new_addr((uint64_t)(size_t)ctx[num])); + +# if defined(__x86_64__) + + SET_REG("r8", 0); + SET_REG("r9", 1); + SET_REG("r10", 2); + SET_REG("r11", 3); + SET_REG("r12", 4); + SET_REG("r13", 5); + SET_REG("r14", 6); + SET_REG("r15", 7); + SET_REG("rdi", 8); + SET_REG("rsi", 9); + SET_REG("rbp", 10); + SET_REG("rbx", 11); + SET_REG("rdx", 12); + SET_REG("rax", 13); + SET_REG("rcx", 14); + SET_REG("rsp", 15); + SET_REG("rip", 16); + +# elif defined(__i386__) + + // gs, fs, es, ds + SET_REG("edi", 4); + SET_REG("esi", 5); + SET_REG("ebp", 6); + SET_REG("esp", 7); + SET_REG("ebx", 8); + SET_REG("edx", 9); + SET_REG("ecx", 10); + SET_REG("eax", 11); + SET_REG("eip", 14); + SET_REG("eflags", 16); + +# elif defined(__aarch64__) + + // 0 is `fault_address` + SET_REG("x0", 1); + SET_REG("x1", 2); + SET_REG("x2", 3); + SET_REG("x3", 4); + SET_REG("x4", 5); + SET_REG("x5", 6); + SET_REG("x6", 7); + SET_REG("x7", 8); + SET_REG("x8", 9); + SET_REG("x9", 10); + SET_REG("x10", 11); + SET_REG("x11", 12); + SET_REG("x12", 13); + SET_REG("x13", 14); + SET_REG("x14", 15); + SET_REG("x15", 16); + SET_REG("x16", 17); + SET_REG("x17", 18); + SET_REG("x18", 19); + SET_REG("x19", 20); + SET_REG("x20", 21); + SET_REG("x21", 22); + SET_REG("x22", 23); + SET_REG("x23", 24); + SET_REG("x24", 25); + SET_REG("x25", 26); + SET_REG("x26", 27); + SET_REG("x27", 28); + SET_REG("x28", 29); + SET_REG("fp", 30); + SET_REG("lr", 31); + SET_REG("sp", 32); + SET_REG("pc", 33); + +# elif defined(__arm__) + + // trap_no, _error_code, oldmask + SET_REG("r0", 3); + SET_REG("r1", 4); + SET_REG("r2", 5); + SET_REG("r3", 6); + SET_REG("r4", 7); + SET_REG("r5", 8); + SET_REG("r6", 9); + SET_REG("r7", 10); + SET_REG("r8", 11); + SET_REG("r9", 12); + SET_REG("r10", 13); + SET_REG("fp", 14); + SET_REG("ip", 15); + SET_REG("sp", 16); + SET_REG("lr", 17); + SET_REG("pc", 18); + +# endif + +# undef SET_REG + +#elif defined(SENTRY_PLATFORM_DARWIN) + +# define SET_REG(name, prop) \ + sentry_value_set_by_key(registers, name, \ + sentry__value_new_addr((uint64_t)(size_t)thread_state->prop)); + +# if defined(__x86_64__) + + _STRUCT_X86_THREAD_STATE64 *thread_state + = &uctx->user_context->uc_mcontext->__ss; + + SET_REG("rax", __rax); + SET_REG("rbx", __rbx); + SET_REG("rcx", __rcx); + SET_REG("rdx", __rdx); + SET_REG("rdi", __rdi); + SET_REG("rsi", __rsi); + SET_REG("rbp", __rbp); + SET_REG("rsp", __rsp); + SET_REG("r8", __r8); + SET_REG("r9", __r9); + SET_REG("r10", __r10); + SET_REG("r11", __r11); + SET_REG("r12", __r12); + SET_REG("r13", __r13); + SET_REG("r14", __r14); + SET_REG("r15", __r15); + SET_REG("rip", __rip); + +# elif defined(__arm64__) + + _STRUCT_ARM_THREAD_STATE64 *thread_state + = &uctx->user_context->uc_mcontext->__ss; + + SET_REG("x0", __x[0]); + SET_REG("x1", __x[1]); + SET_REG("x2", __x[2]); + SET_REG("x3", __x[3]); + SET_REG("x4", __x[4]); + SET_REG("x5", __x[5]); + SET_REG("x6", __x[6]); + SET_REG("x7", __x[7]); + SET_REG("x8", __x[8]); + SET_REG("x9", __x[9]); + SET_REG("x10", __x[10]); + SET_REG("x11", __x[11]); + SET_REG("x12", __x[12]); + SET_REG("x13", __x[13]); + SET_REG("x14", __x[14]); + SET_REG("x15", __x[15]); + SET_REG("x16", __x[16]); + SET_REG("x17", __x[17]); + SET_REG("x18", __x[18]); + SET_REG("x19", __x[19]); + SET_REG("x20", __x[20]); + SET_REG("x21", __x[21]); + SET_REG("x22", __x[22]); + SET_REG("x23", __x[23]); + SET_REG("x24", __x[24]); + SET_REG("x25", __x[25]); + SET_REG("x26", __x[26]); + SET_REG("x27", __x[27]); + SET_REG("x28", __x[28]); + SET_REG("fp", __fp); + SET_REG("lr", __lr); + SET_REG("sp", __sp); + SET_REG("pc", __pc); + +# elif defined(__arm__) + + _STRUCT_ARM_THREAD_STATE *thread_state + = &uctx->user_context->uc_mcontext->__ss; + + SET_REG("r0", __r[0]); + SET_REG("r1", __r[1]); + SET_REG("r2", __r[2]); + SET_REG("r3", __r[3]); + SET_REG("r4", __r[4]); + SET_REG("r5", __r[5]); + SET_REG("r6", __r[6]); + SET_REG("r7", __r[7]); + SET_REG("r8", __r[8]); + SET_REG("r9", __r[9]); + SET_REG("r10", __r[10]); + SET_REG("fp", __r[11]); + SET_REG("ip", __r[12]); + SET_REG("sp", __sp); + SET_REG("lr", __lr); + SET_REG("pc", __pc); + +# endif + +# undef SET_REG + +#elif defined(SENTRY_PLATFORM_WINDOWS) + PCONTEXT ctx = uctx->exception_ptrs.ContextRecord; + +# define SET_REG(name, prop) \ + sentry_value_set_by_key(registers, name, \ + sentry__value_new_addr((uint64_t)(size_t)ctx->prop)); + +# if defined(_M_AMD64) + + if (ctx->ContextFlags & CONTEXT_INTEGER) { + SET_REG("rax", Rax); + SET_REG("rcx", Rcx); + SET_REG("rdx", Rdx); + SET_REG("rbx", Rbx); + SET_REG("rbp", Rbp); + SET_REG("rsi", Rsi); + SET_REG("rdi", Rdi); + SET_REG("r8", R8); + SET_REG("r9", R9); + SET_REG("r10", R10); + SET_REG("r11", R11); + SET_REG("r12", R12); + SET_REG("r13", R13); + SET_REG("r14", R14); + SET_REG("r15", R15); + } + + if (ctx->ContextFlags & CONTEXT_CONTROL) { + SET_REG("rsp", Rsp); + SET_REG("rip", Rip); + } + +# elif defined(_M_IX86) + + if (ctx->ContextFlags & CONTEXT_INTEGER) { + SET_REG("edi", Edi); + SET_REG("esi", Esi); + SET_REG("ebx", Ebx); + SET_REG("edx", Edx); + SET_REG("ecx", Ecx); + SET_REG("eax", Eax); + } + + if (ctx->ContextFlags & CONTEXT_CONTROL) { + SET_REG("ebp", Ebp); + SET_REG("eip", Eip); + SET_REG("eflags", EFlags); + SET_REG("esp", Esp); + } + +# else + // _ARM64_ +# endif + +# undef SET_REG + +#endif + + return registers; +} + static sentry_value_t make_signal_event( const struct signal_slot *sig_slot, const sentry_ucontext_t *uctx) @@ -217,8 +483,10 @@ make_signal_event( sentry_value_t stacktrace = sentry_value_new_stacktrace(&backtrace[0], frame_count); - sentry_value_set_by_key(exc, "stacktrace", stacktrace); + sentry_value_t registers = sentry__registers_from_uctx(uctx); + sentry_value_set_by_key(stacktrace, "registers", registers); + sentry_value_set_by_key(exc, "stacktrace", stacktrace); sentry_event_add_exception(event, exc); return event; @@ -258,21 +526,34 @@ handle_ucontext(const sentry_ucontext_t *uctx) SENTRY_WITH_OPTIONS (options) { sentry__write_crash_marker(options); - sentry_envelope_t *envelope - = sentry__prepare_event(options, event, NULL); - // TODO(tracing): Revisit when investigating transaction flushing during - // hard crashes. + bool should_handle = true; - sentry_session_t *session = sentry__end_current_session_with_status( - SENTRY_SESSION_STATUS_CRASHED); - sentry__envelope_add_session(envelope, session); + if (options->on_crash_func) { + SENTRY_TRACE("invoking `on_crash` hook"); + event = options->on_crash_func(uctx, event, options->on_crash_data); + should_handle = !sentry_value_is_null(event); + } - // capture the envelope with the disk transport - sentry_transport_t *disk_transport - = sentry_new_disk_transport(options->run); - sentry__capture_envelope(disk_transport, envelope); - sentry__transport_dump_queue(disk_transport, options->run); - sentry_transport_free(disk_transport); + if (should_handle) { + sentry_envelope_t *envelope = sentry__prepare_event( + options, event, NULL, !options->on_crash_func); + // TODO(tracing): Revisit when investigating transaction flushing + // during hard crashes. + + sentry_session_t *session = sentry__end_current_session_with_status( + SENTRY_SESSION_STATUS_CRASHED); + sentry__envelope_add_session(envelope, session); + + // capture the envelope with the disk transport + sentry_transport_t *disk_transport + = sentry_new_disk_transport(options->run); + sentry__capture_envelope(disk_transport, envelope); + sentry__transport_dump_queue(disk_transport, options->run); + sentry_transport_free(disk_transport); + } else { + SENTRY_TRACE("event was discarded by the `on_crash` hook"); + sentry_value_decref(event); + } // after capturing the crash event, dump all the envelopes to disk sentry__transport_dump_queue(options->transport, options->run); diff --git a/thirdparty/sentry-native/src/modulefinder/sentry_modulefinder_windows.c b/thirdparty/sentry-native/src/modulefinder/sentry_modulefinder_windows.c index 26e6aa2063..31d5449842 100644 --- a/thirdparty/sentry-native/src/modulefinder/sentry_modulefinder_windows.c +++ b/thirdparty/sentry-native/src/modulefinder/sentry_modulefinder_windows.c @@ -38,43 +38,54 @@ extract_pdb_info(uintptr_t module_addr, sentry_value_t module) return; } - uint32_t relative_addr - = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] - .VirtualAddress; - if (!relative_addr) { - return; - } - - PIMAGE_DEBUG_DIRECTORY debug_dict - = (PIMAGE_DEBUG_DIRECTORY)(module_addr + relative_addr); - if (!debug_dict || debug_dict->Type != IMAGE_DEBUG_TYPE_CODEVIEW) { - return; - } - - struct CodeViewRecord70 *debug_info - = (struct CodeViewRecord70 *)(module_addr - + debug_dict->AddressOfRawData); - if (!debug_info || debug_info->signature != CV_SIGNATURE) { - return; - } - - sentry_value_set_by_key(module, "debug_file", - sentry_value_new_string(debug_info->pdb_filename)); - - sentry_uuid_t debug_id_base - = sentry__uuid_from_native(&debug_info->pdb_signature); char id_buf[50]; - sentry_uuid_as_string(&debug_id_base, id_buf); - id_buf[36] = '-'; - snprintf(id_buf + 37, 10, "%x", debug_info->pdb_age); - sentry_value_set_by_key( - module, "debug_id", sentry_value_new_string(id_buf)); - snprintf(id_buf, sizeof(id_buf), "%08x%X", nt_headers->FileHeader.TimeDateStamp, nt_headers->OptionalHeader.SizeOfImage); sentry_value_set_by_key(module, "code_id", sentry_value_new_string(id_buf)); - sentry_value_set_by_key(module, "type", sentry_value_new_string("pe")); + + IMAGE_DATA_DIRECTORY debug_entry + = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; + + size_t relative_addr = (size_t)debug_entry.VirtualAddress; + if (!relative_addr) { + return; + } + + size_t table_size = (size_t)debug_entry.Size; + size_t entry_size = sizeof(IMAGE_DEBUG_DIRECTORY); + if (table_size % entry_size != 0) { + return; + } + + for (size_t offset = 0; offset < table_size; offset += entry_size) { + PIMAGE_DEBUG_DIRECTORY debug_dict + = (PIMAGE_DEBUG_DIRECTORY)(module_addr + relative_addr + offset); + + if (debug_dict->Type != IMAGE_DEBUG_TYPE_CODEVIEW) { + continue; + } + + struct CodeViewRecord70 *debug_info + = (struct CodeViewRecord70 *)(module_addr + + debug_dict->AddressOfRawData); + if (debug_info->signature != CV_SIGNATURE) { + continue; + } + + sentry_value_set_by_key(module, "debug_file", + sentry_value_new_string(debug_info->pdb_filename)); + + sentry_uuid_t debug_id_base + = sentry__uuid_from_native(&debug_info->pdb_signature); + sentry_uuid_as_string(&debug_id_base, id_buf); + id_buf[36] = '-'; + snprintf(id_buf + 37, 10, "%x", debug_info->pdb_age); + sentry_value_set_by_key( + module, "debug_id", sentry_value_new_string(id_buf)); + + return; + } } static void @@ -97,6 +108,8 @@ load_modules(void) module.modBaseAddr, &vmem_info, sizeof(vmem_info)) && vmem_info.State == MEM_COMMIT) { sentry_value_t rv = sentry_value_new_object(); + sentry_value_set_by_key( + rv, "type", sentry_value_new_string("pe")); sentry_value_set_by_key(rv, "image_addr", sentry__value_new_addr((uint64_t)module.modBaseAddr)); sentry_value_set_by_key(rv, "image_size", diff --git a/thirdparty/sentry-native/src/sentry_backend.h b/thirdparty/sentry-native/src/sentry_backend.h index bb954272a8..0c69692782 100644 --- a/thirdparty/sentry-native/src/sentry_backend.h +++ b/thirdparty/sentry-native/src/sentry_backend.h @@ -25,6 +25,7 @@ struct sentry_backend_s { const sentry_options_t *options); void (*user_consent_changed_func)(sentry_backend_t *); uint64_t (*get_last_crash_func)(sentry_backend_t *); + void (*prune_database_func)(sentry_backend_t *); void *data; bool can_capture_after_shutdown; }; diff --git a/thirdparty/sentry-native/src/sentry_core.c b/thirdparty/sentry-native/src/sentry_core.c index 7ab4706145..1a27fe06c9 100644 --- a/thirdparty/sentry-native/src/sentry_core.c +++ b/thirdparty/sentry-native/src/sentry_core.c @@ -16,6 +16,7 @@ #include "sentry_session.h" #include "sentry_string.h" #include "sentry_sync.h" +#include "sentry_tracing.h" #include "sentry_transport.h" #include "sentry_value.h" @@ -23,13 +24,12 @@ # include "integrations/sentry_integration_qt.h" #endif -#ifdef SENTRY_PERFORMANCE_MONITORING -# include "sentry_tracing.h" -#endif - static sentry_options_t *g_options = NULL; static sentry_mutex_t g_options_lock = SENTRY__MUTEX_INIT; +/// see sentry_get_crashed_last_run() for the possible values +static int g_last_crash = -1; + const sentry_options_t * sentry__options_getref(void) { @@ -161,6 +161,7 @@ sentry_init(sentry_options_t *options) last_crash = backend->get_last_crash_func(backend); } + g_last_crash = sentry__has_crash_marker(options); g_options = options; // *after* setting the global options, trigger a scope and consent flush, @@ -181,7 +182,11 @@ sentry_init(sentry_options_t *options) // after initializing the transport, we will submit all the unsent envelopes // and handle remaining sessions. + SENTRY_TRACE("processing and pruning old runs"); sentry__process_old_runs(options, last_crash); + if (backend && backend->prune_database_func) { + backend->prune_database_func(backend); + } if (options->auto_session_tracking) { sentry_start_session(); @@ -367,27 +372,29 @@ event_is_considered_error(sentry_value_t event) return false; } -#ifdef SENTRY_PERFORMANCE_MONITORING bool sentry__event_is_transaction(sentry_value_t event) { sentry_value_t event_type = sentry_value_get_by_key(event, "type"); return sentry__string_eq("transaction", sentry_value_as_string(event_type)); } -#endif sentry_uuid_t sentry_capture_event(sentry_value_t event) { -#ifdef SENTRY_PERFORMANCE_MONITORING if (sentry__event_is_transaction(event)) { return sentry_uuid_nil(); } else { return sentry__capture_event(event); } -#else - return sentry__capture_event(event); -#endif +} + +bool +sentry__roll_dice(double probability) +{ + uint64_t rnd; + return probability >= 1.0 || sentry__getrandom(&rnd, sizeof(rnd)) + || ((double)rnd / (double)UINT64_MAX) <= probability; } sentry_uuid_t @@ -401,15 +408,11 @@ sentry__capture_event(sentry_value_t event) SENTRY_WITH_OPTIONS (options) { was_captured = true; -#ifdef SENTRY_PERFORMANCE_MONITORING if (sentry__event_is_transaction(event)) { envelope = sentry__prepare_transaction(options, event, &event_id); } else { - envelope = sentry__prepare_event(options, event, &event_id); + envelope = sentry__prepare_event(options, event, &event_id, true); } -#else - envelope = sentry__prepare_event(options, event, &event_id); -#endif if (envelope) { if (options->session) { sentry_options_t *mut_options = sentry__options_lock(); @@ -421,8 +424,15 @@ sentry__capture_event(sentry_value_t event) mut_options->session->init = false; sentry__options_unlock(); } - sentry__capture_envelope(options->transport, envelope); - was_sent = true; + + bool should_skip = !sentry__roll_dice(options->sample_rate); + if (should_skip) { + SENTRY_DEBUG("throwing away event due to sample rate"); + sentry_envelope_free(envelope); + } else { + sentry__capture_envelope(options->transport, envelope); + was_sent = true; + } } } if (!was_captured) { @@ -431,15 +441,6 @@ sentry__capture_event(sentry_value_t event) return was_sent ? event_id : sentry_uuid_nil(); } -bool -sentry__roll_dice(double probability) -{ - uint64_t rnd; - return probability >= 1.0 || sentry__getrandom(&rnd, sizeof(rnd)) - || ((double)rnd / (double)UINT64_MAX) <= probability; -} - -#ifdef SENTRY_PERFORMANCE_MONITORING bool sentry__should_send_transaction(sentry_value_t tx_cxt) { @@ -456,11 +457,10 @@ sentry__should_send_transaction(sentry_value_t tx_cxt) } return send; } -#endif sentry_envelope_t * sentry__prepare_event(const sentry_options_t *options, sentry_value_t event, - sentry_uuid_t *event_id) + sentry_uuid_t *event_id, bool invoke_before_send) { sentry_envelope_t *envelope = NULL; @@ -468,12 +468,6 @@ sentry__prepare_event(const sentry_options_t *options, sentry_value_t event, sentry__record_errors_on_current_session(1); } - bool should_skip = !sentry__roll_dice(options->sample_rate); - if (should_skip) { - SENTRY_DEBUG("throwing away event due to sample rate"); - goto fail; - } - SENTRY_WITH_SCOPE (scope) { SENTRY_TRACE("merging scope into event"); sentry_scope_mode_t mode = SENTRY_SCOPE_ALL; @@ -483,7 +477,7 @@ sentry__prepare_event(const sentry_options_t *options, sentry_value_t event, sentry__scope_apply_to_event(scope, options, event, mode); } - if (options->before_send_func) { + if (options->before_send_func && invoke_before_send) { SENTRY_TRACE("invoking `before_send` hook"); event = options->before_send_func(event, NULL, options->before_send_data); @@ -524,7 +518,6 @@ fail: return NULL; } -#ifdef SENTRY_PERFORMANCE_MONITORING sentry_envelope_t * sentry__prepare_transaction(const sentry_options_t *options, sentry_value_t transaction, sentry_uuid_t *event_id) @@ -555,7 +548,6 @@ fail: sentry_value_decref(transaction); return NULL; } -#endif void sentry_handle_exception(const sentry_ucontext_t *uctx) @@ -723,11 +715,9 @@ sentry_set_transaction(const char *transaction) sentry_free(scope->transaction); scope->transaction = sentry__string_clone(transaction); -#ifdef SENTRY_PERFORMANCE_MONITORING if (scope->transaction_object) { sentry_transaction_set_name(scope->transaction_object, transaction); } -#endif } } @@ -739,7 +729,6 @@ sentry_set_level(sentry_level_t level) } } -#ifdef SENTRY_PERFORMANCE_MONITORING sentry_transaction_t * sentry_transaction_start( sentry_transaction_context_t *opaque_tx_cxt, sentry_value_t sampling_ctx) @@ -1019,4 +1008,21 @@ fail: sentry__span_free(opaque_span); return; } -#endif + +int +sentry_get_crashed_last_run() +{ + return g_last_crash; +} + +int +sentry_clear_crashed_last_run() +{ + bool success = false; + sentry_options_t *options = sentry__options_lock(); + if (options) { + success = sentry__clear_crash_marker(options); + } + sentry__options_unlock(); + return success ? 0 : 1; +} diff --git a/thirdparty/sentry-native/src/sentry_core.h b/thirdparty/sentry-native/src/sentry_core.h index 90377d5738..6ee6c387e7 100644 --- a/thirdparty/sentry-native/src/sentry_core.h +++ b/thirdparty/sentry-native/src/sentry_core.h @@ -29,22 +29,19 @@ */ bool sentry__should_skip_upload(void); -#ifdef SENTRY_PERFORMANCE_MONITORING /** * Given a well-formed event, returns whether an event is a transaction or not. * Defaults to false, which will also be returned if the event is malformed. */ bool sentry__event_is_transaction(sentry_value_t event); -#endif /** * Convert the given event into an envelope. This assumes that the event * being passed in is not a transaction. * * More specifically, it will do the following things: - * - sample the event, possibly discarding it, * - apply the scope to it, - * - call the before_send hook on it, + * - call the before_send hook on it (if invoke_before_send == true), * - add the event to a new envelope, * - record errors on the current session, * - add any attachments to the envelope as well @@ -53,14 +50,13 @@ bool sentry__event_is_transaction(sentry_value_t event); * `event_id` out-parameter. */ sentry_envelope_t *sentry__prepare_event(const sentry_options_t *options, - sentry_value_t event, sentry_uuid_t *event_id); + sentry_value_t event, sentry_uuid_t *event_id, bool invoke_before_send); /** * Sends a sentry event, regardless of its type. */ sentry_uuid_t sentry__capture_event(sentry_value_t event); -#ifdef SENTRY_PERFORMANCE_MONITORING /** * Convert the given transaction into an envelope. This assumes that the * event being passed in is a transaction. @@ -78,7 +74,6 @@ sentry_uuid_t sentry__capture_event(sentry_value_t event); */ sentry_envelope_t *sentry__prepare_transaction(const sentry_options_t *options, sentry_value_t transaction, sentry_uuid_t *event_id); -#endif /** * This function will submit the `envelope` to the given `transport`, first @@ -122,9 +117,7 @@ void sentry__options_unlock(void); // these for now are only needed outside of core for tests #ifdef SENTRY_UNITTEST bool sentry__roll_dice(double probability); -# ifdef SENTRY_PERFORMANCE_MONITORING bool sentry__should_send_transaction(sentry_value_t tx_cxt); -# endif #endif #endif diff --git a/thirdparty/sentry-native/src/sentry_database.c b/thirdparty/sentry-native/src/sentry_database.c index a2c1463580..62a619d8a6 100644 --- a/thirdparty/sentry-native/src/sentry_database.c +++ b/thirdparty/sentry-native/src/sentry_database.c @@ -235,6 +235,8 @@ sentry__process_old_runs(const sentry_options_t *options, uint64_t last_crash) sentry__capture_envelope(options->transport, session_envelope); } +static const char *g_last_crash_filename = "last_crash"; + bool sentry__write_crash_marker(const sentry_options_t *options) { @@ -244,7 +246,7 @@ sentry__write_crash_marker(const sentry_options_t *options) } sentry_path_t *marker_path - = sentry__path_join_str(options->database_path, "last_crash"); + = sentry__path_join_str(options->database_path, g_last_crash_filename); if (!marker_path) { sentry_free(iso_time); return false; @@ -260,3 +262,34 @@ sentry__write_crash_marker(const sentry_options_t *options) } return !rv; } + +bool +sentry__has_crash_marker(const sentry_options_t *options) +{ + sentry_path_t *marker_path + = sentry__path_join_str(options->database_path, g_last_crash_filename); + if (!marker_path) { + return false; + } + + bool result = sentry__path_is_file(marker_path); + sentry__path_free(marker_path); + return result; +} + +bool +sentry__clear_crash_marker(const sentry_options_t *options) +{ + sentry_path_t *marker_path + = sentry__path_join_str(options->database_path, g_last_crash_filename); + if (!marker_path) { + return false; + } + + int rv = sentry__path_remove(marker_path); + sentry__path_free(marker_path); + if (rv) { + SENTRY_DEBUG("removing the crash timestamp file has failed"); + } + return !rv; +} diff --git a/thirdparty/sentry-native/src/sentry_database.h b/thirdparty/sentry-native/src/sentry_database.h index 086ebab8e2..2d99bedb04 100644 --- a/thirdparty/sentry-native/src/sentry_database.h +++ b/thirdparty/sentry-native/src/sentry_database.h @@ -75,4 +75,14 @@ void sentry__process_old_runs( */ bool sentry__write_crash_marker(const sentry_options_t *options); +/** + * This will check whether the `/last_crash` file exists. + */ +bool sentry__has_crash_marker(const sentry_options_t *options); + +/** + * This will remove the `/last_crash` file. + */ +bool sentry__clear_crash_marker(const sentry_options_t *options); + #endif diff --git a/thirdparty/sentry-native/src/sentry_envelope.c b/thirdparty/sentry-native/src/sentry_envelope.c index 4e13669bb4..cfcf5af824 100644 --- a/thirdparty/sentry-native/src/sentry_envelope.c +++ b/thirdparty/sentry-native/src/sentry_envelope.c @@ -201,22 +201,15 @@ sentry_envelope_get_event(const sentry_envelope_t *envelope) } for (size_t i = 0; i < envelope->contents.items.item_count; i++) { -#ifdef SENTRY_PERFORMANCE_MONITORING if (!sentry_value_is_null(envelope->contents.items.items[i].event) && !sentry__event_is_transaction( envelope->contents.items.items[i].event)) { return envelope->contents.items.items[i].event; } -#else - if (!sentry_value_is_null(envelope->contents.items.items[i].event)) { - return envelope->contents.items.items[i].event; - } -#endif } return sentry_value_new_null(); } -#ifdef SENTRY_PERFORMANCE_MONITORING sentry_value_t sentry_envelope_get_transaction(const sentry_envelope_t *envelope) { @@ -232,7 +225,6 @@ sentry_envelope_get_transaction(const sentry_envelope_t *envelope) } return sentry_value_new_null(); } -#endif sentry_envelope_item_t * sentry__envelope_add_event(sentry_envelope_t *envelope, sentry_value_t event) @@ -264,7 +256,6 @@ sentry__envelope_add_event(sentry_envelope_t *envelope, sentry_value_t event) return item; } -#ifdef SENTRY_PERFORMANCE_MONITORING sentry_envelope_item_t * sentry__envelope_add_transaction( sentry_envelope_t *envelope, sentry_value_t transaction) @@ -293,17 +284,16 @@ sentry__envelope_add_transaction( sentry_value_incref(event_id); sentry__envelope_set_header(envelope, "event_id", event_id); -# ifdef SENTRY_UNITTEST +#ifdef SENTRY_UNITTEST sentry_value_t now = sentry_value_new_string("2021-12-16T05:53:59.343Z"); -# else +#else sentry_value_t now = sentry__value_new_string_owned( sentry__msec_time_to_iso8601(sentry__msec_time())); -# endif +#endif sentry__envelope_set_header(envelope, "sent_at", now); return item; } -#endif sentry_envelope_item_t * sentry__envelope_add_session( diff --git a/thirdparty/sentry-native/src/sentry_envelope.h b/thirdparty/sentry-native/src/sentry_envelope.h index e5b11295f9..b5a8f1ab09 100644 --- a/thirdparty/sentry-native/src/sentry_envelope.h +++ b/thirdparty/sentry-native/src/sentry_envelope.h @@ -36,13 +36,11 @@ sentry_uuid_t sentry__envelope_get_event_id(const sentry_envelope_t *envelope); sentry_envelope_item_t *sentry__envelope_add_event( sentry_envelope_t *envelope, sentry_value_t event); -#ifdef SENTRY_PERFORMANCE_MONITORING /** * Add a transaction to this envelope. */ sentry_envelope_item_t *sentry__envelope_add_transaction( sentry_envelope_t *envelope, sentry_value_t transaction); -#endif /** * Add a session to this envelope. diff --git a/thirdparty/sentry-native/src/sentry_info.c b/thirdparty/sentry-native/src/sentry_info.c new file mode 100644 index 0000000000..b2918127b3 --- /dev/null +++ b/thirdparty/sentry-native/src/sentry_info.c @@ -0,0 +1,19 @@ +#include "sentry_boot.h" + +const char * +sentry_sdk_version() +{ + return SENTRY_SDK_VERSION; +} + +const char * +sentry_sdk_name() +{ + return SENTRY_SDK_NAME; +} + +const char * +sentry_sdk_user_agent() +{ + return SENTRY_SDK_USER_AGENT; +} diff --git a/thirdparty/sentry-native/src/sentry_options.c b/thirdparty/sentry-native/src/sentry_options.c index e74c88f292..b0a6fe8aa6 100644 --- a/thirdparty/sentry-native/src/sentry_options.c +++ b/thirdparty/sentry-native/src/sentry_options.c @@ -33,6 +33,9 @@ sentry_options_new(void) opts->release = sentry__string_clone(getenv("SENTRY_RELEASE")); opts->environment = sentry__string_clone(getenv("SENTRY_ENVIRONMENT")); #endif + if (!opts->environment) { + opts->environment = sentry__string_clone("production"); + } opts->max_breadcrumbs = SENTRY_BREADCRUMBS_MAX; opts->user_consent = SENTRY_USER_CONSENT_UNKNOWN; opts->auto_session_tracking = true; @@ -51,11 +54,8 @@ sentry_options_new(void) opts->sample_rate = 1.0; opts->refcount = 1; opts->shutdown_timeout = SENTRY_DEFAULT_SHUTDOWN_TIMEOUT; - -#ifdef SENTRY_PERFORMANCE_MONITORING opts->traces_sample_rate = 0.0; opts->max_spans = 0; -#endif return opts; } @@ -122,6 +122,14 @@ sentry_options_set_before_send( opts->before_send_data = data; } +void +sentry_options_set_on_crash( + sentry_options_t *opts, sentry_crash_function_t func, void *data) +{ + opts->on_crash_func = func; + opts->on_crash_data = data; +} + void sentry_options_set_dsn(sentry_options_t *opts, const char *raw_dsn) { @@ -378,7 +386,6 @@ sentry_options_set_database_pathw(sentry_options_t *opts, const wchar_t *path) } #endif -#ifdef SENTRY_PERFORMANCE_MONITORING /** * Sets the maximum number of spans that can be attached to a * transaction. @@ -429,4 +436,10 @@ sentry_options_get_traces_sample_rate(sentry_options_t *opts) { return opts->traces_sample_rate; } -#endif + +void +sentry_options_set_backend(sentry_options_t *opts, sentry_backend_t *backend) +{ + sentry__backend_free(opts->backend); + opts->backend = backend; +} diff --git a/thirdparty/sentry-native/src/sentry_options.h b/thirdparty/sentry-native/src/sentry_options.h index ba75e2ee21..c6b3c10dc8 100644 --- a/thirdparty/sentry-native/src/sentry_options.h +++ b/thirdparty/sentry-native/src/sentry_options.h @@ -54,12 +54,12 @@ typedef struct sentry_options_s { sentry_transport_t *transport; sentry_event_function_t before_send_func; void *before_send_data; + sentry_crash_function_t on_crash_func; + void *on_crash_data; -#ifdef SENTRY_PERFORMANCE_MONITORING /* Experimentally exposed */ double traces_sample_rate; size_t max_spans; -#endif /* everything from here on down are options which are stored here but not exposed through the options API */ diff --git a/thirdparty/sentry-native/src/sentry_scope.c b/thirdparty/sentry-native/src/sentry_scope.c index 61e83550f1..321b8f41e6 100644 --- a/thirdparty/sentry-native/src/sentry_scope.c +++ b/thirdparty/sentry-native/src/sentry_scope.c @@ -1,5 +1,4 @@ #include "sentry_scope.h" -#include "sentry.h" #include "sentry_backend.h" #include "sentry_core.h" #include "sentry_database.h" @@ -8,6 +7,7 @@ #include "sentry_string.h" #include "sentry_symbolizer.h" #include "sentry_sync.h" +#include "sentry_tracing.h" #include "sentry_value.h" #include @@ -20,10 +20,6 @@ # define SENTRY_BACKEND "inproc" #endif -#ifdef SENTRY_PERFORMANCE_MONITORING -# include "sentry_tracing.h" -#endif - static bool g_scope_initialized = false; static sentry_scope_t g_scope = { 0 }; static sentry_mutex_t g_lock = SENTRY__MUTEX_INIT; @@ -80,11 +76,8 @@ get_scope(void) g_scope.breadcrumbs = sentry_value_new_list(); g_scope.level = SENTRY_LEVEL_ERROR; g_scope.client_sdk = get_client_sdk(); - -#ifdef SENTRY_PERFORMANCE_MONITORING g_scope.transaction_object = NULL; g_scope.span = NULL; -#endif g_scope_initialized = true; @@ -105,11 +98,8 @@ sentry__scope_cleanup(void) sentry_value_decref(g_scope.contexts); sentry_value_decref(g_scope.breadcrumbs); sentry_value_decref(g_scope.client_sdk); - -#ifdef SENTRY_PERFORMANCE_MONITORING sentry__transaction_decref(g_scope.transaction_object); sentry__span_decref(g_scope.span); -#endif } sentry__mutex_unlock(&g_lock); } @@ -241,7 +231,6 @@ sentry__symbolize_stacktrace(sentry_value_t stacktrace) } } -#ifdef SENTRY_PERFORMANCE_MONITORING sentry_value_t sentry__get_span_or_transaction(const sentry_scope_t *scope) { @@ -254,7 +243,7 @@ sentry__get_span_or_transaction(const sentry_scope_t *scope) } } -# ifdef SENTRY_UNITTEST +#ifdef SENTRY_UNITTEST sentry_value_t sentry__scope_get_span_or_transaction() { @@ -263,7 +252,6 @@ sentry__scope_get_span_or_transaction() } return sentry_value_new_null(); } -# endif #endif void @@ -328,7 +316,6 @@ sentry__scope_apply_to_event(const sentry_scope_t *scope, sentry_value_t contexts = sentry__value_clone(scope->contexts); -#ifdef SENTRY_PERFORMANCE_MONITORING // prep contexts sourced from scope; data about transaction on scope needs // to be extracted and inserted sentry_value_t scope_trace = sentry__value_get_trace_context( @@ -339,7 +326,6 @@ sentry__scope_apply_to_event(const sentry_scope_t *scope, } sentry_value_set_by_key(contexts, "trace", scope_trace); } -#endif // merge contexts sourced from scope into the event sentry_value_t event_contexts = sentry_value_get_by_key(event, "contexts"); diff --git a/thirdparty/sentry-native/src/sentry_scope.h b/thirdparty/sentry-native/src/sentry_scope.h index cde4597514..207b1a9957 100644 --- a/thirdparty/sentry-native/src/sentry_scope.h +++ b/thirdparty/sentry-native/src/sentry_scope.h @@ -20,7 +20,6 @@ typedef struct sentry_scope_s { sentry_level_t level; sentry_value_t client_sdk; -#ifdef SENTRY_PERFORMANCE_MONITORING // The span attached to this scope, if any. // // Conceptually, every transaction is a span, so it should be possible to @@ -31,7 +30,6 @@ typedef struct sentry_scope_s { // `name` property nested in transaction_object or span. sentry_transaction_t *transaction_object; sentry_span_t *span; -#endif } sentry_scope_t; /** @@ -98,9 +96,7 @@ void sentry__scope_apply_to_event(const sentry_scope_t *scope, #endif -#ifdef SENTRY_PERFORMANCE_MONITORING // this is only used in unit tests #ifdef SENTRY_UNITTEST sentry_value_t sentry__scope_get_span_or_transaction(); #endif -#endif diff --git a/thirdparty/sentry-native/src/sentry_tracing.c b/thirdparty/sentry-native/src/sentry_tracing.c index d30785f380..49b607f1eb 100644 --- a/thirdparty/sentry-native/src/sentry_tracing.c +++ b/thirdparty/sentry-native/src/sentry_tracing.c @@ -1,9 +1,7 @@ -#include "sentry_boot.h" - +#include "sentry_tracing.h" #include "sentry_alloc.h" #include "sentry_logger.h" #include "sentry_string.h" -#include "sentry_tracing.h" #include "sentry_utils.h" #include "sentry_value.h" #include diff --git a/thirdparty/sentry-native/src/sentry_tracing.h b/thirdparty/sentry-native/src/sentry_tracing.h index 16c15f77c8..bccc9bc78c 100644 --- a/thirdparty/sentry-native/src/sentry_tracing.h +++ b/thirdparty/sentry-native/src/sentry_tracing.h @@ -1,7 +1,6 @@ #ifndef SENTRY_TRACING_H_INCLUDED #define SENTRY_TRACING_H_INCLUDED -#include "sentry_boot.h" #include "sentry_value.h" /** diff --git a/thirdparty/sentry-native/src/sentry_utils.c b/thirdparty/sentry-native/src/sentry_utils.c index 65f2a2415f..569fa08333 100644 --- a/thirdparty/sentry-native/src/sentry_utils.c +++ b/thirdparty/sentry-native/src/sentry_utils.c @@ -218,8 +218,7 @@ sentry__dsn_new(const char *raw_dsn) sentry_url_t url; memset(&url, 0, sizeof(sentry_url_t)); size_t path_len; - char *tmp; - char *end; + char *project_id; sentry_dsn_t *dsn = SENTRY_MAKE(sentry_dsn_t); if (!dsn) { @@ -255,16 +254,14 @@ sentry__dsn_new(const char *raw_dsn) path_len--; } - tmp = strrchr(url.path, '/'); - if (!tmp) { + project_id = strrchr(url.path, '/'); + if (!project_id || strlen(project_id + 1) == 0) { goto exit; } - dsn->project_id = (uint64_t)strtoll(tmp + 1, &end, 10); - if (end != tmp + strlen(tmp)) { - goto exit; - } - *tmp = 0; + dsn->project_id = sentry__string_clone(project_id + 1); + *project_id = 0; + dsn->path = url.path; url.path = NULL; @@ -299,6 +296,7 @@ sentry__dsn_decref(sentry_dsn_t *dsn) sentry_free(dsn->path); sentry_free(dsn->public_key); sentry_free(dsn->secret_key); + sentry_free(dsn->project_id); sentry_free(dsn); } } @@ -329,7 +327,7 @@ init_string_builder_for_url(sentry_stringbuilder_t *sb, const sentry_dsn_t *dsn) sentry__stringbuilder_append_int64(sb, (int64_t)dsn->port); sentry__stringbuilder_append(sb, dsn->path); sentry__stringbuilder_append(sb, "/api/"); - sentry__stringbuilder_append_int64(sb, (int64_t)dsn->project_id); + sentry__stringbuilder_append(sb, dsn->project_id); } char * diff --git a/thirdparty/sentry-native/src/sentry_utils.h b/thirdparty/sentry-native/src/sentry_utils.h index cb79c08f1e..8b19e65c26 100644 --- a/thirdparty/sentry-native/src/sentry_utils.h +++ b/thirdparty/sentry-native/src/sentry_utils.h @@ -49,7 +49,7 @@ typedef struct sentry_dsn_s { char *path; char *secret_key; char *public_key; - uint64_t project_id; + char *project_id; int port; long refcount; bool is_valid; diff --git a/thirdparty/sentry-native/src/sentry_uuid.c b/thirdparty/sentry-native/src/sentry_uuid.c index aefa4c4f61..ad5e349996 100644 --- a/thirdparty/sentry-native/src/sentry_uuid.c +++ b/thirdparty/sentry-native/src/sentry_uuid.c @@ -102,28 +102,26 @@ sentry_uuid_as_string(const sentry_uuid_t *uuid, char str[37]) #undef B } -#ifdef SENTRY_PERFORMANCE_MONITORING void sentry__internal_uuid_as_string(const sentry_uuid_t *uuid, char str[37]) { -# define B(X) (unsigned char)uuid->bytes[X] +#define B(X) (unsigned char)uuid->bytes[X] snprintf(str, 33, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%" "02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", B(0), B(1), B(2), B(3), B(4), B(5), B(6), B(7), B(8), B(9), B(10), B(11), B(12), B(13), B(14), B(15)); -# undef B +#undef B } void sentry__span_uuid_as_string(const sentry_uuid_t *uuid, char str[17]) { -# define B(X) (unsigned char)uuid->bytes[X] +#define B(X) (unsigned char)uuid->bytes[X] snprintf(str, 17, "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", B(0), B(1), B(2), B(3), B(4), B(5), B(6), B(7)); -# undef B +#undef B } -#endif #ifdef SENTRY_PLATFORM_WINDOWS sentry_uuid_t diff --git a/thirdparty/sentry-native/src/sentry_uuid.h b/thirdparty/sentry-native/src/sentry_uuid.h index e2e219f86f..c16b943fa9 100644 --- a/thirdparty/sentry-native/src/sentry_uuid.h +++ b/thirdparty/sentry-native/src/sentry_uuid.h @@ -3,7 +3,6 @@ #include "sentry_boot.h" -#ifdef SENTRY_PERFORMANCE_MONITORING /** * Converts a sentry UUID to a string representation used for internal * sentry UUIDs such as event IDs. @@ -22,5 +21,3 @@ void sentry__span_uuid_as_string(const sentry_uuid_t *uuid, char str[17]); */ sentry_uuid_t sentry__uuid_from_native(const GUID *guid); #endif - -#endif diff --git a/thirdparty/sentry-native/src/sentry_value.c b/thirdparty/sentry-native/src/sentry_value.c index cbb367df9d..9d78efd9ec 100644 --- a/thirdparty/sentry-native/src/sentry_value.c +++ b/thirdparty/sentry-native/src/sentry_value.c @@ -1009,7 +1009,6 @@ sentry__value_new_hexstring(const uint8_t *bytes, size_t len) return sentry__value_new_string_owned(buf); } -#ifdef SENTRY_PERFORMANCE_MONITORING sentry_value_t sentry__value_new_span_uuid(const sentry_uuid_t *uuid) { @@ -1033,7 +1032,6 @@ sentry__value_new_internal_uuid(const sentry_uuid_t *uuid) buf[32] = '\0'; return sentry__value_new_string_owned(buf); } -#endif sentry_value_t sentry__value_new_uuid(const sentry_uuid_t *uuid) @@ -1202,12 +1200,16 @@ sentry_event_add_thread(sentry_value_t event, sentry_value_t thread) } void -sentry_event_value_add_stacktrace(sentry_value_t event, void **ips, size_t len) +sentry_value_set_stacktrace(sentry_value_t value, void **ips, size_t len) { sentry_value_t stacktrace = sentry_value_new_stacktrace(ips, len); + sentry_value_set_by_key(value, "stacktrace", stacktrace); +} +void +sentry_event_value_add_stacktrace(sentry_value_t event, void **ips, size_t len) +{ sentry_value_t thread = sentry_value_new_object(); - sentry_value_set_by_key(thread, "stacktrace", stacktrace); - + sentry_value_set_stacktrace(thread, ips, len); sentry_event_add_thread(event, thread); } diff --git a/thirdparty/sentry-native/src/sentry_value.h b/thirdparty/sentry-native/src/sentry_value.h index 7dfa6eb8c2..437789940b 100644 --- a/thirdparty/sentry-native/src/sentry_value.h +++ b/thirdparty/sentry-native/src/sentry_value.h @@ -118,9 +118,7 @@ typedef struct sentry_jsonwriter_s sentry_jsonwriter_t; void sentry__jsonwriter_write_value( sentry_jsonwriter_t *jw, sentry_value_t value); -#ifdef SENTRY_PERFORMANCE_MONITORING sentry_value_t sentry__value_new_span_uuid(const sentry_uuid_t *uuid); sentry_value_t sentry__value_new_internal_uuid(const sentry_uuid_t *uuid); #endif -#endif diff --git a/thirdparty/sentry-native/tests/assertions.py b/thirdparty/sentry-native/tests/assertions.py index acba4558ee..178e837cf5 100644 --- a/thirdparty/sentry-native/tests/assertions.py +++ b/thirdparty/sentry-native/tests/assertions.py @@ -1,11 +1,11 @@ import datetime import email import gzip -import sys import platform import re -from .conditions import is_android +import sys +from .conditions import is_android VERSION_RE = re.compile(r"(\d+\.\d+\.\d+)(?:[-\.]?)(.*)") @@ -40,6 +40,7 @@ def assert_meta( release="test-example-release", integration=None, transaction="test-transaction", + sdk_override=None, ): event = envelope.get_event() @@ -54,12 +55,14 @@ def assert_meta( } expected_sdk = { "name": "sentry.native", - "version": "0.4.15", + "version": "0.5.0", "packages": [ - {"name": "github:getsentry/sentry-native", "version": "0.4.15"}, + {"name": "github:getsentry/sentry-native", "version": "0.5.0"}, ], } - if not is_android: + if is_android: + expected_sdk["name"] = "sentry.native.android" + else: if sys.platform == "win32": assert_matches( event["contexts"]["os"], @@ -92,6 +95,9 @@ def assert_meta( ) assert event["contexts"]["os"]["build"] is not None + if sdk_override != None: + expected_sdk["name"] = sdk_override + assert_matches(event, expected) assert_matches(event["sdk"], expected_sdk) assert_matches( @@ -188,6 +194,25 @@ def assert_crash(envelope): assert_stacktrace(envelope, inside_exception=True, check_size=False) +def assert_crash_timestamp(has_files, tmp_path): + # The crash file should survive a `sentry_init` and should still be there + # even after restarts. + if has_files: + with open("{}/.sentry-native/last_crash".format(tmp_path)) as f: + crash_timestamp = f.read() + assert_timestamp(crash_timestamp) + + +def assert_before_send(envelope): + event = envelope.get_event() + assert_matches(event, {"adapted_by": "before_send"}) + + +def assert_no_before_send(envelope): + event = envelope.get_event() + assert ("adapted_by", "before_send") not in event.items() + + def assert_crashpad_upload(req): multipart = gzip.decompress(req.get_data()) msg = email.message_from_bytes(bytes(str(req.headers), encoding="utf8") + multipart) diff --git a/thirdparty/sentry-native/tests/cmake.py b/thirdparty/sentry-native/tests/cmake.py index c59ba6db87..a0566023a3 100644 --- a/thirdparty/sentry-native/tests/cmake.py +++ b/thirdparty/sentry-native/tests/cmake.py @@ -175,7 +175,7 @@ def cmake(cwd, targets, options=None): buildcmd.append("--parallel") if "code-checker" in os.environ.get("RUN_ANALYZER", ""): buildcmd = [ - "CodeChecker", + "codechecker", "log", "--output", "compilation.json", @@ -206,7 +206,7 @@ def cmake(cwd, targets, options=None): ] disables = ["--disable={}".format(d) for d in disable] checkcmd = [ - "CodeChecker", + "codechecker", "check", "--jobs", str(os.cpu_count()), diff --git a/thirdparty/sentry-native/tests/requirements.txt b/thirdparty/sentry-native/tests/requirements.txt index fcbf849f66..dd2fd18e86 100644 --- a/thirdparty/sentry-native/tests/requirements.txt +++ b/thirdparty/sentry-native/tests/requirements.txt @@ -1,3 +1,3 @@ -black==21.9b0 +black==22.3.0 pytest==6.2.5 pytest-httpserver==1.0.1 diff --git a/thirdparty/sentry-native/tests/test_integration_crashpad.py b/thirdparty/sentry-native/tests/test_integration_crashpad.py index 7eb0ca2c2a..8a5651edb2 100644 --- a/thirdparty/sentry-native/tests/test_integration_crashpad.py +++ b/thirdparty/sentry-native/tests/test_integration_crashpad.py @@ -46,7 +46,7 @@ def test_crashpad_reinstall(cmake, httpserver): assert len(httpserver.log) == 1 -def test_crashpad_crash(cmake, httpserver): +def run_crashpad_dumping_crash(cmake, httpserver, custom_args): tmp_path = cmake(["sentry_example"], {"SENTRY_BACKEND": "crashpad"}) env = dict(os.environ, SENTRY_DSN=make_dsn(httpserver)) @@ -57,7 +57,8 @@ def test_crashpad_crash(cmake, httpserver): child = run( tmp_path, "sentry_example", - ["log", "start-session", "attachment", "overflow-breadcrumbs", "crash"], + ["log", "start-session", "attachment", "overflow-breadcrumbs", "crash"] + + custom_args, env=env, ) assert child.returncode # well, its a crash after all @@ -78,9 +79,112 @@ def test_crashpad_crash(cmake, httpserver): else (outputs[1].get_data(), outputs[0]) ) - envelope = Envelope.deserialize(session) - assert_session(envelope, {"status": "crashed", "errors": 1}) + return session, multipart + +def run_crashpad_non_dumping_crash(cmake, httpserver, custom_args): + tmp_path = cmake(["sentry_example"], {"SENTRY_BACKEND": "crashpad"}) + + env = dict(os.environ, SENTRY_DSN=make_dsn(httpserver)) + httpserver.expect_request("/api/123456/envelope/").respond_with_data("OK") + + with httpserver.wait(timeout=5, raise_assertions=False) as waiting: + child = run( + tmp_path, + "sentry_example", + [ + "log", + "start-session", + "attachment", + "overflow-breadcrumbs", + "crash", + ] + + custom_args, + env=env, + ) + assert child.returncode # well, its a crash after all + + assert waiting.result is False + + # the session crash heuristic on mac uses timestamps, so make sure we have + # a small delay here + time.sleep(1) + + run(tmp_path, "sentry_example", ["log", "no-setup"], check=True, env=env) + + assert len(httpserver.log) == 1 + output = httpserver.log[0][0] + session = output.get_data() + + return session + + +def test_crashpad_crash(cmake, httpserver): + session, multipart = run_crashpad_dumping_crash(cmake, httpserver, []) + + envelope = Envelope.deserialize(session) + + assert_session(envelope, {"status": "crashed", "errors": 1}) + assert_crashpad_upload(multipart) + + +@pytest.mark.skipif( + sys.platform == "darwin", + reason="crashpad doesn't provide SetFirstChanceExceptionHandler on macOS", +) +def test_crashpad_crash_before_send(cmake, httpserver): + session, multipart = run_crashpad_dumping_crash(cmake, httpserver, ["before-send"]) + + envelope = Envelope.deserialize(session) + + assert_session(envelope, {"status": "crashed", "errors": 1}) + assert_crashpad_upload(multipart) + + # TODO(supervacuus): we would expect to see a change coming from the + # before_send() hook, but in contrast to the other backends the crashpad + # backend currently only checks for null-value as a signal not to produce + # a minidump and after this decrefs the event. + + +@pytest.mark.skipif( + sys.platform == "darwin", + reason="crashpad doesn't provide SetFirstChanceExceptionHandler on macOS", +) +def test_crashpad_crash_discarding_before_send(cmake, httpserver): + session = run_crashpad_non_dumping_crash( + cmake, httpserver, ["discarding-before-send"] + ) + + envelope = Envelope.deserialize(session) + + assert_session(envelope, {"status": "abnormal", "errors": 0}) + + +@pytest.mark.skipif( + sys.platform == "darwin", + reason="crashpad doesn't provide SetFirstChanceExceptionHandler on macOS", +) +def test_crashpad_crash_discarding_on_crash(cmake, httpserver): + session = run_crashpad_non_dumping_crash(cmake, httpserver, ["discarding-on-crash"]) + + envelope = Envelope.deserialize(session) + + assert_session(envelope, {"status": "abnormal", "errors": 0}) + + +@pytest.mark.skipif( + sys.platform == "darwin", + reason="crashpad doesn't provide SetFirstChanceExceptionHandler on macOS", +) +def test_crashpad_crash_discarding_before_send_and_on_crash(cmake, httpserver): + session, multipart = run_crashpad_dumping_crash( + cmake, httpserver, ["discarding-before-send", "on-crash"] + ) + + envelope = Envelope.deserialize(session) + + # on_crash() is defined and overrules the discarding before_send() + assert_session(envelope, {"status": "crashed", "errors": 1}) assert_crashpad_upload(multipart) @@ -135,3 +239,24 @@ def test_crashpad_dump_inflight(cmake, httpserver): # we trigger 10 normal events, and 1 crash assert len(httpserver.log) >= 11 + + +def test_disable_backend(cmake, httpserver): + tmp_path = cmake(["sentry_example"], {"SENTRY_BACKEND": "crashpad"}) + + env = dict(os.environ, SENTRY_DSN=make_dsn(httpserver)) + + with httpserver.wait(timeout=5, raise_assertions=False) as waiting: + child = run( + tmp_path, "sentry_example", ["disable-backend", "log", "crash"], env=env + ) + # we crash so process should return non-zero + assert child.returncode + + # crashpad is disabled, and we are only crashing, so we expect the wait to timeout + assert waiting.result is False + + run(tmp_path, "sentry_example", ["log", "no-setup"], check=True, env=env) + + # crashpad is disabled, and we are only crashing, so we expect no requests + assert len(httpserver.log) == 0 diff --git a/thirdparty/sentry-native/tests/test_integration_http.py b/thirdparty/sentry-native/tests/test_integration_http.py index a1b8367db7..042d91a814 100644 --- a/thirdparty/sentry-native/tests/test_integration_http.py +++ b/thirdparty/sentry-native/tests/test_integration_http.py @@ -23,7 +23,9 @@ from .assertions import ( pytestmark = pytest.mark.skipif(not has_http, reason="tests need http") -auth_header = "Sentry sentry_key=uiaeosnrtdy, sentry_version=7, sentry_client=sentry.native/0.4.15" +auth_header = ( + "Sentry sentry_key=uiaeosnrtdy, sentry_version=7, sentry_client=sentry.native/0.5.0" +) def test_capture_http(cmake, httpserver): diff --git a/thirdparty/sentry-native/tests/test_integration_stdout.py b/thirdparty/sentry-native/tests/test_integration_stdout.py index 8998fefbac..ecb2c6f954 100644 --- a/thirdparty/sentry-native/tests/test_integration_stdout.py +++ b/thirdparty/sentry-native/tests/test_integration_stdout.py @@ -1,10 +1,11 @@ -import pytest +import os import subprocess import sys -import os import time + +import pytest + from . import check_output, run, Envelope -from .conditions import has_breakpad, has_files from .assertions import ( assert_attachment, assert_meta, @@ -14,8 +15,11 @@ from .assertions import ( assert_crash, assert_minidump, assert_timestamp, - assert_session, + assert_before_send, + assert_no_before_send, + assert_crash_timestamp, ) +from .conditions import has_breakpad, has_files def test_capture_stdout(cmake): @@ -42,6 +46,28 @@ def test_capture_stdout(cmake): assert_event(envelope) +def test_sdk_name_override(cmake): + sdk_name = "cUsToM.SDK" + tmp_path = cmake( + ["sentry_example"], + { + "SENTRY_BACKEND": "none", + "SENTRY_TRANSPORT": "none", + "SENTRY_SDK_NAME": sdk_name, + }, + ) + + output = check_output( + tmp_path, + "sentry_example", + ["stdout", "capture-event"], + ) + envelope = Envelope.deserialize(output) + + assert_meta(envelope, sdk_override=sdk_name) + assert_event(envelope) + + @pytest.mark.skipif(not has_files, reason="test needs a local filesystem") def test_multi_process(cmake): # NOTE: It would have been nice to do *everything* in a unicode-named @@ -89,52 +115,118 @@ def test_multi_process(cmake): assert len(runs) == 0 -def test_inproc_crash_stdout(cmake): +def run_crash_stdout_for(backend, cmake, example_args): tmp_path = cmake( ["sentry_example"], - {"SENTRY_BACKEND": "inproc", "SENTRY_TRANSPORT": "none"}, + {"SENTRY_BACKEND": backend, "SENTRY_TRANSPORT": "none"}, ) - child = run(tmp_path, "sentry_example", ["attachment", "crash"]) - assert child.returncode # well, its a crash after all + child = run(tmp_path, "sentry_example", ["attachment", "crash"] + example_args) + assert child.returncode # well, it's a crash after all + + return tmp_path, check_output(tmp_path, "sentry_example", ["stdout", "no-setup"]) + + +def test_inproc_crash_stdout(cmake): + tmp_path, output = run_crash_stdout_for("inproc", cmake, []) - output = check_output(tmp_path, "sentry_example", ["stdout", "no-setup"]) envelope = Envelope.deserialize(output) - # The crash file should survive a `sentry_init` and should still be there - # even after restarts. - if has_files: - with open("{}/.sentry-native/last_crash".format(tmp_path)) as f: - crash_timestamp = f.read() - assert_timestamp(crash_timestamp) - + assert_crash_timestamp(has_files, tmp_path) assert_meta(envelope, integration="inproc") assert_breadcrumb(envelope) assert_attachment(envelope) + assert_crash(envelope) + +def test_inproc_crash_stdout_before_send(cmake): + tmp_path, output = run_crash_stdout_for("inproc", cmake, ["before-send"]) + + envelope = Envelope.deserialize(output) + + assert_crash_timestamp(has_files, tmp_path) + assert_meta(envelope, integration="inproc") + assert_breadcrumb(envelope) + assert_attachment(envelope) + assert_crash(envelope) + assert_before_send(envelope) + + +def test_inproc_crash_stdout_discarding_on_crash(cmake): + tmp_path, output = run_crash_stdout_for("inproc", cmake, ["discarding-on-crash"]) + + # since the on_crash() handler discards further processing we expect an empty response + assert len(output) == 0 + + assert_crash_timestamp(has_files, tmp_path) + + +def test_inproc_crash_stdout_before_send_and_on_crash(cmake): + tmp_path, output = run_crash_stdout_for( + "inproc", cmake, ["before-send", "on-crash"] + ) + + # the on_crash() hook retains the event + envelope = Envelope.deserialize(output) + # but we expect no event modification from before_send() since setting on_crash() disables before_send() + assert_no_before_send(envelope) + + assert_crash_timestamp(has_files, tmp_path) + assert_meta(envelope, integration="inproc") + assert_breadcrumb(envelope) + assert_attachment(envelope) assert_crash(envelope) @pytest.mark.skipif(not has_breakpad, reason="test needs breakpad backend") def test_breakpad_crash_stdout(cmake): - tmp_path = cmake( - ["sentry_example"], - {"SENTRY_BACKEND": "breakpad", "SENTRY_TRANSPORT": "none"}, - ) + tmp_path, output = run_crash_stdout_for("breakpad", cmake, []) - child = run(tmp_path, "sentry_example", ["attachment", "crash"]) - assert child.returncode # well, its a crash after all - - if has_files: - with open("{}/.sentry-native/last_crash".format(tmp_path)) as f: - crash_timestamp = f.read() - assert_timestamp(crash_timestamp) - - output = check_output(tmp_path, "sentry_example", ["stdout", "no-setup"]) envelope = Envelope.deserialize(output) + assert_crash_timestamp(has_files, tmp_path) assert_meta(envelope, integration="breakpad") assert_breadcrumb(envelope) assert_attachment(envelope) - assert_minidump(envelope) + + +@pytest.mark.skipif(not has_breakpad, reason="test needs breakpad backend") +def test_breakpad_crash_stdout_before_send(cmake): + tmp_path, output = run_crash_stdout_for("breakpad", cmake, ["before-send"]) + + envelope = Envelope.deserialize(output) + + assert_crash_timestamp(has_files, tmp_path) + assert_meta(envelope, integration="breakpad") + assert_breadcrumb(envelope) + assert_attachment(envelope) + assert_minidump(envelope) + assert_before_send(envelope) + + +@pytest.mark.skipif(not has_breakpad, reason="test needs breakpad backend") +def test_breakpad_crash_stdout_discarding_on_crash(cmake): + tmp_path, output = run_crash_stdout_for("breakpad", cmake, ["discarding-on-crash"]) + + # since the on_crash() handler discards further processing we expect an empty response + assert len(output) == 0 + + assert_crash_timestamp(has_files, tmp_path) + + +@pytest.mark.skipif(not has_breakpad, reason="test needs breakpad backend") +def test_breakpad_crash_stdout_before_send_and_on_crash(cmake): + tmp_path, output = run_crash_stdout_for( + "breakpad", cmake, ["before-send", "on-crash"] + ) + + # the on_crash() hook retains the event + envelope = Envelope.deserialize(output) + # but we expect no event modification from before_send() since setting on_crash() disables before_send() + assert_no_before_send(envelope) + + assert_crash_timestamp(has_files, tmp_path) + assert_meta(envelope, integration="breakpad") + assert_breadcrumb(envelope) + assert_attachment(envelope) diff --git a/thirdparty/sentry-native/tests/unit/CMakeLists.txt b/thirdparty/sentry-native/tests/unit/CMakeLists.txt index a2791005e0..7c9dc6d173 100644 --- a/thirdparty/sentry-native/tests/unit/CMakeLists.txt +++ b/thirdparty/sentry-native/tests/unit/CMakeLists.txt @@ -24,6 +24,7 @@ add_executable(sentry_test_unit test_envelopes.c test_failures.c test_fuzzfailures.c + test_info.c test_logger.c test_modulefinder.c test_mpack.c @@ -83,7 +84,6 @@ endif() target_compile_definitions(sentry PRIVATE SIZEOF_LONG=${CMAKE_SIZEOF_LONG}) target_compile_definitions(sentry_test_unit PRIVATE SENTRY_UNITTEST) -target_compile_definitions(sentry_test_unit PRIVATE SENTRY_PERFORMANCE_MONITORING) add_test(NAME sentry_test_unit COMMAND sentry_test_unit) diff --git a/thirdparty/sentry-native/tests/unit/fuzz.c b/thirdparty/sentry-native/tests/unit/fuzz.c index 1b79da7e56..b0de75e3e4 100644 --- a/thirdparty/sentry-native/tests/unit/fuzz.c +++ b/thirdparty/sentry-native/tests/unit/fuzz.c @@ -24,8 +24,6 @@ afl-fuzz -i fuzzing-examples -o fuzzing-results -- fuzzing/sentry_fuzz_json @@ # define _CRT_SECURE_NO_WARNINGS #endif -#include "sentry.h" - #include #include diff --git a/thirdparty/sentry-native/tests/unit/test_attachments.c b/thirdparty/sentry-native/tests/unit/test_attachments.c index 4b3a6bbdda..bd4d2d065d 100644 --- a/thirdparty/sentry-native/tests/unit/test_attachments.c +++ b/thirdparty/sentry-native/tests/unit/test_attachments.c @@ -2,7 +2,6 @@ #include "sentry_path.h" #include "sentry_string.h" #include "sentry_testsupport.h" -#include typedef struct { uint64_t called; diff --git a/thirdparty/sentry-native/tests/unit/test_basic.c b/thirdparty/sentry-native/tests/unit/test_basic.c index 342ef00372..d8a51e4618 100644 --- a/thirdparty/sentry-native/tests/unit/test_basic.c +++ b/thirdparty/sentry-native/tests/unit/test_basic.c @@ -1,6 +1,6 @@ #include "sentry_core.h" +#include "sentry_database.h" #include "sentry_testsupport.h" -#include static void send_envelope_test_basic(const sentry_envelope_t *envelope, void *data) @@ -62,14 +62,20 @@ SENTRY_TEST(basic_function_transport) TEST_CHECK_INT_EQUAL(called, 2); } +static void +counting_transport_func(const sentry_envelope_t *UNUSED(envelope), void *data) +{ + uint64_t *called = data; + *called += 1; +} + static sentry_value_t before_send(sentry_value_t event, void *UNUSED(hint), void *data) { uint64_t *called = data; *called += 1; - sentry_value_decref(event); - return sentry_value_new_null(); + return event; } SENTRY_TEST(sampling_before_send) @@ -81,7 +87,7 @@ SENTRY_TEST(sampling_before_send) sentry_options_set_dsn(options, "https://foo@sentry.invalid/42"); sentry_options_set_transport(options, sentry_new_function_transport( - send_envelope_test_basic, &called_transport)); + counting_transport_func, &called_transport)); sentry_options_set_before_send(options, before_send, &called_beforesend); sentry_options_set_sample_rate(options, 0.75); sentry_init(options); @@ -93,7 +99,111 @@ SENTRY_TEST(sampling_before_send) sentry_close(); - TEST_CHECK_INT_EQUAL(called_transport, 0); - // well, its random after all - TEST_CHECK(called_beforesend > 50 && called_beforesend < 100); + // The behavior here has changed with version 0.4.19: + // the documentation (https://develop.sentry.dev/sdk/sessions/#filter-order) + // requires that the sampling-rate filter for all SDKs is executed last. + // This means the `before_send` callback will be invoked every time and only + // the actual transport will be randomly sampled. + TEST_CHECK(called_transport > 50 && called_transport < 100); + TEST_CHECK_INT_EQUAL(called_beforesend, 100); +} + +static sentry_value_t +discarding_before_send(sentry_value_t event, void *UNUSED(hint), void *data) +{ + uint64_t *called = data; + *called += 1; + + sentry_value_decref(event); + return sentry_value_new_null(); +} + +SENTRY_TEST(discarding_before_send) +{ + uint64_t called_beforesend = 0; + uint64_t called_transport = 0; + + sentry_options_t *options = sentry_options_new(); + sentry_options_set_dsn(options, "https://foo@sentry.invalid/42"); + sentry_options_set_transport(options, + sentry_new_function_transport( + counting_transport_func, &called_transport)); + sentry_options_set_before_send( + options, discarding_before_send, &called_beforesend); + sentry_init(options); + + sentry_capture_event( + sentry_value_new_message_event(SENTRY_LEVEL_INFO, NULL, "foo")); + + sentry_close(); + + TEST_CHECK_INT_EQUAL(called_transport, 0); + TEST_CHECK_INT_EQUAL(called_beforesend, 1); +} + +SENTRY_TEST(crash_marker) +{ + sentry_options_t *options = sentry_options_new(); + + // clear returns true, regardless if the file exists + TEST_CHECK(sentry__clear_crash_marker(options)); + + // write should normally be true, even when called multiple times + TEST_CHECK(!sentry__has_crash_marker(options)); + TEST_CHECK(sentry__write_crash_marker(options)); + TEST_CHECK(sentry__has_crash_marker(options)); + TEST_CHECK(sentry__write_crash_marker(options)); + TEST_CHECK(sentry__has_crash_marker(options)); + + TEST_CHECK(sentry__clear_crash_marker(options)); + TEST_CHECK(!sentry__has_crash_marker(options)); + TEST_CHECK(sentry__clear_crash_marker(options)); + + sentry_options_free(options); +} + +SENTRY_TEST(crashed_last_run) +{ + // fails before init() is called + TEST_CHECK_INT_EQUAL(sentry_clear_crashed_last_run(), 1); + + // clear any leftover from previous test runs + sentry_options_t *options = sentry_options_new(); + TEST_CHECK(sentry__clear_crash_marker(options)); + sentry_options_free(options); + + // -1 before sentry_init() + TEST_CHECK_INT_EQUAL(sentry_get_crashed_last_run(), -1); + + options = sentry_options_new(); + sentry_options_set_dsn(options, "https://foo@sentry.invalid/42"); + TEST_CHECK_INT_EQUAL(sentry_init(options), 0); + sentry_close(); + + TEST_CHECK_INT_EQUAL(sentry_get_crashed_last_run(), 0); + + options = sentry_options_new(); + sentry_options_set_dsn(options, "https://foo@sentry.invalid/42"); + + // simulate a crash + TEST_CHECK(sentry__write_crash_marker(options)); + + TEST_CHECK_INT_EQUAL(sentry_init(options), 0); + + TEST_CHECK_INT_EQUAL(sentry_get_crashed_last_run(), 1); + + // clear the status and re-init + TEST_CHECK_INT_EQUAL(sentry_clear_crashed_last_run(), 0); + + sentry_close(); + + // no change yet before sentry_init() is called + TEST_CHECK_INT_EQUAL(sentry_get_crashed_last_run(), 1); + + options = sentry_options_new(); + sentry_options_set_dsn(options, "https://foo@sentry.invalid/42"); + TEST_CHECK_INT_EQUAL(sentry_init(options), 0); + sentry_close(); + + TEST_CHECK_INT_EQUAL(sentry_get_crashed_last_run(), 0); } diff --git a/thirdparty/sentry-native/tests/unit/test_concurrency.c b/thirdparty/sentry-native/tests/unit/test_concurrency.c index 83f7802403..946081dba5 100644 --- a/thirdparty/sentry-native/tests/unit/test_concurrency.c +++ b/thirdparty/sentry-native/tests/unit/test_concurrency.c @@ -1,6 +1,6 @@ #include "sentry_core.h" #include "sentry_testsupport.h" -#include + #include static void diff --git a/thirdparty/sentry-native/tests/unit/test_consent.c b/thirdparty/sentry-native/tests/unit/test_consent.c index 2d1845fb21..f26af345bd 100644 --- a/thirdparty/sentry-native/tests/unit/test_consent.c +++ b/thirdparty/sentry-native/tests/unit/test_consent.c @@ -1,6 +1,5 @@ #include "sentry_path.h" #include "sentry_testsupport.h" -#include static void init_consenting_sentry(void) diff --git a/thirdparty/sentry-native/tests/unit/test_envelopes.c b/thirdparty/sentry-native/tests/unit/test_envelopes.c index 2554be1c73..2e6128a9cb 100644 --- a/thirdparty/sentry-native/tests/unit/test_envelopes.c +++ b/thirdparty/sentry-native/tests/unit/test_envelopes.c @@ -3,7 +3,6 @@ #include "sentry_transport.h" #include "sentry_utils.h" #include "sentry_value.h" -#include SENTRY_TEST(basic_http_request_preparation_for_event) { diff --git a/thirdparty/sentry-native/tests/unit/test_failures.c b/thirdparty/sentry-native/tests/unit/test_failures.c index 96483b316c..4d85957153 100644 --- a/thirdparty/sentry-native/tests/unit/test_failures.c +++ b/thirdparty/sentry-native/tests/unit/test_failures.c @@ -1,6 +1,5 @@ #include "sentry_core.h" #include "sentry_testsupport.h" -#include static int transport_startup_fail( diff --git a/thirdparty/sentry-native/tests/unit/test_fuzzfailures.c b/thirdparty/sentry-native/tests/unit/test_fuzzfailures.c index 109873785d..38b4b237d3 100644 --- a/thirdparty/sentry-native/tests/unit/test_fuzzfailures.c +++ b/thirdparty/sentry-native/tests/unit/test_fuzzfailures.c @@ -2,7 +2,7 @@ #include "sentry_path.h" #include "sentry_testsupport.h" #include "sentry_value.h" -#include + #include static void diff --git a/thirdparty/sentry-native/tests/unit/test_info.c b/thirdparty/sentry-native/tests/unit/test_info.c new file mode 100644 index 0000000000..c3c889b769 --- /dev/null +++ b/thirdparty/sentry-native/tests/unit/test_info.c @@ -0,0 +1,16 @@ +#include "sentry_testsupport.h" + +SENTRY_TEST(assert_sdk_version) +{ + TEST_CHECK_STRING_EQUAL(sentry_sdk_version(), SENTRY_SDK_VERSION); +} + +SENTRY_TEST(assert_sdk_name) +{ + TEST_CHECK_STRING_EQUAL(sentry_sdk_name(), SENTRY_SDK_NAME); +} + +SENTRY_TEST(assert_sdk_user_agent) +{ + TEST_CHECK_STRING_EQUAL(sentry_sdk_user_agent(), SENTRY_SDK_USER_AGENT); +} diff --git a/thirdparty/sentry-native/tests/unit/test_logger.c b/thirdparty/sentry-native/tests/unit/test_logger.c index 18948f2bf5..caec1055e7 100644 --- a/thirdparty/sentry-native/tests/unit/test_logger.c +++ b/thirdparty/sentry-native/tests/unit/test_logger.c @@ -1,7 +1,6 @@ #include "sentry_core.h" #include "sentry_logger.h" #include "sentry_testsupport.h" -#include typedef struct { uint64_t called; diff --git a/thirdparty/sentry-native/tests/unit/test_modulefinder.c b/thirdparty/sentry-native/tests/unit/test_modulefinder.c index 90fc31c066..38440406b6 100644 --- a/thirdparty/sentry-native/tests/unit/test_modulefinder.c +++ b/thirdparty/sentry-native/tests/unit/test_modulefinder.c @@ -1,6 +1,5 @@ #include "sentry_path.h" #include "sentry_testsupport.h" -#include #ifdef SENTRY_PLATFORM_LINUX # include "modulefinder/sentry_modulefinder_linux.h" diff --git a/thirdparty/sentry-native/tests/unit/test_mpack.c b/thirdparty/sentry-native/tests/unit/test_mpack.c index 391a3d892c..28b5d3f87b 100644 --- a/thirdparty/sentry-native/tests/unit/test_mpack.c +++ b/thirdparty/sentry-native/tests/unit/test_mpack.c @@ -1,7 +1,6 @@ #include "sentry_path.h" #include "sentry_scope.h" #include "sentry_testsupport.h" -#include SENTRY_TEST(mpack_removed_tags) { diff --git a/thirdparty/sentry-native/tests/unit/test_path.c b/thirdparty/sentry-native/tests/unit/test_path.c index c165b47b8f..3f25d77a52 100644 --- a/thirdparty/sentry-native/tests/unit/test_path.c +++ b/thirdparty/sentry-native/tests/unit/test_path.c @@ -1,7 +1,6 @@ #include "sentry_path.h" #include "sentry_string.h" #include "sentry_testsupport.h" -#include SENTRY_TEST(recursive_paths) { diff --git a/thirdparty/sentry-native/tests/unit/test_ratelimiter.c b/thirdparty/sentry-native/tests/unit/test_ratelimiter.c index c3d596e3ca..26c42afe83 100644 --- a/thirdparty/sentry-native/tests/unit/test_ratelimiter.c +++ b/thirdparty/sentry-native/tests/unit/test_ratelimiter.c @@ -1,7 +1,6 @@ #include "sentry_ratelimiter.h" #include "sentry_testsupport.h" #include "sentry_utils.h" -#include SENTRY_TEST(rate_limit_parsing) { diff --git a/thirdparty/sentry-native/tests/unit/test_session.c b/thirdparty/sentry-native/tests/unit/test_session.c index 5864526f1c..59fa8774cc 100644 --- a/thirdparty/sentry-native/tests/unit/test_session.c +++ b/thirdparty/sentry-native/tests/unit/test_session.c @@ -2,7 +2,6 @@ #include "sentry_session.h" #include "sentry_testsupport.h" #include "sentry_value.h" -#include static void send_envelope(const sentry_envelope_t *envelope, void *data) @@ -61,6 +60,12 @@ SENTRY_TEST(session_basics) sentry_options_set_transport( options, sentry_new_function_transport(send_envelope, &called)); sentry_options_set_release(options, "my_release"); + + // the default environment is always `production` if not overwritten by the + // OS environment variable `SENTRY_ENVIRONMENT` + // (see https://develop.sentry.dev/sdk/event-payloads/#optional-attributes) + TEST_CHECK_STRING_EQUAL( + sentry_options_get_environment(options), "production"); sentry_options_set_environment(options, "my_environment"); sentry_init(options); diff --git a/thirdparty/sentry-native/tests/unit/test_slice.c b/thirdparty/sentry-native/tests/unit/test_slice.c index af149340d6..5052929dc7 100644 --- a/thirdparty/sentry-native/tests/unit/test_slice.c +++ b/thirdparty/sentry-native/tests/unit/test_slice.c @@ -1,6 +1,5 @@ #include "sentry_slice.h" #include "sentry_testsupport.h" -#include SENTRY_TEST(slice) { diff --git a/thirdparty/sentry-native/tests/unit/test_symbolizer.c b/thirdparty/sentry-native/tests/unit/test_symbolizer.c index 9c18fea7cb..0a2f42b456 100644 --- a/thirdparty/sentry-native/tests/unit/test_symbolizer.c +++ b/thirdparty/sentry-native/tests/unit/test_symbolizer.c @@ -1,6 +1,5 @@ #include "sentry_symbolizer.h" #include "sentry_testsupport.h" -#include TEST_VISIBLE void test_function(void) diff --git a/thirdparty/sentry-native/tests/unit/test_uninit.c b/thirdparty/sentry-native/tests/unit/test_uninit.c index 2cd0859d1f..bf9577ce76 100644 --- a/thirdparty/sentry-native/tests/unit/test_uninit.c +++ b/thirdparty/sentry-native/tests/unit/test_uninit.c @@ -1,5 +1,4 @@ #include "sentry_testsupport.h" -#include SENTRY_TEST(uninitialized) { diff --git a/thirdparty/sentry-native/tests/unit/test_unwinder.c b/thirdparty/sentry-native/tests/unit/test_unwinder.c index a5982ff7ce..b3ac88e0e2 100644 --- a/thirdparty/sentry-native/tests/unit/test_unwinder.c +++ b/thirdparty/sentry-native/tests/unit/test_unwinder.c @@ -1,6 +1,5 @@ #include "sentry_symbolizer.h" #include "sentry_testsupport.h" -#include #define MAX_FRAMES 128 diff --git a/thirdparty/sentry-native/tests/unit/test_utils.c b/thirdparty/sentry-native/tests/unit/test_utils.c index bdc17f2aae..f280f59f71 100644 --- a/thirdparty/sentry-native/tests/unit/test_utils.c +++ b/thirdparty/sentry-native/tests/unit/test_utils.c @@ -2,7 +2,6 @@ #include "sentry_testsupport.h" #include "sentry_utils.h" #include "sentry_value.h" -#include #ifdef SENTRY_PLATFORM_UNIX # include "sentry_unix_pageallocator.h" @@ -72,7 +71,7 @@ SENTRY_TEST(url_parsing_invalid) SENTRY_TEST(dsn_parsing_complete) { sentry_dsn_t *dsn = sentry__dsn_new( - "http://username:password@example.com/foo/bar/42?x=y#z"); + "http://username:password@example.com/foo/bar/42%21?x=y#z"); TEST_CHECK(!!dsn); if (!dsn) { return; @@ -84,10 +83,10 @@ SENTRY_TEST(dsn_parsing_complete) TEST_CHECK_STRING_EQUAL(dsn->public_key, "username"); TEST_CHECK_STRING_EQUAL(dsn->secret_key, "password"); TEST_CHECK_STRING_EQUAL(dsn->path, "/foo/bar"); - TEST_CHECK_INT_EQUAL((int)dsn->project_id, 42); + TEST_CHECK_STRING_EQUAL(dsn->project_id, "42%21"); sentry__dsn_decref(dsn); - dsn = sentry__dsn_new("https://username@example.com/42"); + dsn = sentry__dsn_new("https://username@example.com/42%21"); TEST_CHECK(!!dsn); if (!dsn) { return; @@ -98,22 +97,24 @@ SENTRY_TEST(dsn_parsing_complete) TEST_CHECK_STRING_EQUAL(dsn->public_key, "username"); TEST_CHECK(!dsn->secret_key); TEST_CHECK_STRING_EQUAL(dsn->path, ""); - TEST_CHECK_INT_EQUAL((int)dsn->project_id, 42); + TEST_CHECK_STRING_EQUAL(dsn->project_id, "42%21"); + sentry__dsn_decref(dsn); + + dsn = sentry__dsn_new("https://username@example.com/pathone/pathtwo/42%21"); + TEST_CHECK(!!dsn); + if (!dsn) { + return; + } + TEST_CHECK(dsn->is_valid); + TEST_CHECK_STRING_EQUAL(dsn->path, "/pathone/pathtwo"); + TEST_CHECK_STRING_EQUAL(dsn->project_id, "42%21"); sentry__dsn_decref(dsn); } SENTRY_TEST(dsn_parsing_invalid) { - sentry_dsn_t *dsn - = sentry__dsn_new("http://username:password@example.com/foo/bar?x=y#z"); - TEST_CHECK(!!dsn); - if (dsn) { - TEST_CHECK(!dsn->is_valid); - sentry__dsn_decref(dsn); - } - - dsn = sentry__dsn_new("=https://foo@bar.ingest.sentry.io/" - "1234567"); + sentry_dsn_t *dsn = sentry__dsn_new("=https://foo@bar.ingest.sentry.io/" + "1234567"); TEST_CHECK(!!dsn); if (dsn) { TEST_CHECK(!dsn->is_valid); diff --git a/thirdparty/sentry-native/tests/unit/test_uuid.c b/thirdparty/sentry-native/tests/unit/test_uuid.c index 6be5044f37..2ff38ebd38 100644 --- a/thirdparty/sentry-native/tests/unit/test_uuid.c +++ b/thirdparty/sentry-native/tests/unit/test_uuid.c @@ -1,6 +1,6 @@ #include "sentry_testsupport.h" -#include -#include + +#include "sentry_uuid.h" SENTRY_TEST(uuid_api) { diff --git a/thirdparty/sentry-native/tests/unit/test_value.c b/thirdparty/sentry-native/tests/unit/test_value.c index 46170b1450..6a4044c13c 100644 --- a/thirdparty/sentry-native/tests/unit/test_value.c +++ b/thirdparty/sentry-native/tests/unit/test_value.c @@ -3,7 +3,6 @@ #include "sentry_value.h" #include #include -#include SENTRY_TEST(value_null) { @@ -547,3 +546,21 @@ SENTRY_TEST(value_collections_leak) TEST_CHECK_INT_EQUAL(sentry_value_refcount(obj), 1); sentry_value_decref(obj); } + +SENTRY_TEST(value_set_stacktrace) +{ + sentry_value_t exc + = sentry_value_new_exception("std::out_of_range", "vector"); + sentry_value_set_stacktrace(exc, NULL, 0); + + sentry_value_t stacktrace = sentry_value_get_by_key(exc, "stacktrace"); + TEST_CHECK(!sentry_value_is_null(stacktrace)); + TEST_CHECK(SENTRY_VALUE_TYPE_OBJECT == sentry_value_get_type(stacktrace)); + + sentry_value_t frames = sentry_value_get_by_key(stacktrace, "frames"); + TEST_CHECK(!sentry_value_is_null(frames)); + TEST_CHECK(SENTRY_VALUE_TYPE_LIST == sentry_value_get_type(frames)); + TEST_CHECK(0 < sentry_value_get_length(frames)); + + sentry_value_decref(exc); +} diff --git a/thirdparty/sentry-native/tests/unit/tests.inc b/thirdparty/sentry-native/tests/unit/tests.inc index 6414d109e5..6f14d67d1b 100644 --- a/thirdparty/sentry-native/tests/unit/tests.inc +++ b/thirdparty/sentry-native/tests/unit/tests.inc @@ -1,3 +1,6 @@ +XX(assert_sdk_name) +XX(assert_sdk_user_agent) +XX(assert_sdk_version) XX(background_worker) XX(basic_consent_tracking) XX(basic_function_transport) @@ -15,7 +18,10 @@ XX(child_spans) XX(concurrent_init) XX(concurrent_uninit) XX(count_sampled_events) +XX(crash_marker) +XX(crashed_last_run) XX(custom_logger) +XX(discarding_before_send) XX(distributed_headers) XX(drop_unfinished_spans) XX(dsn_parsing_complete) @@ -84,6 +90,7 @@ XX(value_null) XX(value_object) XX(value_object_merge) XX(value_object_merge_nested) +XX(value_set_stacktrace) XX(value_string) XX(value_unicode) XX(value_wrong_type)