diff --git a/.craft.yml b/.craft.yml index 8fe0ac390..5d4e54e4c 100644 --- a/.craft.yml +++ b/.craft.yml @@ -21,4 +21,4 @@ requireNames: - /^symbolic-.*-py2.py3-none-macosx_11_0_arm64.whl$/ - /^symbolic-.*-py2.py3-none-manylinux_2_28_aarch64.whl$/ - /^symbolic-.*-py2.py3-none-manylinux_2_28_x86_64.whl$/ - - /^symbolic-.*.zip$/ + - /^symbolic-.*.tar.gz$/ diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5d137aba4..671345120 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,6 +7,8 @@ on: env: MANYLINUX_VERSION: manylinux_2_28 + # Pinned to 2025.08.15-1 since manylinux 2025.08.22 onward removes setuptools + MANYLINUX_PIN: 2025.08.15-1 jobs: python-wheel-mac: @@ -36,10 +38,13 @@ jobs: # consumed by cargo and setup.py to obtain the target dir CARGO_BUILD_TARGET: ${{ matrix.target }} - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v4 with: - name: ${{ github.sha }} + name: artifact-macos-${{ matrix.target }} path: py/dist/* + if-no-files-found: "error" + # since this artifact will be merged, compression is not necessary + compression-level: "0" python-wheel-linux: strategy: @@ -61,12 +66,15 @@ jobs: - if: matrix.build-arch == 'x86_64' name: Build in Docker (x86_64) - run: make wheel-manylinux IMAGE=quay.io/pypa/"$MANYLINUX_VERSION"_x86_64 + run: make wheel-manylinux IMAGE=quay.io/pypa/"$MANYLINUX_VERSION"_x86_64:"$MANYLINUX_PIN" - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v4 with: - name: ${{ github.sha }} + name: artifact-linux-${{ matrix.build-arch }} path: py/dist/* + if-no-files-found: "error" + # since this artifact will be merged, compression is not necessary + compression-level: "0" sdist: name: Python sdist @@ -81,7 +89,22 @@ jobs: - run: make sdist - - uses: actions/upload-artifact@v3.1.1 + - uses: actions/upload-artifact@v4 with: - name: ${{ github.sha }} + name: artifact-sdist path: py/dist/* + if-no-files-found: "error" + # since this artifact will be merged, compression is not necessary + compression-level: "0" + + merge: + name: Create Release Artifact + runs-on: ubuntu-latest + needs: [python-wheel-linux, python-wheel-mac, sdist] + steps: + - uses: actions/upload-artifact/merge@v4 + with: + # Craft expects release assets from github to be a single artifact named after the sha. + name: ${{ github.sha }} + pattern: artifact-* + delete-merged: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 483f1e3de..34325cc17 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] name: Rust Test on ${{ matrix.os }} runs-on: ${{ matrix.os }} diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index e24696d75..d00032569 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -2,8 +2,10 @@ name: Danger on: pull_request: - types: [opened, synchronize, reopened, edited, ready_for_review] + types: [opened, synchronize, reopened, edited, ready_for_review, labeled, unlabeled] jobs: danger: - uses: getsentry/github-workflows/.github/workflows/danger.yml@v2 + runs-on: ubuntu-latest + steps: + - uses: getsentry/github-workflows/danger@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a523379b8..e3290798f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,9 +15,16 @@ jobs: runs-on: ubuntu-latest name: "Release a new version" steps: + - name: Get auth token + id: token + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + with: + app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }} + private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }} + - uses: actions/checkout@v3 with: - token: ${{ secrets.GH_RELEASE_PAT }} + token: ${{ steps.token.outputs.token }} fetch-depth: 0 - run: rustup toolchain install stable --profile minimal --no-self-update @@ -25,7 +32,7 @@ jobs: - name: Prepare release uses: getsentry/action-prepare-release@v1 env: - GITHUB_TOKEN: ${{ secrets.GH_RELEASE_PAT }} + GITHUB_TOKEN: ${{ steps.token.outputs.token }} with: version: ${{ github.event.inputs.version }} force: ${{ github.event.inputs.force }} diff --git a/.semgrepignore b/.semgrepignore new file mode 100644 index 000000000..b192bacd5 --- /dev/null +++ b/.semgrepignore @@ -0,0 +1,4 @@ +:include .gitignore + +examples/ +**/tests/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 555377c1d..afb8e346b 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -5,14 +5,15 @@ // C++ language support "ms-vscode.cpptools", // TOML language support - "bungcip.better-toml", + "tamasfe.even-better-toml", // Rust language server "rust-lang.rust-analyzer", // Crates.io dependency versions - "serayuzgur.crates", + "fill-labs.dependi", // Debugger support for Rust and native "vadimcn.vscode-lldb", // PEST syntax support "xoronic.pestfile" + ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 869ec8af1..3f318d5f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,173 @@ # Changelog +## 12.17.0 + +- feat(pdb): Extract the srcsrv integration name for metrics ([#944](https://github.com/getsentry/symbolic/pull/944)) + +## 12.16.3 + +- feat(elf): Added support for dynamic symbols when DYNAMIC segment is missing. ([#935](https://github.com/getsentry/symbolic/pull/935)) +- fix(dwarf): -2 is now an allowed tombstone address in some DWARF sections. + For details, see https://github.com/gimli-rs/gimli/pull/791. ([#937](https://github.com/getsentry/symbolic/pull/937)). + +## 12.16.2 + +**Fixes** + +- sourcemapcache: Tokens are now considered to only extend to the end of the line + (as intended). This means that some lookups that would previously (incorrectly) + have returned unminified source positions now return nothing. ([#932](https://github.com/getsentry/symbolic/pull/932)) + +## 12.16.1 + +**Fixes** + +- symcache: Fixed a bug in symcache generation for functions without line records. ([#930](https://github.com/getsentry/symbolic/pull/930)) + +## 12.16.0 + +**Features** + +- python bindings: Expose SourceMapView.get_source_contents function. ([#921](https://github.com/getsentry/symbolic/pull/921)) +- Change the MSRV version to 1.82. ([#927](https://github.com/getsentry/symbolic/pull/927)) +- build: switch to Python3.11 for releases builds. ([#929](https://github.com/getsentry/symbolic/pull/929)) + +**Fixes** + +- sourcemapcache: Don't return unmapped source locations. ([#922](https://github.com/getsentry/symbolic/pull/922)) + +## 12.15.5 + +**Fixes** + +- demangle: Fixed a crash/abort when providing bad input to the swift demangler. ([#917](https://github.com/getsentry/symbolic/pull/917)) + +## 12.15.4 + +**Fixes** + +- symcache: Fixed a bug introduced in 12.14.0 that resulted in symbols not being inserted. ([#915](https://github.com/getsentry/symbolic/pull/915)) + +## 12.15.3 + +**Features** + +- Allow specifying multiple symbol sources in minidump-stackwalk utility. ([#903](https://github.com/getsentry/symbolic/pull/903)) +- Add a subcommand to extract individual files from a unreal crash report to the `unreal_engine_crash` utility. ([#907](https://github.com/getsentry/symbolic/pull/907)) + +**Fixes** + +- Do not hallucinate frames when stack walking in minidump-stackwalk utility. ([#904](https://github.com/getsentry/symbolic/pull/904)) + +**Improvements** + +- Add normalization for paths in `FileKey`. ([#908](https://github.com/getsentry/symbolic/pull/908)) + +## 12.14.1 + +**Fixes** + +- Restore support for older Rust versions and clarify MSRV policy. ([#902](https://github.com/getsentry/symbolic/pull/902)) + +## 12.14.0 + +**Features** + +- Expose API to apply access pattern hints to a `ByteView`.([#899](https://github.com/getsentry/symbolic/pull/899)). + +**Fixes** + +- symcache: Explicitly map "holes" between functions ([#897](https://github.com/getsentry/symbolic/pull/897)) + +## 12.13.4 + +**Fixes** + +- Parse `debug_str_offs` section in Mach-O files ([#895](https://github.com/getsentry/symbolic/pull/895)) + +## 12.13.3 + +**Improvements** + +- Check UTF-8 validity memory efficiently ([#890](https://github.com/getsentry/symbolic/pull/890)) + +## 12.13.2 + +**Fixes** + +- Fixed GHA-based Windows builds ([#891](https://github.com/getsentry/symbolic/pull/891)). + +## 12.13.1 + +**Fixes** + +- Fixed a compilation issue with older GCC compilers. ([#886](https://github.com/getsentry/symbolic/pull/886)) + +## 12.13.0 + +**Features** + +- Updated libswift demangle to v6.0.3. ([#885](https://github.com/getsentry/symbolic/pull/885)) + +## 12.12.4 + +**Fixes** + +- symcache: Fixed a bug related to to inlinee resolution during symcache conversion. ([#883](https://github.com/getsentry/symbolic/pull/883)) + +## 12.12.3 + +**Fixes** + +- js: Prefer `"debug_id"` for sourcemap debug IDs. ([#878](https://github.com/getsentry/symbolic/pull/878)). + +## 12.12.2 + +**Fixes** + +- js: Fixed an error when reading debug IDs from sourcemaps with + both `"debugId"` and `"debug_id"` keys ([#877](https://github.com/getsentry/symbolic/pull/877)). + +## 12.12.1 + +**Features** + +- feat(js): Sourcemap debug IDs can now be read from the `"debugId"` field in addition to + `"debug_id"` ([#870](https://github.com/getsentry/symbolic/pull/870)). + +## 12.12.0 + +**Fixes** + +- Unship "Support for DWARFv5 embedded source code extension ([#849](https://github.com/getsentry/symbolic/pull/849))". + Unfortunately the check for whether an elf file contains embedded sources is prohibitively expensive in terms of memory. + ([#870](https://github.com/getsentry/symbolic/pull/870)) + +## 12.11.1 + +**Fixes** + +- symbolic-cfi: Skip invalid FDEs when converting DWARF to Breakpad CFI ([#868](https://github.com/getsentry/symbolic/pull/868)) + +**Internal**: + +- Removed `dmsort` dependency and replaced uses with stable std sorts. ([#869](https://github.com/getsentry/symbolic/pull/869)) + +## 12.11.0 + +- Add callback to `symbolic::debuginfo::sourcebundle::SourceBundleWriter` which handles files skipped while writing to the source bundle. ([#864](https://github.com/getsentry/symbolic/pull/864)) + +## 12.10.1 + +- Skip invalid sources ([#861](https://github.com/getsentry/symbolic/pull/861)) + +## 12.10.0 + +**Features** + +- Support for DWARFv5 embedded source code extension ([#849](https://github.com/getsentry/symbolic/pull/849)) +- Updated wasmparser dependency to 0.214.0 ([#849](https://github.com/getsentry/symbolic/pull/853)) + ## 12.9.2 - Downgrade and pin `zip` to fix SourceBundles with >64k files ([#846](https://github.com/getsentry/symbolic/pull/846)) diff --git a/Cargo.lock b/Cargo.lock index 08e5694e2..924a709f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,29 +1,10 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "addr2line" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" -dependencies = [ - "gimli 0.29.0", -] +version = 4 [[package]] name = "addr2line" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "anyhow", "clap", @@ -31,16 +12,16 @@ dependencies = [ ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", @@ -50,18 +31,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] -name = "android-tzdata" -version = "0.1.1" +name = "allocator-api2" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" @@ -80,9 +61,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -95,43 +76,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "anylog" @@ -144,28 +126,36 @@ dependencies = [ "regex", ] +[[package]] +name = "ar_archive_writer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a" +dependencies = [ + "object", +] + [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ast_node" -version = "0.9.8" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab31376d309dd3bfc9cfb3c11c93ce0e0741bbe0354b20e7f8c60b044730b79" +checksum = "2eb025ef00a6da925cf40870b9c8d008526b6004ece399cb0974209720f0b194" dependencies = [ - "proc-macro2", "quote", "swc_macros_common", "syn", @@ -173,9 +163,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", @@ -184,39 +174,25 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "backtrace" -version = "0.3.72" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11" -dependencies = [ - "addr2line 0.22.0", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64-simd" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" dependencies = [ - "simd-abstraction", + "outref", + "vsimd", ] [[package]] name = "better_scoped_tls" -version = "0.1.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794edcc9b3fb07bb4aecaa11f093fd45663b4feadb782d68303a2268bc2701de" +checksum = "7cd228125315b132eed175bf47619ac79b945b26e56b848ba203ae4ea8603609" dependencies = [ "scoped-tls", ] @@ -227,6 +203,21 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597bb81c80a54b6a4381b23faba8d7774b144c94cbd1d6fe3f1329bd776554ab" +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "1.3.2" @@ -235,9 +226,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bitvec" @@ -253,9 +244,9 @@ dependencies = [ [[package]] name = "breakpad-symbols" -version = "0.21.2" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b37cb0d96cbe2c0cb6c4fc8856dc38b87d61abaa220c818f162bee332d3f4193" +checksum = "61f012b493245d982c24a716dd716d06188af966f685ce3cafe02e197ab7fb59" dependencies = [ "async-trait", "cachemap2", @@ -265,7 +256,7 @@ dependencies = [ "minidump-common", "nom", "range-map", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -280,26 +271,36 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.17" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ - "lazy_static", "memchr", - "regex-automata 0.1.10", + "regex-automata", + "serde", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytes" -version = "1.6.0" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "bytes-str" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "7c60b5ce37e0b883c37eb89f79a1e26fbe9c1081945d024eee93e8d91a7e18b3" +dependencies = [ + "bytes", + "serde", +] [[package]] name = "cachemap2" @@ -315,32 +316,32 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.98" +version = "1.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" dependencies = [ + "find-msvc-tools", "jobserver", "libc", - "once_cell", + "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.5", + "windows-link", ] [[package]] @@ -378,18 +379,18 @@ checksum = "b0fc239e0f6cb375d2402d48afb92f76f5404fd1df208a41930ec81eda078bea" [[package]] name = "clap" -version = "4.5.4" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -399,48 +400,48 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "console" -version = "0.15.8" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpp_demangle" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +checksum = "f2bb79cb74d735044c972aae58ed0aaa9a837e85b01106a54c39e42e97f62253" dependencies = [ "cfg-if", ] [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -483,9 +484,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -502,9 +503,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -512,7 +513,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.10.0", "crossterm_winapi", "libc", "mio", @@ -533,15 +534,15 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "debugid" @@ -555,7 +556,7 @@ dependencies = [ [[package]] name = "debuginfo_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "anyhow", "clap", @@ -564,18 +565,18 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", @@ -584,24 +585,18 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", "syn", ] -[[package]] -name = "dmsort" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0bc8fbe9441c17c9f46f75dfe27fa1ddb6c68a461ccaed0481419219d4f10d3" - [[package]] name = "dump_cfi" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "anyhow", "clap", @@ -610,7 +605,7 @@ dependencies = [ [[package]] name = "dump_sources" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "clap", "symbolic", @@ -618,9 +613,9 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elementtree" @@ -633,42 +628,42 @@ dependencies = [ [[package]] name = "elsa" -version = "1.10.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98e71ae4df57d214182a2e5cb90230c0192c6ddfcaa05c36453d46a54713e10" +checksum = "9abf33c656a7256451ebb7d0082c5a471820c31269e49d807c538c252352186e" dependencies = [ "stable_deref_trait", ] [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -685,36 +680,47 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "flate2" -version = "1.0.30" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] [[package]] name = "from_variant" -version = "0.1.8" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc9cc75639b041067353b9bce2450d6847e547276c6fbe4487d7407980e07db" +checksum = "e5ff35a391aef949120a0340d690269b3d9f63460a6106e99bd07b961f345ea9" dependencies = [ - "proc-macro2", "swc_macros_common", "syn", ] @@ -727,15 +733,15 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -744,15 +750,15 @@ dependencies = [ [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-macro", @@ -763,16 +769,22 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.29.0" +name = "getrandom" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] [[package]] name = "gimli" -version = "0.30.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e1d97fbe9722ba9bbd0c97051c2956e726562b61f86a25a4360398a40edfc9" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator 0.3.0", "stable_deref_trait", @@ -791,12 +803,13 @@ dependencies = [ [[package]] name = "half" -version = "2.4.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -806,14 +819,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", + "allocator-api2", "serde", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -823,28 +849,29 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hstr" -version = "0.2.10" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96274be293b8877e61974a607105d09c84caebe9620b47774aa8a6b942042dd4" +checksum = "0c43c0a9e8fbdb3bb9dc8eee85e1e2ac81605418b4c83b6b7413cbf14d56ca5c" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", "new_debug_unreachable", "once_cell", - "phf", "rustc-hash", + "serde", "triomphe", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -858,21 +885,113 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] name = "if_chain" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +checksum = "cd62e6b5e86ea8eeeb8db1de02880a6abc01a397b2ebb64b5d74ac255318f5cb" [[package]] name = "indent_write" @@ -882,13 +1001,14 @@ checksum = "0cfe9645a18782869361d9c8732246be7b410ad4e919d3609ebabdac00ba12c3" [[package]] name = "indexmap" -version = "2.2.6" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", "serde", + "serde_core", ] [[package]] @@ -902,24 +1022,23 @@ dependencies = [ [[package]] name = "insta" -version = "1.39.0" +version = "1.44.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +checksum = "b5c943d4415edd8153251b6f197de5eb1640e56d84e8d9159bea190421c73698" dependencies = [ "console", - "lazy_static", - "linked-hash-map", + "once_cell", "serde", "similar", ] [[package]] name = "is-macro" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a85abdc13717906baccb5a1e435556ce0df215f242892f721dff62bf25288f" +checksum = "1d57a3e447e24c22647738e4607f1df1e0ec6f72e16182c4cd199f647cdfb0e4" dependencies = [ - "Inflector", + "heck", "proc-macro2", "quote", "syn", @@ -927,20 +1046,20 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.12" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -962,16 +1081,17 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom", "libc", ] @@ -983,33 +1103,34 @@ checksum = "72167d68f5fce3b8655487b8038691a3c9984ee769590f93f2a631f4ad64e4f5" [[package]] name = "js-source-scopes" -version = "0.5.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfdc25288ccb82b33c3aa3f14587fd920b825690f3c4f8c5385b1d8998e9a40" +checksum = "632e077b0fb37f6476d2fa0e15ee97afcfc2359a1a68b1990d4fa9f82324e3f0" dependencies = [ "indexmap", "sourcemap", "swc_common", "swc_ecma_parser", "swc_ecma_visit", - "thiserror", + "thiserror 2.0.17", "tracing", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -1019,51 +1140,44 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] -name = "linked-hash-map" -version = "0.5.6" +name = "linux-raw-sys" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "litemap" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] -[[package]] -name = "lockfree-object-pool" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" - [[package]] name = "log" -version = "0.4.21" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -1074,24 +1188,24 @@ checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ] [[package]] name = "minidump" -version = "0.21.2" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d385b740c6b991e6eff48f26e2c6978c9e9e9e2e935f4967bcdf4c2d1d18828" +checksum = "ebc7268c0afe5aa2fd6fde310e6cda158f0b3581f317c5a5c7d170861f9b90a6" dependencies = [ "debugid", "encoding_rs", @@ -1101,7 +1215,7 @@ dependencies = [ "procfs-core", "range-map", "scroll 0.12.0", - "thiserror", + "thiserror 1.0.69", "time", "tracing", "uuid", @@ -1109,11 +1223,11 @@ dependencies = [ [[package]] name = "minidump-common" -version = "0.21.2" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c4d14bcca0fd3ed165a03000480aaa364c6860c34e900cb2dafdf3b95340e77" +checksum = "0cde999358cca8fb9397c4298bb27c4a603c13ee6b3a646da514b20be582a21e" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.10.0", "debugid", "num-derive", "num-traits", @@ -1124,9 +1238,9 @@ dependencies = [ [[package]] name = "minidump-processor" -version = "0.21.2" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7869a9256743611832cdf02d01ee5e2d67055a47727b21a01d47a79839876ca4" +checksum = "41ab4c99352eb8bcc861eb06ceae910fc1d0a8395acc9ffd961fc230c9c12ca0" dependencies = [ "async-trait", "breakpad-symbols", @@ -1138,16 +1252,16 @@ dependencies = [ "scroll 0.12.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tracing", "yaxpeax-x86", ] [[package]] name = "minidump-unwind" -version = "0.21.2" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4fb17e3a2508326b9547166051a979d439d883bcd1058b48a2d1181a0b37cf" +checksum = "3b2bc4d6066050b350c5dddf066a25bfd6c9f20b8919dc66501d831524ab4dd4" dependencies = [ "async-trait", "breakpad-symbols", @@ -1159,7 +1273,7 @@ dependencies = [ [[package]] name = "minidump_stackwalk" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "async-trait", "clap", @@ -1167,7 +1281,7 @@ dependencies = [ "minidump-processor", "minidump-unwind", "symbolic", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "tracing-subscriber", @@ -1182,11 +1296,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "adler", + "adler2", + "simd-adler32", ] [[package]] @@ -1207,7 +1322,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4c25a3bb7d880e8eceab4822f3141ad0700d20f025991c1f03bd3d00219a5fc" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.10.0", ] [[package]] @@ -1241,19 +1356,18 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "overload", - "winapi", + "windows-sys 0.61.2", ] [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -1297,16 +1411,16 @@ dependencies = [ [[package]] name = "object" -version = "0.35.0" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "object_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "clap", "symbolic", @@ -1314,33 +1428,33 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "oorandom" -version = "11.1.3" +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] -name = "outref" -version = "0.1.0" +name = "oorandom" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] -name = "overload" -version = "0.1.1" +name = "outref" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1348,15 +1462,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-link", ] [[package]] @@ -1381,43 +1495,43 @@ dependencies = [ "maybe-owned", "pdb", "range-collections", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_macros", - "phf_shared 0.11.2", + "phf_shared", ] [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "phf_shared 0.11.2", - "rand", + "phf_shared", + "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ "phf_generator", - "phf_shared 0.11.2", + "phf_shared", "proc-macro2", "quote", "syn", @@ -1425,27 +1539,18 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher", + "siphasher 1.0.1", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -1455,9 +1560,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plain" @@ -1467,9 +1572,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -1480,25 +1585,43 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "precomputed-hash" version = "0.1.1" @@ -1507,51 +1630,86 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "procfs-core" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" +checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.10.0", "hex", ] [[package]] name = "proguard" -version = "5.4.1" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b88dddb086b00f5539a95d2c7a2373358fd8bfadb7b1297cc29e0196403a1b98" +checksum = "260b8aaeeb4bc5175bb90a599f51d74a560f19de428c2d058c67eac92b5085d3" dependencies = [ - "lazy_static", + "serde", + "serde_json", + "thiserror 1.0.69", "uuid", + "watto", ] [[package]] -name = "psm" -version = "0.1.21" +name = "proptest" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.10.0", + "num-traits", + "rand 0.9.2", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "psm" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11f2fedc3b7dafdc2851bc52f277377c5473d378859be234bc7ebb593144d01" +dependencies = [ + "ar_archive_writer", "cc", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" -version = "1.0.36" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "radium" version = "0.7.0" @@ -1564,7 +1722,27 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -1573,6 +1751,24 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + [[package]] name = "range-collections" version = "0.2.4" @@ -1595,9 +1791,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -1605,9 +1801,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -1615,96 +1811,90 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.10.0", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] -name = "rustc_version" -version = "0.2.3" +name = "rustix" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "semver 0.9.0", + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", ] [[package]] -name = "rustix" -version = "0.38.34" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", + "fnv", + "quick-error", + "tempfile", + "wait-timeout", ] [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -1744,9 +1934,9 @@ dependencies = [ [[package]] name = "scroll_derive" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" +checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" dependencies = [ "proc-macro2", "quote", @@ -1755,39 +1945,40 @@ dependencies = [ [[package]] name = "semver" -version = "0.9.0" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] -name = "semver" -version = "1.0.23" +name = "seq-macro" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc" [[package]] -name = "semver-parser" -version = "0.7.0" +name = "serde" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] [[package]] -name = "serde" -version = "1.0.203" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1796,20 +1987,22 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", + "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sharded-slab" @@ -1820,11 +2013,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" dependencies = [ "libc", "signal-hook-registry", @@ -1832,9 +2031,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", "mio", @@ -1843,22 +2042,13 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ "libc", ] -[[package]] -name = "simd-abstraction" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" -dependencies = [ - "outref", -] - [[package]] name = "simd-adler32" version = "0.3.7" @@ -1867,9 +2057,9 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "similar" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" dependencies = [ "bstr", "unicode-segmentation", @@ -1877,9 +2067,9 @@ dependencies = [ [[package]] name = "similar-asserts" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e041bb827d1bfca18f213411d51b665309f1afb37a04a5d1464530e13779fc0f" +checksum = "b5b441962c817e33508847a22bd82f03a30cff43642dc2fae8b050566121eb9a" dependencies = [ "console", "similar", @@ -1891,20 +2081,23 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smart-default" @@ -1930,9 +2123,9 @@ dependencies = [ [[package]] name = "sourcemap" -version = "8.0.1" +version = "9.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "208d40b9e8cad9f93613778ea295ed8f3c2b1824217c6cfc7219d3f6f45b96d4" +checksum = "e22afbcb92ce02d23815b9795523c005cb9d3c214f8b7a66318541c240ea7935" dependencies = [ "base64-simd", "bitvec", @@ -1940,7 +2133,6 @@ dependencies = [ "debugid", "if_chain", "rustc-hash", - "rustc_version", "serde", "serde_json", "unicode-id-start", @@ -1949,7 +2141,7 @@ dependencies = [ [[package]] name = "sourcemapcache_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "anyhow", "clap", @@ -1957,23 +2149,33 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "srcsrv" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cd3e3828fb4dd5ba0e7091777edb6c3db3cd2d6fc10547b29b40f6949a29be" +dependencies = [ + "memchr", + "thiserror 2.0.17", +] + [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stacker" -version = "0.1.15" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c886bd4480155fd3ef527d45e9ac8dd7118a898a46530b7b94c3e21866259fce" +checksum = "e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59" dependencies = [ "cc", "cfg-if", "libc", "psm", - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -1984,25 +2186,23 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", - "once_cell", "parking_lot", - "phf_shared 0.10.0", + "phf_shared", "precomputed-hash", "serde", ] [[package]] name = "string_enum" -version = "0.4.4" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e383308aebc257e7d7920224fa055c632478d92744eca77f99be8fa1545b90" +checksum = "ae36a4951ca7bd1cfd991c241584a9824a70f6aff1e7d4f693fb3f2465e4030e" dependencies = [ - "proc-macro2", "quote", "swc_macros_common", "syn", @@ -2016,25 +2216,25 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "swc_atoms" -version = "0.6.7" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6567e4e67485b3e7662b486f1565bdae54bd5b9d6b16b2ba1a9babb1e42125" +checksum = "d4ccbe2ecad10ad7432100f878a107b1d972a8aee83ca53184d00c23a078bb8a" dependencies = [ "hstr", "once_cell", - "rustc-hash", "serde", ] [[package]] name = "swc_common" -version = "0.33.26" +version = "17.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f9706038906e66f3919028f9f7a37f3ed552f1b85578e93f4468742e2da438" +checksum = "259b675d633a26d24efe3802a9d88858c918e6e8f062d3222d3aa02d56a2cf4c" dependencies = [ + "anyhow", "ast_node", "better_scoped_tls", - "cfg-if", + "bytes-str", "either", "from_variant", "new_debug_unreachable", @@ -2042,7 +2242,7 @@ dependencies = [ "once_cell", "rustc-hash", "serde", - "siphasher", + "siphasher 0.3.11", "swc_atoms", "swc_eq_ignore_macros", "swc_visit", @@ -2053,49 +2253,51 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.113.6" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae3fb68e165bb093ea05fe68dfbc5d378c8b41515a5160f733d7b45bfb9d96e" +checksum = "a573a0c72850dec8d4d8085f152d5778af35a2520c3093b242d2d1d50776da7c" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.10.0", "is-macro", "num-bigint", + "once_cell", "phf", - "scoped-tls", + "rustc-hash", "string_enum", "swc_atoms", "swc_common", + "swc_visit", "unicode-id-start", ] [[package]] name = "swc_ecma_parser" -version = "0.144.1" +version = "27.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0499e69683ae5d67a20ff0279b94bc90f29df7922a46331b54d5dd367bf89570" +checksum = "7f1a51af1a92cd4904c073b293e491bbc0918400a45d58227b34c961dd6f52d7" dependencies = [ + "bitflags 2.10.0", "either", - "new_debug_unreachable", "num-bigint", - "num-traits", "phf", + "rustc-hash", + "seq-macro", "serde", - "smallvec", "smartstring", "stacker", "swc_atoms", "swc_common", "swc_ecma_ast", "tracing", - "typed-arena", ] [[package]] name = "swc_ecma_visit" -version = "0.99.1" +version = "18.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6ce28ad8e591f8d627f1f9cb26b25e5d83052a9bc1b674d95fc28040cfa98" +checksum = "a9611a72a4008d62608547a394e5d72a5245413104db096d95a52368a8cc1d63" dependencies = [ + "new_debug_unreachable", "num-bigint", "swc_atoms", "swc_common", @@ -2106,9 +2308,9 @@ dependencies = [ [[package]] name = "swc_eq_ignore_macros" -version = "0.1.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "695a1d8b461033d32429b5befbf0ad4d7a2c4d6ba9cd5ba4e0645c615839e8e4" +checksum = "c16ce73424a6316e95e09065ba6a207eba7765496fed113702278b7711d4b632" dependencies = [ "proc-macro2", "quote", @@ -2117,9 +2319,9 @@ dependencies = [ [[package]] name = "swc_macros_common" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91745f3561057493d2da768437c427c0e979dff7396507ae02f16c981c4a8466" +checksum = "aae1efbaa74943dc5ad2a2fb16cbd78b77d7e4d63188f3c5b4df2b4dcd2faaae" dependencies = [ "proc-macro2", "quote", @@ -2128,30 +2330,17 @@ dependencies = [ [[package]] name = "swc_visit" -version = "0.5.14" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043d11fe683dcb934583ead49405c0896a5af5face522e4682c16971ef7871b9" +checksum = "62fb71484b486c185e34d2172f0eabe7f4722742aad700f426a494bb2de232a2" dependencies = [ "either", - "swc_visit_macros", -] - -[[package]] -name = "swc_visit_macros" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae9ef18ff8daffa999f729db056d2821cd2f790f3a11e46422d19f46bb193e7" -dependencies = [ - "Inflector", - "proc-macro2", - "quote", - "swc_macros_common", - "syn", + "new_debug_unreachable", ] [[package]] name = "symbolic" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "symbolic-cfi", "symbolic-common", @@ -2166,7 +2355,7 @@ dependencies = [ [[package]] name = "symbolic-cabi" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "anyhow", "proguard", @@ -2177,19 +2366,19 @@ dependencies = [ [[package]] name = "symbolic-cfi" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "insta", "similar-asserts", "symbolic-common", "symbolic-debuginfo", "symbolic-testutils", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "symbolic-common" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "debugid", "memmap2", @@ -2203,16 +2392,15 @@ dependencies = [ [[package]] name = "symbolic-debuginfo" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "criterion", "debugid", - "dmsort", "elementtree", "elsa", "fallible-iterator 0.3.0", "flate2", - "gimli 0.30.0", + "gimli", "goblin", "insta", "lazy_static", @@ -2221,17 +2409,19 @@ dependencies = [ "once_cell", "parking_lot", "pdb-addr2line", + "proptest", "regex", "scroll 0.12.0", "serde", "serde_json", "similar-asserts", "smallvec", + "srcsrv", "symbolic-common", "symbolic-ppdb", "symbolic-testutils", "tempfile", - "thiserror", + "thiserror 1.0.69", "wasmparser", "zip", "zstd", @@ -2239,7 +2429,7 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "cc", "cpp_demangle", @@ -2251,7 +2441,7 @@ dependencies = [ [[package]] name = "symbolic-il2cpp" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "indexmap", "serde_json", @@ -2261,7 +2451,7 @@ dependencies = [ [[package]] name = "symbolic-ppdb" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "flate2", "indexmap", @@ -2270,28 +2460,28 @@ dependencies = [ "symbolic-common", "symbolic-debuginfo", "symbolic-testutils", - "thiserror", + "thiserror 1.0.69", "uuid", "watto", ] [[package]] name = "symbolic-sourcemapcache" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "itertools 0.13.0", "js-source-scopes", "sourcemap", "symbolic-common", "symbolic-testutils", - "thiserror", + "thiserror 1.0.69", "tracing", "watto", ] [[package]] name = "symbolic-symcache" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "criterion", "indexmap", @@ -2300,18 +2490,18 @@ dependencies = [ "symbolic-debuginfo", "symbolic-il2cpp", "symbolic-testutils", - "thiserror", + "thiserror 1.0.69", "tracing", "watto", ] [[package]] name = "symbolic-testutils" -version = "12.9.2-dd" +version = "12.17.0-dd" [[package]] name = "symbolic-unreal" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "anylog", "bytes", @@ -2325,13 +2515,13 @@ dependencies = [ "serde", "similar-asserts", "symbolic-testutils", - "thiserror", + "thiserror 1.0.69", "time", ] [[package]] name = "symcache_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "anyhow", "clap", @@ -2340,15 +2530,26 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tap" version = "1.0.1" @@ -2357,30 +2558,51 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ - "cfg-if", "fastrand", + "getrandom", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", ] [[package]] name = "thiserror" -version = "1.0.61" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.17", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -2389,19 +2611,18 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", @@ -2414,61 +2635,55 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", ] [[package]] -name = "tinytemplate" -version = "1.2.1" +name = "tinystr" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ - "serde", - "serde_json", + "displaydoc", + "zerovec", ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "tinytemplate" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ - "tinyvec_macros", + "serde", + "serde_json", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.38.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "pin-project-lite", "tokio-macros", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -2477,9 +2692,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" dependencies = [ "log", "pin-project-lite", @@ -2489,9 +2704,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -2500,9 +2715,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" dependencies = [ "once_cell", "valuable", @@ -2521,14 +2736,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -2539,62 +2754,47 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.12" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b2cb4fbb9995eeb36ac86fadf24031ccd58f99d6b4b2d7b911db70bddb80d90" +checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" dependencies = [ "serde", "stable_deref_trait", ] [[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "unarray" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-id-start" -version = "1.0.4" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02aebfa694eccbbbffdd92922c7de136b9fe764396d2f10e21bce1681477cfc1" +checksum = "81b79ad29b5e19de4260020f8919b443b2ef0277d242ce532ec7b7a2cc8b6007" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unreal_engine_crash" -version = "12.9.2-dd" +version = "12.17.0-dd" dependencies = [ "clap", "symbolic", @@ -2602,41 +2802,65 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.8.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ + "js-sys", "sha1_smol", + "wasm-bindgen", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + +[[package]] +name = "wait-timeout" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] [[package]] name = "walkdir" @@ -2650,40 +2874,37 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasm-bindgen" -version = "0.2.92" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "cfg-if", - "wasm-bindgen-macro", + "wit-bindgen", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.92" +name = "wasm-bindgen" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ - "bumpalo", - "log", + "cfg-if", "once_cell", - "proc-macro2", - "quote", - "syn", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2691,34 +2912,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasmparser" -version = "0.209.1" +version = "0.214.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07035cc9a9b41e62d3bb3a3815a66ab87c993c06fe1cf6b2a3f2a18499d937db" +checksum = "5309c1090e3e84dad0d382f42064e9933fdaedb87e468cc239f0eabea73ddcb6" dependencies = [ "ahash", - "bitflags 2.5.0", - "hashbrown", + "bitflags 2.10.0", + "hashbrown 0.14.5", "indexmap", - "semver 1.0.23", + "semver", "serde", ] @@ -2729,14 +2953,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6746b5315e417144282a047ebb82260d45c92d09bf653fa9ec975e3809be942b" dependencies = [ "leb128", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -2760,11 +2984,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2775,11 +2999,61 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.52.0" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ - "windows-targets 0.52.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", ] [[package]] @@ -2793,11 +3067,20 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.52.5", + "windows-link", ] [[package]] @@ -2817,18 +3100,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2839,9 +3122,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2851,9 +3134,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2863,15 +3146,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2881,9 +3164,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2893,9 +3176,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2905,9 +3188,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2917,9 +3200,21 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wyz" @@ -2955,20 +3250,97 @@ dependencies = [ "yaxpeax-arch", ] +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.8.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", @@ -2977,9 +3349,9 @@ dependencies = [ [[package]] name = "zip" -version = "2.1.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd56a4d5921bc2f99947ac5b3abe5f510b1be7376fdc5e9fce4a23c6a93e87c" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ "arbitrary", "crc32fast", @@ -2988,47 +3360,45 @@ dependencies = [ "flate2", "indexmap", "memchr", - "thiserror", + "thiserror 2.0.17", "zopfli", ] [[package]] name = "zopfli" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5019f391bac5cf252e93bbcc53d039ffd62c7bfb7c150414d61369afe57e946" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" dependencies = [ "bumpalo", "crc32fast", - "lockfree-object-pool", "log", - "once_cell", "simd-adler32", ] [[package]] name = "zstd" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.1.0" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index f60f1aee2..1f236df51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,10 @@ resolver = "2" members = ["symbolic*", "examples/*"] +[workspace.package] +edition = "2021" +rust-version = "1.82" + [workspace.dependencies] anyhow = "1.0.32" anylog = "0.6.4" @@ -13,28 +17,28 @@ clap = "4.4.5" cpp_demangle = "0.4.1" criterion = { version = "0.5.1", features = ["html_reports"] } debugid = "0.8.0" -dmsort = "1.0.2" elementtree = "1.2.3" elsa = "1.8.0" fallible-iterator = "0.3.0" flate2 = { version = "1.0.25", default-features = false, features = [ - "rust_backend", + "rust_backend", ] } -gimli = { version = "0.30.0", default-features = false, features = [ - "read", - "std", - "fallible-iterator", +gimli = { version = "0.32.3", default-features = false, features = [ + "read", + "std", + "fallible-iterator", ] } goblin = { version = "0.8.0", default-features = false } indexmap = "2.0.0" insta = { version = "1.28.0", features = ["yaml"] } itertools = "0.13.0" -js-source-scopes = "0.5.0" +# Point to master branch which has the swc fix for serde compatibility (>= 0.7.0) +js-source-scopes = "0.7.0" lazy_static = "1.4.0" memmap2 = "0.9.0" -minidump = "0.21.0" -minidump-processor = "0.21.0" -minidump-unwind = "0.21.0" +minidump = "0.22.0" +minidump-processor = "0.22.0" +minidump-unwind = "0.22.0" msvc-demangler = "0.10.0" nom = "7.1.3" nom-supreme = "0.8.0" @@ -42,15 +46,17 @@ once_cell = "1.17.1" parking_lot = "0.12.1" pdb-addr2line = "0.10.4" proguard = { version = "5.4.0", features = ["uuid"] } +proptest = "1.6.0" regex = "1.7.1" rustc-demangle = "0.1.21" # keep this in sync with whatever version `goblin` uses scroll = "0.12.0" +# Unpinned - js-source-scopes master branch is now compatible with latest serde serde = { version = "1.0.171", features = ["derive"] } serde_json = "1.0.102" similar-asserts = "1.4.2" smallvec = "1.10.0" -sourcemap = "8.0.1" +sourcemap = "9.2.2" stable_deref_trait = "1.2.0" tempfile = "3.4.0" thiserror = "1.0.39" @@ -60,7 +66,7 @@ tracing = "0.1.34" tracing-subscriber = "0.3.11" uuid = "1.3.0" walkdir = "2.3.1" -wasmparser = "0.209.1" +wasmparser = "0.214.0" watto = { version = "0.1.0", features = ["writer", "strings"] } # We are currently pinning a known good version prior to https://github.com/zip-rs/zip2/issues/189 # (dd) NOTE: previously pinned to 2.1.1, however this version is now yanked from crates.io diff --git a/Makefile b/Makefile index 2294c8159..a27ce2a71 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ build: .PHONY: build sdist: .venv/bin/python - cd py && ../.venv/bin/python setup.py sdist --format=zip + cd py && ../.venv/bin/python setup.py sdist .PHONY: sdist wheel: .venv/bin/python diff --git a/README.md b/README.md index 4ffc8c6db..e494115bf 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ make lint ``` Most likely, new functionality also needs to be added to the Python package. This first requires to -expose new functions in the C ABI. For this, refer to the [Symbolic C-ABI readme](sentry-cabi/README.md). +expose new functions in the C ABI. For this, refer to the [Symbolic C-ABI readme](symbolic-cabi/README.md). We highly recommend to develop and test the python package in a **virtual environment**. Once the ABI has been updated and tested, ensure the virtualenv is active and install the package, which @@ -158,6 +158,13 @@ To run these examples, use the `run` script. For example: ./run minidump_stackwalk mini.dmp /path/to/files ``` +## Supported Rust Versions + +Symbolic tries to not break MSRV compatibility but makes no guarantees about the Rust version. +Although you can expect Rust version compatibility of **at least 6 months**. + +The current MSRV is 1.82. + ## License Symbolic is licensed under the MIT license. It uses some Apache2 licensed code diff --git a/examples/addr2line/Cargo.toml b/examples/addr2line/Cargo.toml index 4750f45ce..ca631c047 100644 --- a/examples/addr2line/Cargo.toml +++ b/examples/addr2line/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "addr2line" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Jan Michael Auer "] edition = "2021" publish = false @@ -10,4 +10,4 @@ publish = false [dependencies] anyhow = { workspace = true } clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic", features = ["demangle"] } +symbolic = { version = "12.17.0-dd", path = "../../symbolic", features = ["demangle"] } diff --git a/examples/debuginfo_debug/Cargo.toml b/examples/debuginfo_debug/Cargo.toml index 77ae79e8c..91757d887 100644 --- a/examples/debuginfo_debug/Cargo.toml +++ b/examples/debuginfo_debug/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "debuginfo_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Markus Stange "] edition = "2021" publish = false @@ -10,6 +10,6 @@ publish = false [dependencies] anyhow = { workspace = true } clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic", features = [ +symbolic = { version = "12.17.0-dd", path = "../../symbolic", features = [ "demangle", ] } diff --git a/examples/dump_cfi/Cargo.toml b/examples/dump_cfi/Cargo.toml index 2a3bef004..c8ccd9a9b 100644 --- a/examples/dump_cfi/Cargo.toml +++ b/examples/dump_cfi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dump_cfi" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Jan Michael Auer "] edition = "2021" publish = false @@ -10,4 +10,4 @@ publish = false [dependencies] anyhow = { workspace = true } clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic", features = ["cfi"] } +symbolic = { version = "12.17.0-dd", path = "../../symbolic", features = ["cfi"] } diff --git a/examples/dump_sources/Cargo.toml b/examples/dump_sources/Cargo.toml index 06e9574ee..810f1c50d 100644 --- a/examples/dump_sources/Cargo.toml +++ b/examples/dump_sources/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dump_sources" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Jan Michael Auer "] edition = "2021" publish = false @@ -9,4 +9,4 @@ publish = false [dependencies] clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic" } +symbolic = { version = "12.17.0-dd", path = "../../symbolic" } diff --git a/examples/minidump_stackwalk/Cargo.toml b/examples/minidump_stackwalk/Cargo.toml index ea3cb973b..83ada8dae 100644 --- a/examples/minidump_stackwalk/Cargo.toml +++ b/examples/minidump_stackwalk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minidump_stackwalk" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Jan Michael Auer "] edition = "2021" publish = false @@ -13,7 +13,7 @@ clap = { workspace = true } minidump = { workspace = true } minidump-processor = { workspace = true } minidump-unwind = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic", features = [ +symbolic = { version = "12.17.0-dd", path = "../../symbolic", features = [ "symcache", "demangle", "cfi", diff --git a/examples/minidump_stackwalk/src/main.rs b/examples/minidump_stackwalk/src/main.rs index fd6a53029..f9cb1c98f 100644 --- a/examples/minidump_stackwalk/src/main.rs +++ b/examples/minidump_stackwalk/src/main.rs @@ -41,42 +41,7 @@ struct ObjectDatabase { by_code_id: HashMap>, } -/// Metadata about an object in the filesystem. -#[derive(Debug, Clone)] -struct ObjectMetadata { - /// The object's path. - path: PathBuf, - /// The object's index in its archive. - index_in_archive: usize, - /// Whether the object has unwind info. - has_unwind_info: bool, - /// Whether the object has symbol info. - has_symbol_info: bool, -} - -/// A SymbolProvider that recursively searches a given path for symbol files. -struct LocalSymbolProvider<'a> { - object_files: ObjectDatabase, - cfi_files: Mutex, - symcaches: Mutex>, - use_cfi: bool, - symbolicate: bool, -} - -impl<'a> LocalSymbolProvider<'a> { - /// Constructs a `LocalSymbolProvider` that will look for symbol files under the given path. - fn new>(path: Option

