Skip to content

case143 — Accidental export (single-release audit)

Field Value
Verdict 🟡 COMPATIBLE_WITH_RISK
Category Risk
Platforms Linux
Flags Bad practice
Detected ChangeKinds
Source files examples/case143_audit_accidental_export/

Verdict: 🟡 COMPATIBLE_WITH_RISK · Cross-check: exported_not_public · Mode: single-release audit (no baseline) · Evidence tier: L2

What it demonstrates

A function compiled with default visibility but never declared in a public header is an accidental export: it ships in the dynamic symbol table, so consumers can bind to it, yet it is not part of the documented API. abicheck finds this from one artifact, with no previous release to diff against.

Why no single source sees it

Source What it sees alone
Binary export table (L0) _Z6renderv, _Z11debug_dumpv — both look like ordinary exports
Public-header AST (L2) declares only render()
Combination debug_dump() is exported but undeclared → EXPORTED_NOT_PUBLIC

The cross-check needs both the binary exports and the public-header decls; neither in isolation can tell an accidental export from an intentional one.

Reproduce

abicheck scan --binary libdemo.so -H include/ --audit

The committed snapshot.abi.json carries the same L0 + L2 provenance a live scan --audit would dump, so tests/test_g20_catalog.py validates the finding compiler-free.

Fix

Add debug_dump to the version script's local block (or mark it __attribute__((visibility("hidden")))) — or, if it is meant to be public, declare it in an installed header.


Source files

  • snapshot.abi.json

See also: Examples overview · All COMPATIBLE_WITH_RISK cases · Category: Risk.