Case 107: task_scheduler_init Removed (historical ABI break)¶
| Field | Value |
|---|---|
| Verdict | ๐ด BREAKING |
| Category | Breaking |
| Platforms | Linux, macOS, Windows |
| Flags | ABI break, API break |
Detected ChangeKinds |
func_removed, type_removed |
| Source files | examples/case107_task_scheduler_init_removed/ |
Category: Class Removal | Verdict: ๐ด BREAKING
Verdict and consumer impact¶
An entire publicly-exported class โ task_scheduler_init โ is removed in v2.
Every consumer that referenced the class (constructed it, called its members,
or held it by value) gets undefined symbol at load time against the new
.so, and source code fails to compile against the new headers.
Recompilation cannot fix an already-deployed binary.
Old/new diff¶
| v1.h | v2.h |
|---|---|
class task_scheduler_init { ... }; |
(removed) |
explicit task_scheduler_init(int max_threads = automatic); |
(removed) |
void initialize(int); void terminate(); bool is_active() const; |
(removed) |
| โ | int active_concurrency(); (replacement helper) |
abicheck command¶
g++ -std=c++17 -shared -fPIC -g v1.cpp -o libfoo_v1.so
g++ -std=c++17 -shared -fPIC -g v2.cpp -o libfoo_v2.so
abicheck compare libfoo_v1.so libfoo_v2.so
Expected abicheck finding¶
Verdict: BREAKING (exit 4)
- type_removed: Type removed: mylib::task_scheduler_init
> Old code references a type that no longer exists; compilation or link
failure.
- func_removed_elf_only: Elf_only function removed: task_scheduler_init(int)
> (and 6 more, one per public ctor/dtor/method) Exported function symbol
removed from the binary; old binaries that link or dlsym() it can fail
even without header evidence.
Additions:
- func_added: New public function: mylib::active_concurrency()
Minimum evidence¶
min_evidence: L1 โ the class's constructors, destructor, and methods are
all defined (and therefore present in DWARF) in v1.cpp; removing the whole
class drops their debug-info entries and their exported symbols together.
No public headers are needed to see the break, though -g is required so
the Runtime failure demonstration below can build a matching app.
Why abicheck catches it¶
DWARF records task_scheduler_init as a DW_TAG_class_type with its member
functions as child DW_TAG_subprogram DIEs; when the class disappears from
v2's compilation unit entirely, abicheck's DWARF-based diff reports both the
type and every one of its exported members as removed.
Runtime failure demonstration¶
Severity: BREAKING
Scenario: compile app against v1, swap in v2 .so without recompile.
# Build old library + app
g++ -shared -fPIC -g v1.cpp -o libfoo.so
g++ -g app.cpp -L. -lfoo -Wl,-rpath,. -o app
./app
# โ active = 1 (expect 1)
# โ active = 0 (expect 0)
# Swap in new library (no recompile)
g++ -shared -fPIC -g v2.cpp -o libfoo.so
./app
# โ ./app: symbol lookup error: ./app: undefined symbol:
# _ZN5mylib19task_scheduler_initD1Ev
# Source rebuild against the v2 header also fails because the class is gone.
# app.cpp includes v2.h instead of v1.h when INCLUDE_V2 is defined.
g++ -std=c++17 -I. -DINCLUDE_V2 -c app.cpp -o app.o
# โ error: 'task_scheduler_init' is not a member of 'mylib'
Why BREAKING: the destructor symbol task_scheduler_init::~task_scheduler_init()
that app's stack-unwind path needs no longer exists in v2's dynamic symbol
table; the runtime linker refuses to resolve it and the process never starts.
Safe redesign¶
Don't remove publicly-exported classes in a minor release. The oneTBB
migration (the real-world case this fixture mirrors) shows the only safe
path:
1. Major SONAME bump (libtbb.so.2 โ libtbb.so.12).
2. Concurrent shipping of compatibility headers via a separate package
(tbb_preview) for a transition release.
3. Strong documentation of the migration with mechanical replacements.
Real-world example: classic TBB deprecated tbb::task_scheduler_init in
2020 and fully removed it in oneTBB 2021.1, alongside the entire tbb::task
low-level API (see case108). Every Boost build that linked TBB, every HPC
code using task_scheduler_init directly, and every downstream package had
to either pin to classic TBB or rewrite its initialization path.
References¶
Source files¶
CMakeLists.txtapp.cppv1.cppv1.hv2.cppv2.h
See also: Examples overview ยท All BREAKING cases ยท Category: Breaking.