Skip to content

Fix font test segfault on SDL3 #3549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

Starbuck5
Copy link
Member

@Starbuck5 Starbuck5 commented Aug 4, 2025

Tested in combination with #3428 and #3544

EDIT: removed extremely misleading AI summary

@Starbuck5 Starbuck5 requested a review from a team as a code owner August 4, 2025 07:16
@Starbuck5 Starbuck5 added font pygame.font sdl3 labels Aug 4, 2025
@ankith26
Copy link
Member

@coderabbitai full review

Copy link

coderabbitai bot commented Aug 13, 2025

✅ Actions performed

Full review triggered.

Copy link

coderabbitai bot commented Aug 13, 2025

Walkthrough

Updated font deallocation in src_c/font.c to conditionally call TTF_CloseFont based on SDL version and a generation check, preventing closure after SDL_ttf teardown. For SDL3+, close only when generations match; for older SDL_ttf, preserve prior nulling-then-close behavior. Public interfaces unchanged.

Changes

Cohort / File(s) Summary of changes
Font deallocation logic
src_c/font.c
Added generation-guarded TTF_CloseFont calls: for SDL 3.0.0+, close only if self->ttf_init_generation equals current_ttf_generation; set self->font to NULL accordingly. For pre-SDL3, retain legacy nulling trick then close. Added explanatory comments and TODO. No public API changes.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant FontObj as Font object
  participant SDLTTF as SDL_ttf

  Caller->>FontObj: deallocate()
  alt SDL >= 3.0.0
    FontObj->>FontObj: check generations (self vs current)
    alt generations match
      FontObj->>SDLTTF: TTF_CloseFont(font)
      FontObj->>FontObj: self->font = NULL
    else generations mismatch
      FontObj->>FontObj: skip close (no-op)
    end
  else SDL < 3.0.0
    FontObj->>FontObj: null underlying face (private trick)
    FontObj->>SDLTTF: TTF_CloseFont(font)
    FontObj->>FontObj: self->font = NULL
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A nibble of bytes, a hop, then a check—
Generations align, we close with respect.
If not, we pause, no segfault despair,
Fonts tucked safely, handled with care.
Thump-thump goes my review-y heart—
SDL3 smartness, a rabbity art. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
src_c/font.c (1)

1213-1232: Wrong version macro: use SDL_TTF_VERSION_ATLEAST for TTF-specific behavior

This guard should key off the SDL_ttf version, not the SDL core version. The rest of the file consistently uses SDL_TTF_VERSION_ATLEAST for TTF API differences. Using SDL_VERSION_ATLEAST here risks selecting the wrong branch on mixed-version builds and is inconsistent.

Apply this diff:

-#if SDL_VERSION_ATLEAST(3, 0, 0)
+#if SDL_TTF_VERSION_ATLEAST(3, 0, 0)
🧹 Nitpick comments (2)
src_c/font.c (2)

1213-1218: Clarify comment to reflect SDL_ttf 3.x semantics

Minor wording nit: This is about SDL_ttf 3.x teardown behavior, not SDL3 core. Tighten the comment for accuracy and consistency with the rest of the file.

Apply this diff:

-        // In SDL3_ttf, it seems that closing a font after its library was
-        // destroyed segfaults. So only close if same generation.
-        // TODO SDL3:
-        // TTF docs say "A well-written program should call TTF_CloseFont()
-        // on any open fonts before calling this function!"
+        // In SDL_ttf 3.x, closing a font after TTF_Quit() may segfault.
+        // Only close when the font was created in the current generation.
+        // TODO(SDL_ttf 3): Docs recommend calling TTF_CloseFont() on all open
+        // fonts before TTF_Quit(); our generation guard intentionally violates
+        // that to avoid crashes when teardown order is not guaranteed.

1213-1232: Optionally clear self->font even if font_initialized is false

If TTF was already quit (font_initialized == 0), this block is skipped and self->font is left non-NULL until the object memory is freed. Harmless, but setting it to NULL defensively avoids any chance of stale handle reuse in future maintenance or re-entrant finalization paths.

You can add this just before calling tp_free (outside the conditional), e.g.:

/* Ensure member cleared even if we skipped TTF_CloseFont because SDL_ttf was quit. */
self->font = NULL;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6e81a0 and bfd0147.

📒 Files selected for processing (1)
  • src_c/font.c (2 hunks)

@Starbuck5
Copy link
Member Author

For reviewers, this PR is still ready for review. I have looked over the coderabbit comments and none of them are valid or need to be done.

Copy link
Member

@ankith26 ankith26 left a comment

Choose a reason for hiding this comment

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

For now I think this is good enough, fixing a segfault should be a priority and this PR does that. Once our SDL3 support is more mature we could investigate into the edge case (quit not in the same generationl) and see if there's a memory leak and then plan a fix (probably keeping track of all open fonts on our side and closing stuff manually on quit might be needed?)

@ankith26 ankith26 merged commit 9734b92 into pygame-community:main Aug 17, 2025
26 checks passed
@ankith26 ankith26 added this to the 2.5.6 milestone Aug 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
font pygame.font sdl3
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants