diff options
authorDodji Seketeli <>2016-08-23 12:38:36 +0200
committerDodji Seketeli <>2016-08-23 12:38:36 +0200
commit09154361a446fcd86f2d5db8da686126150be872 (patch)
parentControl symbols exported from (diff)
Don't walk diff trees indefinitely when applying suppressions
When applying suppressions to diff graphs, if the same diff node appears twice in the graph in a way that creates a cycle, we can get trapped in the cycle when walking the graph. That results in a an infinite loop. Note that the infinite loop appears in the diff::traverse member function, in the for-loop that walks the children nodes of a given node. This patch avoids walking the same node twice when applying suppressions. The test binaries that exhibit the issue come from the two following packages: rh-mariadb101-mariadb-10.1.14-2.el6 and rh-mariadb101-mariadb-10.1.16-1.el6. The sub-packages compared are rh-mariadb101-mariadb-server-10.1.14-2.el6.x86_64.rpm and rh-mariadb101-mariadb-server-10.1.16-1.el6.x86_64.rpm. The debug info packages are rh-mariadb101-mariadb-debuginfo-10.1.16-1.el6.x86_64.rpm and rh-mariadb101-mariadb-debuginfo-10.1.14-2.el6.x86_64.rpm. Once the packages are properly extracted the command line that exhibits the infinite loop is: abidiff --d1 rh-mariadb101-mariadb-10.1.14-2.el6.x86_64/usr/lib/debug --d2 rh-mariadb101-mariadb-10.1.16-1.el6.x86_64/usr/lib/debug rh-mariadb101-mariadb-10.1.14-2.el6.x86_64/opt/rh/rh-mariadb101/root/usr/lib64/mysql/plugin/ rh-mariadb101-mariadb-10.1.16-1.el6.x86_64/opt/rh/rh-mariadb101/root/usr/lib64/mysql/plugin/ This patch has no test because of the cheer size of these packages; the debug info packages alone take more than 100MB :-( I really hope we set up a separate repository with big test packages to overcome this. Maybe something using fedabipkgdiff ... Signed-off-by: Dodji Seketeli <>
1 files changed, 4 insertions, 2 deletions
diff --git a/src/ b/src/
index 9f1dec72..94d830c1 100644
--- a/src/
+++ b/src/
@@ -12513,8 +12513,9 @@ apply_suppressions(diff* diff_tree)
12513 // Apply suppressions to functions and variables that have 12513 // Apply suppressions to functions and variables that have
12514 // changed sub-types. 12514 // changed sub-types.
12515 suppression_categorization_visitor v; 12515 suppression_categorization_visitor v;
12516 diff_tree->context()->forget_visited_diffs();
12516 bool s = diff_tree->context()->visiting_a_node_twice_is_forbidden(); 12517 bool s = diff_tree->context()->visiting_a_node_twice_is_forbidden();
12517 diff_tree->context()->forbid_visiting_a_node_twice(false); 12518 diff_tree->context()->forbid_visiting_a_node_twice(true);
12518 diff_tree->traverse(v); 12519 diff_tree->traverse(v);
12519 diff_tree->context()->forbid_visiting_a_node_twice(s); 12520 diff_tree->context()->forbid_visiting_a_node_twice(s);
12520 } 12521 }
@@ -12545,8 +12546,9 @@ apply_suppressions(const corpus_diff* diff_tree)
12545 // changed functions, variables, as well as sub-types of these, 12546 // changed functions, variables, as well as sub-types of these,
12546 // and apply suppression specifications to these ... 12547 // and apply suppression specifications to these ...
12547 suppression_categorization_visitor v; 12548 suppression_categorization_visitor v;
12549 diff_tree->context()->forget_visited_diffs();
12548 bool s = diff_tree->context()->visiting_a_node_twice_is_forbidden(); 12550 bool s = diff_tree->context()->visiting_a_node_twice_is_forbidden();
12549 diff_tree->context()->forbid_visiting_a_node_twice(false); 12551 diff_tree->context()->forbid_visiting_a_node_twice(true);
12550 const_cast<corpus_diff*>(diff_tree)->traverse(v); 12552 const_cast<corpus_diff*>(diff_tree)->traverse(v);
12551 diff_tree->context()->forbid_visiting_a_node_twice(s); 12553 diff_tree->context()->forbid_visiting_a_node_twice(s);
12552 12554