Skip to content

fix(libc): list stack return address candidates in Windows backtrace reports - #3887

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
reyani-dev:fix/libc-windows-backtrace-stack-candidates
Oct 11, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
reyani-dev:fix/libc-windows-backtrace-stack-candidates

Conversation

@reyani-dev

Copy link
Copy Markdown
Contributor

What

On Windows, the abort() and UCRT invalid-parameter reports (ReportBacktrace in CrashReport.cpp) capture the stack with RtlCaptureStackBackTrace. That stops at the first frame without unwind data: guest code, or our own .prx libraries, which are built with -fno-asynchronous-unwind-tables. So these reports usually end two or three frames in, before reaching any caller. The fault report (ReportCrash) already scans the stack for code addresses ("stack return address candidates"). This PR moves that scan into a helper. ReportCrash uses it unchanged (16 entries over 0x2000 bytes), and ReportBacktrace now uses it too, with 32 entries over 0x4000 bytes, since it starts inside our handler and the UCRT's frames.

Where it matters: catalog titles that abort on Windows. On main a11c8f7, ProsperoTV (PPSA99003) aborts on the poll throw (#3584) and its report ends with:

FATAL: abort() (SIGABRT) on thread 37596
    #0 0x00007ffa04cdac85 libkernel.prx+0x5ac85
    #1 0x00007ffa04cda8d5 libkernel.prx+0x5a8d5
    #2 0x00007ffa04cb49a6 libkernel.prx+0x349a6
    #3 0x00007ffaad09cd30 ucrtbase.dll+0x2cd30

There's no guest frame, so the guest call site has to be found another way. ProsperoLight (PPSA99002), on main plus open PRs for its earlier stops, reports FATAL: UCRT invalid parameter with only libc.prx+0xa9e7, libc.prx+0x9f492 and a stack address. With the scan, the same report lists the libSceNet.prx, libkernel.prx and app.exe return addresses above it, which is how I narrowed it down. That stop isn't on main yet, so I'm not filing it here.

The test's own output with this change:

FATAL: abort() (SIGABRT) on thread 42996
    #0 0x00007ff9620da9f8 libc.prx+0xa9f8
    #1 0x00007ff96216f4e9 libc.prx+0x9f4e9
    #2 0x0000006c3d5ff4f0
  stack return address candidates:
    [rsp+0x8] 0x00007ffaad132139 ucrtbase.dll+0xc2139
    [rsp+0x88] 0x00007ffaad115261 ucrtbase.dll+0xa5261
    [rsp+0xb8] 0x00007ff70388349a windows_backtrace_report_tests.exe+0x349a
    ...

Tested

Windows 11 (26200), WinLibs GCC 15.2.0 r7, Release, main a11c8f7:

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes (Claude Code)

🤖 Generated with Claude Code

reyani-dev and others added 2 commits October 12, 2026 03:41
…reports

The abort() and UCRT invalid-parameter reports capture the stack with
RtlCaptureStackBackTrace, which stops at the first frame without unwind
data (guest code, or our libraries built without asynchronous unwind
tables), so they often end two or three frames in, before any caller.
The fault report already scans the stack for code addresses; that scan
is now a helper the backtrace reports use as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the diff: ReportCrash keeps its 16 entries / 0x2000 bytes through the new helper, ReportBacktrace adds the stack scan, helper is declared in the anonymous namespace before use, and windows_backtrace_report is registered in ctest under if(MINGW) with a regex matching the report. Windows-only, so not built or run here; merging on green CI.

@adriadam10
adriadam10 merged commit 24865e8 into boykopovar:main Oct 11, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants