Skip to content

fix: provide the test stubs for pg_sys extern statics via pg_module_magic! macro - #2284

Closed
peterkyle01 wants to merge 1 commit into
pgcentralfoundation:developfrom
peterkyle01:develop
Closed

fix: provide the test stubs for pg_sys extern statics via pg_module_magic! macro#2284
peterkyle01 wants to merge 1 commit into
pgcentralfoundation:developfrom
peterkyle01:develop

Conversation

@peterkyle01

Copy link
Copy Markdown

Fixes #2281

A pgrx extension is compiled as a .so or .dylib that gets dlopen'd into PostgreSQL at runtime. All the PostgreSQL symbols like CurrentMemoryContext and BufferBlocks are provided by the running PostgreSQL process so the .so doesn't need to define them.

When cargo test runs, Rust produces a standalone test executable which is not loaded into PostgreSQL. Those symbols don't exist anywhere so the linker fails with undefined symbol.

Normally --gc-sections prunes all unreferenced pg_sys extern declarations. But #[typetag::serde] uses inventory::submit!() to register trait implementations via a "life before main" constructor and that constructor unconditionally references the trait impl methods, which reference pg_sys symbols, pulling them into the live-code set and defeating dead code elimination.

In this PR:

The fix adds #[unsafe(no_mangle)] stub definitions for the commonly-leaked pg_sys extern statics CurrentMemoryContext, error_context_stack, PG_exception_stack, emit_log_hook, Log_error_verbosity, Log_line_prefix, Log_destination, Log_destination_string, syslog_sequence_numbers, syslog_split_messages and BufferBlocks inside the pg_magic_func!() macro, gated behind #[cfg(test)].

Why the macro?

  • #[cfg(test)] only fires in the crate under test so dependencies like pgrx-pg-sys are never compiled with cfg(test) by Cargo so placing the stubs in the macro ensures they expand in the extension's own source, where cfg(test) actually works.
  • Every extension already calls pg_module_magic!()
  • The .so build never includes the stubs (no cfg(test)) so PostgreSQL's real symbols are never shadowed.

@eeeebbbbrrrr eeeebbbbrrrr added the wontfix This will not be worked on label May 31, 2026
@eeeebbbbrrrr

Copy link
Copy Markdown
Contributor

Thanks but this is not the right way to handle this.

If your project has normal rust #[test] tests that reference pg_sys:: symbols, either directly or indirectly, that is a bug with your project, it is not something pgrx should accommodate.

It is pgrx's job, as much as it can, to not let its users do things they shouldn't do.

@peterkyle01

Copy link
Copy Markdown
Author

Okay thanks @eeeebbbbrrrr for the review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wontfix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

typetag::serde trait impls leak Postgres symbols into cargo test / coverage binaries (pgrx 0.18+)

2 participants