After the function compute_diff is invoked to compute the diff against
to corpora, the reference count of the diff_context_sptr that it takes
get incremented several times.
So the diff_context_sptr is not automatically released (freed) when
its scope is left.
The reason why the reference count of diff_context_sptr is incremented
is because several diff types (the diff type itself or types extending
it) actually holds a reference to the diff_context_sptr they get
created with. So the lifetime of the diff_context_sptr becomes tied
to the lifetime the different diff objects in a hard-to-predict way.
It actually creates some cyclic references that, in this case, creates
a leak. The diff_context_sptr never gets released.
This patch fixes that by making the diff types hold a weak reference
to the diff_context_sptr they are created with.
* src/abg-comparison.cc (diff::priv::ctxt_): Make this a weak_ptr.
(diff::priv::get_context): Convert the weak pointer to the context
into a shared_ptr and return it.
(diff::priv::is_filtered_out): Adjust to use
diff::priv::get_context() to access the context.
(diff::context): Likewise.
(corpus_diff::priv::ctxt_): Make this a weak_ptr.
(corpus_diff::priv::priv): Add a new overload that takes two
corpora and a diff context.
(corpus_diff::priv::get_context): Convert the weak pointer to the
context into a shared_ptr and return it.
(corpus_diff::priv::ensure_lookup_tables_populated): Adjust to use
the new corpus_diff::priv::get_context to get the context.
(variable_is_suppressed): Likewise.
(corpus_diff::priv::{apply_suppressions_to_added_removed_fns_vars,
apply_filters_and_compute_diff_stats, emit_diff_stats,
categorize_redundant_changed_sub_nodes,
clear_redundancy_categorization}): Likewise.
(corpus_diff::{corpus_diff, context,
apply_filters_and_suppressions_before_reporting}): Adjust.
* tools/abipkgdiff.cc (compare): Make the overload that compares
elf binaries take a diff context output parameter. After the
context is created by this function, it's return to the caller, so
that it's life time is bound to the scope this function was
called from.
(pthread_routine_compare): Create a shared pointer to hold a
reference on a diff context. Pass that shared pointer by
reference to the compare function that compares elf binaries.
Rather than storing corpora in the reports_map, (as those corpora
would then out-live the diff context and thus create memory
corruption issues), emit the report directly into an ostringstream
and store that stream in reports_map.
(compare): In the overoad that compares packages, rather than
trying to get corpora from the report_map, just emit the content
of the ostringstream that is now there.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>