, use_cfi: bool, symbolicate: bool) -> Self { - Self { - object_files: path.map_or(Default::default(), |path| { - Self::create_object_database(path) - }), - cfi_files: Mutex::new(BTreeMap::default()), - symcaches: Mutex::new(SymCaches::default()), - use_cfi, - symbolicate, - } - } - +impl ObjectDatabase { /// Accumulates a database of objects found under the given path. /// /// The objects are saved in a map from `DebugId`s to vectors of @@ -86,11 +51,11 @@ impl<'a> LocalSymbolProvider<'a> { /// * whether the object has unwind info /// * whether the object has symbol info #[tracing::instrument(skip_all, fields(path = ?path.as_ref()))] - fn create_object_database(path: impl AsRef) -> ObjectDatabase { + fn from_path(path: impl AsRef) -> ObjectDatabase { let mut object_db = ObjectDatabase::default(); for entry in WalkDir::new(path).into_iter().filter_map(Result::ok) { // Folders will be recursed into automatically - if !entry.metadata().map_or(false, |md| md.is_file()) { + if !entry.metadata().is_ok_and(|md| md.is_file()) { continue; } @@ -149,6 +114,58 @@ impl<'a> LocalSymbolProvider<'a> { object_db } + /// Merges another [`ObjectDatabase`] into the current one. + fn merge(mut self, other: Self) -> Self { + let Self { + by_debug_id, + by_code_id, + } = other; + + self.by_debug_id.extend(by_debug_id); + self.by_code_id.extend(by_code_id); + + self + } +} + +/// Metadata about an object in the filesystem. +#[derive(Debug, Clone)] +struct ObjectMetadata { + /// The object's path. + path: PathBuf, + /// The object's index in its archive. + index_in_archive: usize, + /// Whether the object has unwind info. + has_unwind_info: bool, + /// Whether the object has symbol info. + has_symbol_info: bool, +} + +/// A SymbolProvider that recursively searches a given path for symbol files. +struct LocalSymbolProvider<'a> { + object_files: ObjectDatabase, + cfi_files: Mutex, + symcaches: Mutex>, + use_cfi: bool, + symbolicate: bool, +} + +impl<'a> LocalSymbolProvider<'a> { + /// Constructs a `LocalSymbolProvider` that will look for symbol files under the given path. + fn new>(path: &[P], use_cfi: bool, symbolicate: bool) -> Self { + Self { + object_files: path + .iter() + .map(ObjectDatabase::from_path) + .reduce(ObjectDatabase::merge) + .unwrap_or_default(), + cfi_files: Mutex::new(BTreeMap::default()), + symcaches: Mutex::new(SymCaches::default()), + use_cfi, + symbolicate, + } + } + /// Fetches the [`ObjectMetadata`] for the given id, using the [`DebugId`] or the [`CodeId`] /// as fallback. fn object_info(&self, id: LookupId) -> Option<&Vec> { @@ -172,6 +189,8 @@ impl<'a> LocalSymbolProvider<'a> { /// Objects which have unwind information are then tried in order. #[tracing::instrument(skip_all, fields(id = ?id))] fn load_cfi(&self, id: LookupId) -> Result { + tracing::info!("loading cficache"); + let object_list = self.object_info(id).ok_or(SymbolError::NotFound)?; let mut found = None; for object_meta in object_list.iter().filter(|object| object.has_unwind_info) { @@ -218,6 +237,8 @@ impl<'a> LocalSymbolProvider<'a> { &self, id: LookupId, ) -> Result, SymCache<'a>>, SymbolError> { + tracing::info!("loading symcache"); + let object_list = self.object_info(id).ok_or(SymbolError::NotFound)?; let mut found = None; for object_meta in object_list.iter().filter(|object| object.has_symbol_info) { @@ -262,7 +283,7 @@ impl<'a> LocalSymbolProvider<'a> { } #[async_trait] -impl<'a> minidump_unwind::SymbolProvider for LocalSymbolProvider<'a> { +impl minidump_unwind::SymbolProvider for LocalSymbolProvider<'_> { #[tracing::instrument( skip(self, module, frame), fields(module.id, frame.instruction = frame.get_instruction()) @@ -272,22 +293,44 @@ impl<'a> minidump_unwind::SymbolProvider for LocalSymbolProvider<'a> { module: &(dyn Module + Sync), frame: &mut (dyn FrameSymbolizer + Send), ) -> Result<(), FillSymbolError> { - if !self.symbolicate { - return Err(FillSymbolError {}); - } - let id = ( module.code_identifier(), module.debug_identifier().unwrap_or_default(), ); tracing::Span::current().record("module.id", tracing::field::debug(&id)); + let instruction = frame.get_instruction(); + + let mut cfi = self.cfi_files.lock().unwrap(); + if let Ok(symbol_file) = cfi + .entry(id.clone()) + .or_insert_with(|| self.load_cfi(id.clone())) + { + // Validity check that the instruction provided points to a valid stack frame. + // + // This is similar to the lookup check below for symcache symbol info. + // If we can already filter out instructions which are definitely not valid, + // we can help the stack walker not hallucinate frames which do not exist. + // + // Returning here without providing any symbol info, will cause the stack walker + // to skip the frame. An error will hallucinate a frame. + let cfi_stack_info = symbol_file + .cfi_stack_info + .get(instruction - module.base_address()); + if cfi_stack_info.is_none() { + return Ok(()); + } + }; + + if !self.symbolicate { + return Err(FillSymbolError {}); + } + let mut symcaches = self.symcaches.lock().unwrap(); - let symcache = symcaches.entry(id.clone()).or_insert_with(|| { - tracing::info!("loading symcache for the first time"); - self.load_symbol_info(id) - }); + let symcache = symcaches + .entry(id.clone()) + .or_insert_with(|| self.load_symbol_info(id)); let symcache = match symcache { Ok(symcache) => symcache, @@ -299,12 +342,22 @@ impl<'a> minidump_unwind::SymbolProvider for LocalSymbolProvider<'a> { tracing::info!("symcache successfully loaded"); - let instruction = frame.get_instruction(); - let source_location = symcache + let Some(source_location) = symcache .get() .lookup(instruction - module.base_address()) .last() - .ok_or(FillSymbolError {})?; + else { + // The instruction definitely belongs to this module, but we cannot + // find the instruction. In which case this is most likely not a real + // frame. + // + // The Minidump stack-walker skips all frames without a name and continues + // the search, but it assumes there is a correct frame if the lookup + // fails. To not hallucinate frames, we return `Ok(())` here (a frame without a name). + // + // See also above, the cfi validity check. + return Ok(()); + }; frame.set_function( source_location.function().name(), @@ -341,10 +394,7 @@ impl<'a> minidump_unwind::SymbolProvider for LocalSymbolProvider<'a> { let mut cfi = self.cfi_files.lock().unwrap(); - let symbol_file = cfi.entry(id.clone()).or_insert_with(|| { - tracing::info!("loading cficache for the first time"); - self.load_cfi(id) - }); + let symbol_file = cfi.entry(id.clone()).or_insert_with(|| self.load_cfi(id)); match symbol_file { Ok(file) => { @@ -486,10 +536,7 @@ impl fmt::Display for Report<'_> { }; for (ti, thread) in self.process_state.threads.iter().enumerate() { - let crashed = self - .process_state - .requesting_thread - .map_or(false, |i| ti == i); + let crashed = self.process_state.requesting_thread == Some(ti); if self.options.crashed_only && !crashed { continue; @@ -613,10 +660,13 @@ impl fmt::Display for Report<'_> { async fn execute(matches: &ArgMatches) -> Result<(), Error> { let minidump_path = matches.get_one::("minidump_file_path").unwrap(); - let symbols_path = matches.get_one::("debug_symbols_path"); + let symbols_path = matches + .get_many::("debug_symbols_path") + .map(|s| s.collect::>()) + .unwrap_or_default(); let symbol_provider = LocalSymbolProvider::new( - symbols_path, + &symbols_path, *matches.get_one("cfi").unwrap(), *matches.get_one("symbolize").unwrap(), ); @@ -658,6 +708,7 @@ async fn main() { ) .arg( Arg::new("debug_symbols_path") + .action(ArgAction::Append) .value_name("symbols") .value_parser(value_parser!(PathBuf)) .help("Path to a folder containing debug symbols"), diff --git a/examples/object_debug/Cargo.toml b/examples/object_debug/Cargo.toml index f7f9cdc47..b069d1e55 100644 --- a/examples/object_debug/Cargo.toml +++ b/examples/object_debug/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "object_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Jan Michael Auer "] edition = "2021" publish = false @@ -9,4 +9,4 @@ publish = false [dependencies] clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic" } +symbolic = { version = "12.17.0-dd", path = "../../symbolic" } diff --git a/examples/sourcemapcache_debug/Cargo.toml b/examples/sourcemapcache_debug/Cargo.toml index fa5c07c15..0fe1c0125 100644 --- a/examples/sourcemapcache_debug/Cargo.toml +++ b/examples/sourcemapcache_debug/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sourcemapcache_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Sentry "] edition = "2021" publish = false @@ -8,7 +8,7 @@ publish = false [dependencies] anyhow = { workspace = true } clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic", features = [ +symbolic = { version = "12.17.0-dd", path = "../../symbolic", features = [ "sourcemapcache", ] } tracing-subscriber = { workspace = true, features = ["env-filter"] } diff --git a/examples/symcache_debug/Cargo.toml b/examples/symcache_debug/Cargo.toml index 8b5daf610..7547e51d3 100644 --- a/examples/symcache_debug/Cargo.toml +++ b/examples/symcache_debug/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "symcache_debug" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Jan Michael Auer "] edition = "2021" publish = false @@ -10,7 +10,7 @@ publish = false [dependencies] anyhow = { workspace = true } clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic", features = [ +symbolic = { version = "12.17.0-dd", path = "../../symbolic", features = [ "symcache", "demangle", "il2cpp", diff --git a/examples/symcache_debug/src/main.rs b/examples/symcache_debug/src/main.rs index 47e1e2703..fcce8a913 100644 --- a/examples/symcache_debug/src/main.rs +++ b/examples/symcache_debug/src/main.rs @@ -2,7 +2,6 @@ use std::fs::File; use std::io::{Cursor, Write}; use std::path::PathBuf; use std::str::FromStr; -use std::u64; use anyhow::{anyhow, Context, Result}; use clap::builder::ValueParser; diff --git a/examples/unreal_engine_crash/Cargo.toml b/examples/unreal_engine_crash/Cargo.toml index bccfc1aca..022a99776 100644 --- a/examples/unreal_engine_crash/Cargo.toml +++ b/examples/unreal_engine_crash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "unreal_engine_crash" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Jan Michael Auer "] edition = "2021" publish = false @@ -9,6 +9,6 @@ publish = false [dependencies] clap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../../symbolic", features = [ +symbolic = { version = "12.17.0-dd", path = "../../symbolic", features = [ "unreal", ] } diff --git a/examples/unreal_engine_crash/src/main.rs b/examples/unreal_engine_crash/src/main.rs index ac3a1e4ea..5b46b58f6 100644 --- a/examples/unreal_engine_crash/src/main.rs +++ b/examples/unreal_engine_crash/src/main.rs @@ -1,20 +1,12 @@ use std::fs::File; -use std::io::Read; +use std::io::{BufWriter, Read, Write}; use std::{cmp, path::PathBuf}; use clap::{value_parser, Arg, ArgMatches, Command}; use symbolic::unreal::{Unreal4Crash, Unreal4FileType}; -fn execute(matches: &ArgMatches) -> Result<(), Box> { - let crash_file_path = matches.get_one::("crash_file_path").unwrap(); - - let mut file = File::open(crash_file_path)?; - let mut file_content = Vec::new(); - file.read_to_end(&mut file_content)?; - - let ue4_crash = Unreal4Crash::parse(&file_content)?; - +fn print_debug(ue4_crash: Unreal4Crash) -> Result<(), Box> { match ue4_crash.file_by_type(Unreal4FileType::Minidump) { Some(m) => println!("Minidump size: {} bytes.", m.data().len()), None => println!("No minidump found in the Unreal Crash provided."), @@ -40,7 +32,26 @@ fn execute(matches: &ArgMatches) -> Result<(), Box> { Ok(()) } -fn main() { +fn extract( + ue4_crash: Unreal4Crash, + matches: &ArgMatches, +) -> Result<(), Box> { + let filename = matches.get_one::("filename").unwrap(); + + let Some(file) = ue4_crash.files().find(|file| file.name() == filename) else { + return Err(format!("No file named '{filename}' in crash report").into()); + }; + + let mut output: Box = match matches.get_one::("output_path") { + Some(output) => Box::new(BufWriter::new(File::create(output)?)), + None => Box::new(std::io::stdout()), + }; + output.write_all(file.data())?; + + Ok(()) +} + +fn main() -> Result<(), Box> { let matches = Command::new("unreal-engine-crash") .about("Unpack an Unreal Engine crash report") .arg( @@ -50,10 +61,38 @@ fn main() { .value_parser(value_parser!(PathBuf)) .help("Path to the crash file"), ) + .subcommand( + Command::new("extract") + .about("extract a single file from the crash file") + .arg( + Arg::new("output_path") + .short('o') + .long("output") + .value_parser(value_parser!(PathBuf)) + .help( + "Path to write the file to, if missing contents are written to stdout", + ), + ) + .arg( + Arg::new("filename") + .required(true) + .value_name("filename") + .help("filename to extract"), + ), + ) .get_matches(); - match execute(&matches) { - Ok(()) => (), - Err(e) => println!("Error: {e}"), + let crash = { + let crash_file_path = matches.get_one::("crash_file_path").unwrap(); + let mut file = File::open(crash_file_path)?; + let mut file_content = Vec::new(); + file.read_to_end(&mut file_content)?; + Unreal4Crash::parse(&file_content)? }; + + match matches.subcommand() { + Some(("extract", matches)) => extract(crash, matches), + None => print_debug(crash), + _ => unreachable!(), + } } diff --git a/py/manylinux.sh b/py/manylinux.sh index 028149410..67231f613 100755 --- a/py/manylinux.sh +++ b/py/manylinux.sh @@ -4,22 +4,22 @@ set -e # Install dependencies needed by our wheel yum -y -q -e 0 install gcc libffi-devel -# upgrade wheel -/opt/python/cp36-cp36m/bin/pip install --upgrade wheel +# Upgrade wheel +/opt/python/cp311-cp311/bin/pip install --upgrade wheel # Install Rust curl https://sh.rustup.rs -sSf | sh -s -- -y export PATH=~/.cargo/bin:$PATH -cat > ~/.cargo/config <~/.cargo/config <=0.1.2"], - setup_requires=["milksnake>=0.1.2"], + # Specify transitive dependencies manually that are required for the build because + # they are not resolved properly since upgrading to python 3.11 in manylinux. + # milksnake -> cffi -> pycparser + # milksnake specifies cffi>=1.6.0 as dependency while cffi does not specify a + # minimum version for pycparser + setup_requires=["milksnake>=0.1.2", "cffi>=1.6.0", "pycparser"], python_requires=">=3.8", milksnake_tasks=[build_native], cmdclass={"sdist": CustomSDist}, diff --git a/py/symbolic/sourcemap.py b/py/symbolic/sourcemap.py index 291ce6bdb..ea02e7e0d 100644 --- a/py/symbolic/sourcemap.py +++ b/py/symbolic/sourcemap.py @@ -172,6 +172,11 @@ def get_source_name(self, idx: int) -> str | None: name = self._methodcall(lib.symbolic_sourcemapview_get_source_name, idx) return decode_str(name, free=True) or None + def get_source_contents(self, idx: int) -> str | None: + """Returns the contents of the source at the given index.""" + name = self._methodcall(lib.symbolic_sourcemapview_get_source_contents, idx) + return decode_str(name, free=True) or None + def iter_sources(self) -> Generator[tuple[int, str | None], None, None]: """Iterates over the sources in the file.""" for src_id in range(self.source_count): diff --git a/symbolic-cabi/Cargo.toml b/symbolic-cabi/Cargo.toml index 9b0e360e4..a2c767bd5 100644 --- a/symbolic-cabi/Cargo.toml +++ b/symbolic-cabi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "symbolic-cabi" -version = "12.9.2-dd" +version = "12.17.0-dd" license = "MIT" authors = [ "Armin Ronacher ", @@ -23,7 +23,7 @@ crate-type = ["cdylib", "lib"] proguard = { workspace = true, features = ["uuid"] } anyhow = "1.0.32" sourcemap = { workspace = true } -symbolic = { version = "12.9.2-dd", path = "../symbolic", features = [ +symbolic = { version = "12.17.0-dd", path = "../symbolic", features = [ "cfi", "debuginfo", "demangle", diff --git a/symbolic-cabi/include/symbolic.h b/symbolic-cabi/include/symbolic.h index 96b3a49f3..b0081a179 100644 --- a/symbolic-cabi/include/symbolic.h +++ b/symbolic-cabi/include/symbolic.h @@ -657,6 +657,11 @@ struct SymbolicTokenMatch *symbolic_sourcemapview_lookup_token_with_function_nam const struct SymbolicSourceView *symbolic_sourcemapview_get_sourceview(const struct SymbolicSourceMapView *source_map, uint32_t index); +/** + * Return the number of sources. + */ +uint32_t symbolic_sourcemapview_get_source_count(const struct SymbolicSourceMapView *source_map); + /** * Return the source name for an index. */ @@ -664,9 +669,10 @@ struct SymbolicStr symbolic_sourcemapview_get_source_name(const struct SymbolicS uint32_t index); /** - * Return the number of sources. + * Return the source contents for an index. */ -uint32_t symbolic_sourcemapview_get_source_count(const struct SymbolicSourceMapView *source_map); +struct SymbolicStr symbolic_sourcemapview_get_source_contents(const struct SymbolicSourceMapView *source_map, + uint32_t index); /** * Returns a specific token. diff --git a/symbolic-cabi/src/core.rs b/symbolic-cabi/src/core.rs index 6e0d8e922..893ba3fba 100644 --- a/symbolic-cabi/src/core.rs +++ b/symbolic-cabi/src/core.rs @@ -87,7 +87,7 @@ impl From for SymbolicStr { } } -impl<'a> From<&'a str> for SymbolicStr { +impl From<&str> for SymbolicStr { fn from(string: &str) -> SymbolicStr { SymbolicStr::new(string) } @@ -351,11 +351,7 @@ pub unsafe extern "C" fn symbolic_str_free(string: *mut SymbolicStr) { /// Returns true if the uuid is nil. #[no_mangle] pub unsafe extern "C" fn symbolic_uuid_is_nil(uuid: *const SymbolicUuid) -> bool { - if let Ok(uuid) = Uuid::from_slice(&(*uuid).data[..]) { - uuid == Uuid::nil() - } else { - false - } + Uuid::from_bytes((*uuid).data) == Uuid::nil() } /// Formats the UUID into a string. @@ -364,6 +360,6 @@ pub unsafe extern "C" fn symbolic_uuid_is_nil(uuid: *const SymbolicUuid) -> bool /// `symbolic_cstr_free`. #[no_mangle] pub unsafe extern "C" fn symbolic_uuid_to_str(uuid: *const SymbolicUuid) -> SymbolicStr { - let uuid = Uuid::from_slice(&(*uuid).data[..]).unwrap_or_default(); + let uuid = Uuid::from_bytes((*uuid).data); SymbolicStr::from_string(uuid.hyphenated().to_string()) } diff --git a/symbolic-cabi/src/proguard.rs b/symbolic-cabi/src/proguard.rs index 02798312e..92c91caec 100644 --- a/symbolic-cabi/src/proguard.rs +++ b/symbolic-cabi/src/proguard.rs @@ -33,7 +33,7 @@ struct Inner<'a> { impl<'slf, 'a: 'slf> AsSelf<'slf> for Inner<'a> { type Ref = Inner<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } diff --git a/symbolic-cabi/src/sourcemap.rs b/symbolic-cabi/src/sourcemap.rs index 2c0fa80fe..7df2bc09c 100644 --- a/symbolic-cabi/src/sourcemap.rs +++ b/symbolic-cabi/src/sourcemap.rs @@ -227,6 +227,15 @@ ffi_fn! { } } +ffi_fn! { + /// Return the number of sources. + unsafe fn symbolic_sourcemapview_get_source_count( + source_map: *const SymbolicSourceMapView + ) -> Result { + Ok(SymbolicSourceMapView::as_rust(source_map).inner.get_source_count()) + } +} + ffi_fn! { /// Return the source name for an index. unsafe fn symbolic_sourcemapview_get_source_name( @@ -240,11 +249,14 @@ ffi_fn! { } ffi_fn! { - /// Return the number of sources. - unsafe fn symbolic_sourcemapview_get_source_count( - source_map: *const SymbolicSourceMapView - ) -> Result { - Ok(SymbolicSourceMapView::as_rust(source_map).inner.get_source_count()) + /// Return the source contents for an index. + unsafe fn symbolic_sourcemapview_get_source_contents( + source_map: *const SymbolicSourceMapView, + index: u32 + ) -> Result { + let view = SymbolicSourceMapView::as_rust(source_map); + let contents_opt = view.inner.get_source_contents(index); + Ok(contents_opt.unwrap_or("").into()) } } @@ -254,7 +266,7 @@ ffi_fn! { source_map: *const SymbolicSourceMapView, index: u32 ) -> Result<*mut SymbolicTokenMatch> { - let token = SymbolicSourceMapView::as_rust(source_map).inner.get_token(index); + let token = SymbolicSourceMapView::as_rust(source_map).inner.get_token(index as usize); Ok(token.map(make_token_match).unwrap_or_else(ptr::null_mut)) } } diff --git a/symbolic-cfi/Cargo.toml b/symbolic-cfi/Cargo.toml index f9ca5534a..2dc90ce6a 100644 --- a/symbolic-cfi/Cargo.toml +++ b/symbolic-cfi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "symbolic-cfi" -version = "12.9.2-dd" +version = "12.17.0-dd" license = "MIT" authors = [ "Armin Ronacher ", @@ -12,11 +12,12 @@ repository = "https://github.com/getsentry/symbolic" description = """ A library to process call frame information """ -edition = "2021" +edition.workspace = true +rust-version.workspace = true [dependencies] -symbolic-common = { version = "12.9.2-dd", path = "../symbolic-common" } -symbolic-debuginfo = { version = "12.9.2-dd", path = "../symbolic-debuginfo" } +symbolic-common = { version = "12.17.0-dd", path = "../symbolic-common" } +symbolic-debuginfo = { version = "12.17.0-dd", path = "../symbolic-debuginfo" } thiserror = { workspace = true } [dev-dependencies] diff --git a/symbolic-cfi/src/lib.rs b/symbolic-cfi/src/lib.rs index 9f710e41a..939700e17 100644 --- a/symbolic-cfi/src/lib.rs +++ b/symbolic-cfi/src/lib.rs @@ -717,6 +717,15 @@ impl AsciiCfiWriter { R: Reader + Eq, U: UnwindSection, { + // We have seen FDEs with an initial address of `u64::MAX` in user-provided + // DWARF files. Such FDEs will invariably fail to process because of either + // an address overflow error in `gimli` or an underflow in the `length` + // calculation below. Therefore, we skip them immediately so we don't abort + // the processing of the entire file. + if fde.initial_address() == u64::MAX { + return Ok(()); + } + // Retrieves the register that specifies the return address. We need to assign a special // format to this register for Breakpad. let ra = fde.cie().return_address_register(); @@ -785,7 +794,7 @@ impl AsciiCfiWriter { // row. let mut ra_written = false; for &(register, ref rule) in row.registers() { - if !rule_cache.get(®ister).map_or(false, |c| c == &rule) { + if rule_cache.get(®ister) != Some(&rule) { rule_cache.insert(register, rule); if register == ra { ra_written = true; @@ -894,7 +903,7 @@ impl AsciiCfiWriter { // occur with a `code_start` close to the end of a function's code range, it seems // likely that these belong to the function epilog and code_size has a different meaning // in this case. Until this value is understood, skip these entries. - if frame.code_size > i32::max_value() as u32 { + if frame.code_size > i32::MAX as u32 { continue; } @@ -1189,7 +1198,7 @@ struct CfiCacheV1<'a> { byteview: ByteView<'a>, } -impl<'a> CfiCacheV1<'a> { +impl CfiCacheV1<'_> { pub fn raw(&self) -> &[u8] { &self.byteview } @@ -1268,7 +1277,7 @@ fn write_preamble(mut writer: W, version: u32) -> Result<(), io::Error impl<'a> CfiCache<'a> { /// Load a symcache from a `ByteView`. pub fn from_bytes(byteview: ByteView<'a>) -> Result { - if byteview.len() == 0 || byteview.starts_with(b"STACK") { + if byteview.is_empty() || byteview.starts_with(b"STACK") { let inner = CfiCacheInner::Unversioned(CfiCacheV1 { byteview }); return Ok(CfiCache { inner }); } diff --git a/symbolic-cfi/tests/snapshots/test_cfi__cfi_elf.snap b/symbolic-cfi/tests/snapshots/test_cfi__cfi_elf.snap index 35363db14..7e119c613 100644 --- a/symbolic-cfi/tests/snapshots/test_cfi__cfi_elf.snap +++ b/symbolic-cfi/tests/snapshots/test_cfi__cfi_elf.snap @@ -1,7 +1,5 @@ --- -created: "2019-07-05T18:52:40.332785Z" -creator: insta@0.8.1 -source: minidump/tests/test_cfi.rs +source: symbolic-cfi/tests/test_cfi.rs expression: cfi --- STACK CFI INIT 1dc0 2a .cfa: $rsp 8 + @@ -1502,4 +1500,3 @@ STACK CFI 14c90 .cfa: $rsp 24 + STACK CFI 14c92 .cfa: $rsp 16 + STACK CFI 14c94 .cfa: $rsp 8 + STACK CFI INIT 14ca0 2 .cfa: $rsp 8 + .ra: .cfa -8 + ^ - diff --git a/symbolic-cfi/tests/snapshots/test_cfi__cfi_macho.snap b/symbolic-cfi/tests/snapshots/test_cfi__cfi_macho.snap index 1a247ca53..e8f2ea5e6 100644 --- a/symbolic-cfi/tests/snapshots/test_cfi__cfi_macho.snap +++ b/symbolic-cfi/tests/snapshots/test_cfi__cfi_macho.snap @@ -1,7 +1,6 @@ --- -source: symbolic-minidump/tests/test_cfi.rs +source: symbolic-cfi/tests/test_cfi.rs expression: cfi - --- STACK CFI INIT d20 1a .cfa: $rsp 8 + .ra: .cfa -8 + ^ STACK CFI INIT d40 1a .cfa: $rsp 8 + .ra: .cfa -8 + ^ @@ -302,4 +301,3 @@ STACK CFI INIT db50 41 .cfa: $rsp 8 + .ra: .cfa -8 + ^ STACK CFI db51 .cfa: $rsp 16 + STACK CFI INIT dba0 d0 .cfa: $rsp 320 + .ra: .cfa -8 + ^ $rbx: .cfa -16 + ^ STACK CFI INIT dc70 34 .cfa: $rsp 16 + .ra: .cfa -8 + ^ $rbx: .cfa -16 + ^ - diff --git a/symbolic-cfi/tests/snapshots/test_cfi__cfi_pdb_windows.snap b/symbolic-cfi/tests/snapshots/test_cfi__cfi_pdb_windows.snap index 7f87ea4da..e768b5d69 100644 --- a/symbolic-cfi/tests/snapshots/test_cfi__cfi_pdb_windows.snap +++ b/symbolic-cfi/tests/snapshots/test_cfi__cfi_pdb_windows.snap @@ -1,7 +1,5 @@ --- -created: "2019-04-03T18:49:08.328347Z" -creator: insta@0.7.4 -source: minidump/tests/test_cfi.rs +source: symbolic-cfi/tests/test_cfi.rs expression: cfi --- STACK WIN 4 1000 114 11 0 8 0 0 0 1 $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = @@ -156,4 +154,3 @@ STACK WIN 4 358f 187 0 0 0 4 24 0 1 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $es STACK WIN 4 35b7 ef 0 0 0 8 24 0 1 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $20 $T0 40 - ^ = $23 $T0 44 - ^ = STACK WIN 4 35b8 ed 0 0 0 c 24 0 1 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp $T0 8 + = $20 $T0 40 - ^ = $23 $T0 44 - ^ = $24 $T0 48 - ^ = STACK WIN 4 371a c 0 0 0 0 0 0 1 $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = - diff --git a/symbolic-cfi/tests/snapshots/test_cfi__cfi_pe_windows.snap b/symbolic-cfi/tests/snapshots/test_cfi__cfi_pe_windows.snap index 3e4ad0296..99d98520c 100644 --- a/symbolic-cfi/tests/snapshots/test_cfi__cfi_pe_windows.snap +++ b/symbolic-cfi/tests/snapshots/test_cfi__cfi_pe_windows.snap @@ -1,6 +1,5 @@ --- source: symbolic-cfi/tests/test_cfi.rs -assertion_line: 105 expression: cfi --- STACK CFI INIT 1010 55 .cfa: $rsp 80 + $rbx: .cfa 16 - ^ $rsi: .cfa 24 - ^ $rdi: .cfa 32 - ^ .ra: .cfa 8 - ^ @@ -44,4 +43,3 @@ STACK CFI INIT 1de8 1b9 .cfa: $rsp 48 + $rsi: .cfa 16 - ^ $rdi: .cfa 24 - ^ $r14 STACK CFI INIT 2090 2 .cfa: $rsp 8 + .ra: .cfa 8 - ^ STACK CFI INIT 20ac 1e .cfa: $rsp 48 + $rbp: .cfa 16 - ^ .ra: .cfa 8 - ^ STACK CFI INIT 20ca 18 .cfa: $rsp 16 + $rbp: .cfa 16 - ^ .ra: .cfa 8 - ^ - diff --git a/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_linux.snap b/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_linux.snap index e05b652a7..e6a9ba137 100644 --- a/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_linux.snap +++ b/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_linux.snap @@ -1,7 +1,5 @@ --- -created: "2019-02-20T15:42:11.809248Z" -creator: insta@0.6.3 -source: minidump/tests/test_cfi.rs +source: symbolic-cfi/tests/test_cfi.rs expression: cfi --- STACK CFI INIT 1dc0 2a .cfa: $rsp 8 + .ra: .cfa -8 + ^ @@ -1502,4 +1500,3 @@ STACK CFI 14c90 .cfa: $rsp 24 + STACK CFI 14c92 .cfa: $rsp 16 + STACK CFI 14c94 .cfa: $rsp 8 + STACK CFI INIT 14ca0 2 .cfa: $rsp 8 + .ra: .cfa -8 + ^ - diff --git a/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_macos.snap b/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_macos.snap index 755f55fb4..d31e56fc5 100644 --- a/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_macos.snap +++ b/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_macos.snap @@ -1,7 +1,5 @@ --- -created: "2019-02-20T15:42:11.796554Z" -creator: insta@0.6.3 -source: minidump/tests/test_cfi.rs +source: symbolic-cfi/tests/test_cfi.rs expression: cfi --- STACK CFI INIT d20 1a .cfa: $rsp 8 + .ra: .cfa -8 + ^ @@ -217,4 +215,3 @@ STACK CFI INIT db30 a .cfa: $rsp 8 + .ra: .cfa -8 + ^ STACK CFI INIT db40 a .cfa: $rsp 8 + .ra: .cfa -8 + ^ STACK CFI INIT db50 41 .cfa: $rsp 8 + .ra: .cfa -8 + ^ STACK CFI db51 .cfa: $rsp 16 + - diff --git a/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_windows.snap b/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_windows.snap index f0e0e89ba..9059f5562 100644 --- a/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_windows.snap +++ b/symbolic-cfi/tests/snapshots/test_cfi__cfi_sym_windows.snap @@ -1,7 +1,5 @@ --- -created: "2019-02-20T15:42:11.796623Z" -creator: insta@0.6.3 -source: minidump/tests/test_cfi.rs +source: symbolic-cfi/tests/test_cfi.rs expression: cfi --- STACK WIN 4 1000 114 11 0 8 0 0 0 1 $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = @@ -158,4 +156,3 @@ STACK WIN 4 35b8 ed 0 0 0 c 24 0 1 $T0 $ebp = $eip $T0 4 + ^ = $ebp $T0 ^ = $esp STACK WIN 4 371a c 0 0 0 0 0 0 1 $T0 .raSearch = $eip $T0 ^ = $esp $T0 4 + = STACK WIN 0 2dc4 14 0 0 0 0 0 0 0 0 STACK WIN 0 30fc 13 0 0 0 0 0 0 0 0 - diff --git a/symbolic-common/Cargo.toml b/symbolic-common/Cargo.toml index 5c6ded1d9..8a64ddd63 100644 --- a/symbolic-common/Cargo.toml +++ b/symbolic-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "symbolic-common" -version = "12.9.2-dd" +version = "12.17.0-dd" license = "MIT" authors = [ "Armin Ronacher ", @@ -14,7 +14,8 @@ description = """ Common types and utilities for symbolic, a library to symbolicate and process stack traces from native applications, minidumps or minified JavaScript. """ -edition = "2021" +edition.workspace = true +rust-version.workspace = true [package.metadata.docs.rs] all-features = true diff --git a/symbolic-common/src/byteview.rs b/symbolic-common/src/byteview.rs index f535a6111..b4f8af558 100644 --- a/symbolic-common/src/byteview.rs +++ b/symbolic-common/src/byteview.rs @@ -233,6 +233,41 @@ impl<'a> ByteView<'a> { pub fn as_slice(&self) -> &[u8] { self.backing.deref() } + + /// Applies a [`AccessPattern`] hint to the backing storage. + /// + /// A hint can be applied when the predominantly access pattern + /// for this byte view is known. + /// + /// Applying the wrong hint may have significant effects on performance. + /// + /// Hints are applied on best effort basis, not all platforms + /// support the same hints, not all backing storages support + /// hints. + /// + /// # Example + /// + /// ``` + /// use std::io::Write; + /// use symbolic_common::{ByteView, AccessPattern}; + /// + /// fn main() -> Result<(), std::io::Error> { + /// let mut file = tempfile::tempfile()?; + /// let view = ByteView::map_file_ref(&file)?; + /// let _ = view.hint(AccessPattern::Random); + /// Ok(()) + /// } + /// ``` + pub fn hint(&self, hint: AccessPattern) -> Result<(), io::Error> { + let _hint = hint; // silence unused lint + match self.backing.deref() { + ByteViewBacking::Buf(_) => Ok(()), + #[cfg(unix)] + ByteViewBacking::Mmap(mmap) => mmap.advise(_hint.to_madvise()), + #[cfg(not(unix))] + ByteViewBacking::Mmap(_) => Ok(()), + } + } } impl AsRef<[u8]> for ByteView<'_> { @@ -253,6 +288,43 @@ impl Deref for ByteView<'_> { unsafe impl StableDeref for ByteView<'_> {} +/// Values supported by [`ByteView::hint`]. +/// +/// This is largely an abstraction over [`madvise(2)`] and [`fadvise(2)`]. +/// +/// [`madvise(2)`]: https://man7.org/linux/man-pages/man2/madvise.2.html +/// [`fadvise(2)`]: https://man7.org/linux/man-pages/man2/posix_fadvise.2.html +#[derive(Debug, Default, Clone, Copy)] +pub enum AccessPattern { + /// No special treatment. + /// + /// The operating system is in full control of the buffer, + /// a generally good default. + /// + /// This is the default. + #[default] + Normal, + /// Expect access to be random. + /// + /// Read ahead might be less useful than normally. + Random, + /// Expect access to be in sequential order, read ahead might be very useful. + /// After reading data there is a high chance it will not be accessed again + /// and can be aggressively freed. + Sequential, +} + +impl AccessPattern { + #[cfg(unix)] + fn to_madvise(self) -> memmap2::Advice { + match self { + AccessPattern::Normal => memmap2::Advice::Normal, + AccessPattern::Random => memmap2::Advice::Random, + AccessPattern::Sequential => memmap2::Advice::Sequential, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/symbolic-common/src/cell.rs b/symbolic-common/src/cell.rs index 19ce3d4eb..671422a40 100644 --- a/symbolic-common/src/cell.rs +++ b/symbolic-common/src/cell.rs @@ -80,7 +80,7 @@ pub trait AsSelf<'slf> { type Ref: ?Sized; /// Returns a reference to `self` with downcasted lifetime. - fn as_self(&'slf self) -> &Self::Ref; + fn as_self(&'slf self) -> &'slf Self::Ref; } impl AsSelf<'_> for u8 { @@ -106,7 +106,7 @@ where { type Ref = [T::Ref]; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { &*(self as *const [T] as *const [T::Ref]) } } } @@ -117,7 +117,7 @@ where { type Ref = T::Ref; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { (*self).as_self() } } @@ -128,7 +128,7 @@ where { type Ref = T::Ref; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { (**self).as_self() } } @@ -140,7 +140,7 @@ where { type Ref = [T::Ref]; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { (**self).as_self() } } @@ -151,7 +151,7 @@ where { type Ref = T::Ref; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { (**self).as_self() } } @@ -162,7 +162,7 @@ where { type Ref = T::Ref; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { (**self).as_self() } } @@ -368,7 +368,7 @@ mod tests { impl<'slf> AsSelf<'slf> for Foo<'_> { type Ref = Foo<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } diff --git a/symbolic-common/src/path.rs b/symbolic-common/src/path.rs index 8772729ec..52bcfa021 100644 --- a/symbolic-common/src/path.rs +++ b/symbolic-common/src/path.rs @@ -54,7 +54,7 @@ fn is_windows_driveletter>(path: P) -> bool { if let (Some(drive_letter), Some(b':')) = (path.first(), path.get(1)) { if drive_letter.is_ascii_alphabetic() { - return path.get(2).map_or(true, is_windows_separator); + return path.get(2).is_none_or(is_windows_separator); } } @@ -69,11 +69,11 @@ fn is_absolute_windows_path>(path: P) -> bool { /// Returns `true` fn is_semi_absolute_windows_path>(path: P) -> bool { - path.as_ref().first().map_or(false, is_windows_separator) + path.as_ref().first().is_some_and(is_windows_separator) } fn is_absolute_unix_path>(path: P) -> bool { - path.as_ref().first().map_or(false, is_unix_separator) + path.as_ref().first().is_some_and(is_unix_separator) } fn is_windows_path>(path: P) -> bool { diff --git a/symbolic-debuginfo/Cargo.toml b/symbolic-debuginfo/Cargo.toml index 52e125307..428b2f498 100644 --- a/symbolic-debuginfo/Cargo.toml +++ b/symbolic-debuginfo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "symbolic-debuginfo" -version = "12.9.2-dd" +version = "12.17.0-dd" license = "MIT" authors = [ "Armin Ronacher ", @@ -13,7 +13,8 @@ description = """ A library to inspect and load DWARF debugging information from binaries, such as Mach-O or ELF. """ -edition = "2021" +edition.workspace = true +rust-version.workspace = true exclude = ["tests/**/*"] @@ -68,6 +69,7 @@ ms = [ "pdb-addr2line", "scroll", "smallvec", + "srcsrv", ] ppdb = ["symbolic-ppdb"] # Source bundle creation @@ -87,7 +89,6 @@ js = [] wasm = ["dwarf", "wasmparser"] [dependencies] -dmsort = { workspace = true } debugid = { workspace = true } elementtree = { workspace = true, optional = true } elsa = { workspace = true, optional = true } @@ -106,8 +107,9 @@ scroll = { workspace = true, optional = true } serde = { workspace = true } serde_json = { workspace = true, optional = true } smallvec = { workspace = true, optional = true } -symbolic-common = { version = "12.9.2-dd", path = "../symbolic-common" } -symbolic-ppdb = { version = "12.9.2-dd", path = "../symbolic-ppdb", optional = true } +srcsrv = { version = "0.2", optional = true } +symbolic-common = { version = "12.17.0-dd", path = "../symbolic-common" } +symbolic-ppdb = { version = "12.17.0-dd", path = "../symbolic-ppdb", optional = true } thiserror = { workspace = true } wasmparser = { workspace = true, optional = true } zip = { workspace = true, optional = true } @@ -116,6 +118,7 @@ zstd = { workspace = true, optional = true } [dev-dependencies] criterion = { workspace = true } insta = { workspace = true } +proptest = {workspace = true } tempfile = { workspace = true } similar-asserts = { workspace = true } symbolic-testutils = { path = "../symbolic-testutils" } diff --git a/symbolic-debuginfo/fuzz/Cargo.toml b/symbolic-debuginfo/fuzz/Cargo.toml index 4a22260e6..bcb500ddf 100644 --- a/symbolic-debuginfo/fuzz/Cargo.toml +++ b/symbolic-debuginfo/fuzz/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "symbolic-debuginfo-fuzz" -version = "12.9.2-dd" +version = "12.17.0-dd" authors = ["Automatically generated"] publish = false edition = "2021" diff --git a/symbolic-debuginfo/src/base.rs b/symbolic-debuginfo/src/base.rs index b3c350817..92ea3a2a2 100644 --- a/symbolic-debuginfo/src/base.rs +++ b/symbolic-debuginfo/src/base.rs @@ -235,7 +235,7 @@ pub struct Symbol<'data> { pub size: u64, } -impl<'data> Symbol<'data> { +impl Symbol<'_> { /// Returns the name of this symbol as string. pub fn name(&self) -> Option<&str> { self.name.as_ref().map(Cow::as_ref) @@ -251,7 +251,7 @@ impl<'data> Symbol<'data> { } } -impl<'d> fmt::Debug for Symbol<'d> { +impl fmt::Debug for Symbol<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Symbol") .field("name", &self.name().unwrap_or("")) @@ -351,7 +351,7 @@ impl<'data> SymbolMap<'data> { let end = match range.end_bound() { Bound::Included(end) => *end, Bound::Excluded(end) => *end - 1, - Bound::Unbounded => u64::max_value(), + Bound::Unbounded => u64::MAX, }; if end <= start || symbol.contains(end) { @@ -413,7 +413,7 @@ impl<'d> From>> for SymbolMap<'d> { // // Inlined functions will generally not appear in this list, unless they _also_ have an // explicit function body, in which case they will have a unique address, again. - dmsort::sort_by_key(&mut symbols, Self::key); + symbols.sort_by_key(Self::key); // Compute sizes of consecutive symbols if the size has not been provided by the symbol // iterator. In the same go, drop all but the first symbols at any given address. We do @@ -597,7 +597,7 @@ pub struct LineInfo<'data> { #[cfg(test)] impl LineInfo<'static> { - pub(crate) fn new(address: u64, size: u64, file: &[u8], line: u64) -> LineInfo { + pub(crate) fn new(address: u64, size: u64, file: &[u8], line: u64) -> LineInfo<'_> { LineInfo { address, size: Some(size), diff --git a/symbolic-debuginfo/src/breakpad.rs b/symbolic-debuginfo/src/breakpad.rs index 6c91aedbf..92cf2bdfe 100644 --- a/symbolic-debuginfo/src/breakpad.rs +++ b/symbolic-debuginfo/src/breakpad.rs @@ -605,7 +605,7 @@ pub struct BreakpadLineRecords<'d> { finished: bool, } -impl<'d> Iterator for BreakpadLineRecords<'d> { +impl Iterator for BreakpadLineRecords<'_> { type Item = Result; fn next(&mut self) -> Option { @@ -752,13 +752,13 @@ impl<'d> BreakpadStackCfiRecord<'d> { } } -impl<'d> PartialEq for BreakpadStackCfiRecord<'d> { +impl PartialEq for BreakpadStackCfiRecord<'_> { fn eq(&self, other: &Self) -> bool { self.start == other.start && self.size == other.size && self.init_rules == other.init_rules } } -impl<'d> Eq for BreakpadStackCfiRecord<'d> {} +impl Eq for BreakpadStackCfiRecord<'_> {} /// An iterator over stack cfi delta records associated with a particular /// [`BreakpadStackCfiRecord`]. @@ -1159,7 +1159,7 @@ impl fmt::Debug for BreakpadObject<'_> { impl<'slf, 'data: 'slf> AsSelf<'slf> for BreakpadObject<'data> { type Ref = BreakpadObject<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } @@ -1263,7 +1263,7 @@ pub struct BreakpadDebugSession<'data> { lines: Lines<'data>, } -impl<'data> BreakpadDebugSession<'data> { +impl BreakpadDebugSession<'_> { /// Returns an iterator over all functions in this debug file. pub fn functions(&self) -> BreakpadFunctionIterator<'_> { BreakpadFunctionIterator::new(&self.file_map, self.lines.clone()) @@ -1285,7 +1285,7 @@ impl<'data> BreakpadDebugSession<'data> { } } -impl<'data, 'session> DebugSession<'session> for BreakpadDebugSession<'data> { +impl<'session> DebugSession<'session> for BreakpadDebugSession<'_> { type Error = BreakpadError; type FunctionIterator = BreakpadFunctionIterator<'session>; type FileIterator = BreakpadFileIterator<'session>; @@ -1557,14 +1557,14 @@ mod parsing { } /// Parse a sequence of non-whitespace characters. - fn non_whitespace(input: &str) -> ParseResult<&str> { + fn non_whitespace(input: &str) -> ParseResult<'_, &str> { take_while(|c: char| !c.is_whitespace())(input) } /// Parse to the end of input and return the resulting string. /// /// If there is no input, return [`UNKNOWN_NAME`] instead. - fn name(input: &str) -> ParseResult<&str> { + fn name(input: &str) -> ParseResult<'_, &str> { rest.map(|name: &str| if name.is_empty() { UNKNOWN_NAME } else { name }) .parse(input) } @@ -1572,7 +1572,7 @@ mod parsing { /// Attempt to parse the character `m` followed by one or more spaces. /// /// Returns true if the parse was successful. - fn multiple(input: &str) -> ParseResult { + fn multiple(input: &str) -> ParseResult<'_, bool> { let (mut input, multiple) = char('m').opt().parse(input)?; let multiple = multiple.is_some(); if multiple { @@ -1582,14 +1582,14 @@ mod parsing { } /// Parse a line number as a signed decimal number and return `max(0, n)`. - fn line_num(input: &str) -> ParseResult { + fn line_num(input: &str) -> ParseResult<'_, u64> { pair(char('-').opt(), num_dec!(u64)) .map(|(sign, num)| if sign.is_some() { 0 } else { num }) .parse(input) } /// Parse a [`BreakpadStackWinRecordType`]. - fn stack_win_record_type(input: &str) -> ParseResult { + fn stack_win_record_type(input: &str) -> ParseResult<'_, BreakpadStackWinRecordType> { alt(( char('0').value(BreakpadStackWinRecordType::Fpo), char('1').value(BreakpadStackWinRecordType::Trap), @@ -1603,7 +1603,7 @@ mod parsing { /// Parse a [`BreakpadModuleRecord`]. /// /// A module record has the form `MODULE ( )?`. - fn module_record(input: &str) -> ParseResult { + fn module_record(input: &str) -> ParseResult<'_, BreakpadModuleRecord<'_>> { let (input, _) = tag("MODULE") .terminated(multispace1) .context("module record prefix") @@ -1627,14 +1627,16 @@ mod parsing { /// /// A module record has the form `MODULE ( )?`. /// This will fail if there is any input left over after the record. - pub fn module_record_final(input: &str) -> Result> { + pub fn module_record_final( + input: &str, + ) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(module_record)(input) } /// Parse the `CodeId` variant of a [`BreakpadInfoRecord`]. /// /// A `CodeId` record has the form `CODE_ID ( )?`. - fn info_code_id_record(input: &str) -> ParseResult { + fn info_code_id_record(input: &str) -> ParseResult<'_, BreakpadInfoRecord<'_>> { let (input, _) = tag("CODE_ID") .terminated(multispace1) .context("info code_id record prefix") @@ -1656,7 +1658,7 @@ mod parsing { /// Parse the `Other` variant of a [`BreakpadInfoRecord`]. /// /// An `Other` record has the form `( )?`. - fn info_other_record(input: &str) -> ParseResult { + fn info_other_record(input: &str) -> ParseResult<'_, BreakpadInfoRecord<'_>> { let (input, (scope, info)) = pair( non_whitespace .terminated(multispace1.or(eof)) @@ -1673,7 +1675,7 @@ mod parsing { /// Parse a [`BreakpadInfoRecord`]. /// /// An INFO record has the form `INFO ( | )`. - fn info_record(input: &str) -> ParseResult { + fn info_record(input: &str) -> ParseResult<'_, BreakpadInfoRecord<'_>> { let (input, _) = tag("INFO") .terminated(multispace1) .context("info record prefix") @@ -1690,14 +1692,14 @@ mod parsing { /// /// An INFO record has the form `INFO ( | )`. /// This will fail if there is any input left over after the record. - pub fn info_record_final(input: &str) -> Result> { + pub fn info_record_final(input: &str) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(info_record)(input) } /// Parse a [`BreakpadFileRecord`]. /// /// A FILE record has the form `FILE ( )?`. - fn file_record(input: &str) -> ParseResult { + fn file_record(input: &str) -> ParseResult<'_, BreakpadFileRecord<'_>> { let (input, _) = tag("FILE") .terminated(multispace1) .context("file record prefix") @@ -1720,14 +1722,14 @@ mod parsing { /// /// A FILE record has the form `FILE ( )?`. /// This will fail if there is any input left over after the record. - pub fn file_record_final(input: &str) -> Result> { + pub fn file_record_final(input: &str) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(file_record)(input) } /// Parse a [`BreakpadInlineOriginRecord`]. /// /// An INLINE_ORIGIN record has the form `INLINE_ORIGIN `. - fn inline_origin_record(input: &str) -> ParseResult { + fn inline_origin_record(input: &str) -> ParseResult<'_, BreakpadInlineOriginRecord<'_>> { let (input, _) = tag("INLINE_ORIGIN") .terminated(multispace1) .context("inline origin record prefix") @@ -1752,14 +1754,14 @@ mod parsing { /// This will fail if there is any input left over after the record. pub fn inline_origin_record_final( input: &str, - ) -> Result> { + ) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(inline_origin_record)(input) } /// Parse a [`BreakpadPublicRecord`]. /// /// A PUBLIC record has the form `PUBLIC (m )?

( )?`. - fn public_record(input: &str) -> ParseResult { + fn public_record(input: &str) -> ParseResult<'_, BreakpadPublicRecord<'_>> { let (input, _) = tag("PUBLIC") .terminated(multispace1) .context("public record prefix") @@ -1792,14 +1794,16 @@ mod parsing { /// /// A PUBLIC record has the form `PUBLIC (m )?
( )?`. /// This will fail if there is any input left over after the record. - pub fn public_record_final(input: &str) -> Result> { + pub fn public_record_final( + input: &str, + ) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(public_record)(input) } /// Parse a [`BreakpadFuncRecord`]. /// /// A FUNC record has the form `FUNC (m )?
( )?`. - fn func_record(input: &str) -> ParseResult { + fn func_record(input: &str) -> ParseResult<'_, BreakpadFuncRecord<'_>> { let (input, _) = tag("FUNC") .terminated(multispace1) .context("func record prefix") @@ -1835,14 +1839,14 @@ mod parsing { /// /// A FUNC record has the form `FUNC (m )?
( )?`. /// This will fail if there is any input left over after the record. - pub fn func_record_final(input: &str) -> Result> { + pub fn func_record_final(input: &str) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(func_record)(input) } /// Parse a [`BreakpadLineRecord`]. /// /// A LINE record has the form `
`. - fn line_record(input: &str) -> ParseResult { + fn line_record(input: &str) -> ParseResult<'_, BreakpadLineRecord> { let (input, (address, size, line, file_id)) = tuple(( num_hex!(u64).terminated(multispace1).context("address"), num_hex!(u64).terminated(multispace1).context("size"), @@ -1874,7 +1878,7 @@ mod parsing { /// Parse a [`BreakpadInlineRecord`]. /// /// An INLINE record has the form `INLINE [
]+`. - fn inline_record(input: &str) -> ParseResult { + fn inline_record(input: &str) -> ParseResult<'_, BreakpadInlineRecord> { let (input, _) = tag("INLINE") .terminated(multispace1) .context("inline record prefix") @@ -1932,7 +1936,7 @@ mod parsing { /// Parse a [`BreakpadStackCfiDeltaRecord`]. /// /// A STACK CFI Delta record has the form `STACK CFI
`. - fn stack_cfi_delta_record(input: &str) -> ParseResult { + fn stack_cfi_delta_record(input: &str) -> ParseResult<'_, BreakpadStackCfiDeltaRecord<'_>> { let (input, _) = tag("STACK CFI") .terminated(multispace1) .context("stack cfi prefix") @@ -1955,14 +1959,14 @@ mod parsing { /// This will fail if there is any input left over after the record. pub fn stack_cfi_delta_record_final( input: &str, - ) -> Result> { + ) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(stack_cfi_delta_record)(input) } /// Parse a [`BreakpadStackCfiRecord`]. /// /// A STACK CFI INIT record has the form `STACK CFI INIT
`. - fn stack_cfi_record(input: &str) -> ParseResult { + fn stack_cfi_record(input: &str) -> ParseResult<'_, BreakpadStackCfiRecord<'_>> { let (input, _) = tag("STACK CFI INIT") .terminated(multispace1) .context("stack cfi init prefix") @@ -1994,7 +1998,7 @@ mod parsing { /// This will fail if there is any input left over after the record. pub fn stack_cfi_record_final( input: &str, - ) -> Result> { + ) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(stack_cfi_record)(input) } @@ -2002,7 +2006,7 @@ mod parsing { /// /// A STACK WIN record has the form /// `STACK WIN ( | )`. - fn stack_win_record(input: &str) -> ParseResult { + fn stack_win_record(input: &str) -> ParseResult<'_, BreakpadStackWinRecord<'_>> { let (input, _) = tag("STACK WIN") .terminated(multispace1) .context("stack win prefix") @@ -2079,7 +2083,7 @@ mod parsing { /// This will fail if there is any input left over after the record. pub fn stack_win_record_final( input: &str, - ) -> Result> { + ) -> Result, ErrorTree> { nom_supreme::final_parser::final_parser(stack_win_record)(input) } @@ -2087,7 +2091,7 @@ mod parsing { /// [`BreakpadStackWinRecord`]. /// /// This will fail if there is any input left over after the record. - pub fn stack_record_final(input: &str) -> Result { + pub fn stack_record_final(input: &str) -> Result, ParseBreakpadError> { nom_supreme::final_parser::final_parser(alt(( stack_cfi_record.map(BreakpadStackRecord::Cfi), stack_win_record.map(BreakpadStackRecord::Win), @@ -2104,12 +2108,12 @@ mod tests { let record = BreakpadModuleRecord::parse(string)?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadModuleRecord { - ⋮ os: "Linux", - ⋮ arch: "x86_64", - ⋮ id: "492E2DD23CC306CA9C494EEF1533A3810", - ⋮ name: "crash", - ⋮} + BreakpadModuleRecord { + os: "Linux", + arch: "x86_64", + id: "492E2DD23CC306CA9C494EEF1533A3810", + name: "crash", + } "#); Ok(()) @@ -2122,12 +2126,12 @@ mod tests { let record = BreakpadModuleRecord::parse(string)?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadModuleRecord { - ⋮ os: "Linux", - ⋮ arch: "x86_64", - ⋮ id: "6216C672A8D33EC9CF4A1BAB8B29D00E", - ⋮ name: "libdispatch.so", - ⋮} + BreakpadModuleRecord { + os: "Linux", + arch: "x86_64", + id: "6216C672A8D33EC9CF4A1BAB8B29D00E", + name: "libdispatch.so", + } "#); Ok(()) @@ -2139,10 +2143,10 @@ mod tests { let record = BreakpadFileRecord::parse(string)?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadFileRecord { - ⋮ id: 37, - ⋮ name: "/usr/include/libkern/i386/_OSByteOrder.h", - ⋮} + BreakpadFileRecord { + id: 37, + name: "/usr/include/libkern/i386/_OSByteOrder.h", + } "#); Ok(()) @@ -2154,10 +2158,10 @@ mod tests { let record = BreakpadFileRecord::parse(string)?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadFileRecord { - ⋮ id: 38, - ⋮ name: "/usr/local/src/filename with spaces.c", - ⋮} + BreakpadFileRecord { + id: 38, + name: "/usr/local/src/filename with spaces.c", + } "#); Ok(()) @@ -2201,13 +2205,13 @@ mod tests { let record = BreakpadFuncRecord::parse(string, Lines::default())?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadFuncRecord { - ⋮ multiple: false, - ⋮ address: 5936, - ⋮ size: 26, - ⋮ parameter_size: 0, - ⋮ name: "", - ⋮} + BreakpadFuncRecord { + multiple: false, + address: 5936, + size: 26, + parameter_size: 0, + name: "", + } "#); Ok(()) @@ -2219,13 +2223,13 @@ mod tests { let record = BreakpadFuncRecord::parse(string, Lines::default())?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadFuncRecord { - ⋮ multiple: true, - ⋮ address: 5936, - ⋮ size: 26, - ⋮ parameter_size: 0, - ⋮ name: "", - ⋮} + BreakpadFuncRecord { + multiple: true, + address: 5936, + size: 26, + parameter_size: 0, + name: "", + } "#); Ok(()) @@ -2237,13 +2241,13 @@ mod tests { let record = BreakpadFuncRecord::parse(string, Lines::default())?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadFuncRecord { - ⋮ multiple: false, - ⋮ address: 0, - ⋮ size: 15, - ⋮ parameter_size: 0, - ⋮ name: "", - ⋮} + BreakpadFuncRecord { + multiple: false, + address: 0, + size: 15, + parameter_size: 0, + name: "", + } "#); Ok(()) @@ -2254,14 +2258,14 @@ mod tests { let string = b"1730 6 93 20"; let record = BreakpadLineRecord::parse(string)?; - insta::assert_debug_snapshot!(record, @r###" - ⋮BreakpadLineRecord { - ⋮ address: 5936, - ⋮ size: 6, - ⋮ line: 93, - ⋮ file_id: 20, - ⋮} - "###); + insta::assert_debug_snapshot!(record, @r" + BreakpadLineRecord { + address: 5936, + size: 6, + line: 93, + file_id: 20, + } + "); Ok(()) } @@ -2271,14 +2275,14 @@ mod tests { let string = b"e0fd10 5 -376 2225"; let record = BreakpadLineRecord::parse(string)?; - insta::assert_debug_snapshot!(record, @r###" + insta::assert_debug_snapshot!(record, @r" BreakpadLineRecord { address: 14744848, size: 5, line: 0, file_id: 2225, } - "###); + "); Ok(()) } @@ -2290,14 +2294,14 @@ mod tests { let record = BreakpadLineRecord::parse(string)?; insta::assert_debug_snapshot!( - record, @r###" + record, @r" BreakpadLineRecord { address: 4096, size: 28, line: 2972, file_id: 2, } - "###); + "); Ok(()) } @@ -2308,12 +2312,12 @@ mod tests { let record = BreakpadPublicRecord::parse(string)?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadPublicRecord { - ⋮ multiple: false, - ⋮ address: 20864, - ⋮ parameter_size: 0, - ⋮ name: "__clang_call_terminate", - ⋮} + BreakpadPublicRecord { + multiple: false, + address: 20864, + parameter_size: 0, + name: "__clang_call_terminate", + } "#); Ok(()) @@ -2325,12 +2329,12 @@ mod tests { let record = BreakpadPublicRecord::parse(string)?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadPublicRecord { - ⋮ multiple: true, - ⋮ address: 20864, - ⋮ parameter_size: 0, - ⋮ name: "__clang_call_terminate", - ⋮} + BreakpadPublicRecord { + multiple: true, + address: 20864, + parameter_size: 0, + name: "__clang_call_terminate", + } "#); Ok(()) @@ -2342,12 +2346,12 @@ mod tests { let record = BreakpadPublicRecord::parse(string)?; insta::assert_debug_snapshot!(record, @r#" - ⋮BreakpadPublicRecord { - ⋮ multiple: false, - ⋮ address: 20864, - ⋮ parameter_size: 0, - ⋮ name: "", - ⋮} + BreakpadPublicRecord { + multiple: false, + address: 20864, + parameter_size: 0, + name: "", + } "#); Ok(()) @@ -2358,7 +2362,7 @@ mod tests { let string = b"INLINE 0 3082 52 1410 49200 10"; let record = BreakpadInlineRecord::parse(string)?; - insta::assert_debug_snapshot!(record, @r###" + insta::assert_debug_snapshot!(record, @r" BreakpadInlineRecord { inline_depth: 0, call_site_line: 3082, @@ -2371,7 +2375,7 @@ mod tests { }, ], } - "###); + "); Ok(()) } @@ -2381,7 +2385,7 @@ mod tests { let string = b"INLINE 6 642 8 207 8b110 18 8b154 18"; let record = BreakpadInlineRecord::parse(string)?; - insta::assert_debug_snapshot!(record, @r###" + insta::assert_debug_snapshot!(record, @r" BreakpadInlineRecord { inline_depth: 6, call_site_line: 642, @@ -2398,7 +2402,7 @@ mod tests { }, ], } - "###); + "); Ok(()) } @@ -2469,7 +2473,7 @@ mod tests { let string = b"STACK WIN 3 8a10b ec b 0 c c 4 0 0 1"; let record = BreakpadStackWinRecord::parse(string)?; - insta::assert_debug_snapshot!(record, @r###" + insta::assert_debug_snapshot!(record, @r" BreakpadStackWinRecord { ty: Standard, code_start: 565515, @@ -2483,7 +2487,7 @@ mod tests { uses_base_pointer: true, program_string: None, } - "###); + "); Ok(()) } diff --git a/symbolic-debuginfo/src/dwarf.rs b/symbolic-debuginfo/src/dwarf.rs index 2e41bc823..6de54b5b0 100644 --- a/symbolic-debuginfo/src/dwarf.rs +++ b/symbolic-debuginfo/src/dwarf.rs @@ -330,7 +330,7 @@ impl<'d> DwarfLineProgram<'d> { } // Sequences are not guaranteed to be in order. - dmsort::sort_by_key(&mut sequences, |x| x.start); + sequences.sort_by_key(|x| x.start); DwarfLineProgram { header: state_machine.header().clone(), @@ -366,7 +366,7 @@ struct UnitRef<'d, 'a> { unit: &'a Unit<'d>, } -impl<'d, 'a> UnitRef<'d, 'a> { +impl<'d> UnitRef<'d, '_> { /// Resolve the binary value of an attribute. #[inline(always)] fn slice_value(&self, value: AttributeValue>) -> Option<&'d [u8]> { @@ -996,7 +996,7 @@ struct FunctionsOutput<'a, 'd> { pub seen_ranges: &'a mut BTreeSet<(u64, u64)>, } -impl<'a, 'd> FunctionsOutput<'a, 'd> { +impl<'a> FunctionsOutput<'a, '_> { pub fn with_seen_ranges(seen_ranges: &'a mut BTreeSet<(u64, u64)>) -> Self { Self { functions: Vec::new(), @@ -1097,6 +1097,8 @@ struct DwarfSections<'data> { debug_str_offsets: DwarfSectionData<'data, gimli::read::DebugStrOffsets>>, debug_ranges: DwarfSectionData<'data, gimli::read::DebugRanges>>, debug_rnglists: DwarfSectionData<'data, gimli::read::DebugRngLists>>, + debug_macinfo: DwarfSectionData<'data, gimli::read::DebugMacinfo>>, + debug_macro: DwarfSectionData<'data, gimli::read::DebugMacro>>, } impl<'data> DwarfSections<'data> { @@ -1116,6 +1118,8 @@ impl<'data> DwarfSections<'data> { debug_str_offsets: DwarfSectionData::load(dwarf), debug_ranges: DwarfSectionData::load(dwarf), debug_rnglists: DwarfSectionData::load(dwarf), + debug_macinfo: DwarfSectionData::load(dwarf), + debug_macro: DwarfSectionData::load(dwarf), } } } @@ -1156,6 +1160,8 @@ impl<'d> DwarfInfo<'d> { debug_str: sections.debug_str.to_gimli(), debug_str_offsets: sections.debug_str_offsets.to_gimli(), debug_types: Default::default(), + debug_macinfo: sections.debug_macinfo.to_gimli(), + debug_macro: sections.debug_macro.to_gimli(), locations: Default::default(), ranges: RangeLists::new( sections.debug_ranges.to_gimli(), @@ -1230,7 +1236,7 @@ impl<'d> DwarfInfo<'d> { } /// Returns an iterator over all compilation units. - fn units(&'d self, bcsymbolmap: Option<&'d BcSymbolMap<'d>>) -> DwarfUnitIterator<'_> { + fn units(&'d self, bcsymbolmap: Option<&'d BcSymbolMap<'d>>) -> DwarfUnitIterator<'d> { DwarfUnitIterator { info: self, bcsymbolmap, @@ -1242,7 +1248,7 @@ impl<'d> DwarfInfo<'d> { impl<'slf, 'd: 'slf> AsSelf<'slf> for DwarfInfo<'d> { type Ref = DwarfInfo<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { std::mem::transmute(self) } } } @@ -1356,7 +1362,7 @@ impl<'data> DwarfDebugSession<'data> { } } -impl<'data, 'session> DebugSession<'session> for DwarfDebugSession<'data> { +impl<'session> DebugSession<'session> for DwarfDebugSession<'_> { type Error = DwarfError; type FunctionIterator = DwarfFunctionIterator<'session>; type FileIterator = DwarfFileIterator<'session>; @@ -1487,3 +1493,23 @@ impl<'s> Iterator for DwarfFunctionIterator<'s> { } impl std::iter::FusedIterator for DwarfFunctionIterator<'_> {} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::macho::MachObject; + + #[cfg(feature = "macho")] + #[test] + fn test_loads_debug_str_offsets() { + // File generated using dsymutil + + let data = std::fs::read("tests/fixtures/helloworld").unwrap(); + + let obj = MachObject::parse(&data).unwrap(); + + let sections = DwarfSections::from_dwarf(&obj); + assert_eq!(sections.debug_str_offsets.data.len(), 48); + } +} diff --git a/symbolic-debuginfo/src/elf.rs b/symbolic-debuginfo/src/elf.rs index ed65c2fab..c5271abd1 100644 --- a/symbolic-debuginfo/src/elf.rs +++ b/symbolic-debuginfo/src/elf.rs @@ -76,7 +76,7 @@ impl<'data> ElfObject<'data> { /// Tests whether the buffer could contain an ELF object. pub fn test(data: &[u8]) -> bool { data.get(0..elf::header::SELFMAG) - .map_or(false, |data| data == elf::header::ELFMAG) + .is_some_and(|data| data == elf::header::ELFMAG) } // Pulled from https://github.com/m4b/goblin/blob/master/src/elf/mod.rs#L393-L424 as it @@ -291,6 +291,30 @@ impl<'data> ElfObject<'data> { return_partial_on_err!(elf::Symtab::parse(data, dyn_info.symtab, num_syms, ctx)); } + // If the dynamic symbol table is empty, try finding a SHT_DYNSYM section in the section headers. + // See https://refspecs.linuxfoundation.org/LSB_2.1.0/LSB-Core-generic/LSB-Core-generic/elftypes.html: + // + // > This section holds a minimal set of symbols adequate for dynamic linking. See also SHT_SYMTAB. Currently, an object file may have either a section of SHT_SYMTAB type or a section of SHT_DYNSYM type, but not both. + if obj.dynsyms.is_empty() { + if let Some(shdr) = obj + .section_headers + .iter() + .find(|h| h.sh_type == elf::section_header::SHT_DYNSYM) + { + let size = shdr.sh_entsize; + let count = if size == 0 { 0 } else { shdr.sh_size / size }; + obj.dynsyms = return_partial_on_err!(elf::Symtab::parse( + data, + shdr.sh_offset as usize, + count as usize, + ctx + )); + + obj.dynstrtab = + return_partial_on_err!(get_strtab(&obj.section_headers, shdr.sh_link as usize)); + } + } + obj.shdr_relocs = vec![]; for (idx, section) in obj.section_headers.iter().enumerate() { let is_rela = section.sh_type == elf::section_header::SHT_RELA; @@ -356,7 +380,7 @@ impl<'data> ElfObject<'data> { /// /// - None if there is no gnu_debuglink section /// - DebugLinkError if this section exists, but is malformed - pub fn debug_link(&self) -> Result, DebugLinkError> { + pub fn debug_link(&self) -> Result>, DebugLinkError<'_>> { self.section("gnu_debuglink") .map(|section| DebugLink::from_data(section.data, self.endianity())) .transpose() @@ -746,7 +770,7 @@ impl fmt::Debug for ElfObject<'_> { impl<'slf, 'data: 'slf> AsSelf<'slf> for ElfObject<'data> { type Ref = ElfObject<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } @@ -863,7 +887,7 @@ pub struct ElfSymbolIterator<'data, 'object> { load_addr: u64, } -impl<'data, 'object> Iterator for ElfSymbolIterator<'data, 'object> { +impl<'data> Iterator for ElfSymbolIterator<'data, '_> { type Item = Symbol<'data>; fn next(&mut self) -> Option { @@ -891,7 +915,7 @@ impl<'data, 'object> Iterator for ElfSymbolIterator<'data, 'object> { }; // We are only interested in symbols pointing into sections with executable flag. - if !section.map_or(false, |header| header.is_executable()) { + if !section.is_some_and(|header| header.is_executable()) { continue; } @@ -939,6 +963,7 @@ impl<'data> DebugLink<'data> { /// - A filename, with any leading directory components removed, followed by a zero byte, /// - zero to three bytes of padding, as needed to reach the next four-byte boundary within the section, and /// - a four-byte CRC checksum, stored in the same endianness used for the executable file itself. + /// /// (from ) /// /// # Errors diff --git a/symbolic-debuginfo/src/function_builder.rs b/symbolic-debuginfo/src/function_builder.rs index af1ff4fd7..0bc2cad07 100644 --- a/symbolic-debuginfo/src/function_builder.rs +++ b/symbolic-debuginfo/src/function_builder.rs @@ -237,14 +237,14 @@ struct FunctionBuilderInlinee<'s> { } /// Implement ordering in DFS order, i.e. first by address and then by depth. -impl<'s> PartialOrd for FunctionBuilderInlinee<'s> { +impl PartialOrd for FunctionBuilderInlinee<'_> { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } /// Implement ordering in DFS order, i.e. first by address and then by depth. -impl<'s> Ord for FunctionBuilderInlinee<'s> { +impl Ord for FunctionBuilderInlinee<'_> { fn cmp(&self, other: &Self) -> std::cmp::Ordering { (self.address, self.depth).cmp(&(other.address, other.depth)) } diff --git a/symbolic-debuginfo/src/js.rs b/symbolic-debuginfo/src/js.rs index d47c88971..bf3341fe9 100644 --- a/symbolic-debuginfo/src/js.rs +++ b/symbolic-debuginfo/src/js.rs @@ -29,15 +29,23 @@ pub fn discover_sourcemaps_location(contents: &str) -> Option<&str> { } /// Quickly reads the embedded `debug_id` key from a source map. +/// +/// Both `debugId` and `debug_id` are supported as field names. If both +/// are set, the latter takes precedence. pub fn discover_sourcemap_embedded_debug_id(contents: &str) -> Option { + // Deserialize from `"debugId"` or `"debug_id"`, + // preferring the latter. #[derive(Deserialize)] struct DebugIdInSourceMap { - debug_id: Option, + #[serde(rename = "debugId")] + debug_id_new: Option, + #[serde(rename = "debug_id")] + debug_id_old: Option, } serde_json::from_str(contents) .ok() - .and_then(|x: DebugIdInSourceMap| x.debug_id) + .and_then(|x: DebugIdInSourceMap| x.debug_id_old.or(x.debug_id_new)) } /// Parses a `debugId` comment in a file to discover a sourcemap's debug ID. @@ -49,3 +57,59 @@ pub fn discover_debug_id(contents: &str) -> Option { } None } + +#[cfg(test)] +mod tests { + use debugid::DebugId; + + use crate::js::discover_sourcemap_embedded_debug_id; + + #[test] + fn test_debugid_snake_case() { + let input = r#"{ + "version":3, + "sources":["coolstuff.js"], + "names":["x","alert"], + "mappings":"AAAA,GAAIA,GAAI,EACR,IAAIA,GAAK,EAAG,CACVC,MAAM", + "debug_id":"00000000-0000-0000-0000-000000000000" + }"#; + + assert_eq!( + discover_sourcemap_embedded_debug_id(input), + Some(DebugId::default()) + ); + } + + #[test] + fn test_debugid_camel_case() { + let input = r#"{ + "version":3, + "sources":["coolstuff.js"], + "names":["x","alert"], + "mappings":"AAAA,GAAIA,GAAI,EACR,IAAIA,GAAK,EAAG,CACVC,MAAM", + "debugId":"00000000-0000-0000-0000-000000000000" + }"#; + + assert_eq!( + discover_sourcemap_embedded_debug_id(input), + Some(DebugId::default()) + ); + } + + #[test] + fn test_debugid_both() { + let input = r#"{ + "version":3, + "sources":["coolstuff.js"], + "names":["x","alert"], + "mappings":"AAAA,GAAIA,GAAI,EACR,IAAIA,GAAK,EAAG,CACVC,MAAM", + "debug_id":"00000000-0000-0000-0000-000000000000", + "debugId":"11111111-1111-1111-1111-111111111111" + }"#; + + assert_eq!( + discover_sourcemap_embedded_debug_id(input), + Some(DebugId::default()) + ); + } +} diff --git a/symbolic-debuginfo/src/macho/bcsymbolmap.rs b/symbolic-debuginfo/src/macho/bcsymbolmap.rs index 6a4c15e47..bd9c6c70d 100644 --- a/symbolic-debuginfo/src/macho/bcsymbolmap.rs +++ b/symbolic-debuginfo/src/macho/bcsymbolmap.rs @@ -78,7 +78,7 @@ impl From for BcSymbolMapError { impl<'slf> AsSelf<'slf> for BcSymbolMap<'_> { type Ref = BcSymbolMap<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } @@ -194,7 +194,7 @@ pub struct BcSymbolMapIterator<'a, 'd> { iter: std::slice::Iter<'a, &'d str>, } -impl<'a, 'd> Iterator for BcSymbolMapIterator<'a, 'd> { +impl<'d> Iterator for BcSymbolMapIterator<'_, 'd> { type Item = &'d str; fn next(&mut self) -> Option { diff --git a/symbolic-debuginfo/src/macho/compact.rs b/symbolic-debuginfo/src/macho/compact.rs index 4929a3b04..52d95a73f 100644 --- a/symbolic-debuginfo/src/macho/compact.rs +++ b/symbolic-debuginfo/src/macho/compact.rs @@ -272,7 +272,7 @@ //! (subtract the global count to get the local index). //! //! > Unclear detail: If the global palette is smaller than 127, can the local -//! palette be larger than 128? +//! > palette be larger than 128? //! //! To compress these entries into a single 32-bit value, the address is truncated //! to 24 bits and packed with the index. The addresses stored in these entries @@ -2103,10 +2103,9 @@ mod test { const COMPRESSED_PAGE_KIND: u32 = 3; fn align(offset: u32, align: u32) -> u32 { - // Adding `align - 1` to a value push unaligned values to the next multiple, - // and integer division + multiplication can then remove the remainder. - ((offset + align - 1) / align) * align + offset.div_ceil(align) * align } + fn pack_x86_rbp_registers(regs: [u8; 5]) -> u32 { let mut result: u32 = 0; let base_offset = 0; @@ -2505,7 +2504,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { @@ -2537,7 +2536,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { @@ -2574,7 +2573,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { @@ -2631,7 +2630,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { @@ -2895,7 +2894,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { @@ -2927,7 +2926,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { @@ -2964,7 +2963,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { @@ -3021,7 +3020,7 @@ mod test { let opcode = Opcode( X86_MODE_RBP_FRAME | pack_x86_rbp_registers(registers) - | (stack_size as u32) << stack_size_offset, + | ((stack_size as u32) << stack_size_offset), ); let expected = vec![ CompactCfiOp::RegisterIs { diff --git a/symbolic-debuginfo/src/macho/mod.rs b/symbolic-debuginfo/src/macho/mod.rs index 7fd53b399..85dbefb05 100644 --- a/symbolic-debuginfo/src/macho/mod.rs +++ b/symbolic-debuginfo/src/macho/mod.rs @@ -349,10 +349,8 @@ impl<'d> MachObject<'d> { /// /// This is an indication that BCSymbolMaps are needed to symbolicate crash reports correctly. pub fn requires_symbolmap(&self) -> bool { - self.symbols().any(|s| { - s.name() - .map_or(false, |n| n.starts_with(SWIFT_HIDDEN_PREFIX)) - }) + self.symbols() + .any(|s| s.name().is_some_and(|n| n.starts_with(SWIFT_HIDDEN_PREFIX))) } } @@ -375,7 +373,7 @@ impl fmt::Debug for MachObject<'_> { impl<'slf, 'd: 'slf> AsSelf<'slf> for MachObject<'d> { type Ref = MachObject<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } @@ -468,7 +466,7 @@ impl<'data> Dwarf<'data> for MachObject<'data> { for section in segment.into_iter() { let (header, data) = section.ok()?; if let Ok(sec) = header.name() { - if sec.starts_with("__") && &sec[2..] == section_name { + if sec.starts_with("__") && map_section_name(&sec[2..]) == section_name { // In some cases, dsymutil leaves sections headers but removes their // data from the file. While the addr and size parameters are still // set, `header.offset` is 0 in that case. We skip them just like the @@ -492,6 +490,13 @@ impl<'data> Dwarf<'data> for MachObject<'data> { } } +/// See . +fn map_section_name(name: &str) -> &str { + match name { + "debug_str_offs" => "debug_str_offsets", + _ => name, + } +} /// An iterator over symbols in the MachO file. /// /// Returned by [`MachObject::symbols`](struct.MachObject.html#method.symbols). @@ -559,7 +564,7 @@ pub struct FatMachObjectIterator<'d, 'a> { data: &'d [u8], } -impl<'d, 'a> Iterator for FatMachObjectIterator<'d, 'a> { +impl<'d> Iterator for FatMachObjectIterator<'d, '_> { type Item = Result, MachError>; fn next(&mut self) -> Option { @@ -647,7 +652,7 @@ impl fmt::Debug for FatMachO<'_> { impl<'slf, 'd: 'slf> AsSelf<'slf> for FatMachO<'d> { type Ref = FatMachO<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } @@ -661,7 +666,7 @@ enum MachObjectIteratorInner<'d, 'a> { /// An iterator over objects in a [`MachArchive`](struct.MachArchive.html). pub struct MachObjectIterator<'d, 'a>(MachObjectIteratorInner<'d, 'a>); -impl<'d, 'a> Iterator for MachObjectIterator<'d, 'a> { +impl<'d> Iterator for MachObjectIterator<'d, '_> { type Item = Result, MachError>; fn next(&mut self) -> Option { @@ -796,13 +801,14 @@ impl<'d> MachArchive<'d> { impl<'slf, 'd: 'slf> AsSelf<'slf> for MachArchive<'d> { type Ref = MachArchive<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } #[cfg(test)] mod tests { + use super::*; #[test] diff --git a/symbolic-debuginfo/src/object.rs b/symbolic-debuginfo/src/object.rs index e3281ce7f..8cd5260f6 100644 --- a/symbolic-debuginfo/src/object.rs +++ b/symbolic-debuginfo/src/object.rs @@ -371,7 +371,7 @@ impl<'data> Object<'data> { impl<'slf, 'data: 'slf> AsSelf<'slf> for Object<'data> { type Ref = Object<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { std::mem::transmute(self) } } } @@ -449,7 +449,7 @@ pub enum ObjectDebugSession<'d> { PortablePdb(PortablePdbDebugSession<'d>), } -impl<'d> ObjectDebugSession<'d> { +impl ObjectDebugSession<'_> { /// Returns an iterator over all functions in this debug file. /// /// Functions are iterated in the order they are declared in their compilation units. The @@ -606,7 +606,7 @@ pub enum SymbolIterator<'data, 'object> { PortablePdb(PortablePdbSymbolIterator<'data>), } -impl<'data, 'object> Iterator for SymbolIterator<'data, 'object> { +impl<'data> Iterator for SymbolIterator<'data, '_> { type Item = Symbol<'data>; fn next(&mut self) -> Option { @@ -758,7 +758,7 @@ impl<'d> Archive<'d> { impl<'slf, 'd: 'slf> AsSelf<'slf> for Archive<'d> { type Ref = Archive<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { std::mem::transmute(self) } } } @@ -778,7 +778,7 @@ enum ObjectIteratorInner<'d, 'a> { /// An iterator over [`Object`](enum.Object.html)s in an [`Archive`](struct.Archive.html). pub struct ObjectIterator<'d, 'a>(ObjectIteratorInner<'d, 'a>); -impl<'d, 'a> Iterator for ObjectIterator<'d, 'a> { +impl<'d> Iterator for ObjectIterator<'d, '_> { type Item = Result, ObjectError>; fn next(&mut self) -> Option { diff --git a/symbolic-debuginfo/src/pdb.rs b/symbolic-debuginfo/src/pdb.rs index 9aa30e524..a13c423c6 100644 --- a/symbolic-debuginfo/src/pdb.rs +++ b/symbolic-debuginfo/src/pdb.rs @@ -16,6 +16,7 @@ use pdb_addr2line::pdb::{ }; use pdb_addr2line::ModuleProvider; use smallvec::SmallVec; +use srcsrv; use thiserror::Error; use symbolic_common::{ @@ -251,6 +252,31 @@ impl<'data> PdbObject<'data> { false } + /// Returns the SRCSRV VCS integration name if available. + /// + /// This extracts the version control system identifier from the SRCSRV stream, + /// if present. Common values include "perforce", "tfs", "git", etc. + /// Returns `None` if no SRCSRV stream exists or if it cannot be parsed. + pub fn srcsrv_vcs_name(&self) -> Option { + let mut pdb = self.pdb.write(); + + // Try to open the "srcsrv" named stream + let stream = match pdb.named_stream(b"srcsrv") { + Ok(stream) => stream, + Err(_) => return None, + }; + + // Parse the stream to extract VCS name + let stream_data = stream.as_slice(); + if let Ok(parsed_stream) = srcsrv::SrcSrvStream::parse(stream_data) { + parsed_stream + .version_control_description() + .map(|s| s.to_string()) + } else { + None + } + } + /// Determines whether this object is malformed and was only partially parsed pub fn is_malformed(&self) -> bool { false @@ -298,7 +324,7 @@ impl fmt::Debug for PdbObject<'_> { impl<'slf, 'data: 'slf> AsSelf<'slf> for PdbObject<'data> { type Ref = PdbObject<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { std::mem::transmute(self) } } } @@ -434,7 +460,7 @@ pub struct PdbSymbolIterator<'data, 'object> { executable_sections: &'object ExecutableSections, } -impl<'data, 'object> Iterator for PdbSymbolIterator<'data, 'object> { +impl<'data> Iterator for PdbSymbolIterator<'data, '_> { type Item = Symbol<'data>; fn next(&mut self) -> Option { @@ -565,7 +591,7 @@ impl<'d> PdbDebugInfo<'d> { } /// Returns an iterator over all compilation units (modules). - fn units(&'d self) -> PdbUnitIterator<'_> { + fn units(&'d self) -> PdbUnitIterator<'d> { PdbUnitIterator { debug_info: self, index: 0, @@ -576,7 +602,7 @@ impl<'d> PdbDebugInfo<'d> { self.type_formatter.modules() } - fn get_module(&'d self, index: usize) -> Result>, PdbError> { + fn get_module(&'d self, index: usize) -> Result>, PdbError> { // Silently ignore module references out-of-bound let module = match self.modules().get(index) { Some(module) => module, @@ -599,7 +625,7 @@ impl<'d> PdbDebugInfo<'d> { impl<'slf, 'd: 'slf> AsSelf<'slf> for PdbDebugInfo<'d> { type Ref = PdbDebugInfo<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { std::mem::transmute(self) } } } @@ -746,6 +772,7 @@ impl<'s> Unit<'s> { /// For example we have observed in a real-world pdb that has: /// - A function 0x33ea50 (size 0xc) /// - With one line record: 0x33e850 (size 0x26) + /// /// The line record is completely outside the range of the function. fn sanitize_lines(func: &mut Function) { let fn_start = func.address; @@ -905,7 +932,7 @@ impl<'s> Unit<'s> { if symbol.ends_scope() { depth -= 1; - if proc_offsets.last().map_or(false, |&(d, _)| d >= depth) { + if proc_offsets.last().is_some_and(|&(d, _)| d >= depth) { proc_offsets.pop(); } } diff --git a/symbolic-debuginfo/src/pe.rs b/symbolic-debuginfo/src/pe.rs index 146226e8e..e99cfcfbf 100644 --- a/symbolic-debuginfo/src/pe.rs +++ b/symbolic-debuginfo/src/pe.rs @@ -248,7 +248,7 @@ impl<'data> PeObject<'data> { /// Determines whether this object contains stack unwinding information. pub fn has_unwind_info(&self) -> bool { - !self.is_stub && self.exception_data().map_or(false, |e| !e.is_empty()) + !self.is_stub && self.exception_data().is_some_and(|e| !e.is_empty()) } /// Returns the raw data of the PE file. @@ -377,7 +377,7 @@ impl fmt::Debug for PeObject<'_> { impl<'slf, 'data: 'slf> AsSelf<'slf> for PeObject<'data> { type Ref = PeObject<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } @@ -463,7 +463,7 @@ pub struct PeSymbolIterator<'data, 'object> { exports: std::slice::Iter<'object, pe::export::Export<'data>>, } -impl<'data, 'object> Iterator for PeSymbolIterator<'data, 'object> { +impl<'data> Iterator for PeSymbolIterator<'data, '_> { type Item = Symbol<'data>; fn next(&mut self) -> Option { @@ -506,9 +506,9 @@ pub struct PeEmbeddedPortablePDB<'data> { uncompressed_size: usize, } -impl<'data, 'object> PeEmbeddedPortablePDB<'data> { +impl PeEmbeddedPortablePDB<'_> { /// Returns the uncompressed size of the Portable PDB buffer. - pub fn get_size(&'object self) -> usize { + pub fn get_size(&self) -> usize { self.uncompressed_size } diff --git a/symbolic-debuginfo/src/ppdb.rs b/symbolic-debuginfo/src/ppdb.rs index 25ae919f8..c22c96a70 100644 --- a/symbolic-debuginfo/src/ppdb.rs +++ b/symbolic-debuginfo/src/ppdb.rs @@ -26,7 +26,7 @@ pub struct PortablePdbObject<'data> { impl<'data> PortablePdbObject<'data> { /// Returns the Portable PDB contained in this object. - pub fn portable_pdb(&self) -> &PortablePdb { + pub fn portable_pdb(&self) -> &PortablePdb<'_> { &self.ppdb } @@ -214,7 +214,7 @@ impl<'data> PortablePdbDebugSession<'data> { } } -impl<'data, 'session> DebugSession<'session> for PortablePdbDebugSession<'data> { +impl<'session> DebugSession<'session> for PortablePdbDebugSession<'_> { type Error = FormatError; type FunctionIterator = PortablePdbFunctionIterator<'session>; type FileIterator = PortablePdbFileIterator<'session>; diff --git a/symbolic-debuginfo/src/sourcebundle.rs b/symbolic-debuginfo/src/sourcebundle/mod.rs similarity index 91% rename from symbolic-debuginfo/src/sourcebundle.rs rename to symbolic-debuginfo/src/sourcebundle/mod.rs index ebddd50e6..d87afe9a5 100644 --- a/symbolic-debuginfo/src/sourcebundle.rs +++ b/symbolic-debuginfo/src/sourcebundle/mod.rs @@ -42,14 +42,17 @@ //! bundle a file entry has a `url` and might carry `headers` or individual debug IDs //! per source file. +mod utf8_reader; + use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::error::Error; -use std::fmt; +use std::fmt::{Display, Formatter}; use std::fs::{File, OpenOptions}; -use std::io::{BufReader, BufWriter, Read, Seek, Write}; +use std::io::{BufReader, BufWriter, ErrorKind, Read, Seek, Write}; use std::path::Path; use std::sync::Arc; +use std::{fmt, io}; use parking_lot::Mutex; use regex::Regex; @@ -59,6 +62,7 @@ use zip::{write::SimpleFileOptions, ZipWriter}; use symbolic_common::{Arch, AsSelf, CodeId, DebugId, SourceLinkMappings}; +use self::utf8_reader::Utf8Reader; use crate::base::*; use crate::js::{ discover_debug_id, discover_sourcemap_embedded_debug_id, discover_sourcemaps_location, @@ -84,7 +88,7 @@ lazy_static::lazy_static! { #[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum SourceBundleErrorKind { - /// The source bundle container is damanged. + /// The source bundle container is damaged. BadZip, /// An error when reading/writing the manifest. @@ -550,7 +554,7 @@ impl<'data> SourceBundleIndex<'data> { let zip_path = Arc::new(zip_path.clone()); if !file_info.path.is_empty() { indexed_files.insert( - FileKey::Path(file_info.path.clone().into()), + FileKey::Path(normalize_path(&file_info.path).into()), zip_path.clone(), ); } @@ -783,7 +787,7 @@ impl<'data> SourceBundle<'data> { impl<'slf, 'data: 'slf> AsSelf<'slf> for SourceBundle<'data> { type Ref = SourceBundle<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { std::mem::transmute(self) } } } @@ -879,7 +883,7 @@ pub struct SourceBundleDebugSession<'data> { source_links: SourceLinkMappings, } -impl<'data> SourceBundleDebugSession<'data> { +impl SourceBundleDebugSession<'_> { /// Returns an iterator over all source files in this debug file. pub fn files(&self) -> SourceBundleFileIterator<'_> { SourceBundleFileIterator { @@ -936,7 +940,7 @@ impl<'data> SourceBundleDebugSession<'data> { &self, path: &str, ) -> Result>, SourceBundleError> { - self.get_source_file_descriptor(FileKey::Path(path.into())) + self.get_source_file_descriptor(FileKey::Path(normalize_path(path).into())) } /// Like [`source_by_path`](Self::source_by_path) but looks up by URL. @@ -969,7 +973,7 @@ impl<'data> SourceBundleDebugSession<'data> { } } -impl<'data, 'session> DebugSession<'session> for SourceBundleDebugSession<'data> { +impl<'session> DebugSession<'session> for SourceBundleDebugSession<'_> { type Error = SourceBundleError; type FunctionIterator = SourceBundleFunctionIterator<'session>; type FileIterator = SourceBundleFileIterator<'session>; @@ -990,7 +994,7 @@ impl<'data, 'session> DebugSession<'session> for SourceBundleDebugSession<'data> impl<'slf, 'data: 'slf> AsSelf<'slf> for SourceBundleDebugSession<'data> { type Ref = SourceBundleDebugSession<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { unsafe { std::mem::transmute(self) } } } @@ -1035,13 +1039,47 @@ fn sanitize_bundle_path(path: &str) -> String { sanitized } +/// Normalizes all paths to follow the Linux standard of using forward slashes. +fn normalize_path(path: &str) -> String { + path.replace('\\', "/") +} + +/// Contains information about a file skipped in the SourceBundleWriter +#[derive(Debug)] +pub struct SkippedFileInfo<'a> { + path: &'a str, + reason: &'a str, +} + +impl<'a> SkippedFileInfo<'a> { + fn new(path: &'a str, reason: &'a str) -> Self { + Self { path, reason } + } + + /// Returns the path of the skipped file. + pub fn path(&self) -> &str { + self.path + } + + /// Get the human-readable reason why the file was skipped + pub fn reason(&self) -> &str { + self.reason + } +} + +impl Display for SkippedFileInfo<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "Skipped file {} due to: {}", self.path, self.reason) + } +} + /// Writer to create [`SourceBundles`]. /// /// Writers can either [create a new file] or be created from an [existing file]. Then, use /// [`add_file`] to add files and finally call [`finish`] to flush the archive to /// the underlying writer. /// -/// Note that dropping the writer +/// Note that dropping the writer without calling [`finish`] will result in an incomplete bundle. /// /// ```no_run /// # use std::fs::File; @@ -1070,6 +1108,7 @@ where manifest: SourceBundleManifest, writer: ZipWriter, collect_il2cpp: bool, + skipped_file_callback: Box, } fn default_file_options() -> SimpleFileOptions { @@ -1097,6 +1136,7 @@ where manifest: SourceBundleManifest::new(), writer: ZipWriter::new(writer), collect_il2cpp: false, + skipped_file_callback: Box::new(|_| ()), }) } @@ -1185,18 +1225,14 @@ where pub fn add_file( &mut self, path: S, - mut file: R, + file: R, info: SourceFileInfo, ) -> Result<(), SourceBundleError> where S: AsRef, R: Read, { - let mut buf = String::new(); - - if let Err(e) = file.read_to_string(&mut buf) { - return Err(SourceBundleError::new(SourceBundleErrorKind::ReadFailed, e)); - } + let mut file_reader = Utf8Reader::new(file); let full_path = self.file_path(path.as_ref()); let unique_path = self.unique_path(full_path); @@ -1204,12 +1240,62 @@ where self.writer .start_file(unique_path.clone(), default_file_options()) .map_err(|e| SourceBundleError::new(SourceBundleErrorKind::WriteFailed, e))?; - self.writer - .write_all(buf.as_bytes()) - .map_err(|e| SourceBundleError::new(SourceBundleErrorKind::WriteFailed, e))?; - self.manifest.files.insert(unique_path, info); - Ok(()) + match io::copy(&mut file_reader, &mut self.writer) { + Err(e) => { + self.writer + .abort_file() + .map_err(|e| SourceBundleError::new(SourceBundleErrorKind::WriteFailed, e))?; + + // ErrorKind::InvalidData is returned by Utf8Reader when the file is not valid UTF-8. + let error_kind = match e.kind() { + ErrorKind::InvalidData => SourceBundleErrorKind::ReadFailed, + _ => SourceBundleErrorKind::WriteFailed, + }; + + Err(SourceBundleError::new(error_kind, e)) + } + Ok(_) => { + self.manifest.files.insert(unique_path, info); + Ok(()) + } + } + } + + /// Calls add_file, and handles any ReadFailed errors by calling the skipped_file_callback. + fn add_file_skip_read_failed( + &mut self, + path: S, + file: R, + info: SourceFileInfo, + ) -> Result<(), SourceBundleError> + where + S: AsRef, + R: Read, + { + let result = self.add_file(&path, file, info); + + if let Err(e) = &result { + if e.kind == SourceBundleErrorKind::ReadFailed { + let reason = e.to_string(); + let skipped_info = SkippedFileInfo::new(path.as_ref(), &reason); + (self.skipped_file_callback)(skipped_info); + + return Ok(()); + } + } + + result + } + + /// Set a callback, which is called for every file that is skipped from being included in the + /// source bundle. The callback receives information about the file being skipped. + pub fn with_skipped_file_callback( + mut self, + callback: impl FnMut(SkippedFileInfo) + 'static, + ) -> Self { + self.skipped_file_callback = Box::new(callback); + self } /// Writes a single object into the bundle. @@ -1297,7 +1383,7 @@ where collect_il2cpp_sources(&source, &mut referenced_files); } - self.add_file(bundle_path, source.as_slice(), info)?; + self.add_file_skip_read_failed(bundle_path, source.as_slice(), info)?; } files_handled.insert(filename); @@ -1314,7 +1400,7 @@ where info.set_ty(SourceFileType::Source); info.set_path(filename.clone()); - self.add_file(bundle_path, source, info)?; + self.add_file_skip_read_failed(bundle_path, source, info)? } } @@ -1470,6 +1556,50 @@ mod tests { is_sendsync::(); } + #[test] + fn test_normalize_paths() -> Result<(), SourceBundleError> { + let mut writer = Cursor::new(Vec::new()); + let mut bundle = SourceBundleWriter::start(&mut writer)?; + + for filename in &[ + "C:\\users\\martin\\mydebugfile.cs", + "/usr/martin/mydebugfile.h", + ] { + let mut info = SourceFileInfo::new(); + info.set_ty(SourceFileType::Source); + info.set_path(filename.to_string()); + bundle.add_file_skip_read_failed( + sanitize_bundle_path(filename), + &b"somerandomdata"[..], + info, + )?; + } + + bundle.finish()?; + let bundle_bytes = writer.into_inner(); + let bundle = SourceBundle::parse(&bundle_bytes)?; + + let session = bundle.debug_session().unwrap(); + + assert!(session + .source_by_path("C:\\users\\martin\\mydebugfile.cs")? + .is_some()); + assert!(session + .source_by_path("C:/users/martin/mydebugfile.cs")? + .is_some()); + assert!(session + .source_by_path("C:\\users\\martin/mydebugfile.cs")? + .is_some()); + assert!(session + .source_by_path("/usr/martin/mydebugfile.h")? + .is_some()); + assert!(session + .source_by_path("\\usr\\martin\\mydebugfile.h")? + .is_some()); + + Ok(()) + } + #[test] fn test_source_descriptor() -> Result<(), SourceBundleError> { let mut writer = Cursor::new(Vec::new()); diff --git a/symbolic-debuginfo/src/sourcebundle/utf8_reader.rs b/symbolic-debuginfo/src/sourcebundle/utf8_reader.rs new file mode 100644 index 000000000..64713814e --- /dev/null +++ b/symbolic-debuginfo/src/sourcebundle/utf8_reader.rs @@ -0,0 +1,306 @@ +//! UTF-8 reader used by the sourcebundle module to read files. + +use std::cmp; +use std::io::{Error, ErrorKind, Read, Result}; +use std::str; + +use thiserror::Error; + +const MAX_UTF8_SEQUENCE_SIZE: usize = 4; + +#[derive(Debug, Error)] +#[error("Invalid UTF-8 sequence")] +pub(crate) struct UTF8ReaderError; + +pub struct Utf8Reader { + inner: R, + + /// A buffer of `MAX_UTF8_SEQUENCE_SIZE` bytes, which we use when the end of a read is not a + /// valid UTF-8 sequence. We read into this buffer until we have a valid UTF-8 sequence, or + /// the reader is exhausted, or the buffer is full. Assuming we get a valid UTF-8 sequence, + /// we then on next read read from this buffer. + buffer: [u8; MAX_UTF8_SEQUENCE_SIZE], + + /// The index of the first byte in the buffer that has not been read. + buffer_start: usize, + + /// The index of the last byte in the buffer that is part of the UTF-8 sequence. We only read + /// up to this index, bytes after this index are discarded. + buffer_end: usize, +} + +impl Utf8Reader { + pub fn new(inner: R) -> Self { + Self { + inner, + buffer: [0; MAX_UTF8_SEQUENCE_SIZE], + buffer_start: 0, + buffer_end: 0, + } + } + + /// The slice of the buffer that should be read next. + fn buffer_to_read(&self) -> &[u8] { + &self.buffer[self.buffer_start..self.buffer_end] + } + + /// Advances the buffer start index by the given amount. + fn advance(&mut self, amt: usize) { + self.buffer_start += amt; + } + + /// Reads bytes from the buffer into the given buffer. + fn read_from_buffer(&mut self, buf: &mut [u8]) -> Result { + let bytes_copied = slice_copy(buf, self.buffer_to_read()); + self.advance(bytes_copied); + + Ok(bytes_copied) + } +} + +impl Utf8Reader +where + R: Read, +{ + /// Reads bytes from the inner reader into the given buffer. + /// + /// If a UTF-8 sequence only partially fits into the buffer, the remaining + /// bytes are written to `self.buffer`. + fn read_from_inner(&mut self, buf: &mut [u8]) -> Result { + let read_from_inner = self.inner.read(buf)?; + let read_portion = &buf[..read_from_inner]; + + let invalid_portion = ending_incomplete_utf8_sequence(read_portion)?; + + slice_copy(&mut self.buffer, invalid_portion); + self.read_into_buffer_until_utf8(invalid_portion.len())?; + + Ok(read_from_inner) + } + + /// Reads bytes from the inner reader into self.buffer until the buffer contains a valid UTF-8 + /// sequence. + /// + /// Before calling this method, self.buffer[..start_index] should contain the bytes that are + /// part of the incomplete UTF-8 sequence that we are trying to complete (or, it should be + /// empty, in which case, this function is a no-op) + /// + /// Then, we read one byte at a time from the inner reader into self.buffer, until we have a + /// valid UTF-8 sequence. + /// + /// Lastly, we set self.buffer_start to start_index (so we don't reread the bytes that started + /// the incomplete UTF-8 sequence) and self.buffer_end to the index of the last byte in the + /// buffer that is part of the UTF-8 sequence. + /// + /// The next read from the Utf8Reader will read from + /// self.buffer[self.buffer_start..self.buffer_end]. + fn read_into_buffer_until_utf8(&mut self, start_index: usize) -> Result<()> { + let bytes_until_utf8 = read_until_utf8(&mut self.inner, &mut self.buffer, start_index)?; + + self.buffer_start = start_index; + self.buffer_end = bytes_until_utf8; + + Ok(()) + } +} + +impl Read for Utf8Reader +where + R: Read, +{ + fn read(&mut self, buf: &mut [u8]) -> Result { + let read_from_buffer = self.read_from_buffer(buf)?; + + // self.read_from_inner overwrites self.buffer, so we can only call it if we have read + // everything from the buffer. + let read_from_inner = match self.buffer_to_read() { + [] => self.read_from_inner(&mut buf[read_from_buffer..])?, + _ => 0, + }; + + Ok(read_from_buffer + read_from_inner) + } +} + +/// Reads a single byte at a time from the inner reader into the buffer, starting from +/// current_index, until either the buffer contains a valid UTF-8 sequence, the reader is +/// exhausted, or the 4 bytes total have been read into the buffer (the maximum size of a +/// UTF-8 sequence). The 4 bytes also includes bytes already in the buffer when the function is +/// called, as indicated by the current_index parameter. +/// +/// If the buffer is empty (i.e. current_index is 0), we will return Ok(0) without reading +/// anything from the reader. An empty byte sequence is a valid UTF-8 sequence (the +/// empty string). +/// +/// Returns the number of bytes read into the buffer (including bytes already in the buffer +/// when the function is called), or an error if the reader errors or if reading a valid UTF-8 +/// sequence is not possible. +/// +/// The buffer must have a length of at least 4, otherwise this function can panic. +fn read_until_utf8( + reader: &mut impl Read, + buffer: &mut [u8], + mut current_index: usize, +) -> Result { + while str::from_utf8(&buffer[..current_index]).is_err() { + if current_index >= MAX_UTF8_SEQUENCE_SIZE + || reader.read(&mut buffer[current_index..current_index + 1])? == 0 + { + // We already have 4 bytes in the buffer (maximum UTF-8 sequence size), or the stream + // has been exhausted without finding a valid UTF-8 sequence. + return Err(Error::new(ErrorKind::InvalidData, UTF8ReaderError)); + } + + current_index += 1; + } + + Ok(current_index) +} + +/// Returns the index of the first invalid UTF-8 sequence +/// in the given bytes. If the sequence is valid, returns the +/// length of the bytes. +fn utf8_up_to(bytes: &[u8]) -> usize { + match str::from_utf8(bytes) { + Ok(_) => bytes.len(), + Err(e) => e.valid_up_to(), + } +} + +/// Given a byte slice, determines if the slice ends in what might be an incomplete UTF-8 sequence, +/// returning the incomplete sequence if so. +/// +/// The following return values are possible: +/// - Ok([]) if the byte slice is valid UTF-8, in its entirety. +/// - Ok(incomplete_sequence) if the byte slice is valid up to the `incomplete_sequence` slice +/// returned by this function. `incomplete_sequence` is always a slice of at most 3 bytes +/// occurring at the end of the input slice. In this case, it might be possible to make the +/// input slice a valid UTF-8 sequence by appending bytes to the input slice. +/// - Err(e) if the first UTF-8 violation in the input slice occurs more than 3 bytes from the +/// end of the input slice. In this case, it is definitely not possible to make the sequence +/// valid by appending bytes to the input slice. +fn ending_incomplete_utf8_sequence(bytes: &[u8]) -> Result<&[u8]> { + let valid_up_to = utf8_up_to(bytes); + let invalid_portion = &bytes[valid_up_to..]; + + if invalid_portion.len() >= MAX_UTF8_SEQUENCE_SIZE { + Err(Error::new(ErrorKind::InvalidData, UTF8ReaderError)) + } else { + Ok(invalid_portion) + } +} + +/// Copies as many elements as possible (i.e. the smaller of the two slice lengths) from the +/// beginning of the source slice to the beginning of the destination slice, overwriting anything +/// already in the destination slice. +/// +/// Returns the number of elements copied. +fn slice_copy(dst: &mut [T], src: &[T]) -> usize +where + T: Copy, +{ + let elements_to_copy = cmp::min(dst.len(), src.len()); + dst[..elements_to_copy].copy_from_slice(&src[..elements_to_copy]); + + elements_to_copy +} + +#[cfg(test)] +mod tests { + use super::*; + + use proptest::prelude::*; + + use core::str; + use std::io::Cursor; + + #[test] + fn test_read_empty() { + let mut empty_reader = Utf8Reader::new(Cursor::new(b"")); + + let mut buf = vec![]; + empty_reader + .read_to_end(&mut buf) + .expect("read_to_end errored"); + + assert_eq!(buf, b""); + } + + #[test] + fn test_read_ascii_simple() { + let mut reader = Utf8Reader::new(Cursor::new(b"Hello, world!")); + + let mut buf = vec![]; + reader.read_to_end(&mut buf).expect("read_to_end errored"); + + assert_eq!(buf, b"Hello, world!"); + } + + #[test] + fn test_read_utf8_simple() { + const HELLO_WORLD: &str = "你好世界!"; + let mut reader = Utf8Reader::new(Cursor::new(HELLO_WORLD.as_bytes())); + + let mut buf = vec![]; + reader.read_to_end(&mut buf).expect("read_to_end errored"); + + assert_eq!(buf, HELLO_WORLD.as_bytes()); + } + + #[test] + fn small_reads_splitting_sequence() { + let mut reader = Utf8Reader::new(Cursor::new("🙂".as_bytes())); + + let mut buf = [0; MAX_UTF8_SEQUENCE_SIZE]; + + for i in 0..MAX_UTF8_SEQUENCE_SIZE { + // Read at most one byte at a time. + let bytes_read = reader.read(&mut buf[i..i + 1]).expect("read errored"); + assert_eq!(bytes_read, 1, "bytes read"); + } + + assert_eq!(&buf[..], "🙂".as_bytes()); + } + + #[test] + fn invalid_utf8_sequence() { + let mut reader = Utf8Reader::new(Cursor::new([0b11111111])); + + let mut buf = [0; 1]; + reader.read(&mut buf).expect_err("read should have errored"); + } + + #[test] + fn invalid_utf8_sequence_at_end_of_reader() { + let mut read_buffer = Vec::from(b"Hello, world!"); + + // Cutting off the last byte will invalidate the UTF-8 sequence. + let invalid_sequence = &"🙂".as_bytes()[..'🙂'.len_utf8() - 1]; + read_buffer.extend(invalid_sequence); + + let mut reader = Utf8Reader::new(Cursor::new(&read_buffer)); + reader + .read_to_end(&mut vec![]) + .expect_err("read should have errored"); + } + + proptest! { + #[test] + fn read_arbitrary_string(s in any::()) { + let mut buf = vec![]; + let mut reader = Utf8Reader::new(Cursor::new(&s)); + + reader.read_to_end(&mut buf).unwrap(); + assert_eq!(str::from_utf8(&buf).unwrap(), s); + } + + #[test] + fn dont_read_arbitrary_nonstring(s in any::>()) { + prop_assume!(str::from_utf8(&s).is_err()); + let mut buf = vec![]; + let mut reader = Utf8Reader::new(Cursor::new(&s)); + + reader.read_to_end(&mut buf).unwrap_err(); + } + } +} diff --git a/symbolic-debuginfo/src/wasm.rs b/symbolic-debuginfo/src/wasm.rs index 1454f2f49..bafd252d3 100644 --- a/symbolic-debuginfo/src/wasm.rs +++ b/symbolic-debuginfo/src/wasm.rs @@ -169,7 +169,7 @@ impl fmt::Debug for WasmObject<'_> { impl<'slf, 'd: 'slf> AsSelf<'slf> for WasmObject<'d> { type Ref = WasmObject<'slf>; - fn as_self(&'slf self) -> &Self::Ref { + fn as_self(&'slf self) -> &'slf Self::Ref { self } } @@ -278,7 +278,7 @@ pub struct WasmSymbolIterator<'data, 'object> { _marker: std::marker::PhantomData<&'object u8>, } -impl<'data, 'object> Iterator for WasmSymbolIterator<'data, 'object> { +impl<'data> Iterator for WasmSymbolIterator<'data, '_> { type Item = Symbol<'data>; fn next(&mut self) -> Option { diff --git a/symbolic-debuginfo/src/wasm/parser.rs b/symbolic-debuginfo/src/wasm/parser.rs index f6413ce48..1fa4fd5b7 100644 --- a/symbolic-debuginfo/src/wasm/parser.rs +++ b/symbolic-debuginfo/src/wasm/parser.rs @@ -3,8 +3,8 @@ use super::WasmError; use crate::base::{ObjectKind, Symbol}; use wasmparser::{ - BinaryReader, CompositeType, FuncValidatorAllocations, NameSectionReader, Payload, TypeRef, - Validator, WasmFeatures, + BinaryReader, CompositeInnerType, FuncValidatorAllocations, NameSectionReader, Payload, + TypeRef, Validator, WasmFeatures, }; #[derive(Default)] @@ -20,7 +20,7 @@ impl BitVec { pub fn resize(&mut self, count: usize, value: bool) { self.data.resize( - (count + u64::BITS as usize - 1) / u64::BITS as usize, + count.div_ceil(u64::BITS as usize), if value { u64::MAX } else { u64::MIN }, ); self.len = count; @@ -43,7 +43,7 @@ impl BitVec { } else { let vec_index = index / u64::BITS as usize; let item_bit = index % u64::BITS as usize; - Some(self.data[vec_index] & 1 << item_bit != 0) + Some(self.data[vec_index] & (1 << item_bit) != 0) } } } @@ -83,8 +83,8 @@ impl<'data> super::WasmObject<'data> { for (i, ty) in tsr.into_iter().enumerate() { let mut types = ty?.into_types(); let ty_is_func = matches!( - types.next().map(|s| s.composite_type), - Some(CompositeType::Func(_)) + types.next().map(|s| s.composite_type.inner), + Some(CompositeInnerType::Func(_)) ); if types.next().is_none() && ty_is_func { func_sigs.set(i, true); diff --git a/symbolic-debuginfo/tests/fixtures/helloworld b/symbolic-debuginfo/tests/fixtures/helloworld new file mode 100644 index 000000000..2aed7c6cc Binary files /dev/null and b/symbolic-debuginfo/tests/fixtures/helloworld differ diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_files.snap b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_files.snap index 626dc6650..44a7eb330 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_files.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_files.snap @@ -1,7 +1,5 @@ --- -created: "2019-06-28T08:09:53.890090Z" -creator: insta@0.8.1 -source: debuginfo/tests/test_objects.rs +source: symbolic-debuginfo/tests/test_objects.rs expression: "FilesDebug(&files[..10])" --- c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\system_error @@ -14,4 +12,3 @@ c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.1 c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xstring c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\cstdlib c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xmemory0 - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions.snap b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions.snap index bf64859e4..3d056fd74 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions.snap @@ -1,10 +1,7 @@ --- -created: "2019-02-20T15:25:10.239080Z" -creator: insta@0.6.3 -source: debuginfo/tests/test_objects.rs +source: symbolic-debuginfo/tests/test_objects.rs expression: "FunctionsDebug(&functions[..10], 0)" --- - > 0x1000: google_breakpad::CrashGenerationClient::RequestDump(_EXCEPTION_POINTERS *,MDRawAssertionInfo *) (0x114) 0x1000: crash_generation_client.cc:323 (c:\projects\breakpad-tools\deps\breakpad\src\client\windows\crash_generation) 0x1011: crash_generation_client.cc:324 (c:\projects\breakpad-tools\deps\breakpad\src\client\windows\crash_generation) @@ -132,4 +129,3 @@ expression: "FunctionsDebug(&functions[..10], 0)" 0x1727: exception_handler.cc:289 (c:\projects\breakpad-tools\deps\breakpad\src\client\windows\handler) 0x1741: exception_handler.cc:291 (c:\projects\breakpad-tools\deps\breakpad\src\client\windows\handler) 0x174c: exception_handler.cc:293 (c:\projects\breakpad-tools\deps\breakpad\src\client\windows\handler) - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions_mac_with_inlines.snap b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions_mac_with_inlines.snap index 54e3ccdab..9ba47d342 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions_mac_with_inlines.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_functions_mac_with_inlines.snap @@ -1,9 +1,7 @@ --- source: symbolic-debuginfo/tests/test_objects.rs -assertion_line: 150 expression: "FunctionsDebug(&functions[..10], 0)" --- - > 0xd20: google_breakpad::MinidumpFileWriter::MinidumpFileWriter() (0x1a) 0xd20: minidump_file_writer.cc:93 (/Users/travis/build/getsentry/breakpad-tools/deps/breakpad/src/client) 0xd26: minidump_file_writer.cc:94 (/Users/travis/build/getsentry/breakpad-tools/deps/breakpad/src/client) @@ -163,4 +161,3 @@ expression: "FunctionsDebug(&functions[..10], 0)" > 0x1140: google_breakpad::MinidumpFileWriter::WriteString(wchar_t const*, unsigned int, MDLocationDescriptor*) (0x5) 0x1140: minidump_file_writer.cc:245 (/Users/travis/build/getsentry/breakpad-tools/deps/breakpad/src/client) - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_symbols.snap b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_symbols.snap index fb743ded4..a20b09e98 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_symbols.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__breakpad_symbols.snap @@ -1,8 +1,6 @@ --- -created: "2019-02-20T11:25:23.767168Z" -creator: insta@0.6.3 -source: debuginfo/tests/test_objects.rs -expression: SymbolDebug(&symbols) +source: symbolic-debuginfo/tests/test_objects.rs +expression: SymbolsDebug(&symbols) --- 3726 __CxxFrameHandler3 372c __std_exception_copy @@ -39,4 +37,3 @@ expression: SymbolDebug(&symbols) 37e6 terminate 37ec IsProcessorFeaturePresent 37f2 memcpy - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__elf_files.snap b/symbolic-debuginfo/tests/snapshots/test_objects__elf_files.snap index 34225960f..6b06c6990 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__elf_files.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__elf_files.snap @@ -1,7 +1,5 @@ --- -created: "2019-06-28T08:34:30.750035Z" -creator: insta@0.8.1 -source: debuginfo/tests/test_objects.rs +source: symbolic-debuginfo/tests/test_objects.rs expression: "FilesDebug(&files[..10])" --- /work/linux/main.cpp @@ -14,4 +12,3 @@ expression: "FilesDebug(&files[..10])" /usr/lib/gcc/x86_64-linux-gnu/5/include/stddef.h /usr/include/x86_64-linux-gnu/bits/types.h /usr/include/stdio.h - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__elf_functions.snap b/symbolic-debuginfo/tests/snapshots/test_objects__elf_functions.snap index 6e5c3f7b9..3119318ba 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__elf_functions.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__elf_functions.snap @@ -2,7 +2,6 @@ source: symbolic-debuginfo/tests/test_objects.rs expression: "FunctionsDebug(&functions[..10], 0)" --- - > 0x1ec0: _ZN12_GLOBAL__N_18callbackERKN15google_breakpad18MinidumpDescriptorEPvb (0x3b) 0x1ec0: main.cpp:9 (../linux) 0x1ec2: main.cpp:8 (../linux) @@ -965,4 +964,3 @@ expression: "FunctionsDebug(&functions[..10], 0)" > 0x2dae: InstallDefaultHandler (0xc) 0x2dae: exception_handler.cc:199 (../deps/breakpad/src/client/linux/handler) - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__elf_symbols.snap b/symbolic-debuginfo/tests/snapshots/test_objects__elf_symbols.snap index 2e0c5f3ea..a7bb1d236 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__elf_symbols.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__elf_symbols.snap @@ -1,7 +1,5 @@ --- -created: "2019-02-27T13:05:25.490529Z" -creator: insta@0.6.3 -source: debuginfo/tests/test_objects.rs +source: symbolic-debuginfo/tests/test_objects.rs expression: SymbolsDebug(&symbols) --- 1558 _init @@ -42,7 +40,7 @@ expression: SymbolsDebug(&symbols) 3670 _ZN15google_breakpad16ExceptionHandlerC1ERKNS_18MinidumpDescriptorEPFbPvEPFbS3_S4_bES4_bi 3a10 _ZN15google_breakpad16ExceptionHandler13WriteMinidumpERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFbRKNS_18MinidumpDescriptorEPvbESC_ 3cb0 _ZNSt6vectorIPN15google_breakpad16ExceptionHandlerESaIS2_EE19_M_emplace_back_auxIIS2_EEEvDpOT_ - 3da0 _ZN15google_breakpad18MinidumpDescriptorC1ERKS0_ + 3da0 _ZN15google_breakpad18MinidumpDescriptorC2ERKS0_ 3f20 _ZN15google_breakpad18MinidumpDescriptor10UpdatePathEv 42f0 _ZN15google_breakpad18MinidumpDescriptoraSERKS0_ 43c0 _ZN6logger5writeEPKcm @@ -50,7 +48,7 @@ expression: SymbolsDebug(&symbols) 6e10 _ZNSt6vectorIhN15google_breakpad16PageStdAllocatorIhEEE15_M_range_insertIPKhEEvN9__gnu_cxx17__normal_iteratorIPhS3_EET_SB_St20forward_iterator_tag 71f0 _ZN15google_breakpad11LinuxDumper8LateInitEv 7200 _ZN15google_breakpad11LinuxDumper17EnumerateMappingsEv - 7ac0 _ZN15google_breakpad11LinuxDumperC1EiPKc + 7ac0 _ZN15google_breakpad11LinuxDumperC2EiPKc 8300 _ZN15google_breakpad11LinuxDumperD2Ev 8370 _ZN15google_breakpad11LinuxDumperD0Ev 8390 _ZNK15google_breakpad11LinuxDumper20GetCrashSignalStringEv @@ -71,14 +69,14 @@ expression: SymbolsDebug(&symbols) 94a0 _ZNK15google_breakpad17LinuxPtraceDumper12IsPostMortemEv 94b0 _ZN15google_breakpad17LinuxPtraceDumper15CopyFromProcessEPviPKvm 9640 _ZN15google_breakpad17LinuxPtraceDumper13ThreadsResumeEv - 9700 _ZNK15google_breakpad17LinuxPtraceDumper13BuildProcPathEPciPKc + 9700 _ZNK15google_breakpad17LinuxPtraceDumper13BuildProcPathEPciPKc.localalias.19 97c0 _ZN15google_breakpad17LinuxPtraceDumper16EnumerateThreadsEv 9e50 _ZN15google_breakpad17LinuxPtraceDumperC1Ei 9e80 _ZN15google_breakpad17LinuxPtraceDumper15ReadRegisterSetEPNS_10ThreadInfoEi 9f70 _ZN15google_breakpad17LinuxPtraceDumper13ReadRegistersEPNS_10ThreadInfoEi a050 _ZN15google_breakpad17LinuxPtraceDumper20GetThreadInfoByIndexEmPNS_10ThreadInfoE a690 _ZN15google_breakpad17LinuxPtraceDumper14ThreadsSuspendEv - a8f0 _ZN15google_breakpad17LinuxPtraceDumperD1Ev + a8f0 _ZN15google_breakpad17LinuxPtraceDumperD2Ev a910 _ZN15google_breakpad17LinuxPtraceDumperD0Ev a930 _ZNSt6vectorIiN15google_breakpad16PageStdAllocatorIiEEE17_M_default_appendEm abc0 _ZN12_GLOBAL__N_114MinidumpWriter21WriteThreadListStreamEP14MDRawDirectory.constprop.105 @@ -120,7 +118,7 @@ expression: SymbolsDebug(&symbols) 11220 _ZN15google_breakpad8ElfClassEPKv 11230 _ZN15google_breakpad14FindElfSectionEPKvPKcjPS1_Pm 116a0 _ZN15google_breakpad15FindElfSegmentsEPKvjPNS_15wasteful_vectorINS_10ElfSegmentEEE - 11990 _ZNSt6vectorIN15google_breakpad10ElfSegmentENS0_16PageStdAllocatorIS1_EEE19_M_emplace_back_auxIIRKS1_EEEvDpOT_ + 11990 _ZNSt6vectorIN15google_breakpad10ElfSegmentENS0_16PageStdAllocatorIS1_EEE19_M_emplace_back_auxIJRKS1_EEEvDpOT_ 11be0 _ZN15google_breakpad6FileIDC2EPKc 11cc0 _ZN15google_breakpad6FileID29ConvertIdentifierToUUIDStringB5cxx11ERKNS_15wasteful_vectorIhEE 11e70 _ZN15google_breakpad6FileID25ConvertIdentifierToStringB5cxx11ERKNS_15wasteful_vectorIhEE @@ -146,11 +144,11 @@ expression: SymbolsDebug(&symbols) 13160 my_isspace 13210 _ZN15google_breakpad16MemoryMappedFileC2Ev 13220 _ZN15google_breakpad16MemoryMappedFile5UnmapEv - 13270 _ZN15google_breakpad16MemoryMappedFileD2Ev + 13270 _ZN15google_breakpad16MemoryMappedFileD1Ev 13280 _ZN15google_breakpad16MemoryMappedFile3MapEPKcm - 13430 _ZN15google_breakpad16MemoryMappedFileC1EPKcm + 13430 _ZN15google_breakpad16MemoryMappedFileC2EPKcm 13450 _ZN15google_breakpad12SafeReadLinkEPKcPcm - 13490 _ZN15google_breakpad12_GLOBAL__N_125CrashGenerationClientImplD1Ev + 13490 _ZN15google_breakpad12_GLOBAL__N_125CrashGenerationClientImplD2Ev 134a0 _ZN15google_breakpad12_GLOBAL__N_125CrashGenerationClientImpl11RequestDumpEPKvm 136c0 _ZN15google_breakpad12_GLOBAL__N_125CrashGenerationClientImplD0Ev 136d0 _ZN15google_breakpad21CrashGenerationClient9TryCreateEi @@ -171,4 +169,3 @@ expression: SymbolsDebug(&symbols) 14c30 __libc_csu_init 14ca0 __libc_csu_fini 14ca4 _fini - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__mach_files.snap b/symbolic-debuginfo/tests/snapshots/test_objects__mach_files.snap index a3e6c277c..5b221a9fa 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__mach_files.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__mach_files.snap @@ -1,7 +1,5 @@ --- -created: "2019-06-28T08:34:30.763613Z" -creator: insta@0.8.1 -source: debuginfo/tests/test_objects.rs +source: symbolic-debuginfo/tests/test_objects.rs expression: "FilesDebug(&files[..10])" --- /Users/travis/build/getsentry/breakpad-tools/deps/breakpad/src/client/minidump_file_writer.h @@ -14,4 +12,3 @@ expression: "FilesDebug(&files[..10])" /usr/include/_types/_uint16_t.h /usr/include/sys/_types.h /usr/include/sys/_types/_off_t.h - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__mach_functions.snap b/symbolic-debuginfo/tests/snapshots/test_objects__mach_functions.snap index f490e606f..e88834f17 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__mach_functions.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__mach_functions.snap @@ -1,9 +1,7 @@ --- source: symbolic-debuginfo/tests/test_objects.rs -assertion_line: 396 expression: "FunctionsDebug(&functions[..10], 0)" --- - > 0xd20: _ZN15google_breakpad18MinidumpFileWriterC2Ev (0x1a) 0xd20: minidump_file_writer.cc:93 (../deps/breakpad/src/client) 0xd26: minidump_file_writer.cc:94 (../deps/breakpad/src/client) @@ -188,4 +186,3 @@ expression: "FunctionsDebug(&functions[..10], 0)" > 0x1140: _ZN15google_breakpad18MinidumpFileWriter11WriteStringEPKwjP20MDLocationDescriptor (0x5) 0x1140: minidump_file_writer.cc:245 (../deps/breakpad/src/client) - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__mach_symbols.snap b/symbolic-debuginfo/tests/snapshots/test_objects__mach_symbols.snap index d345cc0eb..e4b8b2b0f 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__mach_symbols.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__mach_symbols.snap @@ -1,8 +1,6 @@ --- -created: "2019-02-20T12:28:37.426989Z" -creator: insta@0.6.3 -source: debuginfo/tests/test_objects.rs -expression: SymbolDebug(&symbols) +source: symbolic-debuginfo/tests/test_objects.rs +expression: SymbolsDebug(&symbols) --- 0 _mh_execute_header d20 _ZN15google_breakpad18MinidumpFileWriterC2Ev @@ -199,4 +197,3 @@ expression: SymbolDebug(&symbols) db50 _ZN15google_breakpad14MachPortSender11SendMessageERNS_15MachSendMessageEj dba0 main dc70 _ZN12_GLOBAL__N_18callbackEPKcS1_Pvb - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__pdb_files.snap b/symbolic-debuginfo/tests/snapshots/test_objects__pdb_files.snap index 7a28c92be..44a7eb330 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__pdb_files.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__pdb_files.snap @@ -1,7 +1,5 @@ --- -created: "2019-06-28T08:20:37.446264Z" -creator: insta@0.8.1 -source: debuginfo/tests/test_objects.rs +source: symbolic-debuginfo/tests/test_objects.rs expression: "FilesDebug(&files[..10])" --- c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\system_error @@ -14,4 +12,3 @@ c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.1 c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xstring c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\cstdlib c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xmemory0 - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__pdb_functions.snap b/symbolic-debuginfo/tests/snapshots/test_objects__pdb_functions.snap index b9322d65f..3b3bc651c 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__pdb_functions.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__pdb_functions.snap @@ -1,9 +1,7 @@ --- source: symbolic-debuginfo/tests/test_objects.rs -assertion_line: 524 expression: "FunctionsDebug(&functions[..10], 0)" --- - > 0x1120: std::basic_string,std::allocator >::~basic_string,std::allocator >() (0x54) 0x1120: xstring:2424 (c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include) 0x1123: xstring:2425 (c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include) @@ -469,4 +467,3 @@ expression: "FunctionsDebug(&functions[..10], 0)" > 0x2690: google_breakpad::scoped_ptr::~scoped_ptr() (0xd) 0x2690: scoped_ptr.h:98 (c:\projects\breakpad-tools\deps\breakpad\src\common) 0x269c: scoped_ptr.h:99 (c:\projects\breakpad-tools\deps\breakpad\src\common) - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__pdb_symbols.snap b/symbolic-debuginfo/tests/snapshots/test_objects__pdb_symbols.snap index d5e9f6495..03a3a0704 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__pdb_symbols.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__pdb_symbols.snap @@ -48,7 +48,7 @@ expression: SymbolsDebug(&symbols) 2e72 ??0bad_array_new_length@std@@QAE@XZ 2e8a ??0exception@std@@QAE@ABV01@@Z 2eb6 ??1bad_alloc@std@@UAE@XZ - 2ec7 ??_Eexception@std@@UAEPAXI@Z + 2ec7 ??_Gexception@std@@UAEPAXI@Z 2ef4 ?__scrt_throw_std_bad_alloc@@YAXXZ 2f11 ?__scrt_throw_std_bad_array_new_length@@YAXXZ 2f2e ?what@exception@std@@UBEPBDXZ @@ -61,11 +61,11 @@ expression: SymbolsDebug(&symbols) 3166 __onexit 31a1 _atexit 3205 ___security_init_cookie - 3250 __matherr + 3250 __get_startup_commit_mode 3253 __get_startup_argv_mode 3257 __get_startup_file_mode 325d ?__scrt_initialize_type_info@@YAXXZ - 3269 ___vcrt_uninitialize + 3269 __should_initialize_environment 326c __initialize_default_precision 328d @_guard_check_icall_nop@4 328e ___local_stdio_scanf_options @@ -122,4 +122,3 @@ expression: SymbolsDebug(&symbols) 37e6 _terminate 37ec _IsProcessorFeaturePresent@4 37f2 _memcpy - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_files.snap b/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_files.snap index 1fc613ad4..52a8d9f6d 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_files.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_files.snap @@ -12,4 +12,3 @@ expression: "FilesDebug(&files[..10])" /mxe/usr/x86_64-w64-mingw32.static/include/stdlib.h /mxe/usr/x86_64-w64-mingw32.static/include/errhandlingapi.h /mxe/usr/x86_64-w64-mingw32.static/include/processthreadsapi.h - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_functions.snap b/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_functions.snap index 1ae2b97d5..35d31fe47 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_functions.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__pe_dwarf_functions.snap @@ -2,7 +2,6 @@ source: symbolic-debuginfo/tests/test_objects.rs expression: "FunctionsDebug(&functions[..10], 0)" --- - > 0x14f0: atexit (0x14) 0x14f0: crtexe.c:418 (/mxe/tmp-gcc-x86_64-w64-mingw32.static/gcc-11.3.0.build_/mingw-w64-v10.0.0/mingw-w64-crt/crt) 0x14f4: crtexe.c:419 (/mxe/tmp-gcc-x86_64-w64-mingw32.static/gcc-11.3.0.build_/mingw-w64-v10.0.0/mingw-w64-crt/crt) @@ -220,4 +219,3 @@ expression: "FunctionsDebug(&functions[..10], 0)" 0x165a: gccmain.c:60 (/mxe/tmp-gcc-x86_64-w64-mingw32.static/gcc-11.3.0.build_/mingw-w64-v10.0.0/mingw-w64-crt/crt) 0x1660: gccmain.c:57 (/mxe/tmp-gcc-x86_64-w64-mingw32.static/gcc-11.3.0.build_/mingw-w64-v10.0.0/mingw-w64-crt/crt) 0x166a: gccmain.c:58 (/mxe/tmp-gcc-x86_64-w64-mingw32.static/gcc-11.3.0.build_/mingw-w64-v10.0.0/mingw-w64-crt/crt) - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__ppdb_files.snap b/symbolic-debuginfo/tests/snapshots/test_objects__ppdb_files.snap index c5e27ef8c..fa4abdf02 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__ppdb_files.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__ppdb_files.snap @@ -1,10 +1,8 @@ --- source: symbolic-debuginfo/tests/test_objects.rs -assertion_line: 656 expression: FilesDebug(&files) --- /Users/swatinem/Coding/sentry-dotnet/samples/foo/Program.cs /Users/swatinem/Coding/sentry-dotnet/samples/foo/obj/Debug/net6.0/foo.GlobalUsings.g.cs /Users/swatinem/Coding/sentry-dotnet/samples/foo/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs /Users/swatinem/Coding/sentry-dotnet/samples/foo/obj/Debug/net6.0/foo.AssemblyInfo.cs - diff --git a/symbolic-debuginfo/tests/snapshots/test_objects__wasm_symbols.snap b/symbolic-debuginfo/tests/snapshots/test_objects__wasm_symbols.snap index 3208bb17a..580378ecf 100644 --- a/symbolic-debuginfo/tests/snapshots/test_objects__wasm_symbols.snap +++ b/symbolic-debuginfo/tests/snapshots/test_objects__wasm_symbols.snap @@ -1,7 +1,5 @@ --- source: symbolic-debuginfo/tests/test_objects.rs expression: SymbolsDebug(&symbols) - --- 8b internal_func - diff --git a/symbolic-debuginfo/tests/test_objects.rs b/symbolic-debuginfo/tests/test_objects.rs index 6372f0a18..861b4e871 100644 --- a/symbolic-debuginfo/tests/test_objects.rs +++ b/symbolic-debuginfo/tests/test_objects.rs @@ -128,23 +128,23 @@ fn test_breakpad() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮Breakpad( - ⋮ BreakpadObject { - ⋮ code_id: Some( - ⋮ CodeId(5ab380779000), - ⋮ ), - ⋮ debug_id: DebugId { - ⋮ uuid: "3249d99d-0c40-4931-8610-f4e4fb0b6936", - ⋮ appendix: 1, - ⋮ }, - ⋮ arch: X86, - ⋮ name: "crash.pdb", - ⋮ has_symbols: true, - ⋮ has_debug_info: true, - ⋮ has_unwind_info: true, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + Breakpad( + BreakpadObject { + code_id: Some( + CodeId(5ab380779000), + ), + debug_id: DebugId { + uuid: "3249d99d-0c40-4931-8610-f4e4fb0b6936", + appendix: 1, + }, + arch: X86, + name: "crash.pdb", + has_symbols: true, + has_debug_info: true, + has_unwind_info: true, + is_malformed: false, + }, + ) "#); Ok(()) @@ -209,24 +209,24 @@ fn test_elf_executable() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮Elf( - ⋮ ElfObject { - ⋮ code_id: Some( - ⋮ CodeId(f1c3bcc0279865fe3058404b2831d9e64135386c), - ⋮ ), - ⋮ debug_id: DebugId { - ⋮ uuid: "c0bcc3f1-9827-fe65-3058-404b2831d9e6", - ⋮ appendix: 0, - ⋮ }, - ⋮ arch: Amd64, - ⋮ kind: Executable, - ⋮ load_address: 0x400000, - ⋮ has_symbols: true, - ⋮ has_debug_info: false, - ⋮ has_unwind_info: true, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + Elf( + ElfObject { + code_id: Some( + CodeId(f1c3bcc0279865fe3058404b2831d9e64135386c), + ), + debug_id: DebugId { + uuid: "c0bcc3f1-9827-fe65-3058-404b2831d9e6", + appendix: 0, + }, + arch: Amd64, + kind: Executable, + load_address: 0x400000, + has_symbols: true, + has_debug_info: false, + has_unwind_info: true, + is_malformed: false, + }, + ) "#); Ok(()) @@ -238,24 +238,53 @@ fn test_elf_debug() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮Elf( - ⋮ ElfObject { - ⋮ code_id: Some( - ⋮ CodeId(f1c3bcc0279865fe3058404b2831d9e64135386c), - ⋮ ), - ⋮ debug_id: DebugId { - ⋮ uuid: "c0bcc3f1-9827-fe65-3058-404b2831d9e6", - ⋮ appendix: 0, - ⋮ }, - ⋮ arch: Amd64, - ⋮ kind: Debug, - ⋮ load_address: 0x400000, - ⋮ has_symbols: true, - ⋮ has_debug_info: true, - ⋮ has_unwind_info: false, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + Elf( + ElfObject { + code_id: Some( + CodeId(f1c3bcc0279865fe3058404b2831d9e64135386c), + ), + debug_id: DebugId { + uuid: "c0bcc3f1-9827-fe65-3058-404b2831d9e6", + appendix: 0, + }, + arch: Amd64, + kind: Debug, + load_address: 0x400000, + has_symbols: true, + has_debug_info: true, + has_unwind_info: false, + is_malformed: false, + }, + ) + "#); + + Ok(()) +} + +#[test] +fn test_elf_dynsyms() -> Result<(), Error> { + let view = ByteView::open(fixture("linux/dynsyms_only"))?; + let object = Object::parse(&view)?; + + insta::assert_debug_snapshot!(object, @r#" + Elf( + ElfObject { + code_id: Some( + CodeId(b931c4fbd186e551bb617b3807d594b9064f5cac), + ), + debug_id: DebugId { + uuid: "fbc431b9-86d1-51e5-bb61-7b3807d594b9", + appendix: 0, + }, + arch: Amd64, + kind: Debug, + load_address: 0x0, + has_symbols: true, + has_debug_info: false, + has_unwind_info: false, + is_malformed: false, + }, + ) "#); Ok(()) @@ -269,6 +298,19 @@ fn test_elf_symbols() -> Result<(), Error> { let symbols = object.symbol_map(); insta::assert_debug_snapshot!("elf_symbols", SymbolsDebug(&symbols)); + let view = ByteView::open(fixture("linux/dynsyms_only"))?; + let object = Object::parse(&view)?; + + let symbols = object.symbol_map(); + insta::assert_debug_snapshot!(SymbolsDebug(&symbols), @r" + 690 __vdso_gettimeofday + 9e0 __vdso_time + a10 clock_gettime + e30 clock_getres + e90 __vdso_getcpu + ec0 __vdso_sgx_enter_enclave + "); + Ok(()) } @@ -388,24 +430,24 @@ fn test_mach_executable() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮MachO( - ⋮ MachObject { - ⋮ code_id: Some( - ⋮ CodeId(67e9247c814e392ba027dbde6748fcbf), - ⋮ ), - ⋮ debug_id: DebugId { - ⋮ uuid: "67e9247c-814e-392b-a027-dbde6748fcbf", - ⋮ appendix: 0, - ⋮ }, - ⋮ arch: Amd64, - ⋮ kind: Executable, - ⋮ load_address: 0x100000000, - ⋮ has_symbols: true, - ⋮ has_debug_info: false, - ⋮ has_unwind_info: true, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + MachO( + MachObject { + code_id: Some( + CodeId(67e9247c814e392ba027dbde6748fcbf), + ), + debug_id: DebugId { + uuid: "67e9247c-814e-392b-a027-dbde6748fcbf", + appendix: 0, + }, + arch: Amd64, + kind: Executable, + load_address: 0x100000000, + has_symbols: true, + has_debug_info: false, + has_unwind_info: true, + is_malformed: false, + }, + ) "#); Ok(()) @@ -417,24 +459,24 @@ fn test_mach_dsym() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮MachO( - ⋮ MachObject { - ⋮ code_id: Some( - ⋮ CodeId(67e9247c814e392ba027dbde6748fcbf), - ⋮ ), - ⋮ debug_id: DebugId { - ⋮ uuid: "67e9247c-814e-392b-a027-dbde6748fcbf", - ⋮ appendix: 0, - ⋮ }, - ⋮ arch: Amd64, - ⋮ kind: Debug, - ⋮ load_address: 0x100000000, - ⋮ has_symbols: true, - ⋮ has_debug_info: true, - ⋮ has_unwind_info: false, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + MachO( + MachObject { + code_id: Some( + CodeId(67e9247c814e392ba027dbde6748fcbf), + ), + debug_id: DebugId { + uuid: "67e9247c-814e-392b-a027-dbde6748fcbf", + appendix: 0, + }, + arch: Amd64, + kind: Debug, + load_address: 0x100000000, + has_symbols: true, + has_debug_info: true, + has_unwind_info: false, + is_malformed: false, + }, + ) "#); Ok(()) @@ -483,27 +525,27 @@ fn test_pe_32() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮Pe( - ⋮ PeObject { - ⋮ code_id: Some( - ⋮ CodeId(5ab380779000), - ⋮ ), - ⋮ debug_id: DebugId { - ⋮ uuid: "3249d99d-0c40-4931-8610-f4e4fb0b6936", - ⋮ appendix: 1, - ⋮ }, - ⋮ debug_file_name: Some( - ⋮ "C:\\projects\\breakpad-tools\\windows\\Release\\crash.pdb", - ⋮ ), - ⋮ arch: X86, - ⋮ kind: Executable, - ⋮ load_address: 0x400000, - ⋮ has_symbols: false, - ⋮ has_debug_info: false, - ⋮ has_unwind_info: false, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + Pe( + PeObject { + code_id: Some( + CodeId(5ab380779000), + ), + debug_id: DebugId { + uuid: "3249d99d-0c40-4931-8610-f4e4fb0b6936", + appendix: 1, + }, + debug_file_name: Some( + "C:\\projects\\breakpad-tools\\windows\\Release\\crash.pdb", + ), + arch: X86, + kind: Executable, + load_address: 0x400000, + has_symbols: false, + has_debug_info: false, + has_unwind_info: false, + is_malformed: false, + }, + ) "#); Ok(()) @@ -515,27 +557,27 @@ fn test_pe_64() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮Pe( - ⋮ PeObject { - ⋮ code_id: Some( - ⋮ CodeId(5c9e09599000), - ⋮ ), - ⋮ debug_id: DebugId { - ⋮ uuid: "f535c5fb-2ae8-4bb8-aa20-6c30be566c5a", - ⋮ appendix: 1, - ⋮ }, - ⋮ debug_file_name: Some( - ⋮ "C:\\Users\\sentry\\source\\repos\\CrashWithException\\x64\\Release\\CrashWithException.pdb", - ⋮ ), - ⋮ arch: Amd64, - ⋮ kind: Executable, - ⋮ load_address: 0x140000000, - ⋮ has_symbols: false, - ⋮ has_debug_info: false, - ⋮ has_unwind_info: true, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + Pe( + PeObject { + code_id: Some( + CodeId(5c9e09599000), + ), + debug_id: DebugId { + uuid: "f535c5fb-2ae8-4bb8-aa20-6c30be566c5a", + appendix: 1, + }, + debug_file_name: Some( + "C:\\Users\\sentry\\source\\repos\\CrashWithException\\x64\\Release\\CrashWithException.pdb", + ), + arch: Amd64, + kind: Executable, + load_address: 0x140000000, + has_symbols: false, + has_debug_info: false, + has_unwind_info: true, + is_malformed: false, + }, + ) "#); Ok(()) @@ -613,20 +655,20 @@ fn test_pdb() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮Pdb( - ⋮ PdbObject { - ⋮ debug_id: DebugId { - ⋮ uuid: "3249d99d-0c40-4931-8610-f4e4fb0b6936", - ⋮ appendix: 1, - ⋮ }, - ⋮ arch: X86, - ⋮ load_address: 0x0, - ⋮ has_symbols: true, - ⋮ has_debug_info: true, - ⋮ has_unwind_info: true, - ⋮ is_malformed: false, - ⋮ }, - ⋮) + Pdb( + PdbObject { + debug_id: DebugId { + uuid: "3249d99d-0c40-4931-8610-f4e4fb0b6936", + appendix: 1, + }, + arch: X86, + load_address: 0x0, + has_symbols: true, + has_debug_info: true, + has_unwind_info: true, + is_malformed: false, + }, + ) "#); Ok(()) @@ -701,29 +743,29 @@ fn test_ppdb() -> Result<(), Error> { let object = Object::parse(&view)?; insta::assert_debug_snapshot!(object, @r#" - ⋮PortablePdb( - ⋮ PortablePdbObject { - ⋮ portable_pdb: PortablePdb { - ⋮ header: Header { - ⋮ signature: 1112167234, - ⋮ major_version: 1, - ⋮ minor_version: 1, - ⋮ version_length: 12, - ⋮ }, - ⋮ version_string: "PDB v1.0", - ⋮ header2: HeaderPart2 { - ⋮ flags: 0, - ⋮ streams: 6, - ⋮ }, - ⋮ has_pdb_stream: true, - ⋮ has_table_stream: true, - ⋮ has_string_stream: true, - ⋮ has_us_stream: true, - ⋮ has_blob_stream: true, - ⋮ has_guid_stream: true, - ⋮ }, - ⋮ }, - ⋮) + PortablePdb( + PortablePdbObject { + portable_pdb: PortablePdb { + header: Header { + signature: 1112167234, + major_version: 1, + minor_version: 1, + version_length: 12, + }, + version_string: "PDB v1.0", + header2: HeaderPart2 { + flags: 0, + streams: 6, + }, + has_pdb_stream: true, + has_table_stream: true, + has_string_stream: true, + has_us_stream: true, + has_blob_stream: true, + has_guid_stream: true, + }, + }, + ) "#); Ok(()) diff --git a/symbolic-debuginfo/tests/test_pdb_srcsrv.rs b/symbolic-debuginfo/tests/test_pdb_srcsrv.rs new file mode 100644 index 000000000..a5aae549b --- /dev/null +++ b/symbolic-debuginfo/tests/test_pdb_srcsrv.rs @@ -0,0 +1,29 @@ +use symbolic_common::ByteView; +use symbolic_debuginfo::pdb::PdbObject; +use symbolic_testutils::fixture; + +type Error = Box; + +#[test] +fn test_pdb_srcsrv_vcs_name() -> Result<(), Error> { + let view = ByteView::open(fixture("windows/crash_with_srcsrv.pdb"))?; + let pdb = PdbObject::parse(&view)?; + + // This PDB file contains Perforce SRCSRV information + let vcs_name = pdb.srcsrv_vcs_name(); + assert_eq!(vcs_name, Some("Perforce".to_string())); + + Ok(()) +} + +#[test] +fn test_pdb_without_srcsrv() -> Result<(), Error> { + let view = ByteView::open(fixture("windows/crash.pdb"))?; + let pdb = PdbObject::parse(&view)?; + + // This PDB file does not contain SRCSRV information + let vcs_name = pdb.srcsrv_vcs_name(); + assert_eq!(vcs_name, None); + + Ok(()) +} diff --git a/symbolic-demangle/Cargo.toml b/symbolic-demangle/Cargo.toml index 8f8bc44c1..50be35d54 100644 --- a/symbolic-demangle/Cargo.toml +++ b/symbolic-demangle/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "symbolic-demangle" -version = "12.9.2-dd" +version = "12.17.0-dd" license = "MIT" authors = [ "Armin Ronacher ", @@ -14,7 +14,8 @@ description = """ A library to demangle symbols from various languages and compilers. """ build = "build.rs" -edition = "2021" +edition.workspace = true +rust-version.workspace = true exclude = ["tests/**/*"] @@ -32,7 +33,7 @@ swift = ["cc"] cpp_demangle = { workspace = true, optional = true } msvc-demangler = { workspace = true, optional = true } rustc-demangle = { workspace = true, optional = true } -symbolic-common = { version = "12.9.2-dd", path = "../symbolic-common" } +symbolic-common = { version = "12.17.0-dd", path = "../symbolic-common" } [build-dependencies] cc = { workspace = true, optional = true } diff --git a/symbolic-demangle/build.rs b/symbolic-demangle/build.rs index 4ce782eb0..1ec58b0a7 100644 --- a/symbolic-demangle/build.rs +++ b/symbolic-demangle/build.rs @@ -3,20 +3,25 @@ fn main() { { cc::Build::new() .cpp(true) + .std("c++17") .files(&[ "src/swiftdemangle.cpp", - "vendor/swift/lib/Demangling/Demangler.cpp", "vendor/swift/lib/Demangling/Context.cpp", + "vendor/swift/lib/Demangling/CrashReporter.cpp", + "vendor/swift/lib/Demangling/Demangler.cpp", + "vendor/swift/lib/Demangling/Errors.cpp", "vendor/swift/lib/Demangling/ManglingUtils.cpp", "vendor/swift/lib/Demangling/NodeDumper.cpp", "vendor/swift/lib/Demangling/NodePrinter.cpp", - "vendor/swift/lib/Demangling/OldDemangler.cpp", + // "vendor/swift/lib/Demangling/OldDemangler.cpp", // "vendor/swift/lib/Demangling/OldRemangler.cpp", "vendor/swift/lib/Demangling/Punycode.cpp", "vendor/swift/lib/Demangling/Remangler.cpp", ]) - .flag_if_supported("-std=c++14") + .flag_if_supported("-fpermissive") + .flag_if_supported("-Wno-changes-meaning") .flag("-DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1") + .flag("-DSWIFT_STDLIB_HAS_TYPE_PRINTING=1") .warnings(false) .include("vendor/swift/include") .compile("swiftdemangle"); diff --git a/symbolic-demangle/src/lib.rs b/symbolic-demangle/src/lib.rs index b6a3ec031..acc9c3cb1 100644 --- a/symbolic-demangle/src/lib.rs +++ b/symbolic-demangle/src/lib.rs @@ -416,7 +416,7 @@ pub trait Demangle { fn try_demangle(&self, opts: DemangleOptions) -> Cow<'_, str>; } -impl<'a> Demangle for Name<'a> { +impl Demangle for Name<'_> { fn detect_language(&self) -> Language { if self.language() != Language::Unknown { return self.language(); diff --git a/symbolic-demangle/tests/test_swift.rs b/symbolic-demangle/tests/test_swift.rs index 72e1b8e70..d3994accc 100644 --- a/symbolic-demangle/tests/test_swift.rs +++ b/symbolic-demangle/tests/test_swift.rs @@ -147,6 +147,9 @@ fn test_demangle_swift_short() { // Swift 5.2 "$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlFyAaC_pcAaC_pcfu_" => "implicit closure #1 (P) in propertyVersusFunction(P, A)", + + // Causes an abort with the Swift 6.0.3 demangler. + "$sTB" => "$sTB", }); } @@ -290,6 +293,10 @@ fn test_demangle_swift_no_args() { "$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlFyAaC_pcAaC_pcfu_" => "implicit closure #1 in propertyVersusFunction", // Swift 5.5.1 - "$s10Speediness17NetworkQualityCLIO3run10sequentialAC6ResultVSb_tYaKFZTf4nd_nTQ0_" => "(1) await resume partial function for specialized static NetworkQualityCLI.run", + "$s10Speediness17NetworkQualityCLIO3run10sequentialAC6ResultVSb_tYaKFZTf4nd_nTQ0_" => "specialized static NetworkQualityCLI.run", + + // Swift 6.0.3 + "$ss27withTaskCancellationHandler9operation8onCancel9isolationxxyYaKXE_yyYbXEScA_pSgYitYaKlFTwb" => "withTaskCancellationHandler", + "$s11Supercharge2AXO7ElementPAAE8elements33_35EDDAA799FBB5B74D2F426690B0D99DLL3for2asSayqd__GSo28NSAccessibilityAttributeNamea_qd__mtSo7AXErrorVYKAcDRd__lFAC3AppC_AC6WindowCTgm5" => "specialized AX.Element.elements", }); } diff --git a/symbolic-demangle/vendor/swift/1-arguments.patch b/symbolic-demangle/vendor/swift/1-arguments.patch index 8feb835bb..5209fc4c2 100644 --- a/symbolic-demangle/vendor/swift/1-arguments.patch +++ b/symbolic-demangle/vendor/swift/1-arguments.patch @@ -1,14 +1,14 @@ -commit 43fca7dd2617ac93f338b5257a2e57c43dcb8154 -Author: Sebastian Zivota -Date: Thu Dec 2 16:15:35 2021 +0100 +commit 80e772078494a73f2fbb5e385de2092e6057d913 +Author: David Herberth +Date: Thu Jan 9 10:54:28 2025 +0100 - Apply patch + apply patch diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h -index db32dbd..f48e1c2 100644 +index f66dd7fd..940c3652 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h -@@ -59,6 +59,7 @@ struct DemangleOptions { +@@ -58,6 +58,7 @@ struct DemangleOptions { bool ShortenArchetype = false; bool ShowPrivateDiscriminators = true; bool ShowFunctionArgumentTypes = true; @@ -21,21 +21,21 @@ index db32dbd..f48e1c2 100644 Opt.ShowPrivateDiscriminators = false; Opt.ShowFunctionArgumentTypes = false; + Opt.ShowFunctionReturnType = false; + Opt.ShowAsyncResumePartial = false; return Opt; }; - }; diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp -index 2a9c0dc..34fa785 100644 +index 6c309bbf..5b251e8d 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp +++ b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp -@@ -863,10 +863,11 @@ private: +@@ -955,10 +955,11 @@ private: if (isSendable) Printer << "@Sendable "; -- printFunctionParameters(LabelList, node->getChild(startIndex), +- printFunctionParameters(LabelList, node->getChild(argIndex), depth, - Options.ShowFunctionArgumentTypes); + if (Options.ShowFunctionArgumentTypes) { -+ printFunctionParameters(LabelList, node->getChild(startIndex), true); ++ printFunctionParameters(LabelList, node->getChild(argIndex), depth, true); + } - if (!Options.ShowFunctionArgumentTypes) @@ -43,3 +43,14 @@ index 2a9c0dc..34fa785 100644 return; if (isAsync) +diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp +index 6c309bbf..5b251e8d 100644 +--- a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp ++++ b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp +@@ -3423,7 +3423,6 @@ NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) { + + int PassID = (int)nextChar() - '0'; + if (PassID < 0 || PassID >= MAX_SPECIALIZATION_PASS) { +- assert(false && "unexpected pass id"); + return nullptr; + } diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/ADL.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/ADL.h new file mode 100644 index 000000000..812d9a4b5 --- /dev/null +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/ADL.h @@ -0,0 +1,135 @@ +//===- llvm/ADT/ADL.h - Argument dependent lookup utilities -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_ADL_H +#define LLVM_ADT_ADL_H + +#include +#include +#include + +namespace llvm { + +// Only used by compiler if both template types are the same. Useful when +// using SFINAE to test for the existence of member functions. +template struct SameType; + +namespace adl_detail { + +using std::begin; + +template +constexpr auto begin_impl(RangeT &&range) + -> decltype(begin(std::forward(range))) { + return begin(std::forward(range)); +} + +using std::end; + +template +constexpr auto end_impl(RangeT &&range) + -> decltype(end(std::forward(range))) { + return end(std::forward(range)); +} + +using std::rbegin; + +template +constexpr auto rbegin_impl(RangeT &&range) + -> decltype(rbegin(std::forward(range))) { + return rbegin(std::forward(range)); +} + +using std::rend; + +template +constexpr auto rend_impl(RangeT &&range) + -> decltype(rend(std::forward(range))) { + return rend(std::forward(range)); +} + +using std::swap; + +template +constexpr void swap_impl(T &&lhs, + T &&rhs) noexcept(noexcept(swap(std::declval(), + std::declval()))) { + swap(std::forward(lhs), std::forward(rhs)); +} + +using std::size; + +template +constexpr auto size_impl(RangeT &&range) + -> decltype(size(std::forward(range))) { + return size(std::forward(range)); +} + +} // end namespace adl_detail + +/// Returns the begin iterator to \p range using `std::begin` and +/// function found through Argument-Dependent Lookup (ADL). +template +constexpr auto adl_begin(RangeT &&range) + -> decltype(adl_detail::begin_impl(std::forward(range))) { + return adl_detail::begin_impl(std::forward(range)); +} + +/// Returns the end iterator to \p range using `std::end` and +/// functions found through Argument-Dependent Lookup (ADL). +template +constexpr auto adl_end(RangeT &&range) + -> decltype(adl_detail::end_impl(std::forward(range))) { + return adl_detail::end_impl(std::forward(range)); +} + +/// Returns the reverse-begin iterator to \p range using `std::rbegin` and +/// function found through Argument-Dependent Lookup (ADL). +template +constexpr auto adl_rbegin(RangeT &&range) + -> decltype(adl_detail::rbegin_impl(std::forward(range))) { + return adl_detail::rbegin_impl(std::forward(range)); +} + +/// Returns the reverse-end iterator to \p range using `std::rend` and +/// functions found through Argument-Dependent Lookup (ADL). +template +constexpr auto adl_rend(RangeT &&range) + -> decltype(adl_detail::rend_impl(std::forward(range))) { + return adl_detail::rend_impl(std::forward(range)); +} + +/// Swaps \p lhs with \p rhs using `std::swap` and functions found through +/// Argument-Dependent Lookup (ADL). +template +constexpr void adl_swap(T &&lhs, T &&rhs) noexcept( + noexcept(adl_detail::swap_impl(std::declval(), std::declval()))) { + adl_detail::swap_impl(std::forward(lhs), std::forward(rhs)); +} + +/// Returns the size of \p range using `std::size` and functions found through +/// Argument-Dependent Lookup (ADL). +template +constexpr auto adl_size(RangeT &&range) + -> decltype(adl_detail::size_impl(std::forward(range))) { + return adl_detail::size_impl(std::forward(range)); +} + +namespace detail { + +template +using IterOfRange = decltype(adl_begin(std::declval())); + +template +using ValueOfRange = + std::remove_reference_t()))>; + +} // namespace detail +} // namespace llvm + +#endif // LLVM_ADT_ADL_H diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/DenseMapInfo.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/DenseMapInfo.h new file mode 100644 index 000000000..07c37e353 --- /dev/null +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/DenseMapInfo.h @@ -0,0 +1,325 @@ +//===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines DenseMapInfo traits for DenseMap. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_DENSEMAPINFO_H +#define LLVM_ADT_DENSEMAPINFO_H + +#include +#include +#include +#include +#include +#include + +namespace llvm { + +namespace densemap::detail { +// A bit mixer with very low latency using one multiplications and one +// xor-shift. The constant is from splitmix64. +inline uint64_t mix(uint64_t x) { + x *= 0xbf58476d1ce4e5b9u; + x ^= x >> 31; + return x; +} +} // namespace densemap::detail + +namespace detail { + +/// Simplistic combination of 32-bit hash values into 32-bit hash values. +inline unsigned combineHashValue(unsigned a, unsigned b) { + uint64_t x = (uint64_t)a << 32 | (uint64_t)b; + return (unsigned)densemap::detail::mix(x); +} + +} // end namespace detail + +/// An information struct used to provide DenseMap with the various necessary +/// components for a given value type `T`. `Enable` is an optional additional +/// parameter that is used to support SFINAE (generally using std::enable_if_t) +/// in derived DenseMapInfo specializations; in non-SFINAE use cases this should +/// just be `void`. +template +struct DenseMapInfo { + //static inline T getEmptyKey(); + //static inline T getTombstoneKey(); + //static unsigned getHashValue(const T &Val); + //static bool isEqual(const T &LHS, const T &RHS); +}; + +// Provide DenseMapInfo for all pointers. Come up with sentinel pointer values +// that are aligned to alignof(T) bytes, but try to avoid requiring T to be +// complete. This allows clients to instantiate DenseMap with forward +// declared key types. Assume that no pointer key type requires more than 4096 +// bytes of alignment. +template +struct DenseMapInfo { + // The following should hold, but it would require T to be complete: + // static_assert(alignof(T) <= (1 << Log2MaxAlign), + // "DenseMap does not support pointer keys requiring more than " + // "Log2MaxAlign bits of alignment"); + static constexpr uintptr_t Log2MaxAlign = 12; + + static inline T* getEmptyKey() { + uintptr_t Val = static_cast(-1); + Val <<= Log2MaxAlign; + return reinterpret_cast(Val); + } + + static inline T* getTombstoneKey() { + uintptr_t Val = static_cast(-2); + Val <<= Log2MaxAlign; + return reinterpret_cast(Val); + } + + static unsigned getHashValue(const T *PtrVal) { + return (unsigned((uintptr_t)PtrVal) >> 4) ^ + (unsigned((uintptr_t)PtrVal) >> 9); + } + + static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } +}; + +// Provide DenseMapInfo for chars. +template<> struct DenseMapInfo { + static inline char getEmptyKey() { return ~0; } + static inline char getTombstoneKey() { return ~0 - 1; } + static unsigned getHashValue(const char& Val) { return Val * 37U; } + + static bool isEqual(const char &LHS, const char &RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for unsigned chars. +template <> struct DenseMapInfo { + static inline unsigned char getEmptyKey() { return ~0; } + static inline unsigned char getTombstoneKey() { return ~0 - 1; } + static unsigned getHashValue(const unsigned char &Val) { return Val * 37U; } + + static bool isEqual(const unsigned char &LHS, const unsigned char &RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for unsigned shorts. +template <> struct DenseMapInfo { + static inline unsigned short getEmptyKey() { return 0xFFFF; } + static inline unsigned short getTombstoneKey() { return 0xFFFF - 1; } + static unsigned getHashValue(const unsigned short &Val) { return Val * 37U; } + + static bool isEqual(const unsigned short &LHS, const unsigned short &RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for unsigned ints. +template<> struct DenseMapInfo { + static inline unsigned getEmptyKey() { return ~0U; } + static inline unsigned getTombstoneKey() { return ~0U - 1; } + static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } + + static bool isEqual(const unsigned& LHS, const unsigned& RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for unsigned longs. +template<> struct DenseMapInfo { + static inline unsigned long getEmptyKey() { return ~0UL; } + static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } + + static unsigned getHashValue(const unsigned long& Val) { + if constexpr (sizeof(Val) == 4) + return DenseMapInfo::getHashValue(Val); + else + return densemap::detail::mix(Val); + } + + static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for unsigned long longs. +template<> struct DenseMapInfo { + static inline unsigned long long getEmptyKey() { return ~0ULL; } + static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } + + static unsigned getHashValue(const unsigned long long& Val) { + return densemap::detail::mix(Val); + } + + static bool isEqual(const unsigned long long& LHS, + const unsigned long long& RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for shorts. +template <> struct DenseMapInfo { + static inline short getEmptyKey() { return 0x7FFF; } + static inline short getTombstoneKey() { return -0x7FFF - 1; } + static unsigned getHashValue(const short &Val) { return Val * 37U; } + static bool isEqual(const short &LHS, const short &RHS) { return LHS == RHS; } +}; + +// Provide DenseMapInfo for ints. +template<> struct DenseMapInfo { + static inline int getEmptyKey() { return 0x7fffffff; } + static inline int getTombstoneKey() { return -0x7fffffff - 1; } + static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } + + static bool isEqual(const int& LHS, const int& RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for longs. +template<> struct DenseMapInfo { + static inline long getEmptyKey() { + return (1UL << (sizeof(long) * 8 - 1)) - 1UL; + } + + static inline long getTombstoneKey() { return getEmptyKey() - 1L; } + + static unsigned getHashValue(const long& Val) { + return (unsigned)(Val * 37UL); + } + + static bool isEqual(const long& LHS, const long& RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for long longs. +template<> struct DenseMapInfo { + static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } + static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } + + static unsigned getHashValue(const long long& Val) { + return (unsigned)(Val * 37ULL); + } + + static bool isEqual(const long long& LHS, + const long long& RHS) { + return LHS == RHS; + } +}; + +// Provide DenseMapInfo for all pairs whose members have info. +template +struct DenseMapInfo> { + using Pair = std::pair; + using FirstInfo = DenseMapInfo; + using SecondInfo = DenseMapInfo; + + static inline Pair getEmptyKey() { + return std::make_pair(FirstInfo::getEmptyKey(), + SecondInfo::getEmptyKey()); + } + + static inline Pair getTombstoneKey() { + return std::make_pair(FirstInfo::getTombstoneKey(), + SecondInfo::getTombstoneKey()); + } + + static unsigned getHashValue(const Pair& PairVal) { + return detail::combineHashValue(FirstInfo::getHashValue(PairVal.first), + SecondInfo::getHashValue(PairVal.second)); + } + + // Expose an additional function intended to be used by other + // specializations of DenseMapInfo without needing to know how + // to combine hash values manually + static unsigned getHashValuePiecewise(const T &First, const U &Second) { + return detail::combineHashValue(FirstInfo::getHashValue(First), + SecondInfo::getHashValue(Second)); + } + + static bool isEqual(const Pair &LHS, const Pair &RHS) { + return FirstInfo::isEqual(LHS.first, RHS.first) && + SecondInfo::isEqual(LHS.second, RHS.second); + } +}; + +// Provide DenseMapInfo for all tuples whose members have info. +template struct DenseMapInfo> { + using Tuple = std::tuple; + + static inline Tuple getEmptyKey() { + return Tuple(DenseMapInfo::getEmptyKey()...); + } + + static inline Tuple getTombstoneKey() { + return Tuple(DenseMapInfo::getTombstoneKey()...); + } + + template + static unsigned getHashValueImpl(const Tuple &values, std::false_type) { + using EltType = std::tuple_element_t; + std::integral_constant atEnd; + return detail::combineHashValue( + DenseMapInfo::getHashValue(std::get(values)), + getHashValueImpl(values, atEnd)); + } + + template + static unsigned getHashValueImpl(const Tuple &, std::true_type) { + return 0; + } + + static unsigned getHashValue(const std::tuple &values) { + std::integral_constant atEnd; + return getHashValueImpl<0>(values, atEnd); + } + + template + static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) { + using EltType = std::tuple_element_t; + std::integral_constant atEnd; + return DenseMapInfo::isEqual(std::get(lhs), std::get(rhs)) && + isEqualImpl(lhs, rhs, atEnd); + } + + template + static bool isEqualImpl(const Tuple &, const Tuple &, std::true_type) { + return true; + } + + static bool isEqual(const Tuple &lhs, const Tuple &rhs) { + std::integral_constant atEnd; + return isEqualImpl<0>(lhs, rhs, atEnd); + } +}; + +// Provide DenseMapInfo for enum classes. +template +struct DenseMapInfo>> { + using UnderlyingType = std::underlying_type_t; + using Info = DenseMapInfo; + + static Enum getEmptyKey() { return static_cast(Info::getEmptyKey()); } + + static Enum getTombstoneKey() { + return static_cast(Info::getTombstoneKey()); + } + + static unsigned getHashValue(const Enum &Val) { + return Info::getHashValue(static_cast(Val)); + } + + static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; } +}; +} // end namespace llvm + +#endif // LLVM_ADT_DENSEMAPINFO_H diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h index e296c1c53..a5477362a 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h @@ -51,11 +51,13 @@ #include #include #include +#include #include #include #include namespace llvm { +template struct DenseMapInfo; /// An opaque object representing a hash code. /// @@ -121,6 +123,8 @@ hash_code hash_value(const std::tuple &arg); template hash_code hash_value(const std::basic_string &arg); +/// Compute a hash_code for a standard string. +template hash_code hash_value(const std::optional &arg); /// Override the execution seed with a fixed value. /// @@ -215,29 +219,30 @@ inline uint64_t hash_17to32_bytes(const char *s, size_t len, uint64_t seed) { uint64_t b = fetch64(s + 8); uint64_t c = fetch64(s + len - 8) * k2; uint64_t d = fetch64(s + len - 16) * k0; - return hash_16_bytes(rotate(a - b, 43) + rotate(c ^ seed, 30) + d, - a + rotate(b ^ k3, 20) - c + len + seed); + return hash_16_bytes(llvm::rotr(a - b, 43) + + llvm::rotr(c ^ seed, 30) + d, + a + llvm::rotr(b ^ k3, 20) - c + len + seed); } inline uint64_t hash_33to64_bytes(const char *s, size_t len, uint64_t seed) { uint64_t z = fetch64(s + 24); uint64_t a = fetch64(s) + (len + fetch64(s + len - 16)) * k0; - uint64_t b = rotate(a + z, 52); - uint64_t c = rotate(a, 37); + uint64_t b = llvm::rotr(a + z, 52); + uint64_t c = llvm::rotr(a, 37); a += fetch64(s + 8); - c += rotate(a, 7); + c += llvm::rotr(a, 7); a += fetch64(s + 16); uint64_t vf = a + z; - uint64_t vs = b + rotate(a, 31) + c; + uint64_t vs = b + llvm::rotr(a, 31) + c; a = fetch64(s + 16) + fetch64(s + len - 32); z = fetch64(s + len - 8); - b = rotate(a + z, 52); - c = rotate(a, 37); + b = llvm::rotr(a + z, 52); + c = llvm::rotr(a, 37); a += fetch64(s + len - 24); - c += rotate(a, 7); + c += llvm::rotr(a, 7); a += fetch64(s + len - 16); uint64_t wf = a + z; - uint64_t ws = b + rotate(a, 31) + c; + uint64_t ws = b + llvm::rotr(a, 31) + c; uint64_t r = shift_mix((vf + ws) * k2 + (wf + vs) * k0); return shift_mix((seed ^ (r * k0)) + vs) * k2; } @@ -267,9 +272,13 @@ struct hash_state { /// seed and the first 64-byte chunk. /// This effectively performs the initial mix. static hash_state create(const char *s, uint64_t seed) { - hash_state state = { - 0, seed, hash_16_bytes(seed, k1), rotate(seed ^ k1, 49), - seed * k1, shift_mix(seed), 0 }; + hash_state state = {0, + seed, + hash_16_bytes(seed, k1), + llvm::rotr(seed ^ k1, 49), + seed * k1, + shift_mix(seed), + 0}; state.h6 = hash_16_bytes(state.h4, state.h5); state.mix(s); return state; @@ -280,10 +289,10 @@ struct hash_state { static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) { a += fetch64(s); uint64_t c = fetch64(s + 24); - b = rotate(b + a + c, 21); + b = llvm::rotr(b + a + c, 21); uint64_t d = a; a += fetch64(s + 8) + fetch64(s + 16); - b += rotate(a, 44) + d; + b += llvm::rotr(a, 44) + d; a += c; } @@ -291,11 +300,11 @@ struct hash_state { /// We mix all 64 bytes even when the chunk length is smaller, but we /// record the actual length. void mix(const char *s) { - h0 = rotate(h0 + h1 + h3 + fetch64(s + 8), 37) * k1; - h1 = rotate(h1 + h4 + fetch64(s + 48), 42) * k1; + h0 = llvm::rotr(h0 + h1 + h3 + fetch64(s + 8), 37) * k1; + h1 = llvm::rotr(h1 + h4 + fetch64(s + 48), 42) * k1; h0 ^= h6; h1 += h3 + fetch64(s + 40); - h2 = rotate(h2 + h5, 33) * k1; + h2 = llvm::rotr(h2 + h5, 33) * k1; h3 = h4 * k1; h4 = h0 + h5; mix_32_bytes(s, h3, h4); @@ -650,24 +659,8 @@ hash_code hash_value(const std::pair &arg) { return hash_combine(arg.first, arg.second); } -// Implementation details for the hash_value overload for std::tuple<...>(...). -namespace hashing { -namespace detail { - -template -hash_code hash_value_tuple_helper(const std::tuple &arg, - std::index_sequence) { - return hash_combine(std::get(arg)...); -} - -} // namespace detail -} // namespace hashing - -template -hash_code hash_value(const std::tuple &arg) { - // TODO: Use std::apply when LLVM starts using C++17. - return ::llvm::hashing::detail::hash_value_tuple_helper( - arg, typename std::index_sequence_for()); +template hash_code hash_value(const std::tuple &arg) { + return std::apply([](const auto &...xs) { return hash_combine(xs...); }, arg); } // Declared and documented above, but defined here so that any of the hashing @@ -677,6 +670,31 @@ hash_code hash_value(const std::basic_string &arg) { return hash_combine_range(arg.begin(), arg.end()); } +template hash_code hash_value(const std::optional &arg) { + return arg ? hash_combine(true, *arg) : hash_value(false); +} + +template <> struct DenseMapInfo { + static inline hash_code getEmptyKey() { return hash_code(-1); } + static inline hash_code getTombstoneKey() { return hash_code(-2); } + static unsigned getHashValue(hash_code val) { + return static_cast(size_t(val)); + } + static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; } +}; + } // namespace llvm +/// Implement std::hash so that hash_code can be used in STL containers. +namespace std { + +template<> +struct hash { + size_t operator()(llvm::hash_code const& Val) const { + return Val; + } +}; + +} // namespace std; + #endif diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/None.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/None.h deleted file mode 100644 index 004ca0ac5..000000000 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/None.h +++ /dev/null @@ -1,26 +0,0 @@ -//===-- None.h - Simple null value for implicit construction ------*- C++ -*-=// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file provides None, an enumerator for use in implicit constructors -// of various (usually templated) types to make such construction more -// terse. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_NONE_H -#define LLVM_ADT_NONE_H - -namespace llvm { -/// A simple null object to allow implicit construction of Optional -/// and similar types without having to spell out the specialization's name. -// (constant value 1 in an attempt to workaround MSVC build issue... ) -enum class NoneType { None = 1 }; -const NoneType None = NoneType::None; -} - -#endif diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/Optional.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/Optional.h deleted file mode 100644 index cdbf2e353..000000000 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/Optional.h +++ /dev/null @@ -1,496 +0,0 @@ -//===- Optional.h - Simple variant for passing optional values --*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file provides Optional, a template class modeled in the spirit of -// OCaml's 'opt' variant. The idea is to strongly type whether or not -// a value can be optional. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_OPTIONAL_H -#define LLVM_ADT_OPTIONAL_H - -#include "llvm/ADT/Hashing.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/STLForwardCompat.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/type_traits.h" -#include -#include -#include -#include - -namespace llvm { - -class raw_ostream; - -namespace optional_detail { - -/// Storage for any type. -// -// The specialization condition intentionally uses -// llvm::is_trivially_copy_constructible instead of -// std::is_trivially_copy_constructible. GCC versions prior to 7.4 may -// instantiate the copy constructor of `T` when -// std::is_trivially_copy_constructible is instantiated. This causes -// compilation to fail if we query the trivially copy constructible property of -// a class which is not copy constructible. -// -// The current implementation of OptionalStorage insists that in order to use -// the trivial specialization, the value_type must be trivially copy -// constructible and trivially copy assignable due to =default implementations -// of the copy/move constructor/assignment. It does not follow that this is -// necessarily the case std::is_trivially_copyable is true (hence the expanded -// specialization condition). -// -// The move constructible / assignable conditions emulate the remaining behavior -// of std::is_trivially_copyable. -template ::value && - std::is_trivially_copy_assignable::value && - (std::is_trivially_move_constructible::value || - !std::is_move_constructible::value) && - (std::is_trivially_move_assignable::value || - !std::is_move_assignable::value))> -class OptionalStorage { - union { - char empty; - T value; - }; - bool hasVal; - -public: - ~OptionalStorage() { reset(); } - - constexpr OptionalStorage() noexcept : empty(), hasVal(false) {} - - constexpr OptionalStorage(OptionalStorage const &other) : OptionalStorage() { - if (other.hasValue()) { - emplace(other.value); - } - } - constexpr OptionalStorage(OptionalStorage &&other) : OptionalStorage() { - if (other.hasValue()) { - emplace(std::move(other.value)); - } - } - - template - constexpr explicit OptionalStorage(in_place_t, Args &&... args) - : value(std::forward(args)...), hasVal(true) {} - - void reset() noexcept { - if (hasVal) { - value.~T(); - hasVal = false; - } - } - - constexpr bool hasValue() const noexcept { return hasVal; } - - T &getValue() LLVM_LVALUE_FUNCTION noexcept { - assert(hasVal); - return value; - } - constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept { - assert(hasVal); - return value; - } -#if LLVM_HAS_RVALUE_REFERENCE_THIS - T &&getValue() && noexcept { - assert(hasVal); - return std::move(value); - } -#endif - - template void emplace(Args &&... args) { - reset(); - ::new ((void *)std::addressof(value)) T(std::forward(args)...); - hasVal = true; - } - - OptionalStorage &operator=(T const &y) { - if (hasValue()) { - value = y; - } else { - ::new ((void *)std::addressof(value)) T(y); - hasVal = true; - } - return *this; - } - OptionalStorage &operator=(T &&y) { - if (hasValue()) { - value = std::move(y); - } else { - ::new ((void *)std::addressof(value)) T(std::move(y)); - hasVal = true; - } - return *this; - } - - OptionalStorage &operator=(OptionalStorage const &other) { - if (other.hasValue()) { - if (hasValue()) { - value = other.value; - } else { - ::new ((void *)std::addressof(value)) T(other.value); - hasVal = true; - } - } else { - reset(); - } - return *this; - } - - OptionalStorage &operator=(OptionalStorage &&other) { - if (other.hasValue()) { - if (hasValue()) { - value = std::move(other.value); - } else { - ::new ((void *)std::addressof(value)) T(std::move(other.value)); - hasVal = true; - } - } else { - reset(); - } - return *this; - } -}; - -template class OptionalStorage { - union { - char empty; - T value; - }; - bool hasVal = false; - -public: - ~OptionalStorage() = default; - - constexpr OptionalStorage() noexcept : empty{} {} - - constexpr OptionalStorage(OptionalStorage const &other) = default; - constexpr OptionalStorage(OptionalStorage &&other) = default; - - OptionalStorage &operator=(OptionalStorage const &other) = default; - OptionalStorage &operator=(OptionalStorage &&other) = default; - - template - constexpr explicit OptionalStorage(in_place_t, Args &&... args) - : value(std::forward(args)...), hasVal(true) {} - - void reset() noexcept { - if (hasVal) { - value.~T(); - hasVal = false; - } - } - - constexpr bool hasValue() const noexcept { return hasVal; } - - T &getValue() LLVM_LVALUE_FUNCTION noexcept { - assert(hasVal); - return value; - } - constexpr T const &getValue() const LLVM_LVALUE_FUNCTION noexcept { - assert(hasVal); - return value; - } -#if LLVM_HAS_RVALUE_REFERENCE_THIS - T &&getValue() && noexcept { - assert(hasVal); - return std::move(value); - } -#endif - - template void emplace(Args &&... args) { - reset(); - ::new ((void *)std::addressof(value)) T(std::forward(args)...); - hasVal = true; - } - - OptionalStorage &operator=(T const &y) { - if (hasValue()) { - value = y; - } else { - ::new ((void *)std::addressof(value)) T(y); - hasVal = true; - } - return *this; - } - OptionalStorage &operator=(T &&y) { - if (hasValue()) { - value = std::move(y); - } else { - ::new ((void *)std::addressof(value)) T(std::move(y)); - hasVal = true; - } - return *this; - } -}; - -} // namespace optional_detail - -template class Optional { - optional_detail::OptionalStorage Storage; - -public: - using value_type = T; - - constexpr Optional() {} - constexpr Optional(NoneType) {} - - constexpr Optional(const T &y) : Storage(in_place, y) {} - constexpr Optional(const Optional &O) = default; - - constexpr Optional(T &&y) : Storage(in_place, std::move(y)) {} - constexpr Optional(Optional &&O) = default; - - template - constexpr Optional(in_place_t, ArgTypes &&...Args) - : Storage(in_place, std::forward(Args)...) {} - - Optional &operator=(T &&y) { - Storage = std::move(y); - return *this; - } - Optional &operator=(Optional &&O) = default; - - /// Create a new object by constructing it in place with the given arguments. - template void emplace(ArgTypes &&... Args) { - Storage.emplace(std::forward(Args)...); - } - - static constexpr Optional create(const T *y) { - return y ? Optional(*y) : Optional(); - } - - Optional &operator=(const T &y) { - Storage = y; - return *this; - } - Optional &operator=(const Optional &O) = default; - - void reset() { Storage.reset(); } - - constexpr const T *getPointer() const { return &Storage.getValue(); } - T *getPointer() { return &Storage.getValue(); } - constexpr const T &getValue() const LLVM_LVALUE_FUNCTION { - return Storage.getValue(); - } - T &getValue() LLVM_LVALUE_FUNCTION { return Storage.getValue(); } - - constexpr explicit operator bool() const { return hasValue(); } - constexpr bool hasValue() const { return Storage.hasValue(); } - constexpr const T *operator->() const { return getPointer(); } - T *operator->() { return getPointer(); } - constexpr const T &operator*() const LLVM_LVALUE_FUNCTION { - return getValue(); - } - T &operator*() LLVM_LVALUE_FUNCTION { return getValue(); } - - template - constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION { - return hasValue() ? getValue() : std::forward(value); - } - - /// Apply a function to the value if present; otherwise return None. - template - auto map(const Function &F) const LLVM_LVALUE_FUNCTION - -> Optional { - if (*this) return F(getValue()); - return None; - } - -#if LLVM_HAS_RVALUE_REFERENCE_THIS - T &&getValue() && { return std::move(Storage.getValue()); } - T &&operator*() && { return std::move(Storage.getValue()); } - - template - T getValueOr(U &&value) && { - return hasValue() ? std::move(getValue()) : std::forward(value); - } - - /// Apply a function to the value if present; otherwise return None. - template - auto map(const Function &F) && - -> Optional { - if (*this) return F(std::move(*this).getValue()); - return None; - } -#endif -}; - -template llvm::hash_code hash_value(const Optional &O) { - return O ? hash_combine(true, *O) : hash_value(false); -} - -template -constexpr bool operator==(const Optional &X, const Optional &Y) { - if (X && Y) - return *X == *Y; - return X.hasValue() == Y.hasValue(); -} - -template -constexpr bool operator!=(const Optional &X, const Optional &Y) { - return !(X == Y); -} - -template -constexpr bool operator<(const Optional &X, const Optional &Y) { - if (X && Y) - return *X < *Y; - return X.hasValue() < Y.hasValue(); -} - -template -constexpr bool operator<=(const Optional &X, const Optional &Y) { - return !(Y < X); -} - -template -constexpr bool operator>(const Optional &X, const Optional &Y) { - return Y < X; -} - -template -constexpr bool operator>=(const Optional &X, const Optional &Y) { - return !(X < Y); -} - -template -constexpr bool operator==(const Optional &X, NoneType) { - return !X; -} - -template -constexpr bool operator==(NoneType, const Optional &X) { - return X == None; -} - -template -constexpr bool operator!=(const Optional &X, NoneType) { - return !(X == None); -} - -template -constexpr bool operator!=(NoneType, const Optional &X) { - return X != None; -} - -template constexpr bool operator<(const Optional &, NoneType) { - return false; -} - -template constexpr bool operator<(NoneType, const Optional &X) { - return X.hasValue(); -} - -template -constexpr bool operator<=(const Optional &X, NoneType) { - return !(None < X); -} - -template -constexpr bool operator<=(NoneType, const Optional &X) { - return !(X < None); -} - -template constexpr bool operator>(const Optional &X, NoneType) { - return None < X; -} - -template constexpr bool operator>(NoneType, const Optional &X) { - return X < None; -} - -template -constexpr bool operator>=(const Optional &X, NoneType) { - return None <= X; -} - -template -constexpr bool operator>=(NoneType, const Optional &X) { - return X <= None; -} - -template -constexpr bool operator==(const Optional &X, const T &Y) { - return X && *X == Y; -} - -template -constexpr bool operator==(const T &X, const Optional &Y) { - return Y && X == *Y; -} - -template -constexpr bool operator!=(const Optional &X, const T &Y) { - return !(X == Y); -} - -template -constexpr bool operator!=(const T &X, const Optional &Y) { - return !(X == Y); -} - -template -constexpr bool operator<(const Optional &X, const T &Y) { - return !X || *X < Y; -} - -template -constexpr bool operator<(const T &X, const Optional &Y) { - return Y && X < *Y; -} - -template -constexpr bool operator<=(const Optional &X, const T &Y) { - return !(Y < X); -} - -template -constexpr bool operator<=(const T &X, const Optional &Y) { - return !(Y < X); -} - -template -constexpr bool operator>(const Optional &X, const T &Y) { - return Y < X; -} - -template -constexpr bool operator>(const T &X, const Optional &Y) { - return Y < X; -} - -template -constexpr bool operator>=(const Optional &X, const T &Y) { - return !(X < Y); -} - -template -constexpr bool operator>=(const T &X, const Optional &Y) { - return !(X < Y); -} - -raw_ostream &operator<<(raw_ostream &OS, NoneType); - -template () - << std::declval())> -raw_ostream &operator<<(raw_ostream &OS, const Optional &O) { - if (O) - OS << *O; - else - OS << None; - return OS; -} - -} // end namespace llvm - -#endif // LLVM_ADT_OPTIONAL_H diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h index 372907be8..8f988d01c 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h @@ -5,19 +5,22 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -// -// This file contains some templates that are useful if you are working with the -// STL at all. -// -// No library is required when using these functions. -// +/// +/// \file +/// This file contains some templates that are useful if you are working with +/// the STL at all. +/// +/// No library is required when using these functions. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_STLEXTRAS_H #define LLVM_ADT_STLEXTRAS_H -#include "llvm/ADT/Optional.h" +#include "llvm/ADT/ADL.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/STLForwardCompat.h" +#include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Config/abi-breaking.h" @@ -32,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -42,42 +46,24 @@ namespace llvm { -// Only used by compiler if both template types are the same. Useful when -// using SFINAE to test for the existence of member functions. -template struct SameType; - -namespace detail { - -template -using IterOfRange = decltype(std::begin(std::declval())); - -template -using ValueOfRange = typename std::remove_reference()))>::type; - -} // end namespace detail - //===----------------------------------------------------------------------===// // Extra additions to //===----------------------------------------------------------------------===// template struct make_const_ptr { - using type = - typename std::add_pointer::type>::type; + using type = std::add_pointer_t>; }; template struct make_const_ref { - using type = typename std::add_lvalue_reference< - typename std::add_const::type>::type; + using type = std::add_lvalue_reference_t>; }; namespace detail { -template using void_t = void; template class Op, class... Args> struct detector { using value_t = std::false_type; }; template