Fix a use after free bug in the tests.
The way the SystemTest fixture works is that it takes
a "FooProblem" object as a type, which contains a ceres::Problem
and a ceres::Solver::Options object.
The Options object also contains a linear_solver_ordering which
contains double* which refer to memory that is allocated when
a problem object is created.
So it is important that the lifetime of the ceres::Problem object
and the ceres::Solver::Options object be tied together. But we were
violating this by creating a FooProblem object on the stack, grabbing
its Options struct and passing it to the SystemTest fixture, which
would then create another instance of FooProblem, grab its Problem
object and copy the modified options struct into it.
In the case where a user provided ordering was being used,
this ordering would now be referring to memory allocated by the first
FooProblem object, which would cause Ceres's internal ApplyOrdering
function to fail.
The fix is ofcourse to Problem and Options object that are born
together.
Change-Id: I07c377a9d5fcabbb6c7ca8aa3460206ce045ffa9
diff --git a/internal/ceres/generate_bundle_adjustment_tests.py b/internal/ceres/generate_bundle_adjustment_tests.py
index b36cf66..89cf8c7 100644
--- a/internal/ceres/generate_bundle_adjustment_tests.py
+++ b/internal/ceres/generate_bundle_adjustment_tests.py
@@ -121,15 +121,17 @@
TEST_F(BundleAdjustmentTest,
%(test_class_name)s) { // NOLINT
- Solver::Options options = *BundleAdjustmentProblem().mutable_solver_options();
- options.num_threads = %(num_threads)s;
- options.linear_solver_type = %(linear_solver)s;
- options.sparse_linear_algebra_library_type = %(sparse_backend)s;
- options.preconditioner_type = %(preconditioner)s;
+ BundleAdjustmentProblem bundle_adjustment_problem;
+ Solver::Options* options = bundle_adjustment_problem.mutable_solver_options();
+ options->num_threads = %(num_threads)s;
+ options->linear_solver_type = %(linear_solver)s;
+ options->sparse_linear_algebra_library_type = %(sparse_backend)s;
+ options->preconditioner_type = %(preconditioner)s;
if (%(ordering)s) {
- options.linear_solver_ordering.reset();
+ options->linear_solver_ordering.reset();
}
- RunSolverForConfigAndExpectResidualsMatch(options);
+ Problem* problem = bundle_adjustment_problem.mutable_problem();
+ RunSolverForConfigAndExpectResidualsMatch(*options, problem);
}
} // namespace internal