agentsclimarketplace

Sanitize stack

Skill 0xZOne/sanitize-stack

A worked example of building a Claude Code skill from scratch: decisions, design, smoke test, maintenance.

Install
npx -y skills add 0xZOne/sanitize-stack

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

This skill should be used when the user asks to "sanitize a crash stack", "scrub a stack trace", "clean up a stack for crbug", "prepare a stack for issues.chromium.org", "prepare a stack for Gerrit", "脱敏崩溃堆栈", or pastes a native crash stack (typically Chromium or a Chromium-based embedder) and expresses intent to attach it to a public issue tracker or code review. Transforms raw symbolicated stacks into paste-ready comments by scrubbing downstream module names, normalizing locale tokens, collapsing verbose C++ template signatures, eliding Chromium boilerplate frames, and flagging residual PII for human review.

SKILL.md

10.9 KB, as published. Nobody here has run it

Sanitize Crash Stack

Transform a raw symbolicated native crash stack into a paste-ready comment for issues.chromium.org, crbug.com, or a Chromium Gerrit CL description. Public trackers require module names and debug output to be free of downstream product identifiers and environment PII; enforce a consistent sanitization and trimming pipeline so every posted stack has the same shape and safety guarantees.

When This Skill Applies

Trigger on a pasted crash stack combined with any of:

  • Intent to file or comment on a public bug (crbug.com, issues.chromium.org, bugs.chromium.org)
  • Intent to attach to a Gerrit CL description or review comment
  • Explicit phrases like "sanitize", "scrub", "脱敏", "clean up before posting"

Skip this skill when:

  • The target is a private/internal tracker and the user explicitly wants the raw stack preserved
  • The stack is not symbolicated (raw addresses + pdb only) — ask the user to symbolicate first using windbg / minidump_stackwalk / llvm-symbolizer
  • The stack is already in Chromium-standard form with no downstream identifiers — in that case offer trim-only mode (Steps 4-6) and skip scrub steps

Input Handling

Locate the stack trace via:

  1. If invoked with a file path argument, read the file with the Read tool
  2. Otherwise, scan the most recent user messages for a block of lines matching native stack trace patterns (function names with !, line numbers, source file references)
  3. If no stack is found, ask the user to paste one

Do not proceed without an explicit stack. Do not fabricate or reconstruct missing frames.

Pipeline

Execute the six steps in order. Record each transformation to produce the final diff summary.

Step 1: Scrub Downstream Module Names

Regex-scan for module name patterns: ^\s*(\w+)\.(dll|exe|so|dylib)!.

Collect every unique module name observed. Classify each as:

  • Chromium-standard: chrome, chrome_elf, content_shell, chromedriver, libchrome, or any module prefixed with test_
  • Downstream / unknown: anything else (examples: brave, vivaldi, opera, msedge, custom embedder names)

Replacement rules:

  • Chromium-standard → preserve as-is; record "Symbols from upstream Chromium build" for the provenance line
  • Downstream → replace every occurrence with chrome.dll (or matching extension: .exechrome.exe, .solibchrome.so, .dyliblibchrome.dylib); record "Module names normalized to chrome.* (symbolicated against upstream source)" for the provenance line

If multiple distinct downstream modules appear, treat as a warning and list all observed names under Safety Review for human confirmation — this may indicate a mixed-process or mis-symbolicated stack.

Step 2: Normalize Locale Tokens

Apply these substitutions before rendering:

SourceReplacement
(CJK line marker, MSVC/WinDbg CN/JP locale)line
Zeile (German)line
ligne (French)line
строка (Russian)line
Any other non-ASCII locale tokenFlag in Safety Review and preserve

Debugger locale pollution is common on Windows; MSVC and WinDbg emit localized line markers depending on the developer's OS language.

Step 3: Collapse C++ Template Signatures

Apply the substitution table, in order. Earlier rules must run before later ones because later rules assume earlier cleanup already happened.

PatternReplacement
std::__Cr::basic_string<char16_t, std::__Cr::char_traits<char16_t>, std::__Cr::allocator<char16_t>>std::u16string
std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>>std::string
std::__Cr::unique_ptr<T, std::__Cr::default_delete<T>>std::unique_ptr<T>
std::__Cr:: prefix anywhere(delete)
base::internal::Invoker<...huge variadic...>::RunImpl<...>Elide frame entirely — boilerplate
base::internal::DecayedFunctorTraits<...>::Invoke<...>Elide frame entirely — boilerplate

Preserve these types verbatim: scoped_refptr<T>, base::WeakPtr<T>, base::OnceCallback<Sig>, base::RepeatingCallback<Sig>, raw_ptr<T>, raw_ref<T>.

Step 4: Classify Signal vs Noise Frames

Keep as signal:

  • Any frame with a source path under chrome/, components/, content/, blink/, third_party/blink/, ui/, net/, gpu/, services/, sandbox/
  • Any frame whose function name matches a class or method mentioned in the current bug context
  • The *::AcceptSyncMessage frame from IPC::ChannelAssociatedGroupController — always keep; this is the decisive marker for sync IPC race diagnosis
  • At least one mojo::InterfaceEndpointClient::HandleValidatedMessage frame for mojo dispatch context
  • Generated mojo *::StubDispatch::AcceptWithResponder frames

