From 8e21dbfddb09f81e47907e7c5098bffa6fe0457f Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Mon, 23 Oct 2023 14:20:33 +0200 Subject: [PATCH 1/2] Update proguard and add `remap_method` fn This function allows best-effort remapping of classes and methods without line info. --- Cargo.lock | 4 ++-- py/symbolic/proguard.py | 19 ++++++++++++++++++ py/tests/test_proguard.py | 6 ++++++ symbolic-cabi/Cargo.toml | 4 ++-- symbolic-cabi/include/symbolic.h | 9 ++++++++- symbolic-cabi/src/proguard.rs | 33 ++++++++++++++++++++++++++++++++ symbolic-common/Cargo.toml | 3 +-- symbolic/Cargo.toml | 2 +- symbolic/README.md | 2 -- symbolic/src/lib.rs | 2 +- 10 files changed, 73 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11c12424b..0168869e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1450,9 +1450,9 @@ dependencies = [ [[package]] name = "proguard" -version = "5.0.2" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cbb571529b37a9001d7ecc050983191399270c42b6c1293d43da748f281c23" +checksum = "1766d401c716ab2d5ddc832468b420e4c51e37c4491ea94fd856ef652664a8d3" dependencies = [ "lazy_static", "uuid", diff --git a/py/symbolic/proguard.py b/py/symbolic/proguard.py index f0490bd7f..a2c04fb3c 100644 --- a/py/symbolic/proguard.py +++ b/py/symbolic/proguard.py @@ -1,4 +1,5 @@ from __future__ import annotations +from typing import Tuple import uuid as uuid_mod @@ -55,6 +56,24 @@ def remap_class(self, klass: str) -> str | None: ) return decode_str(klass, free=True) or None + def remap_method(self, klass: str, method: str) -> Tuple[str, str] | None: + """Remaps the given class name.""" + result = self._methodcall( + lib.symbolic_proguardmapper_remap_method, + encode_str(klass), + encode_str(method), + ) + + try: + output = ( + decode_str(result.frames[0].class_name, free=False), + decode_str(result.frames[0].method, free=False), + ) + finally: + rustcall(lib.symbolic_proguardmapper_result_free, ffi.addressof(result)) + + return output if len(output[0]) > 0 and len(output[1]) > 0 else None + def remap_frame(self, klass: str, method: str, line: int) -> list[JavaStackFrame]: """Remaps the stackframe, given its class, method and line.""" result = self._methodcall( diff --git a/py/tests/test_proguard.py b/py/tests/test_proguard.py index 0fcf6be3e..3d7eac59e 100644 --- a/py/tests/test_proguard.py +++ b/py/tests/test_proguard.py @@ -27,3 +27,9 @@ def test_mapper(res_path): assert remapped[1].line == 44 assert remapped[2].method == "onClickHandler" assert remapped[2].line == 40 + + remapped = mapper.remap_method("android.support.constraint.a.b", "f") + assert remapped == ( + "android.support.constraint.solver.ArrayRow", + "void pickRowVariable()", + ) diff --git a/symbolic-cabi/Cargo.toml b/symbolic-cabi/Cargo.toml index a3e9ce02e..640e781ce 100644 --- a/symbolic-cabi/Cargo.toml +++ b/symbolic-cabi/Cargo.toml @@ -10,7 +10,7 @@ homepage = "https://github.com/getsentry/symbolic" repository = "https://github.com/getsentry/symbolic" description = """ C interface wrapper for symbolic, a library to symbolicate and process stack -traces from native applications, minidumps, minified JavaScripts or ProGuard +traces from native applications, minidumps, minified JavaScript or ProGuard optimized Android apps. """ edition = "2021" @@ -20,7 +20,7 @@ publish = false crate-type = ["cdylib"] [dependencies] -proguard = { version = "5.0.2", features = ["uuid"] } +proguard = { version = "5.1.0", features = ["uuid"] } sourcemap = "7.0.0" symbolic = { version = "12.4.1", path = "../symbolic", features = ["cfi", "debuginfo", "sourcemapcache", "symcache"] } tempfile = "3.4.0" diff --git a/symbolic-cabi/include/symbolic.h b/symbolic-cabi/include/symbolic.h index ed218f7d4..fa739693d 100644 --- a/symbolic-cabi/include/symbolic.h +++ b/symbolic-cabi/include/symbolic.h @@ -3,7 +3,7 @@ #ifndef SYMBOLIC_H_INCLUDED #define SYMBOLIC_H_INCLUDED -/* Generated with cbindgen:0.24.3 */ +/* Generated with cbindgen:0.24.5 */ /* Warning, this file is autogenerated. Do not modify this manually. */ @@ -520,6 +520,13 @@ struct SymbolicProguardRemapResult symbolic_proguardmapper_remap_frame(const str struct SymbolicStr symbolic_proguardmapper_remap_class(const struct SymbolicProguardMapper *mapper, const struct SymbolicStr *class_); +/** + * Remaps a class name. + */ +struct SymbolicProguardRemapResult symbolic_proguardmapper_remap_method(const struct SymbolicProguardMapper *mapper, + const struct SymbolicStr *class_, + const struct SymbolicStr *method); + /** * Returns the UUID of a proguard mapping file. */ diff --git a/symbolic-cabi/src/proguard.rs b/symbolic-cabi/src/proguard.rs index 66bde8809..3d3b627fe 100644 --- a/symbolic-cabi/src/proguard.rs +++ b/symbolic-cabi/src/proguard.rs @@ -117,6 +117,39 @@ ffi_fn! { } } +ffi_fn! { + /// Remaps a class name. + unsafe fn symbolic_proguardmapper_remap_method( + mapper: *const SymbolicProguardMapper, + class: *const SymbolicStr, + method: *const SymbolicStr, + ) -> Result { + let mapper = &SymbolicProguardMapper::as_rust(mapper).inner.get().mapper; + + let class = (*class).as_str(); + let method = (*method).as_str(); + + let (remapped_class, remapped_method) = + mapper.remap_method(class, method).unwrap_or_default(); + + let mut frames = vec![SymbolicJavaStackFrame { + class_name: remapped_class.to_owned().into(), + method: remapped_method.to_owned().into(), + file: "".to_owned().into(), + line: 0, + }]; + + frames.shrink_to_fit(); + let rv = SymbolicProguardRemapResult { + frames: frames.as_mut_ptr(), + len: frames.len(), + }; + std::mem::forget(frames); + + Ok(rv) + } +} + ffi_fn! { /// Returns the UUID of a proguard mapping file. unsafe fn symbolic_proguardmapper_get_uuid( diff --git a/symbolic-common/Cargo.toml b/symbolic-common/Cargo.toml index 1cf2930bb..12336017b 100644 --- a/symbolic-common/Cargo.toml +++ b/symbolic-common/Cargo.toml @@ -12,8 +12,7 @@ repository = "https://github.com/getsentry/symbolic" readme = "README.md" description = """ Common types and utilities for symbolic, a library to symbolicate and process -stack traces from native applications, minidumps, minified JavaScripts or -ProGuard optimized Android apps. +stack traces from native applications, minidumps or minified JavaScript. """ edition = "2021" diff --git a/symbolic/Cargo.toml b/symbolic/Cargo.toml index a657096d7..b07f37ce1 100644 --- a/symbolic/Cargo.toml +++ b/symbolic/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/getsentry/symbolic" readme = "README.md" description = """ A library to symbolicate and process stack traces from native applications, -minidumps, Unreal Engine 4, minified JavaScripts or ProGuard optimized Android apps. +minidumps, Unreal Engine 4 or minified JavaScript. """ edition = "2021" diff --git a/symbolic/README.md b/symbolic/README.md index bc4ca275f..6a70955ac 100644 --- a/symbolic/README.md +++ b/symbolic/README.md @@ -26,7 +26,6 @@ Symbolic provides the following functionality: - Basic token mapping - Heuristics to find original function names based on minified sources - Indexed sourcemap to sourcemap merging -- Proguard function mappings - Minidump / Breakpad processing - Generate Breakpad symbol files from Mach, ELF and PDBs - Process Minidumps to retrieve stack traces @@ -48,7 +47,6 @@ of the features: - **`minidump`**: Rust bindings for the Breakpad Minidump processor. Additionally, this includes facilities to extract stack unwinding information (sometimes called CFI) from object files. This feature requires a C++11 compiler on the PATH. -- **`proguard`**: Processing of Proguard mapping files to look up mangled Java function paths. - **`sourcemap`**: Processing and expansion of JavaScript source maps, as well as lookups for minified function names. - **`symcache`**: An optimized, platform-independent storage for common debugging information. diff --git a/symbolic/src/lib.rs b/symbolic/src/lib.rs index 4e84bf8d8..45f60450c 100644 --- a/symbolic/src/lib.rs +++ b/symbolic/src/lib.rs @@ -18,7 +18,7 @@ //! - Objective C / Objective C++ //! - Rust //! - Swift -//! - JavaScript sourcemap expansion (vie `symbolic-cabi` only, use `sourcemap` crate instead) +//! - JavaScript sourcemap expansion (via `symbolic-cabi` only, use `sourcemap` crate instead) //! - Proguard function mappings (via `symbolic-cabi` only, use `proguard` crate instead) //! - Breakpad processing //! - Generate Breakpad symbol files from Mach, ELF and PDBs From 8231446579c436a95d0f645b5b7a646445e1f646 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Mon, 23 Oct 2023 14:29:19 +0200 Subject: [PATCH 2/2] lints and test fix --- CHANGELOG.md | 4 ++++ py/tests/test_proguard.py | 11 +++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb9eb9f82..b4e1e4b29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Emit a MODULE record for PE files ([#814](https://github.com/getsentry/symbolic/pull/814)) +**Features** + +- Update proguard and add `remap_method` fn ([#818](https://github.com/getsentry/symbolic/pull/818)) + ## 12.4.1 **Fixes** diff --git a/py/tests/test_proguard.py b/py/tests/test_proguard.py index 3d7eac59e..1b92d6b31 100644 --- a/py/tests/test_proguard.py +++ b/py/tests/test_proguard.py @@ -13,6 +13,11 @@ def test_mapper(res_path): == "android.support.constraint.ConstraintLayout$LayoutParams" ) + assert mapper.remap_method("android.support.constraint.a.b", "f") == ( + "android.support.constraint.solver.ArrayRow", + "pickRowVariable", + ) + remapped = mapper.remap_frame("android.support.constraint.a.b", "a", 116) assert len(remapped) == 1 assert remapped[0].class_name == "android.support.constraint.solver.ArrayRow" @@ -27,9 +32,3 @@ def test_mapper(res_path): assert remapped[1].line == 44 assert remapped[2].method == "onClickHandler" assert remapped[2].line == 40 - - remapped = mapper.remap_method("android.support.constraint.a.b", "f") - assert remapped == ( - "android.support.constraint.solver.ArrayRow", - "void pickRowVariable()", - )