libabigail/tools/abipkgdiff.cc

1807 lines
52 KiB
C++
Raw Normal View History

// -*- Mode: C++ -*-
//
// Copyright (C) 2015-2016 Red Hat, Inc.
//
// This file is part of the GNU Application Binary Interface Generic
// Analysis and Instrumentation Library (libabigail). This library is
// free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 3, or (at your option) any
// later version.
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details.
// You should have received a copy of the GNU Lesser General Public
// License along with this program; see the file COPYING-LGPLV3. If
// not, see <http://www.gnu.org/licenses/>.
//
// Author: Sinny Kumari
/// @file
/// This program compares the ABIs of binaries inside two packages.
///
/// For now, the supported package formats are Deb and RPM, but
/// support for other formats would be greatly appreciated.
///
/// The program takes the two packages to compare as well as their
/// associated debug info packages.
///
/// The program extracts the content of the two packages into a
/// temporary directory , looks for the ELF binaries in there,
/// compares their ABIs and emit a report about the changes.
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// As this program uses libpthread to perform several tasks
/// concurrently, here is a coarse grain description of the sequence
/// of actions performed, including where things are done
/// concurrently.
///
/// (steps 1/ to /5 are performed in sequence)
///
/// 1/ the first package and its debug info are extracted concurrently.
/// One thread extracts the package (and maps its content) and another one
/// extracts the debug info package.
///
/// 2/ the second package and its debug info are extracted in parallel.
/// One thread extracts the package (and maps its content) and another one
/// extracts the debug info package.
///
/// 3/ the file system trees of extracted packages are traversed to
/// identify existing pairs and a list of arguments for future comparison
/// is made. The trees are traversed concurrently.
///
/// 4/ comparisons are performed concurrently.
///
/// 5/ the reports are then emitted to standard output, always in the same
/// order.
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
// For package configuration macros.
#include "config.h"
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <ftw.h>
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
#include <algorithm>
#include <map>
#include <assert.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <elf.h>
#include <elfutils/libdw.h>
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
#include <unistd.h>
#include <pthread.h>
Add --version option to several libabigail tools This patch changed the revision number of the libabigail library to make it reflect the fact that we are not in "release candidate" mode, before the first 1.0 release. So the revision number is now "rc0". The configuration manager has been updated to support version numbers that are strings, so that it can supports things like "rc0". Then, several libabigail tools have been modified to support the --version option to display their version number. * configure.ac: Set the version revision to "rc0". * doc/manuals/abicompat.rst: Adjust manual for new --version option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abilint.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-config.h (config::{m_format_minor, m_format_major}): Make these be strings. (config::{get,set}_format_minor_version_number): Make these return strings. (config::{get,set}_format_major_version_number): Make these return or take strings. (abigail_get_library_version): Make this take strings. * src/abg-config.cc (config::config): Adjust. (config::{get,set}_format_major_version_number): Make these return or take strings. (config::{get,set}_format_minor_version_number): Make these return strings. (abigail_get_library_version): Make this take strings. * include/abg-version.h.in: Make the version variables be strings. * src/abg-writer.cc (write_translation_unit): The version numbers are now strings so adjust. * tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc (options::display_version): New data member. (options::options): Initialize it. (display_usage): Add documentation for new --version option. (parse_command_line): Parse new --version option. (main): Support --version. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-11-16 10:39:15 +00:00
#include "abg-config.h"
#include "abg-tools-utils.h"
#include "abg-comparison.h"
Split suppression engine off of abg-comparison.{cc,h} Until now, the suppression engine was part of the comparison engine. The code of both was in the abg-comparison.{cc,h} files. For the sake of greater modularity, this patch separates the suppression engine from the comparison engine. The suppression engine now lives in include/abg-suppression.h and src/abg-suppression.cc. The patch also updates logical consumers of the suppression engine to adapt them to the change. * include/Makefile.am: Add abg-suppression.h to source distribution. * include/abg-comparison.h: Remove abg-ini.h include directive. (suppression_sptr, suppressions_type): Move these typedefs to abg-fwd.h. (class suppression_base, type_suppression) (type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions to the new abg-suppression.h. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function declarations to the new abg-suppression.h. (type_suppression, type_suppression_sptr, type_suppression_type) (function_suppression, function_suppression_sptr) (function_suppressions_type, variable_suppression) (variable_suppression_sptr, variable_suppressions_type): Move these forward declaration and typedefs to the new abg-suppression.h. (diff_context::suppressions): Adjust return type to suppr::suppressions_type&. (diff_context::add_suppression): Adjust parameter type to suppr::suppressions_sptr. (diff_context::add_suppressions): Adjust parameter type suppr::suppressions_type&. (is_type_diff, is_decl_diff, is_var_diff, is_function_decl_diff) (is_pointer_diff, is_reference_diff, is_fn_parm_diff) (is_base_diff, is_child_node_of_function_parm_diff) (is_child_node_of_base_diff): Declare these new functions. They were previously static, local to abg-comparison.cc only. Now they need to be exported because they are used by the suppression engine's code that now lives in its one files. * include/abg-fwd.h (suppr::{suppression_base, suppression_sptr, suppressions_type}): Forward declare these here. * include/abg-suppression.h (class suppression_base) (type_suppression, type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions here, in the namespace suppr. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function decalration here, in the namespace suppr. (type_suppression_sptr, type_suppressions_type) (function_suppression_sptr, function_suppressions_type) (variable_suppression_sptr, variable_suppressions_type): Move these typedefs here, in the namespace suppr. * src/Makefile.am: add src/abg-suppression.cc to source distribution. * src/abg-comparison.cc (is_type_diff, is_decl_diff, is_var_diff) (is_function_decl_diff, is_pointer_diff, is_reference_diff) (is_reference_or_pointer_diff, is_fn_parm_diff, is_base_diff) (is_child_node_of_function_parm_diff, is_child_node_of_base_diff): Export these functions. (*suppression*): Move all the suppression-related definitions to the new abg-suppression.cc. * src/abg-suppression.cc: New file. Contains all the *suppression* definitions from src/abg-comparison.cc, that are put in the suppr namespace. * tools/abicompat.cc: Adjust. * tools/abidiff.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-07 09:28:21 +00:00
#include "abg-suppression.h"
#include "abg-dwarf-reader.h"
using std::cout;
using std::cerr;
using std::string;
using std::ostream;
using std::vector;
using std::map;
using std::tr1::shared_ptr;
Bug 19867 - abipkgdiff skips symbolic links When comparing two directories, abipkgdiff skips symbolic links pointing to ELF binaries altogether. It only consider regular files. This is a problem when abipkgdiff is given two directories that only contain symbolic links. In that case, abipkgdiff just performs no comparison. This patch makes abipkgdiff resolve the symbolic link to its target file. * include/abg-tools-utils.h (maybe_get_symlink_target_file_path): Declare new function. * src/abg-tools-utils.cc (get_stat): Use lstat here, not stat. Update comment. * tools/abipkgdiff.cc (first_package_tree_walker_callback_fn) (second_package_tree_walker_callback_fn): Follow symbolic links to elf files to get their target paths, and only work with that target path. (maybe_get_symlink_target_file_path): Define new function. * test-diff-pkg/symlink-dir-test1-report0.txt New test material. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/test-diff-pkg.cc (in_out_spec): Run this test harness over the new test material above. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-25 10:48:11 +00:00
using abigail::tools_utils::maybe_get_symlink_target_file_path;
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
using abigail::tools_utils::emit_prefix;
using abigail::tools_utils::check_file;
using abigail::tools_utils::guess_file_type;
using abigail::tools_utils::string_ends_with;
using abigail::tools_utils::file_type;
using abigail::tools_utils::make_path_absolute;
using abigail::tools_utils::abidiff_status;
using abigail::ir::corpus_sptr;
using abigail::comparison::diff_context;
using abigail::comparison::diff_context_sptr;
using abigail::comparison::compute_diff;
using abigail::comparison::corpus_diff_sptr;
Split suppression engine off of abg-comparison.{cc,h} Until now, the suppression engine was part of the comparison engine. The code of both was in the abg-comparison.{cc,h} files. For the sake of greater modularity, this patch separates the suppression engine from the comparison engine. The suppression engine now lives in include/abg-suppression.h and src/abg-suppression.cc. The patch also updates logical consumers of the suppression engine to adapt them to the change. * include/Makefile.am: Add abg-suppression.h to source distribution. * include/abg-comparison.h: Remove abg-ini.h include directive. (suppression_sptr, suppressions_type): Move these typedefs to abg-fwd.h. (class suppression_base, type_suppression) (type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions to the new abg-suppression.h. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function declarations to the new abg-suppression.h. (type_suppression, type_suppression_sptr, type_suppression_type) (function_suppression, function_suppression_sptr) (function_suppressions_type, variable_suppression) (variable_suppression_sptr, variable_suppressions_type): Move these forward declaration and typedefs to the new abg-suppression.h. (diff_context::suppressions): Adjust return type to suppr::suppressions_type&. (diff_context::add_suppression): Adjust parameter type to suppr::suppressions_sptr. (diff_context::add_suppressions): Adjust parameter type suppr::suppressions_type&. (is_type_diff, is_decl_diff, is_var_diff, is_function_decl_diff) (is_pointer_diff, is_reference_diff, is_fn_parm_diff) (is_base_diff, is_child_node_of_function_parm_diff) (is_child_node_of_base_diff): Declare these new functions. They were previously static, local to abg-comparison.cc only. Now they need to be exported because they are used by the suppression engine's code that now lives in its one files. * include/abg-fwd.h (suppr::{suppression_base, suppression_sptr, suppressions_type}): Forward declare these here. * include/abg-suppression.h (class suppression_base) (type_suppression, type_suppression::insertion_range) (type_suppression::insertion_range::boundary) (type_suppression::insertion_range::integer_boundary) (type_suppression::insertion_range::fn_call_expr_boundary) (function_suppression, function_suppression::parameter_spec) (variable_suppression): Move these type definitions here, in the namespace suppr. (read_suppressions, is_type_suppression, is_integer_boundary) (is_fn_call_expr_boundary, is_function_suppression) (is_variable_suppression, operator&) (operator|): Move these function decalration here, in the namespace suppr. (type_suppression_sptr, type_suppressions_type) (function_suppression_sptr, function_suppressions_type) (variable_suppression_sptr, variable_suppressions_type): Move these typedefs here, in the namespace suppr. * src/Makefile.am: add src/abg-suppression.cc to source distribution. * src/abg-comparison.cc (is_type_diff, is_decl_diff, is_var_diff) (is_function_decl_diff, is_pointer_diff, is_reference_diff) (is_reference_or_pointer_diff, is_fn_parm_diff, is_base_diff) (is_child_node_of_function_parm_diff, is_child_node_of_base_diff): Export these functions. (*suppression*): Move all the suppression-related definitions to the new abg-suppression.cc. * src/abg-suppression.cc: New file. Contains all the *suppression* definitions from src/abg-comparison.cc, that are put in the suppr namespace. * tools/abicompat.cc: Adjust. * tools/abidiff.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-05-07 09:28:21 +00:00
using abigail::suppr::suppression_sptr;
using abigail::suppr::suppressions_type;
using abigail::suppr::read_suppressions;
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
using abigail::dwarf_reader::get_soname_of_elf_file;
using abigail::dwarf_reader::get_type_of_elf_file;
using abigail::dwarf_reader::read_corpus_from_elf;
/// Set to true if the user wants to see verbose information about the
/// progress of what's being done.
static bool verbose;
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// The key for getting the thread-local elf_file_paths vector, which
/// contains the set of files of a given package. The vector is populated
/// by a worker function that is invoked on each file contained in the
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// package, specifically by the
/// {first,second}_package_tree_walker_callback_fn() functions. Its content
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// is relevant only until the mapping of the packages elf files is done.
static pthread_key_t elf_file_paths_tls_key;
/// A convenience typedef for a map of corpus diffs
typedef map<string, corpus_diff_sptr> corpora_report_map;
/// This map is used to gather the computed diffs of ELF pairs
static corpora_report_map reports_map;
/// This map is used to keep environments for differing corpora
/// referenced. The environment needs to be kept alive longer than
/// all the objects that depend on it.
static map<corpus_diff_sptr, abigail::ir::environment_sptr> env_map;
/// This mutex is used to control access to the reports_map
static pthread_mutex_t map_lock = PTHREAD_MUTEX_INITIALIZER;
/// This mutex is used to control access to the pre-computed list of ELF pairs
static pthread_mutex_t arg_lock = PTHREAD_MUTEX_INITIALIZER;
/// This points to the set of options shared by all the routines of the
/// program.
static struct options *prog_options;
/// The options passed to the current program.
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
class options
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
options();
public:
string wrong_option;
string prog_name;
bool display_usage;
Add --version option to several libabigail tools This patch changed the revision number of the libabigail library to make it reflect the fact that we are not in "release candidate" mode, before the first 1.0 release. So the revision number is now "rc0". The configuration manager has been updated to support version numbers that are strings, so that it can supports things like "rc0". Then, several libabigail tools have been modified to support the --version option to display their version number. * configure.ac: Set the version revision to "rc0". * doc/manuals/abicompat.rst: Adjust manual for new --version option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abilint.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-config.h (config::{m_format_minor, m_format_major}): Make these be strings. (config::{get,set}_format_minor_version_number): Make these return strings. (config::{get,set}_format_major_version_number): Make these return or take strings. (abigail_get_library_version): Make this take strings. * src/abg-config.cc (config::config): Adjust. (config::{get,set}_format_major_version_number): Make these return or take strings. (config::{get,set}_format_minor_version_number): Make these return strings. (abigail_get_library_version): Make this take strings. * include/abg-version.h.in: Make the version variables be strings. * src/abg-writer.cc (write_translation_unit): The version numbers are now strings so adjust. * tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc (options::display_version): New data member. (options::options): Initialize it. (display_usage): Add documentation for new --version option. (parse_command_line): Parse new --version option. (main): Support --version. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-11-16 10:39:15 +00:00
bool display_version;
bool missing_operand;
bool abignore;
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
bool parallel;
string package1;
string package2;
string debug_package1;
string debug_package2;
bool keep_tmp_files;
bool compare_dso_only;
bool show_linkage_names;
bool show_redundant_changes;
Add the option of printing the file, line and column information about a type being reported. * bash-completion/abicompat: Complete the new "--no-show-locs" option. * bash-completion/abidiff: Likewise. * bash-completion/abidw: Likewise. * bash-completion/abipkgdiff: Likewise. * doc/manuals/abicompat.rst: Mention the new "--no-show-locs" option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-comparison.h (show_locs): Add declarations. * src/abg-comparison.cc: (diff_context::priv): Add a new switch called "show_locs_" and set its default value to false. (report_loc_info): New function. Outputting the extra information is conditionalized based on the associated diff contexts settings. (show_locs): define a getter/setter for diff_context::priv::show_locs_. ({distinct,pointer,reference,qualified_type,enum,class,scope,fn_parm, typedef,corpus}_diff::report): Call report_loc_info when appropriate. (maybe_report_diff_for_member): Likewise. (represent): Accept a const reference to a diff_context_sptr as a first argument and call report_loc_info on its second argument. * src/abg-dwarf-reader.cc: * tests/data/Makefile.am: Add the new test reference files. * tests/data/test-abicompat/test0-fn-changed-report-2.txt: New test reference output. * tests/data/test-abicompat/test5-fn-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-pkg/dirpkg-3-report-2.txt: Likewise. * tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise. * tests/test-abidiff.cc: Explicitly create a diff context and turn off location emitting. * tests/test-diff-dwarf.cc: Likewise. * tests/test-abicompat.cc: Add --no-show-locs to all existing test arguments. Run a few of the existing tests again, but without this option. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tools/abicompat.cc: Handle the new "--no-show-locs" option. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-16 09:55:28 +00:00
bool show_locs;
bool show_added_syms;
bool show_added_binaries;
bool fail_if_no_debug_info;
vector<string> suppression_paths;
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
options(const string& program_name)
: prog_name(program_name),
display_usage(),
Add --version option to several libabigail tools This patch changed the revision number of the libabigail library to make it reflect the fact that we are not in "release candidate" mode, before the first 1.0 release. So the revision number is now "rc0". The configuration manager has been updated to support version numbers that are strings, so that it can supports things like "rc0". Then, several libabigail tools have been modified to support the --version option to display their version number. * configure.ac: Set the version revision to "rc0". * doc/manuals/abicompat.rst: Adjust manual for new --version option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abilint.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-config.h (config::{m_format_minor, m_format_major}): Make these be strings. (config::{get,set}_format_minor_version_number): Make these return strings. (config::{get,set}_format_major_version_number): Make these return or take strings. (abigail_get_library_version): Make this take strings. * src/abg-config.cc (config::config): Adjust. (config::{get,set}_format_major_version_number): Make these return or take strings. (config::{get,set}_format_minor_version_number): Make these return strings. (abigail_get_library_version): Make this take strings. * include/abg-version.h.in: Make the version variables be strings. * src/abg-writer.cc (write_translation_unit): The version numbers are now strings so adjust. * tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc (options::display_version): New data member. (options::options): Initialize it. (display_usage): Add documentation for new --version option. (parse_command_line): Parse new --version option. (main): Support --version. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-11-16 10:39:15 +00:00
display_version(),
missing_operand(),
abignore(true),
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
parallel(true),
keep_tmp_files(),
compare_dso_only(),
show_linkage_names(true),
show_redundant_changes(),
Add the option of printing the file, line and column information about a type being reported. * bash-completion/abicompat: Complete the new "--no-show-locs" option. * bash-completion/abidiff: Likewise. * bash-completion/abidw: Likewise. * bash-completion/abipkgdiff: Likewise. * doc/manuals/abicompat.rst: Mention the new "--no-show-locs" option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-comparison.h (show_locs): Add declarations. * src/abg-comparison.cc: (diff_context::priv): Add a new switch called "show_locs_" and set its default value to false. (report_loc_info): New function. Outputting the extra information is conditionalized based on the associated diff contexts settings. (show_locs): define a getter/setter for diff_context::priv::show_locs_. ({distinct,pointer,reference,qualified_type,enum,class,scope,fn_parm, typedef,corpus}_diff::report): Call report_loc_info when appropriate. (maybe_report_diff_for_member): Likewise. (represent): Accept a const reference to a diff_context_sptr as a first argument and call report_loc_info on its second argument. * src/abg-dwarf-reader.cc: * tests/data/Makefile.am: Add the new test reference files. * tests/data/test-abicompat/test0-fn-changed-report-2.txt: New test reference output. * tests/data/test-abicompat/test5-fn-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-pkg/dirpkg-3-report-2.txt: Likewise. * tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise. * tests/test-abidiff.cc: Explicitly create a diff context and turn off location emitting. * tests/test-diff-dwarf.cc: Likewise. * tests/test-abicompat.cc: Add --no-show-locs to all existing test arguments. Run a few of the existing tests again, but without this option. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tools/abicompat.cc: Handle the new "--no-show-locs" option. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-16 09:55:28 +00:00
show_locs(true),
show_added_syms(true),
show_added_binaries(true),
fail_if_no_debug_info()
{}
};
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
/// Abstract ELF files from the packages which ABIs ought to be
/// compared
class elf_file
{
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
private:
elf_file();
public:
string path;
string name;
string soname;
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
off_t size;
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
abigail::dwarf_reader::elf_type type;
/// The path to the elf file.
///
/// @param path the path to the elf file.
elf_file(const string& path)
: path(path)
{
abigail::tools_utils::base_name(path, name);
get_soname_of_elf_file(path, soname);
get_type_of_elf_file(path, type);
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
struct stat estat;
stat(path.c_str(), &estat);
size = estat.st_size;
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
}
};
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
/// A convenience typedef for a shared pointer to elf_file.
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
typedef shared_ptr<elf_file> elf_file_sptr;
/// A convenience typedef for a pointer to a function type that
/// the ftw() function accepts.
typedef int (*ftw_cb_type)(const char *, const struct stat*, int);
/// Abstract the result of comparing two packages.
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
///
/// This contains the the paths of the set of added binaries, removed
/// binaries, and binaries whic ABI changed.
struct abi_diff
{
vector<elf_file_sptr> added_binaries;
vector<elf_file_sptr> removed_binaries;
vector<string> changed_binaries;
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
/// Test if the current diff carries changes.
///
/// @return true iff the current diff carries changes.
bool
has_changes()
{
return (!added_binaries.empty()
|| !removed_binaries.empty()
||!changed_binaries.empty());
}
};
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
/// Abstracts a package.
class package
{
string path_;
string extracted_dir_path_;
abigail::tools_utils::file_type type_;
bool is_debug_info_;
map<string, elf_file_sptr> path_elf_file_sptr_map_;
shared_ptr<package> debug_info_package_;
public:
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
/// Constructor for the @ref package type.
///
/// @param path the path to the package.
///
/// @parm dir the temporary directory where to extract the content
/// of the package.
///
/// @param is_debug_info true if the pacakge is a debug info package.
package(const string& path,
const string& dir,
bool is_debug_info = false)
: path_(path),
is_debug_info_(is_debug_info)
{
type_ = guess_file_type(path);
Make abipkgdiff compare directories containing binaries abipkgdiff knows how to compare the ABI of binaries contained in .deb and .rpm files. This patch adds support for comparing the ABI of binaries contained in two directories. * include/abg-tools-utils.h (enum file_type): Add a new FILE_TYPE_DIR enumerator. * src/abg-tools-utils.cc (operator<<(ostream&, file_type)): Support serialization of the new FILE_TYPE_DIR enumerator. (guess_file_type): Detect that the path given is a directory. * tools/abipkgdiff.cc (package::package): If the package is a directory, then set its extracted directory path to the path of the directory. (package::erase_extraction_directory): Do not erase the extraction directory if the package is a directory provided by the user. (extract_package): If the package is a directory provided by the user, then there is nothing to extract. (main): If the first package is a directory, then the second one should be a directory as well. * tools/abidiff.cc (main): Support directories as input. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/dirpkg-0-dir{1,2}/libobj-v0.so: New binary test inputs. * test/data/test-diff-pkg/dirpkg-0-report-0.txt: New input test file. * tests/data/test-diff-pkg/dirpkg-1-dir{1,2}/obj-v0.cc: Source code of the binary test inputs above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the new test input files above to the set of tests this harness has to run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 09:44:08 +00:00
if (type_ == abigail::tools_utils::FILE_TYPE_DIR)
extracted_dir_path_ = path;
else
extracted_dir_path_ = extracted_packages_parent_dir() + "/" + dir;
}
/// Getter of the path of the package.
///
/// @return the path of the package.
const string&
path() const
{return path_;}
/// Setter of the path of the package.
///
/// @param s the new path.
void
path(const string& s)
{path_ = s;}
/// Getter for the path to the root dir where the packages are
/// extracted.
///
/// @return the path to the root dir where the packages are
/// extracted.
static const string&
extracted_packages_parent_dir();
/// Getter for the path to the directory where the packages are
/// extracted for the current thread.
///
/// @return the path to the directory where the packages are
/// extracted for the current thread.
const string&
extracted_dir_path() const
{return extracted_dir_path_;}
/// Setter for the path to the directory where the packages are
/// extracted for the current thread.
///
/// @param p the new path.
void
extracted_dir_path(const string& p)
{extracted_dir_path_ = p;}
/// Getter for the file type of the current package.
///
/// @return the file type of the current package.
abigail::tools_utils::file_type
type() const
{return type_;}
/// Setter for the file type of the current package.
///
/// @param t the new file type.
void type(abigail::tools_utils::file_type t)
{type_ = t;}
/// Test if the current package is a debug info package.
///
/// @return true iff the current package is a debug info package.
bool
is_debug_info() const
{return is_debug_info_;}
/// Set the flag that says if the current package is a debug info package.
///
/// @param f the new flag.
void
is_debug_info(bool f)
{is_debug_info_ = f;}
/// Getter for the path <-> elf_file map.
///
/// @return the the path <-> elf_file map.
const map<string, elf_file_sptr>&
path_elf_file_sptr_map() const
{return path_elf_file_sptr_map_;}
/// Getter for the path <-> elf_file map.
///
/// @return the the path <-> elf_file map.
map<string, elf_file_sptr>&
path_elf_file_sptr_map()
{return path_elf_file_sptr_map_;}
/// Getter for the debug info package associated to the current
/// package.
///
/// @return the debug info package associated to the current
/// package.
const shared_ptr<package>&
debug_info_package() const
{return debug_info_package_;}
/// Setter for the debug info package associated to the current
/// package.
///
/// @param p the new debug info package.
void
debug_info_package(const shared_ptr<package> p)
{debug_info_package_ = p;}
/// Erase the content of the temporary extraction directory that has
/// been populated by the @ref extract_package() function;
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
void
erase_extraction_directory() const
{
Make abipkgdiff compare directories containing binaries abipkgdiff knows how to compare the ABI of binaries contained in .deb and .rpm files. This patch adds support for comparing the ABI of binaries contained in two directories. * include/abg-tools-utils.h (enum file_type): Add a new FILE_TYPE_DIR enumerator. * src/abg-tools-utils.cc (operator<<(ostream&, file_type)): Support serialization of the new FILE_TYPE_DIR enumerator. (guess_file_type): Detect that the path given is a directory. * tools/abipkgdiff.cc (package::package): If the package is a directory, then set its extracted directory path to the path of the directory. (package::erase_extraction_directory): Do not erase the extraction directory if the package is a directory provided by the user. (extract_package): If the package is a directory provided by the user, then there is nothing to extract. (main): If the first package is a directory, then the second one should be a directory as well. * tools/abidiff.cc (main): Support directories as input. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/dirpkg-0-dir{1,2}/libobj-v0.so: New binary test inputs. * test/data/test-diff-pkg/dirpkg-0-report-0.txt: New input test file. * tests/data/test-diff-pkg/dirpkg-1-dir{1,2}/obj-v0.cc: Source code of the binary test inputs above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the new test input files above to the set of tests this harness has to run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 09:44:08 +00:00
if (type() == abigail::tools_utils::FILE_TYPE_DIR)
// If we are comparing two directories, do not erase the
// directory as it was provided by the user; it's not a
// temporary directory we created ourselves.
return;
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Erasing temporary extraction directory "
<< extracted_dir_path()
<< " ...";
string cmd = "rm -rf " + extracted_dir_path();
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " FAILED\n";
}
else
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " DONE\n";
}
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
/// Erase the content of all the temporary extraction directories.
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
void
erase_extraction_directories() const
{
erase_extraction_directory();
if (debug_info_package())
debug_info_package()->erase_extraction_directory();
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
}
};
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// Arguments passed to the package extraction functions.
struct package_descriptor
{
package &pkg;
const options& opts;
ftw_cb_type callback;
};
/// Arguments passed to the comparison workers.
struct compare_args
{
const elf_file elf1;
const string& debug_dir1;
const elf_file elf2;
const string& debug_dir2;
const options& opts;
/// Constructor for compare_args, which is used to pass
/// information to the comparison threads.
///
/// @param elf1 the first elf file to consider.
///
/// @param debug_dir1 the directory where the debug info file for @p
/// elf1 is stored.
///
/// @param elf2 the second elf file to consider.
///
/// @param debug_dir2 the directory where the debug info file for @p
/// elf2 is stored.
///
/// @param opts the options the current program has been called with.
compare_args(const elf_file &elf1, const string& debug_dir1,
const elf_file &elf2, const string& debug_dir2,
const options& opts)
: elf1(elf1), debug_dir1(debug_dir1), elf2(elf2),
debug_dir2(debug_dir2), opts(opts)
{}
};
/// A convenience typedef for arguments passed to the comparison workers.
typedef shared_ptr<compare_args> compare_args_sptr;
/// Getter for the path to the parent directory under which packages
/// extracted by the current thread are placed.
///
/// @return the path to the parent directory under which packages
/// extracted by the current thread are placed.
const string&
package::extracted_packages_parent_dir()
{
// I tried to declare this in thread-local storage, but GCC 4.4.7
// won't let me. So for now, I am just making it static. I'll deal
// with this later when I have to.
//static __thread string p;
static string p;
if (p.empty())
{
const char *tmpdir = getenv("TMPDIR");
if (tmpdir != NULL)
p = tmpdir;
else
p = "/tmp";
using abigail::tools_utils::get_random_number_as_string;
string libabigail_tmp_dir_template = p;
libabigail_tmp_dir_template += "/libabigail-tmp-dir-XXXXXX";
if (!mkdtemp(const_cast<char*>(libabigail_tmp_dir_template.c_str())))
abort();
p = libabigail_tmp_dir_template;
}
return p;
}
/// A convenience typedef for shared_ptr of package.
typedef shared_ptr<package> package_sptr;
/// Show the usage of this program.
///
/// @param prog_name the name of the program.
///
/// @param out the output stream to emit the usage to .
static void
display_usage(const string& prog_name, ostream& out)
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix(prog_name, out)
<< "usage: " << prog_name << " [options] <package1> <package2>\n"
<< " where options can be:\n"
<< " --debug-info-pkg1|--d1 <path> path of debug-info package of package1\n"
<< " --debug-info-pkg2|--d2 <path> path of debug-info package of package2\n"
<< " --suppressions|--suppr <path> specify supression specification path\n"
<< " --keep-tmp-files don't erase created temporary files\n"
<< " --dso-only compare shared libraries only\n"
<< " --no-linkage-name do not display linkage names of "
"added/removed/changed\n"
<< " --redundant display redundant changes\n"
<< " --no-show-locs do not show location information\n"
<< " --no-added-syms do not display added functions or variables\n"
<< " --no-added-binaries do not display added binaries\n"
<< " --no-abignore do not look for *.abignore files\n"
<< " --no-parallel do not execute in parallel\n"
<< " --fail-no-dbg fail if no debug info was found\n"
<< " --verbose emit verbose progress messages\n"
<< " --help|-h display this help message\n"
<< " --version|-v display program version information"
" and exit\n";
}
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
#ifdef WITH_RPM
/// Extract an RPM package.
///
/// @param package_path the path to the package to extract.
///
/// @param extracted_package_dir_path the path where to extract the
/// package to.
///
/// @return true upon successful completion, false otherwise.
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
static bool
extract_rpm(const string& package_path,
const string& extracted_package_dir_path)
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Extracting package "
<< package_path
<< " to "
<< extracted_package_dir_path
<< " ...";
string cmd = "test -d " +
extracted_package_dir_path +
" && rm -rf " + extracted_package_dir_path;
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "command " << cmd << " FAILED\n";
}
cmd = "mkdir -p " + extracted_package_dir_path + " && cd " +
extracted_package_dir_path + " && rpm2cpio " + package_path +
" | cpio -dium --quiet";
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " FAILED\n";
return false;
}
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " DONE\n";
return true;
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
}
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
#endif // WITH_RPM
#ifdef WITH_DEB
/// Extract a Debian binary package.
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
///
/// @param package_path the path to the package to extract.
///
/// @param extracted_package_dir_path the path where to extract the
/// package to.
///
/// @return true upon successful completion, false otherwise.
static bool
extract_deb(const string& package_path,
const string& extracted_package_dir_path)
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Extracting package "
<< package_path
<< "to "
<< extracted_package_dir_path
<< " ...";
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
string cmd = "test -d " +
extracted_package_dir_path +
" && rm -rf " + extracted_package_dir_path;
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "command " << cmd << " FAILED\n";
}
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
cmd = "mkdir -p " + extracted_package_dir_path + " && dpkg -x " +
package_path + " " + extracted_package_dir_path;
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " FAILED\n";
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
return false;
}
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " DONE\n";
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
return true;
}
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
#endif // WITH_DEB
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
#ifdef WITH_TAR
/// Extract a GNU Tar archive.
///
/// @param package_path the path to the archive to extract.
///
/// @param extracted_package_dir_path the path where to extract the
/// archive to.
///
/// @return true upon successful completion, false otherwise.
static bool
extract_tar(const string& package_path,
const string& extracted_package_dir_path)
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Extracting tar archive "
<< package_path
<< " to "
<< extracted_package_dir_path
<< " ...";
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
string cmd = "test -d " +
extracted_package_dir_path +
" && rm -rf " + extracted_package_dir_path;
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "command " << cmd << " FAILED\n";
}
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
cmd = "mkdir -p " + extracted_package_dir_path + " && cd " +
extracted_package_dir_path + " && tar -xf " + package_path;
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " FAILED\n";
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
return false;
}
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " DONE\n";
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
return true;
}
#endif // WITH_TAR
/// Erase the temporary directories created for the extraction of two
/// packages.
///
/// @param first_package the first package to consider.
///
/// @param second_package the second package to consider.
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
static void
erase_created_temporary_directories(const package& first_package,
const package& second_package)
{
first_package.erase_extraction_directories();
second_package.erase_extraction_directories();
}
/// Erase the root of all the temporary directories created by the
/// current thread.
static void
erase_created_temporary_directories_parent()
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Erasing temporary extraction parent directory "
<< package::extracted_packages_parent_dir()
<< " ...";
string cmd = "rm -rf " + package::extracted_packages_parent_dir();
if (system(cmd.c_str()))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "FAILED\n";
}
else
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "DONE\n";
}
}
/// Extract the content of a package.
///
/// @param package the package we are looking at.
static bool
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
extract_package(const package& package)
{
switch(package.type())
{
case abigail::tools_utils::FILE_TYPE_RPM:
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
#ifdef WITH_RPM
if (!extract_rpm(package.path(), package.extracted_dir_path()))
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Error while extracting package" << package.path() << "\n";
return false;
}
return true;
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
#else
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Support for rpm hasn't been enabled. Please consider "
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
"enabling it at package configure time\n";
return false;
#endif // WITH_RPM
break;
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
case abigail::tools_utils::FILE_TYPE_DEB:
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
#ifdef WITH_DEB
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
if (!extract_deb(package.path(), package.extracted_dir_path()))
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Error while extracting package" << package.path() << "\n";
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
return false;
}
return true;
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
#else
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Support for deb hasn't been enabled. Please consider "
Make the support of RPM and DEB package formats conditional If at configure time the libabigail source tarball detects that rpm2cpio and cpio are present then it enables the support for rpm files. Users can explicitly enable or disable that support by passing --enable-rpm or --disable-rpm to configure. Similarly if it detects that dpkg is present at configure time then it enables the support for deb files. Users can explicitly enable or disable that support by passing --enable-deb or --disable-deb to configure. * config.h.in: Define WITH_DEB and WITH_RPM pre-processor macros. * configure.ac: Add --enable-{rpm,deb} switches. Check for rpm2cpio and cpio programs, unless --disable-rpm was provided. If they are found and if --enable-rpm=auto was provided, then consider that --enable-rpm=yes was provided. In that case, set the WITH_RPM macro to 1. Otherwise, undefine that macro. Similarly, check for dpkg unless --disable-deb was provided. If it's found and if --enable-deb=auto was provided, consider that --enable-deb=yes was provided. In that case, set the WITH_DEB macro to 1. Otherwise, undefine that macro. Define the ENABLE_RPM and ENABLE_DEB conditional automake variables, if the rpm resp. deb support is enabled. Emit a notice about the rpm and deb features being enabled or not, at the end of the configure process. * tests/test-diff-pkg.cc: Include the config.h header. (in_out_spec): Guard rpm tests by the WITH_RPM macro. Similarly, guard deb tests by the WITH_DEB macro. * tools/abipkgdiff.cc: Include the config.h header. (extract_rpm): Guard this function definition with the WITH_RPM macro. (extract_deb): Guard this function definition with the WITH_DEB macro. (extract_package): Guard the handling of rpm packages with the WITH_RPM macro and the handling of deb package with the WITH_DEB macro. If a package not-support package format is encountered, emit an appropriate error message and error out. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-14 10:49:57 +00:00
"enabling it at package configure time\n";
return false;
#endif // WITH_DEB
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
break;
Make abipkgdiff compare directories containing binaries abipkgdiff knows how to compare the ABI of binaries contained in .deb and .rpm files. This patch adds support for comparing the ABI of binaries contained in two directories. * include/abg-tools-utils.h (enum file_type): Add a new FILE_TYPE_DIR enumerator. * src/abg-tools-utils.cc (operator<<(ostream&, file_type)): Support serialization of the new FILE_TYPE_DIR enumerator. (guess_file_type): Detect that the path given is a directory. * tools/abipkgdiff.cc (package::package): If the package is a directory, then set its extracted directory path to the path of the directory. (package::erase_extraction_directory): Do not erase the extraction directory if the package is a directory provided by the user. (extract_package): If the package is a directory provided by the user, then there is nothing to extract. (main): If the first package is a directory, then the second one should be a directory as well. * tools/abidiff.cc (main): Support directories as input. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/dirpkg-0-dir{1,2}/libobj-v0.so: New binary test inputs. * test/data/test-diff-pkg/dirpkg-0-report-0.txt: New input test file. * tests/data/test-diff-pkg/dirpkg-1-dir{1,2}/obj-v0.cc: Source code of the binary test inputs above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the new test input files above to the set of tests this harness has to run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 09:44:08 +00:00
case abigail::tools_utils::FILE_TYPE_DIR:
// The input package is just a directory that contains binaries,
// there is nothing to extract.
break;
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
case abigail::tools_utils::FILE_TYPE_TAR:
#ifdef WITH_TAR
if (!extract_tar(package.path(), package.extracted_dir_path()))
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Error while extracting GNU tar archive "
<< package.path() << "\n";
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
return false;
}
return true;
#else
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Support for GNU tar hasn't been enabled. Please consider "
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
"enabling it at package configure time\n";
return false;
#endif // WITH_TAR
break;
default:
return false;
}
return true;
}
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// A wrapper to call extract_package in a separate thread.
///
/// @param pkg the package we want to extract.
///
/// @return via pthread_exit() a pointer to a boolean value of true upon
/// successful completion, false otherwise.
static void
pthread_routine_extract_package(void *pkg)
{
const package &package = *static_cast<class package*>(pkg);
pthread_exit(new bool(extract_package(package)));
}
/// A callback function invoked by the ftw() function while walking
/// the directory of files extracted from the first package.
///
/// @param fpath the path to the file being considered.
///
/// @param stat the stat struct of the file.
static int
first_package_tree_walker_callback_fn(const char *fpath,
const struct stat *,
int /*flag*/)
{
Bug 19867 - abipkgdiff skips symbolic links When comparing two directories, abipkgdiff skips symbolic links pointing to ELF binaries altogether. It only consider regular files. This is a problem when abipkgdiff is given two directories that only contain symbolic links. In that case, abipkgdiff just performs no comparison. This patch makes abipkgdiff resolve the symbolic link to its target file. * include/abg-tools-utils.h (maybe_get_symlink_target_file_path): Declare new function. * src/abg-tools-utils.cc (get_stat): Use lstat here, not stat. Update comment. * tools/abipkgdiff.cc (first_package_tree_walker_callback_fn) (second_package_tree_walker_callback_fn): Follow symbolic links to elf files to get their target paths, and only work with that target path. (maybe_get_symlink_target_file_path): Define new function. * test-diff-pkg/symlink-dir-test1-report0.txt New test material. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/test-diff-pkg.cc (in_out_spec): Run this test harness over the new test material above. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-25 10:48:11 +00:00
string path = fpath;
// If path is a symbolic link, then set it to the path of its target
// file.
maybe_get_symlink_target_file_path(path, path);
if (guess_file_type(path) == abigail::tools_utils::FILE_TYPE_ELF)
{
Bug 19867 - abipkgdiff skips symbolic links When comparing two directories, abipkgdiff skips symbolic links pointing to ELF binaries altogether. It only consider regular files. This is a problem when abipkgdiff is given two directories that only contain symbolic links. In that case, abipkgdiff just performs no comparison. This patch makes abipkgdiff resolve the symbolic link to its target file. * include/abg-tools-utils.h (maybe_get_symlink_target_file_path): Declare new function. * src/abg-tools-utils.cc (get_stat): Use lstat here, not stat. Update comment. * tools/abipkgdiff.cc (first_package_tree_walker_callback_fn) (second_package_tree_walker_callback_fn): Follow symbolic links to elf files to get their target paths, and only work with that target path. (maybe_get_symlink_target_file_path): Define new function. * test-diff-pkg/symlink-dir-test1-report0.txt New test material. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/test-diff-pkg.cc (in_out_spec): Run this test harness over the new test material above. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-25 10:48:11 +00:00
vector<string> *elf_file_paths
= static_cast<vector<string>*>(pthread_getspecific(elf_file_paths_tls_key));
elf_file_paths->push_back(path);
}
return 0;
}
/// A callback function invoked by the ftw() function while walking
/// the directory of files extracted from the second package.
///
/// @param fpath the path to the file being considered.
///
/// @param stat the stat struct of the file.
static int
second_package_tree_walker_callback_fn(const char *fpath,
const struct stat *,
int /*flag*/)
{
Bug 19867 - abipkgdiff skips symbolic links When comparing two directories, abipkgdiff skips symbolic links pointing to ELF binaries altogether. It only consider regular files. This is a problem when abipkgdiff is given two directories that only contain symbolic links. In that case, abipkgdiff just performs no comparison. This patch makes abipkgdiff resolve the symbolic link to its target file. * include/abg-tools-utils.h (maybe_get_symlink_target_file_path): Declare new function. * src/abg-tools-utils.cc (get_stat): Use lstat here, not stat. Update comment. * tools/abipkgdiff.cc (first_package_tree_walker_callback_fn) (second_package_tree_walker_callback_fn): Follow symbolic links to elf files to get their target paths, and only work with that target path. (maybe_get_symlink_target_file_path): Define new function. * test-diff-pkg/symlink-dir-test1-report0.txt New test material. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/test-diff-pkg.cc (in_out_spec): Run this test harness over the new test material above. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-25 10:48:11 +00:00
string path = fpath;
// If path is a symbolic link, then set it to the path of its target
// file.
maybe_get_symlink_target_file_path(path, path);
if (guess_file_type(path) == abigail::tools_utils::FILE_TYPE_ELF)
{
Bug 19867 - abipkgdiff skips symbolic links When comparing two directories, abipkgdiff skips symbolic links pointing to ELF binaries altogether. It only consider regular files. This is a problem when abipkgdiff is given two directories that only contain symbolic links. In that case, abipkgdiff just performs no comparison. This patch makes abipkgdiff resolve the symbolic link to its target file. * include/abg-tools-utils.h (maybe_get_symlink_target_file_path): Declare new function. * src/abg-tools-utils.cc (get_stat): Use lstat here, not stat. Update comment. * tools/abipkgdiff.cc (first_package_tree_walker_callback_fn) (second_package_tree_walker_callback_fn): Follow symbolic links to elf files to get their target paths, and only work with that target path. (maybe_get_symlink_target_file_path): Define new function. * test-diff-pkg/symlink-dir-test1-report0.txt New test material. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/test-diff-pkg.cc (in_out_spec): Run this test harness over the new test material above. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-25 10:48:11 +00:00
vector<string> *elf_file_paths
= static_cast<vector<string>*>(pthread_getspecific(elf_file_paths_tls_key));
elf_file_paths->push_back(path);
}
Bug 19867 - abipkgdiff skips symbolic links When comparing two directories, abipkgdiff skips symbolic links pointing to ELF binaries altogether. It only consider regular files. This is a problem when abipkgdiff is given two directories that only contain symbolic links. In that case, abipkgdiff just performs no comparison. This patch makes abipkgdiff resolve the symbolic link to its target file. * include/abg-tools-utils.h (maybe_get_symlink_target_file_path): Declare new function. * src/abg-tools-utils.cc (get_stat): Use lstat here, not stat. Update comment. * tools/abipkgdiff.cc (first_package_tree_walker_callback_fn) (second_package_tree_walker_callback_fn): Follow symbolic links to elf files to get their target paths, and only work with that target path. (maybe_get_symlink_target_file_path): Define new function. * test-diff-pkg/symlink-dir-test1-report0.txt New test material. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir1/targets/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/symlinks/libfoo.so: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.c: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/foo.o: Likewise. * test-diff-pkg/symlink-dir-test1/dir2/targets/libfoo.so: Likewise. * tests/data/Makefile.am: Add the new test material to source distribution. * tests/test-diff-pkg.cc (in_out_spec): Run this test harness over the new test material above. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-03-25 10:48:11 +00:00
/// We go through the files of the newer (second) pkg to look for
/// suppression specifications, matching the "*.abignore" name pattern.
else if (prog_options->abignore && string_ends_with(fpath, ".abignore"))
prog_options->suppression_paths.push_back(fpath);
return 0;
}
/// Check that the suppression specification files supplied are
/// present. If not, emit an error on stderr.
///
/// @param opts the options instance to use.
///
/// @return true if all suppression specification files are present,
/// false otherwise.
static bool
maybe_check_suppression_files(const options& opts)
{
for (vector<string>::const_iterator i = opts.suppression_paths.begin();
i != opts.suppression_paths.end();
++i)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
if (!check_file(*i, cerr, opts.prog_name))
return false;
return true;
}
/// Update the diff context from the @ref options data structure.
///
/// @param ctxt the diff context to update.
///
/// @param opts the instance of @ref options to consider.
static void
set_diff_context_from_opts(diff_context_sptr ctxt,
const options& opts)
{
ctxt->default_output_stream(&cout);
ctxt->error_output_stream(&cerr);
ctxt->show_redundant_changes(opts.show_redundant_changes);
Add the option of printing the file, line and column information about a type being reported. * bash-completion/abicompat: Complete the new "--no-show-locs" option. * bash-completion/abidiff: Likewise. * bash-completion/abidw: Likewise. * bash-completion/abipkgdiff: Likewise. * doc/manuals/abicompat.rst: Mention the new "--no-show-locs" option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-comparison.h (show_locs): Add declarations. * src/abg-comparison.cc: (diff_context::priv): Add a new switch called "show_locs_" and set its default value to false. (report_loc_info): New function. Outputting the extra information is conditionalized based on the associated diff contexts settings. (show_locs): define a getter/setter for diff_context::priv::show_locs_. ({distinct,pointer,reference,qualified_type,enum,class,scope,fn_parm, typedef,corpus}_diff::report): Call report_loc_info when appropriate. (maybe_report_diff_for_member): Likewise. (represent): Accept a const reference to a diff_context_sptr as a first argument and call report_loc_info on its second argument. * src/abg-dwarf-reader.cc: * tests/data/Makefile.am: Add the new test reference files. * tests/data/test-abicompat/test0-fn-changed-report-2.txt: New test reference output. * tests/data/test-abicompat/test5-fn-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-pkg/dirpkg-3-report-2.txt: Likewise. * tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise. * tests/test-abidiff.cc: Explicitly create a diff context and turn off location emitting. * tests/test-diff-dwarf.cc: Likewise. * tests/test-abicompat.cc: Add --no-show-locs to all existing test arguments. Run a few of the existing tests again, but without this option. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tools/abicompat.cc: Handle the new "--no-show-locs" option. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-16 09:55:28 +00:00
ctxt->show_locs(opts.show_locs);
ctxt->show_linkage_names(opts.show_linkage_names);
ctxt->show_added_fns(opts.show_added_syms);
ctxt->show_added_vars(opts.show_added_syms);
ctxt->show_added_symbols_unreferenced_by_debug_info
(opts.show_added_syms);
ctxt->switch_categories_off
(abigail::comparison::ACCESS_CHANGE_CATEGORY
| abigail::comparison::COMPATIBLE_TYPE_CHANGE_CATEGORY
| abigail::comparison::HARMLESS_DECL_NAME_CHANGE_CATEGORY
| abigail::comparison::NON_VIRT_MEM_FUN_CHANGE_CATEGORY
| abigail::comparison::STATIC_DATA_MEMBER_CHANGE_CATEGORY
| abigail::comparison::HARMLESS_ENUM_CHANGE_CATEGORY
| abigail::comparison::HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY);
suppressions_type supprs;
for (vector<string>::const_iterator i = opts.suppression_paths.begin();
i != opts.suppression_paths.end();
++i)
read_suppressions(*i, supprs);
ctxt->add_suppressions(supprs);
}
/// Compare the ABI two elf files, using their associated debug info.
///
/// The result of the comparison is emitted to standard output.
///
/// @param elf1 the first elf file to consider.
///
/// @param debug_dir1 the directory where the debug info file for @p
/// elf1 is stored.
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// The result of the comparison is saved to a global corpus map.
///
/// @param elf2 the second eld file to consider.
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// @args the list of argument sets used for comparison
///
/// @param debug_dir2 the directory where the debug info file for @p
/// elf2 is stored.
///
/// @param opts the options the current program has been called with.
///
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// @param env the environment encapsulating the entire comparison.
///
/// @param diff the shared pointer to be set to the result of the comparison.
///
/// @return the status of the comparison.
static abidiff_status
compare(const elf_file& elf1,
const string& debug_dir1,
const elf_file& elf2,
const string& debug_dir2,
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
const options& opts,
abigail::ir::environment_sptr &env,
corpus_diff_sptr &diff)
{
char *di_dir1 = (char*) debug_dir1.c_str(),
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
*di_dir2 = (char*) debug_dir2.c_str();
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Comparing the ABIs of file "
<< elf1.path
<< " and "
<< elf2.path
<< "...\n";
abigail::dwarf_reader::status c1_status = abigail::dwarf_reader::STATUS_OK,
c2_status = abigail::dwarf_reader::STATUS_OK;
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< " Reading file "
<< elf1.path
<< " ...\n";
Introduce the concept of environment There are resources needed by the type system and other artifacts of libabigail. Today, when the life time of those resources need to be greater than all of artifacts of Abigail, then said resources are made global. But then global resources are not great, if anything because they complicate the future use of the library in concurrent computing setups. As I was in the need to add one resource to be used by the type system, I decided to sit down and first overhaul how these long lived resources needed to be handled. And here comes the concept of "environment". An environment is a place where one can put resources that need to live longer than all the other artifacts of the Abigail system. And so, the code that creates Abigail artifacts needs and environment of for said artifacts to use. In other words, artifacts now use an environment. This has interesting and strong implications. We can only compare two artifacts if they use the same environment. This is quite a strong requirement. But then when this requirement is fulfilled, comparing two types amounts to just comparing two pointer values; hash values for types can also be cached. Now *that* is great for speed of comparison, is it not? This patch introduce the concept environment (which is basically a new abigail::ir::environment type), removes the global variables and uses the environment instead. Each ABI artifact (either type or decl) now has a ::get_environment() member function to get its environment. This patch also disables the caching of hash values because the caching must happen only *after* all types have been canonicalized. We were not respecting that requirement until now, and that introduces wrong hash values. A subsequent patch is going to re-introduce hash value caching again, once the infrastructure is in place to set a flag in the environment (hah!) once type canonicalization is done, and then later read that flag when some client code requests a hash value, to know if we should look in the hash value cache or not. The patch obviously changes the output of numerous regression tests (if anything b/c it disables hash value caching) so 'make check' yields regressions. But then, it's only the subsequent patch that updates the tests. * include/abg-ir.h: Adjust note about memory management. (class environment): Declare new class. (translation_unit::translation_unit): Take an environment in parameter. (translation_unit::{g,s}et_environment): Declare new member functions. (type_or_decl_base::{g,s}et_environment): Likewise. (type_or_decl_base::{get_cached_hash_value, set_cached_hash_value}): Change the name of decl_base::peek_hash_value() and decl_base::set_hash() here into these and move them here. (type_or_decl_base::hashing_started): Move decl_base::hashing_started() here. ({g,s}et_environment_for_artifact): Declare new functions. (class decl_base): Move member functions hashing_started(), peek_hash_value() and set_hash() on to the type_or_decl_base base class. (scope_decl::scope_decl): Initialize the virtual member type_or_decl_base(). (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove these static member functions. They are now non-static member functions of the new environment type. * src/abg-ir.cc (class environment_setter): New internal class. (get_canonical_types_map): Remove. This now becomes a member function of the environment type. (class usage_watchdog): Remove. (usage_watchdog_{s,w}ptr): Remove these typedefs. (get_usage_watchdog_wptr, ref_usage_watchdog) (maybe_cleanup_type_system_data): Remove these functions. (translation_unit::priv::usage_watchdog_): Remove data member. (translation_unit::priv::env_): New data member. (translation_unit::priv::priv): Take an environment and initialize the new env_ data member. Do not initialize the removed usage_watchdog_. (translation_unit::translation_unit): Take an environment parameter. (translation_unit::get_global_scope): Set the environment of a new global scope. (translation_unit::{g,s}et_environment): New accessors. (translation_unit::bind_function_type_life_time): Set the environment of the function type. (struct environment::priv): New class. (environment::{environment, ~environment, get_canonical_types_map, get_variadic_parameter_type_decl, canonicalization_is_done}): New member functions. (struct type_or_decl_base::priv): New class. (type_or_decl_base::{type_or_decl_base, hashing_started, get_cached_hash_value, set_cached_hash_value, set_environment, get_environment, traverse}): New member functions. ({s,g}get_environment_for_artifact): New functions. (decl_base::priv::{hash_, hashing_started}): Remove. (decl_base::priv::priv): Adjust. (decl_base::decl_base): In the copy constructor, initialize the virtual base type_or_decl_base. Do not initialize hash_ and hashing_started data member that got removed. (decl_base::{hashing_started, peek_hash_value, set_hash}): Remove member functions. (strip_typedef): Set the environment of the new type which has its typedefs stripped off. Adjust the call to type_or_void(). (scope_decl::{add, insert}_member_decl): Set the environment of the new member decl to the environment of its scope. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Set the environment for the newly synthesized type. Adjust calls to type_or_void(). (type_or_void): Take an environment in parameter. Get the void type from the environment. (get_canonical_types_map): Remove. (type_base::get_canonical_type_for): Get the canonical types map from the environment, not from a global variable. (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove. (pointer_type_def::pointer_type_def): Adjust call to type_or_void. (reference_type_def::reference_type_def): Likewise. (function_decl::parameter::get_pretty_representation): Get the variadic parameter type decl from the environment. (class_decl::priv::classes_being_compared_): Remove static data member. (class_decl::priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started): Use the "classes being compared" map from the environment. (class_decl::base_spec::get_hash): Adjust. (keep_type_alive): Get the alive types array from the environment) not from a global variable anymore. (get_next_string): Put the counter in thread-local storage. * src/abg-hash.cc (scope_decl::hash::operator()) (function_decl::hash::operator()): Do not handle caching (here). * include/abg-corpus.h (corpus::{g,s}et_environment): Declare new accessors. * src/abg-corpus.cc (corpus::priv::env): New data member. (corpus::priv::priv): Initialize it. (corpus::corpus): Take an environment in parameter. (corpus::{g,s}et_environment): Define new member functions (corpus::add): Set the environment of the newly added translation unit, if it's not set already set. In any case, assert that the translation unit must use the same environment as the corpus. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take an environment parameter. ({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new functions. * src/abg-dwarf-reader.cc (read_context::{env_, offline_callbacks_}): New data members. (read_context::read_context): Initialize them. (read_context::clear_per_translation_unit_data): Do not touch the void type declaration, it doesn't belong to the translation unit. (read_context::{env, offline_callbacks}): New accessors. (read_context::{create_default_dwfl}): New member function. (read_context::dwfl_handle): Add a setter overload. ({s,g}et_debug_info_root_path): Define new accessors. (create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr): Remove these. (build_translation_unit_and_add_to_ir): Adjust to pass the environment to the newly created translation unit. (build_function_decl): Adjust to pass the environment to the created function and parameter types. Get variadic parameter type node from the current environment, not from a global variable. And do not try to canonicalize function types here. (read_debug_info_into_corpus): Set the environment of the newly created corpus. (build_ir_node_for_void_type): Get the void type node from the current environment, rather than from a global variable. (create_read_context): Take the environment in parameter. Create the default dwarf front end library handle using the new member function of the read context. Set the current environment used by the reader. (read_corpus_from_elf): Take an environment in parameter. Overhaul. This is now simpler. (has_alt_debug_info): Adjust the call to create_read_context() to make it pass an empty environment. * include/abg-fwd.h (class environment): Forward declare. * include/abg-reader.h (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream) (read_corpus_from_native_xml): Take an environment in parameter. * src/abg-reader.cc (read_context::m_env): New data member. (read_context::read_context): Initialize it. (read_context::{get_environment, set_environment}): New data member. (read_translation_unit): Set environment of the new translation unit. (read_corpus_from_input): Set the environment of the new corpus. (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream, read_corpus_from_native_xml): Take an environment in parameter. (build_function_parameter): Get variadic parameter type from the environment. * src/abg-comparison.cc (compute_diff): Add asserts in all the overloads to ensure that the artifact being compared come from the same environment. * tests/print-diff-tree.cc (main): Create an env for the ABI artifacts to use. * tests/test-abidiff.cc (main): Likewise. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-ir-walker.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/test-read-write.cc (main): Likewise. * tools/abicompat.cc (main): Likewise. * tools/abidiff.cc (main): Likewise. * tools/abidw.cc (main): Likewise. * tools/abilint.cc (main): Likewise. * tools/abipkgdiff.cc (main): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 20:27:50 +00:00
corpus_sptr corpus1 = read_corpus_from_elf(elf1.path, &di_dir1, env.get(),
/*load_all_types=*/false,
c1_status);
if (!(c1_status & abigail::dwarf_reader::STATUS_OK))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Could not read file '"
<< elf1.path
<< "' properly\n";
return abigail::tools_utils::ABIDIFF_ERROR;
}
if (opts.fail_if_no_debug_info
&& (c1_status & abigail::dwarf_reader::STATUS_DEBUG_INFO_NOT_FOUND))
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "Could not find debug info file";
if (di_dir1 && strcmp(di_dir1, ""))
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << " under " << di_dir1 << "\n";
else
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "\n";
return abigail::tools_utils::ABIDIFF_ERROR;
}
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< " DONE reading file "
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
<< elf1.path
<< "\n";
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< " Reading file "
<< elf2.path
<< " ...\n";
Introduce the concept of environment There are resources needed by the type system and other artifacts of libabigail. Today, when the life time of those resources need to be greater than all of artifacts of Abigail, then said resources are made global. But then global resources are not great, if anything because they complicate the future use of the library in concurrent computing setups. As I was in the need to add one resource to be used by the type system, I decided to sit down and first overhaul how these long lived resources needed to be handled. And here comes the concept of "environment". An environment is a place where one can put resources that need to live longer than all the other artifacts of the Abigail system. And so, the code that creates Abigail artifacts needs and environment of for said artifacts to use. In other words, artifacts now use an environment. This has interesting and strong implications. We can only compare two artifacts if they use the same environment. This is quite a strong requirement. But then when this requirement is fulfilled, comparing two types amounts to just comparing two pointer values; hash values for types can also be cached. Now *that* is great for speed of comparison, is it not? This patch introduce the concept environment (which is basically a new abigail::ir::environment type), removes the global variables and uses the environment instead. Each ABI artifact (either type or decl) now has a ::get_environment() member function to get its environment. This patch also disables the caching of hash values because the caching must happen only *after* all types have been canonicalized. We were not respecting that requirement until now, and that introduces wrong hash values. A subsequent patch is going to re-introduce hash value caching again, once the infrastructure is in place to set a flag in the environment (hah!) once type canonicalization is done, and then later read that flag when some client code requests a hash value, to know if we should look in the hash value cache or not. The patch obviously changes the output of numerous regression tests (if anything b/c it disables hash value caching) so 'make check' yields regressions. But then, it's only the subsequent patch that updates the tests. * include/abg-ir.h: Adjust note about memory management. (class environment): Declare new class. (translation_unit::translation_unit): Take an environment in parameter. (translation_unit::{g,s}et_environment): Declare new member functions. (type_or_decl_base::{g,s}et_environment): Likewise. (type_or_decl_base::{get_cached_hash_value, set_cached_hash_value}): Change the name of decl_base::peek_hash_value() and decl_base::set_hash() here into these and move them here. (type_or_decl_base::hashing_started): Move decl_base::hashing_started() here. ({g,s}et_environment_for_artifact): Declare new functions. (class decl_base): Move member functions hashing_started(), peek_hash_value() and set_hash() on to the type_or_decl_base base class. (scope_decl::scope_decl): Initialize the virtual member type_or_decl_base(). (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove these static member functions. They are now non-static member functions of the new environment type. * src/abg-ir.cc (class environment_setter): New internal class. (get_canonical_types_map): Remove. This now becomes a member function of the environment type. (class usage_watchdog): Remove. (usage_watchdog_{s,w}ptr): Remove these typedefs. (get_usage_watchdog_wptr, ref_usage_watchdog) (maybe_cleanup_type_system_data): Remove these functions. (translation_unit::priv::usage_watchdog_): Remove data member. (translation_unit::priv::env_): New data member. (translation_unit::priv::priv): Take an environment and initialize the new env_ data member. Do not initialize the removed usage_watchdog_. (translation_unit::translation_unit): Take an environment parameter. (translation_unit::get_global_scope): Set the environment of a new global scope. (translation_unit::{g,s}et_environment): New accessors. (translation_unit::bind_function_type_life_time): Set the environment of the function type. (struct environment::priv): New class. (environment::{environment, ~environment, get_canonical_types_map, get_variadic_parameter_type_decl, canonicalization_is_done}): New member functions. (struct type_or_decl_base::priv): New class. (type_or_decl_base::{type_or_decl_base, hashing_started, get_cached_hash_value, set_cached_hash_value, set_environment, get_environment, traverse}): New member functions. ({s,g}get_environment_for_artifact): New functions. (decl_base::priv::{hash_, hashing_started}): Remove. (decl_base::priv::priv): Adjust. (decl_base::decl_base): In the copy constructor, initialize the virtual base type_or_decl_base. Do not initialize hash_ and hashing_started data member that got removed. (decl_base::{hashing_started, peek_hash_value, set_hash}): Remove member functions. (strip_typedef): Set the environment of the new type which has its typedefs stripped off. Adjust the call to type_or_void(). (scope_decl::{add, insert}_member_decl): Set the environment of the new member decl to the environment of its scope. (synthesize_type_from_translation_unit) (synthesize_function_type_from_translation_unit): Set the environment for the newly synthesized type. Adjust calls to type_or_void(). (type_or_void): Take an environment in parameter. Get the void type from the environment. (get_canonical_types_map): Remove. (type_base::get_canonical_type_for): Get the canonical types map from the environment, not from a global variable. (type_decl::{get_void_type_decl, get_variadic_parameter_type_decl}): Remove. (pointer_type_def::pointer_type_def): Adjust call to type_or_void. (reference_type_def::reference_type_def): Likewise. (function_decl::parameter::get_pretty_representation): Get the variadic parameter type decl from the environment. (class_decl::priv::classes_being_compared_): Remove static data member. (class_decl::priv::{mark_as_being_compared, unmark_as_being_compared, comparison_started): Use the "classes being compared" map from the environment. (class_decl::base_spec::get_hash): Adjust. (keep_type_alive): Get the alive types array from the environment) not from a global variable anymore. (get_next_string): Put the counter in thread-local storage. * src/abg-hash.cc (scope_decl::hash::operator()) (function_decl::hash::operator()): Do not handle caching (here). * include/abg-corpus.h (corpus::{g,s}et_environment): Declare new accessors. * src/abg-corpus.cc (corpus::priv::env): New data member. (corpus::priv::priv): Initialize it. (corpus::corpus): Take an environment in parameter. (corpus::{g,s}et_environment): Define new member functions (corpus::add): Set the environment of the newly added translation unit, if it's not set already set. In any case, assert that the translation unit must use the same environment as the corpus. * include/abg-dwarf-reader.h (create_read_context) (read_corpus_from_elf): Take an environment parameter. ({s,g}et_debug_info_root_path, {s,g}et_environment): Declare new functions. * src/abg-dwarf-reader.cc (read_context::{env_, offline_callbacks_}): New data members. (read_context::read_context): Initialize them. (read_context::clear_per_translation_unit_data): Do not touch the void type declaration, it doesn't belong to the translation unit. (read_context::{env, offline_callbacks}): New accessors. (read_context::{create_default_dwfl}): New member function. (read_context::dwfl_handle): Add a setter overload. ({s,g}et_debug_info_root_path): Define new accessors. (create_default_dwfl, create_dwfl_sptr, create_default_dwfl_sptr): Remove these. (build_translation_unit_and_add_to_ir): Adjust to pass the environment to the newly created translation unit. (build_function_decl): Adjust to pass the environment to the created function and parameter types. Get variadic parameter type node from the current environment, not from a global variable. And do not try to canonicalize function types here. (read_debug_info_into_corpus): Set the environment of the newly created corpus. (build_ir_node_for_void_type): Get the void type node from the current environment, rather than from a global variable. (create_read_context): Take the environment in parameter. Create the default dwarf front end library handle using the new member function of the read context. Set the current environment used by the reader. (read_corpus_from_elf): Take an environment in parameter. Overhaul. This is now simpler. (has_alt_debug_info): Adjust the call to create_read_context() to make it pass an empty environment. * include/abg-fwd.h (class environment): Forward declare. * include/abg-reader.h (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream) (read_corpus_from_native_xml): Take an environment in parameter. * src/abg-reader.cc (read_context::m_env): New data member. (read_context::read_context): Initialize it. (read_context::{get_environment, set_environment}): New data member. (read_translation_unit): Set environment of the new translation unit. (read_corpus_from_input): Set the environment of the new corpus. (read_translation_unit_from_file) (read_translation_unit_from_buffer) (read_translation_unit_from_istream, read_corpus_from_native_xml): Take an environment in parameter. (build_function_parameter): Get variadic parameter type from the environment. * src/abg-comparison.cc (compute_diff): Add asserts in all the overloads to ensure that the artifact being compared come from the same environment. * tests/print-diff-tree.cc (main): Create an env for the ABI artifacts to use. * tests/test-abidiff.cc (main): Likewise. * tests/test-diff-dwarf.cc (main): Likewise. * tests/test-ir-walker.cc (main): Likewise. * tests/test-read-dwarf.cc (main): Likewise. * tests/test-read-write.cc (main): Likewise. * tools/abicompat.cc (main): Likewise. * tools/abidiff.cc (main): Likewise. * tools/abidw.cc (main): Likewise. * tools/abilint.cc (main): Likewise. * tools/abipkgdiff.cc (main): Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-07 20:27:50 +00:00
corpus_sptr corpus2 = read_corpus_from_elf(elf2.path, &di_dir2, env.get(),
/*load_all_types=*/false,
c2_status);
if (!(c2_status & abigail::dwarf_reader::STATUS_OK))
{
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Could not find the read file '"
<< elf2.path
<< "' properly\n";
return abigail::tools_utils::ABIDIFF_ERROR;
}
if (opts.fail_if_no_debug_info
&& (c2_status & abigail::dwarf_reader::STATUS_DEBUG_INFO_NOT_FOUND))
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Could not find debug info file";
if (di_dir1 && strcmp(di_dir2, ""))
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< " under " << di_dir2 << "\n";
else
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr) << "\n";
return abigail::tools_utils::ABIDIFF_ERROR;
}
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< " DONE reading file " << elf2.path << "\n";
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< " Comparing the ABIs of: \n"
<< " " << elf1.path << "\n"
<< " " << elf2.path << "\n";
diff_context_sptr ctxt(new diff_context);
set_diff_context_from_opts(ctxt, opts);
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
diff = compute_diff(corpus1, corpus2, ctxt);
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Comparing the ABIs of file "
<< elf1.path
<< " and "
<< elf2.path
<< " is DONE\n";
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
abidiff_status s = abigail::tools_utils::ABIDIFF_OK;
if (diff->has_net_changes())
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
s |= abigail::tools_utils::ABIDIFF_ABI_CHANGE;
if (diff->has_incompatible_changes())
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
s |= abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE;
return s;
}
/// A wrapper to call compare in a separate thread.
/// The result of the comparison is saved to a global corpus map.
///
/// @args the vector of argument sets used for comparison.
///
/// @return the status of the comparison via pthread_exit().
static void
pthread_routine_compare(vector<compare_args_sptr> *args)
{
abidiff_status s, status = abigail::tools_utils::ABIDIFF_OK;
compare_args_sptr a;
corpus_diff_sptr diff;
while (true)
{
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
pthread_mutex_lock(&arg_lock);
if (args->empty())
a = compare_args_sptr();
else
{
a = *args->begin();
args->erase(args->begin());
}
pthread_mutex_unlock(&arg_lock);
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
if (!a)
break;
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
abigail::ir::environment_sptr env(new abigail::ir::environment);
status |= s = compare(a->elf1, a->debug_dir1,
a->elf2, a->debug_dir2,
a->opts, env, diff);
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
const string key = a->elf1.path;
if ((s & abigail::tools_utils::ABIDIFF_ABI_CHANGE)
|| (verbose && diff->has_changes()))
{
pthread_mutex_lock(&map_lock);
reports_map[key] = diff;
// We need to keep the environment around, until the corpus is
// report()-ed.
env_map[diff] = env;
pthread_mutex_unlock(&map_lock);
}
else
{
pthread_mutex_lock(&map_lock);
reports_map[key] = corpus_diff_sptr();
pthread_mutex_unlock(&map_lock);
}
}
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
pthread_exit(new abidiff_status(status));
}
/// Create maps of the content of a given package.
///
/// The maps contain relevant metadata about the content of the
/// files. These maps are used afterwards during the comparison of
/// the content of the package. Note that the maps are stored in the
/// object that represents that package.
///
/// @param package the package to consider.
///
/// @param opts the options the current program has been called with.
///
/// @param true upon successful completion, false otherwise.
static bool
create_maps_of_package_content(package& package,
const options& opts,
ftw_cb_type callback)
{
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
vector<string> *elf_file_paths = new vector<string>;
pthread_setspecific(elf_file_paths_tls_key, elf_file_paths);
if (verbose)
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Analyzing the content of package "
<< package.path()
<< " extracted to "
<< package.extracted_dir_path()
<< " ...\n";
if (ftw(package.extracted_dir_path().c_str(), callback, 16))
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Error while inspecting files in package"
<< package.extracted_dir_path() << "\n";
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
return false;
}
if (verbose)
emit_prefix("abipkgdiff", cerr)
<< "Found " << elf_file_paths->size() << " files in "
<< package.extracted_dir_path() << "\n";
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
for (vector<string>::const_iterator file =
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
elf_file_paths->begin();
file != elf_file_paths->end();
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
++file)
{
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
elf_file_sptr e (new elf_file(*file));
if (opts.compare_dso_only)
{
if (e->type != abigail::dwarf_reader::ELF_TYPE_DSO)
{
if (verbose)
emit_prefix("abipkgdiff", cerr)
<< "skipping non-DSO file " << e->path << "\n";
continue;
}
}
else
{
if (e->type != abigail::dwarf_reader::ELF_TYPE_DSO
Bug 19961 - Distinguish between PI executable and shared library In the ELF format, Position Independent Executables (aka PIE) and shared libraries are marked as being of type ET_DYN. So just looking at the type of the ELF file is not enough to discriminate a position independent executable from a shared library. And this is the problem. Libabigail just looks at the type of the ELF file to discriminate PIE binaries from shared libraries binaries. So it treats both kinds of binaries as being shared libraries. When we run abipkgdiff with the --dso-only option, the tool considers both PIEs and shared libraries, even though the intent of the --dso-only option is have the tool consider shared libraries only. With this patch, we introduce a new enumerator ELF_TYPE_PI_EXEC (to the elf_type enum) for PIE binaries. From now on, a file will be properly recognized as being of the ELF_TYPE_DSO kind only if it is a shared library. * include/abg-dwarf-reader.h (elf_type): Add new enumerator ELF_TYPE_PI_EXEC. * src/abg-dwarf-reader.cc (lookup_data_tag_from_dynamic_segment): New function for data tag lookup in dynamic segment of an elf (elf_file_type): Return ELF_TYPE_PI_EXEC file type for a PI executable. (get_elf_file_type): Change this to take an elf handle. (get_type_of_elf_file): New function that got factorized out of ... (load_dt_soname_and_needed): ... this one. * tools/abipkgdiff.cc (create_maps_of_package_content): Also consider ELF_TYPE_PI_EXEC file type. (compare): Likewise. * tests/test-diff-pkg.cc (in_out_specs): Test case additions * tests/data/Makefile.am: Include test files * tests/data/test-diff-pkg/tarpkg-1-dir1.tar.gz: New test data * tests/data/test-diff-pkg/tarpkg-1-dir2.tar.gz: New test data * tests/data/test-diff-pkg/tarpkg-1-report-0.txt: New test result Signed-off-by: Sinny Kumari <sinny@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-04-19 18:31:56 +00:00
&& e->type != abigail::dwarf_reader::ELF_TYPE_EXEC
&& e->type != abigail::dwarf_reader::ELF_TYPE_PI_EXEC)
{
if (verbose)
emit_prefix("abipkgdiff", cerr)
<< "skipping non-DSO non-executable file " << e->path << "\n";
continue;
}
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
if (e->soname.empty())
package.path_elf_file_sptr_map()[e->name] = e;
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
else
package.path_elf_file_sptr_map()[e->soname] = e;
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
pthread_setspecific(elf_file_paths_tls_key, /*value=*/NULL);
delete elf_file_paths;
if (verbose)
emit_prefix("abipkgdiff", cerr)
<< " Analysis of " << package.path() << " DONE\n";
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
return true;
}
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
static inline bool
pthread_join(pthread_t thr)
{
bool *thread_retval;
if (!pthread_join(thr, reinterpret_cast<void**>(&thread_retval)))
{
bool retval = *thread_retval;
delete thread_retval;
return retval;
}
else
return false;
}
/// Extract the content of a package and map its content.
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// Also extract its accompanying debuginfo package.
///
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// The extracting is done to a temporary directory.
///
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// @param a the set of arguments needed for successful extraction;
/// specifically the package itself, the options the current package has been
/// called with and a callback to traverse the directory structure.
///
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
/// @return via pthread_exit() true upon successful completion, false
/// otherwise.
static void
pthread_routine_extract_pkg_and_map_its_content(package_descriptor *a)
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
{
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
pthread_t thr_pkg, thr_debug;
package& package = a->pkg;
const options& opts = a->opts;
ftw_cb_type callback = a->callback;
bool has_debug_info_pkg, result = true;
// The debug-info package usually takes longer to extract than the main
// package plus that package's mapping for ELFs and optionally suppression
// specs, so we run it ASAP.
if ((has_debug_info_pkg = package.debug_info_package()))
{
if (pthread_create(&thr_debug, /*attr=*/NULL,
reinterpret_cast<void*(*)(void*)>(pthread_routine_extract_package),
package.debug_info_package().get()))
{
result = false;
goto exit;
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
// Wait for debug-info package extraction to complete if we're
// not running in parallel.
if (!opts.parallel)
{
result = pthread_join(thr_debug);
if (!result)
goto exit;
}
}
// Extract the package itself.
if (pthread_create(&thr_pkg, /*attr=*/NULL,
reinterpret_cast<void*(*)(void*)>(pthread_routine_extract_package),
&package))
result = false;
// We need to wait for the package's successful extraction, if we
// want to do a mapping on its files.
if (result)
result = pthread_join(thr_pkg);
// If extracting the package failed, there's no sense in going further.
if (result)
result = create_maps_of_package_content(package, opts, callback);
// Let's wait for both extractions to finish before we exit.
if (has_debug_info_pkg && opts.parallel)
result &= pthread_join(thr_debug);
exit:
pthread_exit(new bool(result));
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
}
/// Prepare the packages for comparison.
///
/// This function extracts the content of each package and maps it.
///
/// @param first_package the first package to prepare.
///
/// @param second_package the second package to prepare.
///
/// @param opts the options the current program has been called with.
///
/// @return true upon successful completion, false otherwise.
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
static bool
prepare_packages(package& first_package,
package& second_package,
const options& opts)
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
{
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
bool result = true;
const int npkgs = 2;
pthread_t extract_thread[npkgs];
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
package_descriptor ea[] =
{
{
first_package,
opts,
first_package_tree_walker_callback_fn
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
},
{
second_package,
opts,
second_package_tree_walker_callback_fn
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
},
};
// Since we can't pass custom arguments to the callback of ftw(),
// and we are going to walk two directory trees in parallel, we
// need a separate thread-local vector of files for each package.
pthread_key_create(&elf_file_paths_tls_key, /*destructor=*/NULL);
for (int i = 0; i < npkgs; ++i)
{
pthread_create(&extract_thread[i], /*attr=*/NULL,
reinterpret_cast<void*(*)(void*)>(pthread_routine_extract_pkg_and_map_its_content),
&ea[i]);
if (!opts.parallel)
// We're not running in parallel, so wait for the first package set to
// finish extracting before starting to work on the second one.
result &= pthread_join(extract_thread[i]);
}
if (opts.parallel)
{
// We're running in parallel, so we collect the threads here.
for (int i = 0; i < npkgs; ++i)
result &= pthread_join(extract_thread[i]);
}
pthread_key_delete(elf_file_paths_tls_key);
return result;
}
/// Compare the added sizes of a ELF pair specified by @a1
/// with the sizes of a ELF pair from @a2.
///
/// Larger filesize strongly raises the possibility of larger debug-info,
/// hence longer diff time. For a package containing several relatively
/// large and small ELFs, it is often more efficient to start working on
/// the larger ones first. This function is used to order the pairs by
/// size, starting from the largest.
///
/// @a1 the first set of arguments containing also the size information about
/// the ELF pair being compared.
///
/// @a2 the second set of arguments containing also the size information about
/// the ELF pair being compared.
bool
elf_size_is_greater(const compare_args_sptr &a1, const compare_args_sptr &a2)
{
off_t s1 = a1->elf1.size + a1->elf2.size;
off_t s2 = a2->elf1.size + a2->elf2.size;
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
return s1 > s2;
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
}
/// Compare the ABI of two packages
///
/// @param first_package the first package to consider.
///
/// @param second_package the second package to consider.
///
/// @param options the options the current program has been called
/// with.
///
/// @param diff out parameter. If this function returns true, then
/// this parameter is set to the result of the comparison.
///
/// @return the status of the comparison.
static abidiff_status
compare(package& first_package,
package& second_package,
const options& opts,
abi_diff& diff)
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
{
if (!prepare_packages(first_package, second_package, opts))
return abigail::tools_utils::ABIDIFF_ERROR;
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
// Setting debug-info path of libraries
string debug_dir1, debug_dir2, relative_debug_path = "/usr/lib/debug/";
if (first_package.debug_info_package()
&& second_package.debug_info_package())
{
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
debug_dir1 =
first_package.debug_info_package()->extracted_dir_path() +
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
relative_debug_path;
if (second_package.debug_info_package())
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
debug_dir2 =
second_package.debug_info_package()->extracted_dir_path() +
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
relative_debug_path;
}
abidiff_status status = abigail::tools_utils::ABIDIFF_OK;
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
vector<compare_args_sptr> elf_pairs;
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
for (map<string, elf_file_sptr>::iterator it =
first_package.path_elf_file_sptr_map().begin();
it != first_package.path_elf_file_sptr_map().end();
++it)
{
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
map<string, elf_file_sptr>::iterator iter =
second_package.path_elf_file_sptr_map().find(it->first);
if (iter != second_package.path_elf_file_sptr_map().end()
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
&& (iter->second->type == abigail::dwarf_reader::ELF_TYPE_DSO
Bug 19961 - Distinguish between PI executable and shared library In the ELF format, Position Independent Executables (aka PIE) and shared libraries are marked as being of type ET_DYN. So just looking at the type of the ELF file is not enough to discriminate a position independent executable from a shared library. And this is the problem. Libabigail just looks at the type of the ELF file to discriminate PIE binaries from shared libraries binaries. So it treats both kinds of binaries as being shared libraries. When we run abipkgdiff with the --dso-only option, the tool considers both PIEs and shared libraries, even though the intent of the --dso-only option is have the tool consider shared libraries only. With this patch, we introduce a new enumerator ELF_TYPE_PI_EXEC (to the elf_type enum) for PIE binaries. From now on, a file will be properly recognized as being of the ELF_TYPE_DSO kind only if it is a shared library. * include/abg-dwarf-reader.h (elf_type): Add new enumerator ELF_TYPE_PI_EXEC. * src/abg-dwarf-reader.cc (lookup_data_tag_from_dynamic_segment): New function for data tag lookup in dynamic segment of an elf (elf_file_type): Return ELF_TYPE_PI_EXEC file type for a PI executable. (get_elf_file_type): Change this to take an elf handle. (get_type_of_elf_file): New function that got factorized out of ... (load_dt_soname_and_needed): ... this one. * tools/abipkgdiff.cc (create_maps_of_package_content): Also consider ELF_TYPE_PI_EXEC file type. (compare): Likewise. * tests/test-diff-pkg.cc (in_out_specs): Test case additions * tests/data/Makefile.am: Include test files * tests/data/test-diff-pkg/tarpkg-1-dir1.tar.gz: New test data * tests/data/test-diff-pkg/tarpkg-1-dir2.tar.gz: New test data * tests/data/test-diff-pkg/tarpkg-1-report-0.txt: New test result Signed-off-by: Sinny Kumari <sinny@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-04-19 18:31:56 +00:00
|| iter->second->type == abigail::dwarf_reader::ELF_TYPE_EXEC
|| iter->second->type == abigail::dwarf_reader::ELF_TYPE_PI_EXEC))
{
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
elf_pairs.push_back(compare_args_sptr(new compare_args(*it->second,
debug_dir1, *iter->second,
debug_dir2, opts)));
}
else
{
diff.removed_binaries.push_back(it->second);
status |= abigail::tools_utils::ABIDIFF_ABI_INCOMPATIBLE_CHANGE;
status |= abigail::tools_utils::ABIDIFF_ABI_CHANGE;
}
}
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
// Larger elfs are processed first, since it's usually safe to assume
// their debug-info is larger as well, but the results are still
// in a map ordered by looked up in elf.name order.
std::sort(elf_pairs.begin(), elf_pairs.end(), elf_size_is_greater);
size_t nprocs = opts.parallel ? sysconf(_SC_NPROCESSORS_ONLN) : 1;
assert(nprocs >= 1);
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
// There's no reason to spawn more threads than there are pairs to be diffed.
nprocs = std::min(nprocs, elf_pairs.size());
// if nprocs is zero, it means we have no binary to compare.
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
// We've identified the elf couples to compare, let's spawn NPROCS threads
// to do comparisons.
pthread_t thr;
vector<pthread_t> waitlist;
for (size_t i = 0; i < nprocs; ++i)
{
if (!pthread_create(&thr, /*attr=*/NULL,
reinterpret_cast<void*(*)(void*)>(pthread_routine_compare),
&elf_pairs))
// Record all the threads we will be waiting for.
waitlist.push_back(thr);
}
// Let's iterate over the valid ELF pairs in-order again, this time
// waiting for their diffs to come up from the other threads and reporting
// them ASAP.
for (map<string, elf_file_sptr>::iterator it =
first_package.path_elf_file_sptr_map().begin();
it != first_package.path_elf_file_sptr_map().end();
++it)
{
map<string, elf_file_sptr>::iterator iter =
second_package.path_elf_file_sptr_map().find(it->first);
if (iter != second_package.path_elf_file_sptr_map().end()
&& (iter->second->type == abigail::dwarf_reader::ELF_TYPE_DSO
Bug 19961 - Distinguish between PI executable and shared library In the ELF format, Position Independent Executables (aka PIE) and shared libraries are marked as being of type ET_DYN. So just looking at the type of the ELF file is not enough to discriminate a position independent executable from a shared library. And this is the problem. Libabigail just looks at the type of the ELF file to discriminate PIE binaries from shared libraries binaries. So it treats both kinds of binaries as being shared libraries. When we run abipkgdiff with the --dso-only option, the tool considers both PIEs and shared libraries, even though the intent of the --dso-only option is have the tool consider shared libraries only. With this patch, we introduce a new enumerator ELF_TYPE_PI_EXEC (to the elf_type enum) for PIE binaries. From now on, a file will be properly recognized as being of the ELF_TYPE_DSO kind only if it is a shared library. * include/abg-dwarf-reader.h (elf_type): Add new enumerator ELF_TYPE_PI_EXEC. * src/abg-dwarf-reader.cc (lookup_data_tag_from_dynamic_segment): New function for data tag lookup in dynamic segment of an elf (elf_file_type): Return ELF_TYPE_PI_EXEC file type for a PI executable. (get_elf_file_type): Change this to take an elf handle. (get_type_of_elf_file): New function that got factorized out of ... (load_dt_soname_and_needed): ... this one. * tools/abipkgdiff.cc (create_maps_of_package_content): Also consider ELF_TYPE_PI_EXEC file type. (compare): Likewise. * tests/test-diff-pkg.cc (in_out_specs): Test case additions * tests/data/Makefile.am: Include test files * tests/data/test-diff-pkg/tarpkg-1-dir1.tar.gz: New test data * tests/data/test-diff-pkg/tarpkg-1-dir2.tar.gz: New test data * tests/data/test-diff-pkg/tarpkg-1-report-0.txt: New test result Signed-off-by: Sinny Kumari <sinny@redhat.com> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-04-19 18:31:56 +00:00
|| iter->second->type == abigail::dwarf_reader::ELF_TYPE_EXEC
|| iter->second->type == abigail::dwarf_reader::ELF_TYPE_PI_EXEC))
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
{
second_package.path_elf_file_sptr_map().erase(iter);
while (true)
{
pthread_mutex_lock(&map_lock);
corpora_report_map::iterator d = reports_map.find(it->second->path);
pthread_mutex_unlock(&map_lock);
if (d == reports_map.end())
// No result yet.
continue;
if (!d->second)
// The objects match.
break;
else
{
// Diff created -> report it.
string name = it->second->name;
diff.changed_binaries.push_back(name);
const string prefix = " ";
cout << "================ changes of '"
<< name
<< "'===============\n";
d->second->report(cout, prefix);
cout << "================ end of changes of '"
<< name
<< "'===============\n\n";
pthread_mutex_lock(&map_lock);
env_map.erase(d->second);
reports_map.erase(d);
pthread_mutex_unlock(&map_lock);
break;
}
}
}
}
abidiff_status *s;
// Join the comparison threads and collect the statuses.
for (vector<pthread_t>::iterator it = waitlist.begin(); it != waitlist.end();
++it)
{
pthread_join(*it, reinterpret_cast<void **>(&s));
status |= *s;
delete s;
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
for (map<string, elf_file_sptr>::iterator it =
second_package.path_elf_file_sptr_map().begin();
it != second_package.path_elf_file_sptr_map().end();
++it)
diff.added_binaries.push_back(it->second);
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
if (diff.removed_binaries.size())
{
cout << "Removed binaries:\n";
for (vector<elf_file_sptr>::iterator it = diff.removed_binaries.begin();
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
it != diff.removed_binaries.end(); ++it)
{
cout << " " << (*it)->name << ", ";
string soname;
get_soname_of_elf_file((*it)->path, soname);
if (!soname.empty())
cout << "SONAME: " << soname;
else
cout << "no SONAME";
cout << "\n";
}
}
if (opts.show_added_binaries && diff.added_binaries.size())
{
cout << "Added binaries:\n";
for (vector<elf_file_sptr>::iterator it = diff.added_binaries.begin();
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
it != diff.added_binaries.end(); ++it)
{
cout << " " << *it << ", ";
string soname;
get_soname_of_elf_file((*it)->path, soname);
if (!soname.empty())
cout << "SONAME: " << soname;
else
cout << "no SONAME";
cout << "\n";
}
}
if (!opts.keep_tmp_files)
{
erase_created_temporary_directories(first_package, second_package);
erase_created_temporary_directories_parent();
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
return status;
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
}
/// Compare the ABI of two packages.
///
/// @param first_package the first package to consider.
///
/// @param second_package the second package to consider.
///
/// @param opts the options the current program has been called with.
///
/// @return the status of the comparison.
static abidiff_status
compare(package& first_package, package& second_package, const options& opts)
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
{
abi_diff diff;
return compare(first_package, second_package, opts, diff);
}
/// Parse the command line of the current program.
///
/// @param argc the number of arguments in the @p argv parameter.
///
/// @param argv the array of arguemnts passed to the function. The
/// first argument is the name of this program.
///
/// @param opts the resulting options.
///
/// @return true upon successful parsing.
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
static bool
parse_command_line(int argc, char* argv[], options& opts)
{
if (argc < 2)
return false;
for (int i = 1; i < argc; ++i)
{
if (argv[i][0] != '-')
{
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
if (opts.package1.empty())
opts.package1 = abigail::tools_utils::make_path_absolute(argv[i]).get();
else if (opts.package2.empty())
opts.package2 = abigail::tools_utils::make_path_absolute(argv[i]).get();
else
return false;
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
else if (!strcmp(argv[i], "--debug-info-pkg1")
|| !strcmp(argv[i], "--d1"))
{
int j = i + 1;
if (j >= argc)
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
opts.missing_operand = true;
opts.wrong_option = argv[i];
return true;
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
opts.debug_package1 =
abigail::tools_utils::make_path_absolute(argv[j]).get();
++i;
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
else if (!strcmp(argv[i], "--debug-info-pkg2")
|| !strcmp(argv[i], "--d2"))
{
int j = i + 1;
if (j >= argc)
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
opts.missing_operand = true;
opts.wrong_option = argv[i];
return true;
}
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
opts.debug_package2 =
abigail::tools_utils::make_path_absolute(argv[j]).get();
++i;
}
else if (!strcmp(argv[i], "--keep-tmp-files"))
opts.keep_tmp_files = true;
else if (!strcmp(argv[i], "--dso-only"))
opts.compare_dso_only = true;
else if (!strcmp(argv[i], "--no-linkage-name"))
opts.show_linkage_names = false;
else if (!strcmp(argv[i], "--redundant"))
opts.show_redundant_changes = true;
Add the option of printing the file, line and column information about a type being reported. * bash-completion/abicompat: Complete the new "--no-show-locs" option. * bash-completion/abidiff: Likewise. * bash-completion/abidw: Likewise. * bash-completion/abipkgdiff: Likewise. * doc/manuals/abicompat.rst: Mention the new "--no-show-locs" option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-comparison.h (show_locs): Add declarations. * src/abg-comparison.cc: (diff_context::priv): Add a new switch called "show_locs_" and set its default value to false. (report_loc_info): New function. Outputting the extra information is conditionalized based on the associated diff contexts settings. (show_locs): define a getter/setter for diff_context::priv::show_locs_. ({distinct,pointer,reference,qualified_type,enum,class,scope,fn_parm, typedef,corpus}_diff::report): Call report_loc_info when appropriate. (maybe_report_diff_for_member): Likewise. (represent): Accept a const reference to a diff_context_sptr as a first argument and call report_loc_info on its second argument. * src/abg-dwarf-reader.cc: * tests/data/Makefile.am: Add the new test reference files. * tests/data/test-abicompat/test0-fn-changed-report-2.txt: New test reference output. * tests/data/test-abicompat/test5-fn-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test6-var-changed-report-1.txt: Likewise. * tests/data/test-abicompat/test7-fn-changed-report-2.txt: Likewise. * tests/data/test-diff-filter/test30-pr18904-rvalueref-report1.txt: Likewise. * tests/data/test-diff-filter/test31-pr18535-libstdc++-report-1.txt: Likewise. * tests/data/test-diff-pkg/dirpkg-3-report-2.txt: Likewise. * tests/data/test-diff-suppr/test6-fn-suppr-report-0-1.txt: Likewise. * tests/test-abidiff.cc: Explicitly create a diff context and turn off location emitting. * tests/test-diff-dwarf.cc: Likewise. * tests/test-abicompat.cc: Add --no-show-locs to all existing test arguments. Run a few of the existing tests again, but without this option. * tests/test-diff-filter.cc: Likewise. * tests/test-diff-pkg.cc: Likewise. * tests/test-diff-suppr.cc: Likewise. * tools/abicompat.cc: Handle the new "--no-show-locs" option. * tools/abidiff.cc: Likewise. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-16 09:55:28 +00:00
else if (!strcmp(argv[i], "--no-show-locs"))
opts.show_locs = false;
else if (!strcmp(argv[i], "--no-added-syms"))
opts.show_added_syms = false;
else if (!strcmp(argv[i], "--no-added-binaries"))
opts.show_added_binaries = false;
else if (!strcmp(argv[i], "--fail-no-dbg"))
opts.fail_if_no_debug_info = true;
else if (!strcmp(argv[i], "--verbose"))
verbose = true;
else if (!strcmp(argv[i], "--no-abignore"))
opts.abignore = false;
Bug 19081 - abipkgdiff parallelization Abipkgdiff now attempts to extract packages and compare the resulting ELF pairs in parallel. First off, a thread is spawned to extract each package and each debuginfo package. After the ELF files are extracted, mapped and the threads are successfully collected, the resulting ELF vectors are traversed to identify existing pairs and a list of arguments for future comparison is made. This list is then sorted by size from largest to smallest. Unless --no-parallel is specified on the command line, MIN(pairs,active_processors) threads are spawned, sharing a single list of arguments. This list is processed and a map of (ELF_PATH,DIFF_CORPUS) is created. Meanwhile, the main thread checks this same map for results in the original order of the ELF pairs, ensuring sequential output. After all the diffing and reporting is done, the threads are collected again. * doc/manuals/abipkgdiff.rst: Mention the new --no-parallel option. * tools/Makefile.am: Add -pthread to abipkgdiffs link options. * tools/abipkgdiff.cc (elf_file_paths_tls_key): New key for the thread-local vector of ELF filepaths. (reports_map): A map of the path of the first ELF of a compared pair and a corpus representing the difference. (env_map): A map of the corpus difference and a corresponding environment needed to be kept alive until the diff is reported. ({arg,map}_lock): mutexes to control access to the comparison argument list and the {reports,env}_map respectively. (options): Add a new member "parallel" and set it to true in the ctor. (elf_file): Add a new "size" member and set it in the ctor. (package descriptor): Arguments passed to extract_package_set. (compare_args): Arguments passed to the ELF comparison function. (display_usage): Mention the new "--no-parallel" option. (pthread_routine_extract_package): A wrapper function around extract_package to be used in a multi-threaded environment. ({first_second}_package_tree_walker_callback_fn): Add the new ELF file paths to a thread-specific vector. (compare): In an overload of compare, verbose output is updated to always mention the ELF files being compared for each reported stage. Reporting is no longer done in this function, the resulting difference is instead passed back to the calling function for reporting in the main thread, along with a corresponding environment. (pthread_routine_compare): Accept a pointer to a vector of comparison arguments. This function is to be called NTHREAD times and share the vector passed to it with its other invocations. Create the environment for compare() and store its output in a map if there is a difference. (create_maps_of_package_content): Allocate memory for a thread local vector of ELF paths and dispose of it before returning. (pthread_routine_extract_pkg_and_map_its_content): Renamed from extract_package_and_map_its_content. Extract the debuginfo as well as the regular package in this function. Spawn a separate thread for the extraction of the debug package. (pthread_join): A function handling thread joining throughout package extractions. (prepare_packages): Spawn a thread to extract each set of packages. (elf_size_is_greater): New comparison function used to order ELF pairs by size. (compare): In the overload of compare, pass through the ELF path vectors and identify pairs to be diffed. Put them in a vector and sort it by the summed ELF pair size. Spawn comparison threads and safely check for results in the proper order of the ELF pairs. Report any differences ASAP and collect the threads after all the reporting is done, checking their return status. (parse_command_line): Check for the "--no-parallel" option. Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
2015-11-09 10:02:45 +00:00
else if (!strcmp(argv[i], "--no-parallel"))
opts.parallel = false;
else if (!strcmp(argv[i], "--suppressions")
|| !strcmp(argv[i], "--suppr"))
{
int j = i + 1;
if (j >= argc)
return false;
opts.suppression_paths.push_back(argv[j]);
++i;
}
else if (!strcmp(argv[i], "--help")
|| !strcmp(argv[i], "-h"))
{
opts.display_usage = true;
return true;
}
Add --version option to several libabigail tools This patch changed the revision number of the libabigail library to make it reflect the fact that we are not in "release candidate" mode, before the first 1.0 release. So the revision number is now "rc0". The configuration manager has been updated to support version numbers that are strings, so that it can supports things like "rc0". Then, several libabigail tools have been modified to support the --version option to display their version number. * configure.ac: Set the version revision to "rc0". * doc/manuals/abicompat.rst: Adjust manual for new --version option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abilint.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-config.h (config::{m_format_minor, m_format_major}): Make these be strings. (config::{get,set}_format_minor_version_number): Make these return strings. (config::{get,set}_format_major_version_number): Make these return or take strings. (abigail_get_library_version): Make this take strings. * src/abg-config.cc (config::config): Adjust. (config::{get,set}_format_major_version_number): Make these return or take strings. (config::{get,set}_format_minor_version_number): Make these return strings. (abigail_get_library_version): Make this take strings. * include/abg-version.h.in: Make the version variables be strings. * src/abg-writer.cc (write_translation_unit): The version numbers are now strings so adjust. * tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc (options::display_version): New data member. (options::options): Initialize it. (display_usage): Add documentation for new --version option. (parse_command_line): Parse new --version option. (main): Support --version. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-11-16 10:39:15 +00:00
else if (!strcmp(argv[i], "--version")
|| !strcmp(argv[i], "-v"))
{
opts.display_version = true;
return true;
}
else
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
{
if (strlen(argv[i]) >= 2 && argv[i][0] == '-' && argv[i][1] == '-')
opts.wrong_option = argv[i];
return false;
}
}
return true;
}
int
main(int argc, char* argv[])
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
options opts(argv[0]);
prog_options = &opts;
vector<package_sptr> packages;
if (!parse_command_line(argc, argv, opts))
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "unrecognized option:" << opts.wrong_option
<< "\ntry the --help option for more information\n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
}
if (opts.missing_operand)
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "missing operand\n"
"try the --help option for more information\n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
}
if (opts.display_usage)
{
display_usage(argv[0], cout);
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
}
Add --version option to several libabigail tools This patch changed the revision number of the libabigail library to make it reflect the fact that we are not in "release candidate" mode, before the first 1.0 release. So the revision number is now "rc0". The configuration manager has been updated to support version numbers that are strings, so that it can supports things like "rc0". Then, several libabigail tools have been modified to support the --version option to display their version number. * configure.ac: Set the version revision to "rc0". * doc/manuals/abicompat.rst: Adjust manual for new --version option. * doc/manuals/abidiff.rst: Likewise. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abilint.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * include/abg-config.h (config::{m_format_minor, m_format_major}): Make these be strings. (config::{get,set}_format_minor_version_number): Make these return strings. (config::{get,set}_format_major_version_number): Make these return or take strings. (abigail_get_library_version): Make this take strings. * src/abg-config.cc (config::config): Adjust. (config::{get,set}_format_major_version_number): Make these return or take strings. (config::{get,set}_format_minor_version_number): Make these return strings. (abigail_get_library_version): Make this take strings. * include/abg-version.h.in: Make the version variables be strings. * src/abg-writer.cc (write_translation_unit): The version numbers are now strings so adjust. * tools/{abicompat,abidiff,abidw,abilint,abipkgdiff,abisym}.cc (options::display_version): New data member. (options::options): Initialize it. (display_usage): Add documentation for new --version option. (parse_command_line): Parse new --version option. (main): Support --version. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-11-16 10:39:15 +00:00
if (opts.display_version)
{
string major, minor, revision;
abigail::abigail_get_library_version(major, minor, revision);
cout << major << "." << minor << "." << revision << "\n";
return 0;
}
if (!maybe_check_suppression_files(opts))
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
if (opts.package1.empty() || opts.package2.empty())
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< "Please enter two packages to compare" << "\n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
}
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
package_sptr first_package(new package(opts.package1, "package1"));
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
Remove the last direct fiddling with ELF from abipkgdiff.cc Directly using elfutils from abipkgdiff.cc feels like a taping into the wrong abstraction layer from this level. So this patch moves the determination of the type of elf file into abg-dwarf-reader.cc and uses it from there. The patch also simplifies the instantiation of types elf_file and package, from abipkgdiff.cc. * abg-dwarf-reader.h (enum elf_type): Move this declaration here from abipkgdiff.cc to here. (get_type_of_elf_file): Declare this new function. (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. So now to use this, the user doesn't have to get her hand dirty with elfutils. * src/abg-dwarf-reader.cc (get_soname_from_elf): Change this to take a path to the elf file rather than a Elf* handler. (elf_file_type): Move this static function here, from abipkgdiff.cc. (get_type_of_elf_file): New function. This has been factorized out of create_maps_of_package_content() in abipkgdiff.cc. * tools/abipkgdiff.cc (class elf_file): Changed struct elf_file into this. Make the default constructor private. (elf_file::elf_file): Change the constructor to just take the path to the elf_file. The base name, soname and elf file type are now computed from the path file, in the constructor. This makes instantiation much much easier from the point of view of the user of the type. (struct abi_diff): Renamed struct abi_changes into this. (abi_diff::has_changes): Define new member function. (abi_diffs): Remove this global variable. (package::package): Remove the elf file type from the set of parameters of this constructor. Rather, compute that elf file type from the path to the elf file, in the constructor. Again, this eases the use of the type. (elf_file_type): Remove this from here, as it got moved to abg-dwarf-reader.cc. (compare): In the elf_file overload, return true if the comparison yields ABI changes. (create_maps_of_package_content): Do not fiddle with elfutils stuff here. Rather, just instantiate elf_file and the analyzing of the file magically happens. (compare): Make the package overload take an abi_diff as output parameter, rather than populating a global variable in return. (compare): Add an other overload for package that doesn't take the abi_diff as output parameter and write it in terms of the previous one. (main): Adjust as the instantiation of package is now simpler. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-15 13:25:26 +00:00
package_sptr second_package(new package(opts.package2, "package2"));
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
if (!opts.debug_package1.empty())
first_package->debug_info_package
(package_sptr(new package(opts.debug_package1,
"debug_package1",
/*is_debug_info=*/true)));
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
if (!opts.debug_package2.empty())
second_package->debug_info_package
(package_sptr(new package(opts.debug_package2,
"debug_package2",
/*is_debug_info=*/true)));
Important organizational changes in abipkgdiff.cc This patch introduces many changes that should hopefully improve legibility and ease of maintenance. Here is a list of the topic of the changes: * Avoid using shortened names when the line is not too long. * Use shared_ptr when possible. * When a function parameter is not meant to be nil, do not pass it as a pointer; rather, pass it as a reference. * Avoid doing things that can "fail" in a destructor; e.g, spawning a process. Also, it's not common practise to cleanup a resource in a type destructor, when that resource has not been created in one of the member functions of the type. It eases maintenance when resource creation and cleanup is performed at the same logical level. * tools/abipkgdiff.cc (option::package{1,2}): Rename option::pkg{1,2} into this, to increase legibility. (option::debug_package{1,2}): Likewise, rename option::debug_pkg{1,2} into this. (elf_file::~elf_file): Do not "delete this" in a destructor. This leads to double free. It's when someone invokes the "delete" operator on a pointer to the object that the destructor of the object is executed automatically; so if in the destructor the delete operator is called again, bad things are going to happen. As the destructor is now empty, remove it altogether. (elf_file_sptr): New typedef for shared_ptr<elf_file>. (package::path): Rename package::pkg_path into this, for better legibility. (package::extracted_package_dir_path): Rename package::extracted_pkg_dir_path into this. (package::type): Rename package::pkg_type into this. (package::is_debug_info): Rename package::is_debuginfo_pkg into this. (package::path_elf_file_sptr_map): Rename package::dir_elf_files_map into this because this is a map of path -> elf_file_sptr. Also, now the value of the map element is a elf_file_sptr, no more an elf_file*. (package::debug_info_package): Rename package::debuginfo_pkg into this. (package::package): Adjust for the changes above. (package::{erase_extraction_directory, erase_extraction_directories}): New member functions. (elf_file_paths): Renamed dir_elf_files_path into this. (erase_created_temporary_directories) (create_maps_of_package_content) (extract_package_and_map_its_content, prepare_packages): New static functions. (get_soname, elf_file_type, extract_rpm): Make this static. (extract_package): Take a const package& rather than a package_sptr to express that the function really expects a non-nil object by reference (not by copy) and that the object won't be modified. Using a reference removes the possibility that the pointer could be nil, causing crashes in the code where parameter->something was used. Now only parameter.something can be used, so no crash possible there. This is more solid code. (file_tree_walker_callback_fn): Rename callback() into this. It makes the code more legible and kind of 'self-documented'. At least you get the hint that this is a callback function for some file tree walking (ftw) function. Adjust for the relevant names renaming above. (compare): Rename compute_abidiff into this; again, this increases legibility; at least at the point of use of this function. Rename compare_package() into a an overload of compare() as well. compare_package() used to take a vector of packages. It was hard to guess by reading the signature of the function, which element of the vector is expected to be the first vector of the comparison, which one is to be the second, etc. Now, this function takes two packages, named first_package and second_package. That is more "typed"; that is, the signature is more meaningful. Greater legibility, hopefully. And in the body of the function, the debug information packages are now accessed using the package::debug_info_package data member. Again, this is less surprising, I believe. Also, explicitly erase the temporary files that were created during this comparison. All this simplifies the logic of this function, hopefully. (parse_command_line): Make this static. Add new --d1 and --d2 command line switches that are shortcuts of --debug-info-pkg1 and --debug-info-pkg2. Adjust this function for the relevant name changes above. Make lines be shorter than 80 characters. (main): Do not create any vector of parameters anymore as the compare_packages() function don't take any vector of parameter anymore. Just instantiate first_package and second_package now. Adjust for the relevant name changes above. This hopefully simplifies the logic of this function. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-07-07 07:44:58 +00:00
switch (first_package->type())
{
case abigail::tools_utils::FILE_TYPE_RPM:
if (second_package->type() != abigail::tools_utils::FILE_TYPE_RPM)
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< opts.package2 << " should be an RPM file\n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
}
break;
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
case abigail::tools_utils::FILE_TYPE_DEB:
if (second_package->type() != abigail::tools_utils::FILE_TYPE_DEB)
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< opts.package2 << " should be a DEB file\n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
Add support for .deb files to abipkgdiff This lets abipkgdiff compare debian binary packages. The patch contains test cases for debian package with split debug info that is referenced by the build-id scheme. These test cases come from the bug report https://sourceware.org/bugzilla/show_bug.cgi?id=18792, more particularly from the attachment https://sourceware.org/bugzilla/attachment.cgi?id=8516. * include/abg-tools-utils.h (file_type): Add FILE_TYPE_DEB. * tools/abipkgdiff.cc (extract_deb): New. (extract_package, main): Handle FILE_TYPE_DEB. * src/abg-tools-utils.cc (operator<<): Handle FILE_TYPE_DEB. (guess_file_type): Detect FILE_TYPE_DEB. * tools/abidiff.cc (main): Handle FILE_TYPE_DEB. * tools/abilint.cc (main): Handle FILE_TYPE_DEB. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb: Input debian debug info package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb: Input debug info package * tests/data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb: Input debian package; to be compared by the test harness runtestdiffpkg. * tests/data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt: Reference output for the comparison of the packages above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the input packages above to the set of files to be compared by this test harness. Signed-off-by: Matthias Klose <doko@debian.org> Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-07 08:48:17 +00:00
}
break;
Make abipkgdiff compare directories containing binaries abipkgdiff knows how to compare the ABI of binaries contained in .deb and .rpm files. This patch adds support for comparing the ABI of binaries contained in two directories. * include/abg-tools-utils.h (enum file_type): Add a new FILE_TYPE_DIR enumerator. * src/abg-tools-utils.cc (operator<<(ostream&, file_type)): Support serialization of the new FILE_TYPE_DIR enumerator. (guess_file_type): Detect that the path given is a directory. * tools/abipkgdiff.cc (package::package): If the package is a directory, then set its extracted directory path to the path of the directory. (package::erase_extraction_directory): Do not erase the extraction directory if the package is a directory provided by the user. (extract_package): If the package is a directory provided by the user, then there is nothing to extract. (main): If the first package is a directory, then the second one should be a directory as well. * tools/abidiff.cc (main): Support directories as input. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/dirpkg-0-dir{1,2}/libobj-v0.so: New binary test inputs. * test/data/test-diff-pkg/dirpkg-0-report-0.txt: New input test file. * tests/data/test-diff-pkg/dirpkg-1-dir{1,2}/obj-v0.cc: Source code of the binary test inputs above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the new test input files above to the set of tests this harness has to run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 09:44:08 +00:00
case abigail::tools_utils::FILE_TYPE_DIR:
if (second_package->type() != abigail::tools_utils::FILE_TYPE_DIR)
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< opts.package2 << " should be a directory\n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
Make abipkgdiff compare directories containing binaries abipkgdiff knows how to compare the ABI of binaries contained in .deb and .rpm files. This patch adds support for comparing the ABI of binaries contained in two directories. * include/abg-tools-utils.h (enum file_type): Add a new FILE_TYPE_DIR enumerator. * src/abg-tools-utils.cc (operator<<(ostream&, file_type)): Support serialization of the new FILE_TYPE_DIR enumerator. (guess_file_type): Detect that the path given is a directory. * tools/abipkgdiff.cc (package::package): If the package is a directory, then set its extracted directory path to the path of the directory. (package::erase_extraction_directory): Do not erase the extraction directory if the package is a directory provided by the user. (extract_package): If the package is a directory provided by the user, then there is nothing to extract. (main): If the first package is a directory, then the second one should be a directory as well. * tools/abidiff.cc (main): Support directories as input. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/dirpkg-0-dir{1,2}/libobj-v0.so: New binary test inputs. * test/data/test-diff-pkg/dirpkg-0-report-0.txt: New input test file. * tests/data/test-diff-pkg/dirpkg-1-dir{1,2}/obj-v0.cc: Source code of the binary test inputs above. * tests/data/Makefile.am: Add the new files above to the source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add the new test input files above to the set of tests this harness has to run over. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 09:44:08 +00:00
}
break;
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
case abigail::tools_utils::FILE_TYPE_TAR:
if (second_package->type() != abigail::tools_utils::FILE_TYPE_TAR)
{
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< opts.package2 << " should be a GNU tar archive\n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
Make abipkgdiff compare tar archives containing binaries This patch adds support for comparing the ABI of binaries contained in a tar archive. If the archive is compressed with gzip, bzip2, lzip, lzma or xz, then abipkgdiff recognizes the usual relevant file extensions and lets the GNU tar program handle the decompression. If the archive is not compressed, abipkgdiff recognizes the UStar (Uniform Standard Tape ARchive) format, even if the archive file name doesn't end with the .tar extension, and lets the GNU tar program handle the extraction. If the file ends up with the .tar extension anyway (even if it's not in the UStar format, abipkgdiff lets the GNU tar program handle its extraction. * config.h.in (WITH_TAR): New configuration preprocessor macro. * configure.ac: Add a new --enable-tar option. It's turned on automatically if the tar program is found in the PATH. Adjust the build configuration report to add the tar archive support. * include/abg-tools-utils.h (string_ends_with): Declare new function. (enum file_type): Add a new FILE_TYPE_TAR enumerator. * src/abg-tools-utils.cc (string_ends_with): Define new function. (operator<<(ostream&, file_type)): Serialize the new FILE_TYPE_TAR enumerator. (guess_file_type): Detect UStar format file by reading its magic number. Detect compressed tar files based on the file path extension. * tools/abipkgdiff.cc (extract_tar): Define new function. (extract_package): Handle tar packages. (main): Handle tar archives. * tools/abidiff.cc (main): Handle the new FILE_TYPE_TAR enumerator. * tools/abilint.cc (main): Likewise. * tests/data/test-diff-pkg/tarpkg-0-dir{1,2}.ta{,r,.bz2, gz}: New test input tarballs. * tests/data/test-diff-pkg/tarpkg-0-report-0.txt: New test output reference. * tests/data/Makefile.am: Add the new test data file above to source distribution. * tests/test-diff-pkg.cc (in_out_specs): Add new tests cases. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-08-22 11:59:18 +00:00
}
break;
default:
Emit more informational messages on unrecognized options This is like what was done for abififf, but for abicompat, abidw, abipkgdiff and abilint. * tools/abicompat.cc (options::prog_name): New data member. (display_help, perform_compat_check_in_normal_mode) (perform_compat_check_in_weak_mode, main): Prefix error messages with the name of the program. * tools/abidw.cc (options::wrong_option): New data member. (display_help): Prefix error messages with the name of the program.n (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abilint.cc (optionqs::wrong_option): New data member (display_usage): Prefix error messages with the name of the program. (parse_command_line): Record the name of the unrecognized option. (main): Tell the name of the unrecognized option. Prefix error messages with the name of the program. * tools/abipkgdiff.cc (options::{wrong_option, prog_name}): New data members. (package::erase_extraction_directory, display_usage, extract_rpm) (extract_deb, extract_tar) (erase_created_temporary_directories_parent, extract_package) (compare, create_maps_of_package_content): Prefix error messages with the name of the program. (maybe_check_suppression_files): Adjust. (parse_command_line): Record the name of the unrecognized option, and the name of option which lacks an operand. (main): Give the name of the unrecognized option. Prefix error messages with the name of the program. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2016-02-12 11:37:04 +00:00
emit_prefix("abipkgdiff", cerr)
<< opts.package1 << " should be a valid package file \n";
return (abigail::tools_utils::ABIDIFF_USAGE_ERROR
| abigail::tools_utils::ABIDIFF_ERROR);
}
return compare(*first_package, *second_package, opts);
}