Skip to content

[#77] Detect missing TypeTrees up front in analyze and dump#78

Open
SkowronskiAndrew wants to merge 3 commits into
mainfrom
better-notypetree-errorreporting
Open

[#77] Detect missing TypeTrees up front in analyze and dump#78
SkowronskiAndrew wants to merge 3 commits into
mainfrom
better-notypetree-errorreporting

Conversation

@SkowronskiAndrew

Copy link
Copy Markdown
Collaborator

Fixes #77.

Problem

Running analyze or dump on SerializedFiles without TypeTrees (e.g. player builds / AssetBundles built without type information) produced poor output:

  1. Misleading errors — the native loader falls back to exact-version type matching when there are no TypeTrees, printing Invalid serialized file version. Expected: ... Actual: ... to stderr. The version mismatch is a symptom; the real cause is the missing TypeTrees.
  2. Process crash — for some files the native DLL dereferenced bad memory and the whole process died with Fatal error. 0xC0000005 plus a long managed stack trace. This is a native access violation that cannot be caught in .NET.

Loose dump failures additionally surfaced a raw SerializedFileOpenException with a stack trace, and the archive dump path had no clean handling at all.

Fix

Detect missing TypeTrees before handing the file to the native loader (works for both loose files and entries inside a mounted archive), and handle the case cleanly. This pre-empts both the misleading stderr output and the crash, since the file is never opened natively.

  • SerializedFileDetector — added stream-based overloads of TryDetectSerializedFile/TryParseMetadata (the path-based ones now delegate to them), a parseExtended flag so only the few bytes needed for the EnableTypeTree flag are read, and an IsMissingTypeTrees(Stream) helper.
  • UnityFileStream (new) — a read/seek Stream over UnityFile, so detection works on real paths and archive:/… entries.
  • analyze — rejects no-TypeTree files before opening and reports them in a new Files without TypeTrees summary category, distinct from genuine failures.
  • dump — prints a clear message that it cannot dump a file without TypeTrees, for both the direct-file and archive paths.
  • SerializedFileOpenException — gained a MissingTypeTrees flag.
  • Removed the now-misleading "Note: ... can only be opened if all the types match" hint and the dead GetOpenFailureHint/MissingTypeTreesHint it relied on.

Before / after (analyze)

# before: misleading version errors, then Fatal error 0xC0000005 + stack trace

# after:
Skipped (no TypeTrees): level0
...
Finalizing database. Successfully processed files: 0, Failed files: 0, Files without TypeTrees: 4, Ignored files: 2

Before / after (dump on a no-TypeTree AssetBundle)

# before:
Invalid serialized file version. File: "/CAB-...". Expected version: 6000.5.0a8. Actual version: 6000.6.0a8.
Error: UnityDataTools.FileSystem.SerializedFileOpenException: Failed to open serialized file: "/CAB-..."
   at ... (long stack trace)

# after:
Processing CAB-... 17092 SerializedFile
Error: "CAB-..." has no TypeTrees. The dump command needs TypeTrees to interpret the serialized object data, so this file cannot be dumped.

Testing

  • Added analyze tests (loose + archive no-TypeTree) and dump tests (loose + archive no-TypeTree) asserting the clean messages, the new summary category, and no leaked stack trace.
  • Verified normal analyze/dump (files with TypeTrees) still work.
  • Full suite passes (702 tests).

…eading errors

Analyzing AssetBundles whose SerializedFiles have no TypeTrees handed the
files to the native loader, which emitted misleading "Invalid serialized
file version" errors and could crash the process with an access violation
(0xC0000005) that cannot be caught in .NET.

Detect missing TypeTrees before the native open and skip such files cleanly,
printing the existing "does not have TypeTrees" hint. This unifies the
previously inconsistent outcomes (misleading errors, hard crash, or
"Invalid object id") into the same clear message the loose-file path already
produces, for both loose files and files inside archives.

- SerializedFileDetector: add stream-based overloads of TryDetectSerializedFile
  and TryParseMetadata (path-based ones delegate to them), a parseExtended flag
  to read only the EnableTypeTree flag cheaply, and IsMissingTypeTrees.
- UnityFileStream: a read/seek Stream over UnityFile so detection works on
  real paths and archive:/ entries inside a mounted bundle.
- SerializedFileSQLiteWriter: reject no-TypeTree files before OpenSerializedFile.
- SerializedFileOpenException: add a MissingTypeTrees flag.
- AnalyzerTool: report no-TypeTree files in a new "Files without TypeTrees"
  summary category, distinct from genuine failures.
Now that analyze detects missing TypeTrees and skips the file before any open
attempt, the "...can only be opened if all the types exactly match..." note is
misleading: the file is never handed to the loader regardless of the API build.

Drop the note from the analyze "Skipped (no TypeTrees)" output. The now-dead
GetOpenFailureHint call in the generic open-failure path is also removed, since
missing-TypeTree files are caught earlier. The hint is retained for the dump
command, which still attempts the open and where the explanation is accurate.
dump can never interpret a SerializedFile without TypeTrees, yet it handed
such files to the native loader, producing misleading version mismatch errors
and a raw SerializedFileOpenException with a stack trace (and, for archives,
no clean handling at all).

Detect missing TypeTrees before opening for both the direct-SerializedFile and
the Unity Archive paths, and print a clear message explaining dump cannot
process the file. This reuses the same SerializedFileDetector.IsMissingTypeTrees
check the analyzer uses.

With the dump path no longer relying on it, the now-unused GetOpenFailureHint
and MissingTypeTreesHint are removed from SerializedFileDetector.
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.

analyze: misleading version errors and process crash on AssetBundles without TypeTrees

1 participant