Elide as noise, replacing the contiguous tail at the bottom of the stack with a single summary line.

For the authoritative list of noise-frame families and patterns, consult:

  • references/noise-frames.md — Complete Chromium boilerplate frame classification with regex patterns

The most commonly elided families:

  • base::internal::* (Bind/Invoke machinery)
  • base::TaskAnnotator::*
  • base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::*
  • base::MessagePump*::*, base::RunLoop::*
  • content::BrowserMainLoop::*, content::BrowserMain*, content::ContentMain*
  • ChromeMain, MainDllLoader::*, wWinMain, main, WinMain
  • Mojo dispatch middle frames: MessageDispatcher::Accept, HandleIncomingMessage, HandleIncomingMessageThunk::Accept
  • Sibling mojo stub wrappers: *::Stub<RawPtrImplRefTraits>::AcceptWithResponder (keep only StubDispatch variant)

Replace the elided tail with one line matching the actual boilerplate family:

[base::Bind / TaskAnnotator / MessagePumpForUI / BrowserMain — standard UI-thread dispatch, elided]

Adjust the summary if the crash is on a worker thread (mention ThreadPoolImpl::Worker instead), or on an IO thread (MessagePumpLibevent or similar).

Step 5: Render Markdown Output

Format the sanitized stack as:

  1. Provenance paragraph (outside the code block). Adjust to reflect only the transformations that were actually performed:

    Adding the browser-side crash stack for context. Symbolicated against upstream source; module names normalized to chrome.*, C++ template signatures shortened, standard UI-thread dispatch tail elided. Line numbers are from a symbolicated downstream build and may differ by a few from upstream HEAD.

  2. Fenced code block containing the sanitized frames. Each frame occupies two lines:

    • Line 1: module.dll!<function signature> (collapsed per Step 3)
    • Line 2, indented 4 spaces: source_file.cc:line_number
  3. Elision marker as the last line inside the code block.

  4. Optional ### Why this stack matters section if any of these conditions hold:

    • An AcceptSyncMessage frame is present — explain the sync IPC race window in one paragraph
    • The crash is inside a bound callback invoked from TaskAnnotator — note that the failing work was posted from elsewhere, so the poster site is not directly visible
    • The stack spans a known Chromium trap (re-entrancy into a destroyed object, UAF during shutdown, etc.)

Step 6: Safety Review

Scan the sanitized stack for residual risk patterns before presenting it:

PatternAction
/Users/[^/]+/, C:\\Users\\[^\\]+\\, /home/[^/]+/Flag the username — likely a symbol path leak
\S+@\S+\.\S+ (email literal)Flag
\b[a-z0-9-]+\.(corp|internal|local|intranet)\bFlag internal hostname
IPv4 / IPv6 literalsFlag
Non-ASCII characters (any remaining after Step 2)Flag — suspicious
Original downstream module names (missed in Step 1)Flag — indicates regression in Step 1 matcher

Do not auto-delete flagged items — list them under a ### Safety review section for human judgment. A CamelCase class name that looks like a codename may actually be a legitimate Chromium class (example: JavaScriptTabModalDialogManagerDelegateDesktop). Defer that call to the human.

Output Format

Present the final result to the user in this order:

  1. One-line summary of transformations performed. Example: "Scrubbed 1 downstream module (downstreamchrome), elided 18 boilerplate frames, collapsed 4 template signatures, flagged 0 residual PII."
  2. Provenance paragraph matching actual transformations.
  3. Fenced code block with the sanitized stack.
  4. Optional ### Why this stack matters diagnostic observations.
  5. ### Safety review list (even if empty — print "No residual concerns detected.").
  6. Paste instructions — one sentence reminding the user this content is not auto-posted; manual copy into the tracker or Gerrit comment field is required, and the Preview button should be used before Submit.

Validation Checklist

Before returning the output, verify:

  • Provenance paragraph matches only the transformations actually performed
  • No downstream module names remain (if Step 1 scrub was applied)
  • All non-ASCII characters accounted for (normalized in Step 2 or flagged in Step 6)
  • Elision line accurately reflects the noise family elided (UI thread vs worker vs IO)
  • Safety review section is present (empty-state message if no flags)
  • At least the top signal frame (the crashing function) is preserved with original function name
  • Line numbers are not modified — only module names and template signatures are transformed

Additional Resources

Reference Files

  • references/noise-frames.md — Authoritative list of Chromium frame families classified as noise, with regex patterns and worker-thread variants

Common Mistakes to Avoid

  • Do not guess line numbers against upstream HEAD. Line numbers may differ between downstream builds and upstream; preserve the original numbers and note the possible drift in the provenance paragraph.
  • Do not strip AcceptSyncMessage. It is the decisive marker that distinguishes a sync IPC race from an async dispatch race. Reviewers use it to diagnose the race window.
  • Do not auto-resolve CamelCase flags. Class names that look like product codenames may be legitimate Chromium types. Only a human can decide.
  • Do not post the output directly. This skill prepares a paste-ready block; the user must manually paste and preview in the tracker.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.