Skip to content

Descend into an OEM wrapper archive in check-bugreport - #944

Merged
besendorf merged 1 commit into
mvt-project:mainfrom
va-resident:fix/bugreport-oem-wrapper-archive
Sep 25, 2026
Merged

besendorf merged 1 commit into
mvt-project:mainfrom
va-resident:fix/bugreport-oem-wrapper-archive

Conversation

@va-resident

Copy link
Copy Markdown
Contributor

Fixes #935

Change, cmd_check_bugreport.py (+49/−2) and modules/bugreport/base.py (+10/−3):

  • DUMPSTATE_ENTRY_POINTS moves into modules/bugreport/base.py, next to the
    _get_dumpstate_file() that tries them in that order — so the entry points are named once
    rather than once per caller;
  • _has_dumpstate(file_names) — any(fnmatch.filter(file_names, pattern) for pattern in DUMPSTATE_ENTRY_POINTS), the same matching _get_files_by_pattern() already uses;
  • _nested_bugreport(outer) — only when they are absent: open the outer archive's .zip members
    in memory, names containing bugreport / dumpstate first, and take the first one that does
    carry an entry point. Logs which member was used.

The descent is unreachable for an archive that already has an entry point, which is all 30 normal
collections in the test set — including the 27 that carry some other zip member.

On placement: you asked on #935 where this code should live and passed the question to
@DonnchaC. This is my reading of it — the entry points next to the only code that consumes them,
the descent in the command that owns the archive — but nothing here depends on that choice. Say
where you would rather have it and I will move it.

Measured on 44 bug report collections, upstream vs patched — and re-run on the 14 wrappers
after the descent was simplified, with identical totals, so the numbers below come from the code
this PR ships:

set upstream patched
14 wrapper collections 0 artifacts and 0 records on 13; one tombstones.json with 4 records on the fourteenth; exit 0 throughout 260 artifacts, 586 638 records, 109 502 timeline rows, 94 alerts
30 normal collections, 14 brands (baseline) same artifacts, same records, same alerts — every file identical once record order is normalised

On the controls, 29 of 30 runs differ byte-for-byte in timeline.csv and tombstones.json and 2
of them in alerts.json; the contents are the same records in a different order, and two runs of
the same build differ the same way. Record order in those files is not deterministic in main —
worth a separate issue, and worth knowing before anyone uses a checksum to compare two runs.

Tests: tests/android/test_check_bugreport_wrapper.py, 2 cases — a wrapper is descended into,
and a plain archive that merely contains some other zip is left alone.

Applies to main@777db67 with no other change; pytest tests/android there goes from 99 passed /
1 skipped to 101 passed / 1 skipped. ruff check, ruff format --check and
mypy --platform linux (156 files) pass on the branch.

Related open work (re-checked 2026-09-22, none of these has landed):

MIUI / HyperOS hands out a zip of app logs, ANR traces and tcpdump captures
with the real bugreport-<device>-<timestamp>.zip nested inside. The outer
archive carries none of the entry points the bug report modules read, so every
module reported it found no files and check-bugreport still exited 0 with an
empty result — an empty analysis that looks like a finished one.

Name the entry points once in modules/bugreport/base.py, next to the
_get_dumpstate_file() that tries them, and when an archive has none of them,
open its zip members in memory and use the first one that does.

Measured over 44 bug report collections: the 14 wrapper collections go from 0
artifacts to 260 artifacts and 586638 records; the 30 normal collections are
unchanged, the descent being unreachable for them.

Fixes mvt-project#935
@va-resident
va-resident force-pushed the fix/bugreport-oem-wrapper-archive branch from 42e8881 to b1b9958 Compare September 25, 2026 17:21
@va-resident

Copy link
Copy Markdown
Contributor Author

Rebased onto main after #945 landed. The only conflict was in the import block of modules/bugreport/base.py: DUMPSTATE_ENTRY_POINTS now sits right after SECTION_DURATION. No other changes. Lint, mypy and tests pass.

@besendorf
besendorf merged commit cfaeb99 into mvt-project:main Sep 25, 2026
7 checks passed
@besendorf

Copy link
Copy Markdown
Collaborator

I merged this too early. Foind 2 issues:

The empty-success case remains. If the wrapper has no usable nested ZIP, from_zip() keeps the outer archive⁠�. The command can still exit 0 with an empty analysis, contrary to the expected behavior in #935⁠�. It should report that no bug report was found.

Descent can discard wrapper-only evidence. The same lines replace the outer ZIP and its file list entirely. The tombstone module can currently read tombstones from the wrapper; #935 reports four such records in one collection. If those files are absent from the inner ZIP, this change silently drops them. That case needs a regression test and a way to retain or explicitly account for those files.

2B-4G10 pushed a commit to 2B-4G10/MVT-GUI that referenced this pull request Oct 28, 2026
…-wrapper-archive

Descend into an OEM wrapper archive in check-bugreport
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check-bugreport exits 0 with an empty result on a MIUI / HyperOS wrapper archive

2 participants