Skip to content

Case 58: Global Variable Removed

Field Value
Verdict ๐Ÿ”ด BREAKING
Category Breaking
Platforms Linux, macOS
Flags ABI break, API break
Detected ChangeKinds var_removed
Source files examples/case58_var_removed/

Category: Symbol API | Verdict: BREAKING

What this case is about

v1 exports two global variables: lib_version and lib_debug_level. v2 removes lib_debug_level from the export table (made it static).

Consumers that reference lib_debug_level directly will fail to link or crash at runtime with a missing symbol error.

What breaks at binary level

  • Symbol lookup fails: lib_debug_level is no longer in .dynsym. The dynamic linker cannot resolve the reference โ†’ undefined symbol error or relocation failure at program startup.
  • Direct access patterns break: Code that reads/writes the variable (e.g., lib_debug_level = 3) will fail due to unresolved symbol/relocation at startup, before the program begins execution.

What abicheck detects

  • VAR_REMOVED: The global variable symbol is absent from v2's export table.

Overall verdict: BREAKING

How to reproduce

gcc -shared -fPIC -g bad.c  -o libbad.so
gcc -shared -fPIC -g good.c -o libgood.so

nm -D libbad.so  | grep lib_debug_level  # โ†’ D lib_debug_level
nm -D libgood.so | grep lib_debug_level  # โ†’ (nothing)

python3 -m abicheck.cli dump libbad.so  -o /tmp/v1.json
python3 -m abicheck.cli dump libgood.so -o /tmp/v2.json
python3 -m abicheck.cli compare /tmp/v1.json /tmp/v2.json
# โ†’ BREAKING: VAR_REMOVED

How to fix

Keep the variable exported for backward compatibility, even if deprecated:

int lib_debug_level __attribute__((deprecated)) = 0;

Or use a version script to control when symbols are removed.

References

Real Failure Demo

Severity: BREAKING / LOAD-TIME FAILURE

cmake -S examples -B /tmp/abicheck-examples-build -DCMAKE_BUILD_TYPE=Debug
cmake --build /tmp/abicheck-examples-build --target case59_var_removed_app case59_var_removed_v2

tmp=$(mktemp -d)
cp /tmp/abicheck-examples-build/case59_var_removed/app_v1 "$tmp/"
cp /tmp/abicheck-examples-build/case59_var_removed/libv2.so "$tmp/libv1.so"
(cd "$tmp" && LD_LIBRARY_PATH=. ./app_v1)
# ./app_v1: symbol lookup error: ./app_v1: undefined symbol: lib_debug_level

Source files

  • CMakeLists.txt
  • app.c
  • bad.c
  • good.c

See also: Examples overview ยท All BREAKING cases ยท Category: Breaking.