Skip to content

test(libc): cover the standard exception classes and throw helpers - #9773

Open
DavidSamir wants to merge 1 commit into
boykopovar:mainfrom
DavidSamir:test/libc-standard-exception-classes
Open

DavidSamir wants to merge 1 commit into
boykopovar:mainfrom
DavidSamir:test/libc-standard-exception-classes

Conversation

@DavidSamir

Copy link
Copy Markdown
Contributor

What

Line coverage of libc and libkernel over the CPU-side test suite (gcov, Windows) showed about 110 exports in exception/StandardExceptions.cpp that no test ran. They are the constructors, destructors, what and assignment of the standard exception classes, plus the throw helpers.

How:

  • New test tests/GuestStandardExceptionClasses.cpp, registered as guest_standard_exception_classes next to guest_bad_optional_access (it follows the same pattern):
    • exception, bad_alloc, bad_array_new_length, bad_cast, bad_typeid and bad_function_call:
      • the type record's name, and its base in the standard hierarchy (none for exception, bad_alloc for bad_array_new_length, otherwise exception);
      • the vtable's offset, type and what slot;
      • C1Ev and C2Ev install the vtable, and what() is non-empty and matches the vtable's what;
      • D1Ev and D2Ev run, and D0Ev deletes a malloced object.
    • logic_error, domain_error, invalid_argument, length_error, out_of_range and runtime_error:
      • the same type and vtable checks (base logic_error or exception);
      • what() returns the constructor's message, copied, so changing the caller's buffer afterwards doesn't affect it;
      • the copy constructors share the message;
      • assignment replaces it and returns the object, and self-assignment keeps it;
      • all three destructors run.
    • bad_weak_ptr (no exported constructor): its type, what and destructors.
    • Ten throw helpers throw: _Xbad_alloc, _Xrange_error, _Xlength_error, _Xinvalid_argument, _Throw_bad_weak_ptr, _Xbad_function_call, __throw_bad_variant_access, __cxa_bad_cast, __cxa_bad_typeid and __cxa_throw_bad_array_new_length.
  • what() text for the classes without a message is checked only for being non-empty; the console's exact strings are not pinned.

Tested

  • Windows 11 Pro 26200, WinLibs GCC 15.2.0, Release, no GPU involved: the new test passes, and so do the 21 exception and bad_* tests.
  • Negative control: with Assign keeping the old message, the test fails at the assignment check. Restored, it passes.
  • tools/check_conventions.py passes.

Overlap (tools/pr_overlap.py --branch plus git merge-tree):

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 under Silent stubs in their library's technical debt file
  • 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
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

No test constructed, copied, assigned or destroyed the standard exception
classes libc exports, or called their throw helpers. A new
guest_standard_exception_classes test checks, for exception, bad_alloc,
bad_array_new_length, bad_cast, bad_typeid and bad_function_call, the type
name and base, the vtable, both constructors, what and the three
destructors. For logic_error, domain_error, invalid_argument, length_error,
out_of_range and runtime_error it also checks that what returns the
constructor's message, that copies share it and that assignment replaces
it. bad_weak_ptr's what and destructors and ten throw helpers are run too.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new test checks type records and base relationships, vtable address points, constructors/destructors (including deleting destructors), message ownership and assignment, and all ten throw helpers. I compared its expected object/vtable layout and behavior with StandardExceptions.cpp; the assertions match the implementation. The reported negative control for assignment adds useful red/green evidence.

Hosted register-context tests pass on Ubuntu and macOS Intel in Debug and Release; conventions, eligibility, relinker, ASan and write-watch checks also pass. Linux/Windows product jobs are skipped by policy. The current-main commits since the PR base do not touch StandardExceptions.cpp or this CMake section; merge-tree and diff-check are clean. I did not rerun CTest locally because there is no configured build and less than 1 GB free on disk.

#9775 also adds a separate CMake test registration in this block; the pairwise merge is clean and the registrations do not overlap semantically. No implementation duplicate was found.

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5021 core/libs/prx/libc/CMakeLists.txt
PR 6819 core/libs/prx/libc/CMakeLists.txt
PR 7081 core/libs/prx/libc/CMakeLists.txt
PR 7447 core/libs/prx/libc/CMakeLists.txt
PR 7715 core/libs/prx/libc/CMakeLists.txt
PR 8150 core/libs/prx/libc/CMakeLists.txt
PR 8965 core/libs/prx/libc/CMakeLists.txt
PR 9929 core/libs/prx/libc/CMakeLists.txt
PR 11831 core/libs/prx/libc/CMakeLists.txt
PR 12682 core/libs/prx/libc/CMakeLists.txt
PR 12688 core/libs/prx/libc/CMakeLists.txt
PR 12700 core/libs/prx/libc/CMakeLists.txt
PR 12965 core/libs/prx/libc/CMakeLists.txt
PR 13390 core/libs/prx/libc/CMakeLists.txt
PR 14585 core/libs/prx/libc/CMakeLists.txt

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exact head f934c4b2c53aae56b3abebf933c32c27df08ba94 has a clean merge tree with current main (11f976b27c16ed91633f00039dba5dfd97dd7cc1); conventions and diff-check pass. The test covers the standard exception hierarchy, vtable slots, constructors/destructors, assignment, and throw helpers. The author reports Windows focused and exception-suite results; hosted register-context/relinker checks pass, while product Linux/Windows jobs are skipped. This branch is based on 8b3e39832a, 32 commits behind current main; please rebase and rerun guest_standard_exception_classes before merge. I did not rerun locally.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@DavidSamir The test-local exception-object declarations differ from the public types, for example const char* _ZNKSt9exception4whatEv_nid_postfix(const Object*) at core/libs/tests/GuestStandardExceptionClasses.cpp:20 versus const char* _ZNKSt9exception4whatEv_nid_postfix(const LibcException::ExceptionObject* self) at core/libs/prx/libc/include/Api.hpp:1146; void _ZNSt11logic_errorC1EPKc_nid_postfix(Object*, const char*) at core/libs/tests/GuestStandardExceptionClasses.cpp:105 versus void _ZNSt11logic_errorC1EPKc_nid_postfix(LibcException::ExceptionObject* self, const char* message) at core/libs/prx/libc/include/Api.hpp:1193; void _ZNSt9exceptionD1Ev_nid_postfix(Object*) at core/libs/tests/GuestStandardExceptionClasses.cpp:18 versus void _ZNSt9exceptionD1Ev_nid_postfix(LibcException::ExceptionObject* self) at core/libs/prx/libc/include/Api.hpp:1143, with the same local Object pattern across the constructor, destructor, assignment and what families. Main now requires each exported function to be declared once, in the library's public header (checked by the public_headers tests). Could you use main’s public signatures and types throughout the implementation and tests, or explain why the public declarations need to change?

@wachi35676

Copy link
Copy Markdown
Contributor

Tested head f934c4b2c5 merged onto main 9c435c2812, Windows 11 (WinLibs GCC 15.2.0, Release) and WSL2 Ubuntu 24.04 (GCC 13.3), BUILD_TESTING=ON. This adds the Linux run.

  • guest_standard_exception_classes_tests builds, and guest_standard_exception_classes passes 3 of 3 runs on both hosts against current main's libc.

AI-assisted: yes (Claude Code); results above were run on this machine.

@THEMANnt THEMANnt left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed f934c4b2c53aae56b3abebf933c32c27df08ba94. Approve; the earlier validation blocker is resolved.

The missing native execution step is complete. Reviewed coverage exercises the standard exception type/vtable records, plain and message-object construction/destruction, message ownership/copies/assignment and the ten throw helpers. No actionable findings.

Validation: Compiled the complete exact GuestStandardExceptionClasses.cpp with the pinned exception runtime through its actual combined translation unit, src/exception/Exports.cpp, using project Windows unwind settings and section conversion. This includes Runtime, TypeInfo, StandardExceptions, Unwind and Personality source in their intended order. The complete test executable returns 0, including all throw/catch assertions.

Scope: Existing libc linkage supplies ancillary symbols; this is not a rebuild of every libc source or all exception tests. The earlier standalone StandardExceptions.cpp compilation failures were reviewer-harness errors caused by bypassing Exports.cpp, not defects introduced by this test. No application/game run.

This branch has not been deployed

No deployments
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.

5 participants