summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Cohen <wcohen@redhat.com>2009-05-27 11:14:12 -0400
committerWilliam Cohen <wcohen@redhat.com>2009-05-27 11:14:12 -0400
commit2ed04863c3426f94932d4a4e4b5d6c7b84e49dfd (patch)
treef3eccb813b7496111613614552198bdaf4223deb
parenteee30f40ac28c7090a269611fb1baea5c050c612 (diff)
downloadsystemtap-steved-2ed04863c3426f94932d4a4e4b5d6c7b84e49dfd.tar.gz
systemtap-steved-2ed04863c3426f94932d4a4e4b5d6c7b84e49dfd.tar.xz
systemtap-steved-2ed04863c3426f94932d4a4e4b5d6c7b84e49dfd.zip
Suggest rpms to install using debuginfo-install.
The patch makes use of the RPM libraries to determine which rpm supplied the executable and from that information suggest a command to install the appropriate debuginfo rpm. This is enabled using the "--with-rpm" option for configure. Can be explicitly disabled with "--without-rpm".
-rw-r--r--Makefile.am4
-rw-r--r--Makefile.in41
-rw-r--r--aclocal.m444
-rw-r--r--config.in6
-rwxr-xr-xconfigure489
-rw-r--r--configure.ac198
-rw-r--r--doc/Makefile.in11
-rw-r--r--doc/SystemTap_Tapset_Reference/Makefile.in11
-rw-r--r--dwflpp.cxx4
-rw-r--r--grapher/Makefile.in11
-rw-r--r--main.cxx4
-rw-r--r--rpm_finder.cxx203
-rw-r--r--rpm_finder.h10
-rw-r--r--session.h2
-rw-r--r--systemtap.spec13
15 files changed, 985 insertions, 66 deletions
diff --git a/Makefile.am b/Makefile.am
index 77681c83..f11c24c9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -40,8 +40,8 @@ stap_SOURCES = main.cxx \
cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx \
tapset-been.cxx tapset-procfs.cxx tapset-timers.cxx \
tapset-perfmon.cxx tapset-mark.cxx tapset-itrace.cxx \
- tapset-utrace.cxx task_finder.cxx dwflpp.cxx
-stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@
+ tapset-utrace.cxx task_finder.cxx dwflpp.cxx rpm_finder.cxx
+stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ @rpm_LIBS@
BUILT_SOURCES =
CLEANFILES =
diff --git a/Makefile.in b/Makefile.in
index 062b0639..c8a5d713 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -126,7 +126,7 @@ am_stap_OBJECTS = stap-main.$(OBJEXT) stap-parse.$(OBJEXT) \
stap-tapset-perfmon.$(OBJEXT) stap-tapset-mark.$(OBJEXT) \
stap-tapset-itrace.$(OBJEXT) stap-tapset-utrace.$(OBJEXT) \
stap-task_finder.$(OBJEXT) stap-dwflpp.$(OBJEXT) \
- $(am__objects_1)
+ stap-rpm_finder.$(OBJEXT) $(am__objects_1)
stap_OBJECTS = $(am_stap_OBJECTS)
stap_LINK = $(CXXLD) $(stap_CXXFLAGS) $(CXXFLAGS) $(stap_LDFLAGS) \
$(LDFLAGS) -o $@
@@ -251,6 +251,8 @@ PIELDFLAGS = @PIELDFLAGS@
PKG_CONFIG = @PKG_CONFIG@
PROCFLAGS = @PROCFLAGS@
RANLIB = @RANLIB@
+RPM_CFLAGS = @RPM_CFLAGS@
+RPM_LIBS = @RPM_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@@ -300,6 +302,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+rpm_LIBS = @rpm_LIBS@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sqlite3_LIBS = @sqlite3_LIBS@
@@ -335,8 +338,9 @@ stap_SOURCES = main.cxx parse.cxx staptree.cxx elaborate.cxx \
mdfour.c cache.cxx util.cxx coveragedb.cxx dwarf_wrappers.cxx \
tapset-been.cxx tapset-procfs.cxx tapset-timers.cxx \
tapset-perfmon.cxx tapset-mark.cxx tapset-itrace.cxx \
- tapset-utrace.cxx task_finder.cxx dwflpp.cxx $(am__append_4)
-stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ $(am__append_6)
+ tapset-utrace.cxx task_finder.cxx dwflpp.cxx rpm_finder.cxx \
+ $(am__append_4)
+stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ @rpm_LIBS@ $(am__append_6)
# Arrange for git_version.h to be regenerated at every "make".
# Code fragment is based upon RadeonHD.am.
@@ -609,6 +613,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-modsign.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-nsscommon.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-parse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-rpm_finder.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-staptree.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-been.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapset-itrace.Po@am__quote@
@@ -1224,6 +1229,20 @@ stap-dwflpp.obj: dwflpp.cxx
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-dwflpp.obj `if test -f 'dwflpp.cxx'; then $(CYGPATH_W) 'dwflpp.cxx'; else $(CYGPATH_W) '$(srcdir)/dwflpp.cxx'; fi`
+stap-rpm_finder.o: rpm_finder.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-rpm_finder.o -MD -MP -MF $(DEPDIR)/stap-rpm_finder.Tpo -c -o stap-rpm_finder.o `test -f 'rpm_finder.cxx' || echo '$(srcdir)/'`rpm_finder.cxx
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-rpm_finder.Tpo $(DEPDIR)/stap-rpm_finder.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='rpm_finder.cxx' object='stap-rpm_finder.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-rpm_finder.o `test -f 'rpm_finder.cxx' || echo '$(srcdir)/'`rpm_finder.cxx
+
+stap-rpm_finder.obj: rpm_finder.cxx
+@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-rpm_finder.obj -MD -MP -MF $(DEPDIR)/stap-rpm_finder.Tpo -c -o stap-rpm_finder.obj `if test -f 'rpm_finder.cxx'; then $(CYGPATH_W) 'rpm_finder.cxx'; else $(CYGPATH_W) '$(srcdir)/rpm_finder.cxx'; fi`
+@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-rpm_finder.Tpo $(DEPDIR)/stap-rpm_finder.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='rpm_finder.cxx' object='stap-rpm_finder.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -c -o stap-rpm_finder.obj `if test -f 'rpm_finder.cxx'; then $(CYGPATH_W) 'rpm_finder.cxx'; else $(CYGPATH_W) '$(srcdir)/rpm_finder.cxx'; fi`
+
stap-modsign.o: modsign.cxx
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(stap_CXXFLAGS) $(CXXFLAGS) -MT stap-modsign.o -MD -MP -MF $(DEPDIR)/stap-modsign.Tpo -c -o stap-modsign.o `test -f 'modsign.cxx' || echo '$(srcdir)/'`modsign.cxx
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/stap-modsign.Tpo $(DEPDIR)/stap-modsign.Po
@@ -1248,8 +1267,8 @@ install-man1: $(man1_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $$i; then file=$$i; \
- else file=$(srcdir)/$$i; fi; \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
1*) ;; \
@@ -1293,8 +1312,8 @@ install-man3: $(man3_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $$i; then file=$$i; \
- else file=$(srcdir)/$$i; fi; \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
3*) ;; \
@@ -1338,8 +1357,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $$i; then file=$$i; \
- else file=$(srcdir)/$$i; fi; \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -1465,7 +1484,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/aclocal.m4 b/aclocal.m4
index 696dba2c..e726a5cc 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.10.2 -*- Autoconf -*-
+# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -13,7 +13,7 @@
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],,
+m4_if(AC_AUTOCONF_VERSION, [2.63],,
[m4_warning([this file was generated for autoconf 2.63.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
@@ -175,7 +175,7 @@ else
fi[]dnl
])# PKG_CHECK_MODULES
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -190,7 +190,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.10'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.10.2], [],
+m4_if([$1], [1.10.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -204,12 +204,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.10.2])dnl
+[AM_AUTOMAKE_VERSION([1.10.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
@@ -482,28 +482,19 @@ _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
# Generate code to set up dependency tracking. -*- Autoconf -*-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-#serial 4
+#serial 3
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[# Autoconf 2.62 quotes --file arguments for eval, but not when files
-# are listed without --file. Let's play safe and only enable the eval
-# if we detect the quoting.
-case $CONFIG_FILES in
-*\'*) eval set x "$CONFIG_FILES" ;;
-*) set x $CONFIG_FILES ;;
-esac
-shift
-for mf
-do
+[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
@@ -800,14 +791,14 @@ AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
-# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 6
+# serial 5
# AM_PROG_CC_C_O
# --------------
@@ -819,9 +810,8 @@ AC_REQUIRE_AUX_FILE([compile])dnl
# FIXME: we rely on the cache variable name because
# there is no other way.
set dummy $CC
-am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
+ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
# Losing compiler, so override with the script.
# FIXME: It is wrong to rewrite CC.
# But if we don't then we get into trouble of one sort or another.
@@ -899,13 +889,13 @@ esac
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 4
+# serial 3
# _AM_MANGLE_OPTION(NAME)
# -----------------------
@@ -922,7 +912,7 @@ AC_DEFUN([_AM_SET_OPTION],
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
diff --git a/config.in b/config.in
index dc6be35c..7369cf53 100644
--- a/config.in
+++ b/config.in
@@ -89,3 +89,9 @@
/* Define like PROTOTYPES; this can be used by system headers. */
#undef __PROTOTYPES
+
+/* librpm version specific library name to dlopen. */
+#undef DLOPEN_LIBRPM
+
+/* Define if librpm library is being used. */
+#undef HAVE_LIBRPM
diff --git a/configure b/configure
index 15e1036b..8703acb5 100755
--- a/configure
+++ b/configure
@@ -647,6 +647,9 @@ stap_LIBS
elfutils_abs_srcdir
BUILD_ELFUTILS_FALSE
BUILD_ELFUTILS_TRUE
+RPM_LIBS
+RPM_CFLAGS
+rpm_LIBS
BUILD_GRAPHER_FALSE
BUILD_GRAPHER_TRUE
GRAPHER_LIBS
@@ -784,6 +787,7 @@ enable_docs
enable_refdocs
enable_server
enable_grapher
+with_rpm
with_elfutils
'
ac_precious_vars='build_alias
@@ -801,6 +805,8 @@ CPP
PKG_CONFIG
GRAPHER_CFLAGS
GRAPHER_LIBS
+RPM_CFLAGS
+RPM_LIBS
CXXCPP'
ac_subdirs_all='testsuite'
@@ -1458,6 +1464,8 @@ Optional Features:
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-rpm query rpm database for missing debuginfos
+ [yes/no,], [def.], [auto=librpm.so]
--with-elfutils=DIRECTORY
find elfutils source code in DIRECTORY
@@ -1477,6 +1485,8 @@ Some influential environment variables:
C compiler flags for GRAPHER, overriding pkg-config
GRAPHER_LIBS
linker flags for GRAPHER, overriding pkg-config
+ RPM_CFLAGS C compiler flags for RPM, overriding pkg-config
+ RPM_LIBS linker flags for RPM, overriding pkg-config
CXXCPP C++ preprocessor
Use these variables to override the choices made by `configure' or to help
@@ -5193,9 +5203,8 @@ fi
# FIXME: we rely on the cache variable name because
# there is no other way.
set dummy $CC
-am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
-if test "$am_t" != yes; then
+ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then
# Losing compiler, so override with the script.
# FIXME: It is wrong to rewrite CC.
# But if we don't then we get into trouble of one sort or another.
@@ -7391,6 +7400,469 @@ else
fi
+
+# Integration with rpm library to support missing debuginfo suggestions.
+# --without-rpm: Disable any rpm support.
+# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime.
+# Even with runtime missing `libname.so' GDB will still other run correctly.
+# Missing `libname.so' during ./configure will abort the configuration.
+# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific
+# minor version first such as `librpm-4.6.so' as minor version differences
+# mean API+ABI incompatibility. If the specific match versioned library name
+# could not be found still open dynamically at least `librpm.so'.
+# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try
+# to find librpm for compilation-time linking by pkg-config. GDB binary will
+# be probably linked with the version specific library (as `librpm-4.6.so').
+# Failure to find librpm by pkg-config will abort the configuration.
+# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config
+# cannot find librpm use to the rpmless compilation (like `--without-rpm').
+
+
+# Check whether --with-rpm was given.
+if test "${with_rpm+set}" = set; then
+ withval=$with_rpm;
+else
+ with_rpm="auto"
+fi
+
+
+
+
+if test "x$with_rpm" != "xno"; then
+ if test "x$with_rpm" = "xyes"; then
+ LIBRPM="librpm.so"
+ RPM_REQUIRE=true
+ DLOPEN_REQUIRE=false
+ elif test "x$with_rpm" = "xauto"; then
+ LIBRPM="librpm.so"
+ RPM_REQUIRE=false
+ DLOPEN_REQUIRE=false
+ else
+ LIBRPM="$with_rpm"
+ RPM_REQUIRE=true
+ DLOPEN_REQUIRE=true
+ fi
+ LIBRPM_STRING='"'"$LIBRPM"'"'
+
+ { $as_echo "$as_me:$LINENO: checking specific librpm version" >&5
+$as_echo_n "checking specific librpm version... " >&6; }
+ HAVE_DLOPEN_LIBRPM=false
+ save_LIBS="$LIBS"
+ LIBS="$LIBS -ldl"
+ if test "$cross_compiling" = yes; then
+ { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { $as_echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+$as_echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }; }
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <rpm/rpmlib.h>
+#include <dlfcn.h>
+#include <errno.h>
+
+int
+main ()
+{
+
+ void *h;
+ const char *const *rpmverp;
+ FILE *f;
+
+ f = fopen ("conftest.out", "w");
+ if (!f)
+ {
+ fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out",
+ strerror (errno));
+ return 1;
+ }
+ h = dlopen ($LIBRPM_STRING, RTLD_LAZY);
+ if (!h)
+ {
+ fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ());
+ return 1;
+ }
+ rpmverp = dlsym (h, "RPMVERSION");
+ if (!rpmverp)
+ {
+ fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ());
+ return 1;
+ }
+ fprintf (stderr, "RPMVERSION is: \"");
+ fprintf (stderr, "%s\"\n", *rpmverp);
+
+ /* Try to find the specific librpm version only for "librpm.so" as we do
+ not know how to assemble the version string otherwise. */
+
+ if (strcmp ("librpm.so", $LIBRPM_STRING) != 0)
+ {
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ else
+ {
+ char *h2_name;
+ void *h2;
+ int major, minor;
+
+ if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2)
+ {
+ fprintf (stderr, "Unable to parse RPMVERSION.\n");
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ /* Avoid the square brackets by malloc. */
+ h2_name = malloc (64);
+ sprintf (h2_name, "librpm-%d.%d.so", major, minor);
+ h2 = dlopen (h2_name, RTLD_LAZY);
+ if (!h2)
+ {
+ fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ());
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ if (h2 != h)
+ {
+ fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n",
+ $LIBRPM_STRING, h2_name);
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ /* Found the valid .so name with a specific version. */
+ fprintf (f, "%s\n", h2_name);
+ return 0;
+ }
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ DLOPEN_LIBRPM="`cat conftest.out`"
+ if test "x$DLOPEN_LIBRPM" != "x"; then
+ HAVE_DLOPEN_LIBRPM=true
+ { $as_echo "$as_me:$LINENO: result: $DLOPEN_LIBRPM" >&5
+$as_echo "$DLOPEN_LIBRPM" >&6; }
+ fi
+
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -rf conftest.dSYM
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+ rm -f conftest.out
+
+
+
+
+ if $HAVE_DLOPEN_LIBRPM; then
+
+ { $as_echo "$as_me:$LINENO: checking rpm library API compatibility" >&5
+$as_echo_n "checking rpm library API compatibility... " >&6; }
+ # The compilation requires -Werror to verify anything.
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Duplicate here the declarations to verify they match "symfile.c". */
+#include <rpm/rpmlib.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmdb.h>
+#include <rpm/header.h>
+extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg);
+extern int rpmReadConfigFiles(const char * file, const char * target);
+extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi);
+extern Header rpmdbNextIterator(rpmdbMatchIterator mi);
+extern rpmts rpmtsCreate(void);
+extern rpmts rpmtsFree(rpmts ts);
+extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag,
+ const void * keyp, size_t keylen);
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+
+ LIBRPM_COMPAT=true
+ rpm_LIBS=-lrpm
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+ LIBRPM_COMPAT=false
+ rpm_LIBS=
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$save_CFLAGS"
+
+ if ! $LIBRPM_COMPAT; then
+ HAVE_DLOPEN_LIBRPM=false
+ fi
+ fi
+
+ if $HAVE_DLOPEN_LIBRPM; then
+ DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"'
+
+cat >>confdefs.h <<_ACEOF
+#define DLOPEN_LIBRPM $DLOPEN_LIBRPM_STRING
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBRPM 1
+_ACEOF
+
+ else
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ LIBS="$save_LIBS"
+ if $DLOPEN_REQUIRE; then
+ { { $as_echo "$as_me:$LINENO: error: Specific name $LIBRPM was requested but it could not be opened." >&5
+$as_echo "$as_me: error: Specific name $LIBRPM was requested but it could not be opened." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+pkg_failed=no
+{ $as_echo "$as_me:$LINENO: checking for RPM" >&5
+$as_echo_n "checking for RPM... " >&6; }
+
+if test -n "$RPM_CFLAGS"; then
+ pkg_cv_RPM_CFLAGS="$RPM_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"rpm\"") >&5
+ ($PKG_CONFIG --exists --print-errors "rpm") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ pkg_cv_RPM_CFLAGS=`$PKG_CONFIG --cflags "rpm" 2>/dev/null`
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$RPM_LIBS"; then
+ pkg_cv_RPM_LIBS="$RPM_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"rpm\"") >&5
+ ($PKG_CONFIG --exists --print-errors "rpm") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ pkg_cv_RPM_LIBS=`$PKG_CONFIG --libs "rpm" 2>/dev/null`
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ RPM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "rpm" 2>&1`
+ else
+ RPM_PKG_ERRORS=`$PKG_CONFIG --print-errors "rpm" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$RPM_PKG_ERRORS" >&5
+
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+ HAVE_LIBRPM=false
+elif test $pkg_failed = untried; then
+ HAVE_LIBRPM=false
+else
+ RPM_CFLAGS=$pkg_cv_RPM_CFLAGS
+ RPM_LIBS=$pkg_cv_RPM_LIBS
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+ HAVE_LIBRPM=true
+fi
+
+ if $HAVE_LIBRPM; then
+
+ { $as_echo "$as_me:$LINENO: checking rpm library API compatibility" >&5
+$as_echo_n "checking rpm library API compatibility... " >&6; }
+ # The compilation requires -Werror to verify anything.
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Duplicate here the declarations to verify they match "symfile.c". */
+#include <rpm/rpmlib.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmdb.h>
+#include <rpm/header.h>
+extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg);
+extern int rpmReadConfigFiles(const char * file, const char * target);
+extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi);
+extern Header rpmdbNextIterator(rpmdbMatchIterator mi);
+extern rpmts rpmtsCreate(void);
+extern rpmts rpmtsFree(rpmts ts);
+extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag,
+ const void * keyp, size_t keylen);
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+
+ LIBRPM_COMPAT=true
+ rpm_LIBS=-lrpm
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+ LIBRPM_COMPAT=false
+ rpm_LIBS=
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$save_CFLAGS"
+
+ if ! $LIBRPM_COMPAT; then
+ HAVE_LIBRPM=false
+ RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB"
+ fi
+ fi
+
+ if $HAVE_LIBRPM; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBRPM 1
+_ACEOF
+
+ CFLAGS="$CFLAGS $RPM_CFLAGS"
+ LIBS="$LIBS $RPM_LIBS"
+ else
+ if $RPM_REQUIRE; then
+ { { $as_echo "$as_me:$LINENO: error: $RPM_PKG_ERRORS" >&5
+$as_echo "$as_me: error: $RPM_PKG_ERRORS" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ { $as_echo "$as_me:$LINENO: WARNING: $RPM_PKG_ERRORS" >&5
+$as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;}
+ fi
+ fi
+ fi
+fi
+
+
build_elfutils=no
# Check whether --with-elfutils was given.
@@ -9749,16 +10221,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
- "depfiles":C) test x"$AMDEP_TRUE" != x"" || # Autoconf 2.62 quotes --file arguments for eval, but not when files
-# are listed without --file. Let's play safe and only enable the eval
-# if we detect the quoting.
-case $CONFIG_FILES in
-*\'*) eval set x "$CONFIG_FILES" ;;
-*) set x $CONFIG_FILES ;;
-esac
-shift
-for mf
-do
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
diff --git a/configure.ac b/configure.ac
index 198d77f1..83345959 100644
--- a/configure.ac
+++ b/configure.ac
@@ -272,6 +272,204 @@ AC_ARG_ENABLE([grapher],
PKG_CHECK_MODULES([GRAPHER], [gtkmm-2.4 >= 2.8.0],have_gtkmm=yes,have_gtkmm=no)
AM_CONDITIONAL([BUILD_GRAPHER], [test "x${have_gtkmm}" == "xyes" -a x"$enable_grapher" != "xno"])
+
+# Integration with rpm library to support missing debuginfo suggestions.
+# --without-rpm: Disable any rpm support.
+# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime.
+# Even with runtime missing `libname.so' GDB will still other run correctly.
+# Missing `libname.so' during ./configure will abort the configuration.
+# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific
+# minor version first such as `librpm-4.6.so' as minor version differences
+# mean API+ABI incompatibility. If the specific match versioned library name
+# could not be found still open dynamically at least `librpm.so'.
+# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try
+# to find librpm for compilation-time linking by pkg-config. GDB binary will
+# be probably linked with the version specific library (as `librpm-4.6.so').
+# Failure to find librpm by pkg-config will abort the configuration.
+# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config
+# cannot find librpm use to the rpmless compilation (like `--without-rpm').
+
+AC_ARG_WITH([rpm],
+ [AS_HELP_STRING([--with-rpm],
+ [query rpm database for missing debuginfos [yes/no, def. auto=librpm.so]])], [], [with_rpm="auto"])
+
+m4_pattern_allow([^AC_MSG_ERROR$])
+m4_pattern_allow([^AC_MSG_WARN$])
+if test "x$with_rpm" != "xno"; then
+ if test "x$with_rpm" = "xyes"; then
+ LIBRPM="librpm.so"
+ RPM_REQUIRE=true
+ DLOPEN_REQUIRE=false
+ elif test "x$with_rpm" = "xauto"; then
+ LIBRPM="librpm.so"
+ RPM_REQUIRE=false
+ DLOPEN_REQUIRE=false
+ else
+ LIBRPM="$with_rpm"
+ RPM_REQUIRE=true
+ DLOPEN_REQUIRE=true
+ fi
+ LIBRPM_STRING='"'"$LIBRPM"'"'
+
+ AC_MSG_CHECKING([specific librpm version])
+ HAVE_DLOPEN_LIBRPM=false
+ save_LIBS="$LIBS"
+ LIBS="$LIBS -ldl"
+ AC_RUN_IFELSE(AC_LANG_PROGRAM([[
+#include <rpm/rpmlib.h>
+#include <dlfcn.h>
+#include <errno.h>
+ ]], [[
+ void *h;
+ const char *const *rpmverp;
+ FILE *f;
+
+ f = fopen ("conftest.out", "w");
+ if (!f)
+ {
+ fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out",
+ strerror (errno));
+ return 1;
+ }
+ h = dlopen ($LIBRPM_STRING, RTLD_LAZY);
+ if (!h)
+ {
+ fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ());
+ return 1;
+ }
+ rpmverp = dlsym (h, "RPMVERSION");
+ if (!rpmverp)
+ {
+ fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ());
+ return 1;
+ }
+ fprintf (stderr, "RPMVERSION is: \"");
+ fprintf (stderr, "%s\"\n", *rpmverp);
+
+ /* Try to find the specific librpm version only for "librpm.so" as we do
+ not know how to assemble the version string otherwise. */
+
+ if (strcmp ("librpm.so", $LIBRPM_STRING) != 0)
+ {
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ else
+ {
+ char *h2_name;
+ void *h2;
+ int major, minor;
+
+ if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2)
+ {
+ fprintf (stderr, "Unable to parse RPMVERSION.\n");
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ /* Avoid the square brackets by malloc. */
+ h2_name = malloc (64);
+ sprintf (h2_name, "librpm-%d.%d.so", major, minor);
+ h2 = dlopen (h2_name, RTLD_LAZY);
+ if (!h2)
+ {
+ fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ());
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ if (h2 != h)
+ {
+ fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n",
+ $LIBRPM_STRING, h2_name);
+ fprintf (f, "%s\n", $LIBRPM_STRING);
+ return 0;
+ }
+ /* Found the valid .so name with a specific version. */
+ fprintf (f, "%s\n", h2_name);
+ return 0;
+ }
+ ]]), [
+ DLOPEN_LIBRPM="`cat conftest.out`"
+ if test "x$DLOPEN_LIBRPM" != "x"; then
+ HAVE_DLOPEN_LIBRPM=true
+ AC_MSG_RESULT($DLOPEN_LIBRPM)
+ fi
+ ])
+ rm -f conftest.out
+
+ m4_define([CHECK_LIBRPM_COMPAT], [
+ AC_MSG_CHECKING([rpm library API compatibility])
+ # The compilation requires -Werror to verify anything.
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Werror"
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[
+/* Duplicate here the declarations to verify they match "symfile.c". */
+#include <rpm/rpmlib.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmdb.h>
+#include <rpm/header.h>
+extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg);
+extern int rpmReadConfigFiles(const char * file, const char * target);
+extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi);
+extern Header rpmdbNextIterator(rpmdbMatchIterator mi);
+extern rpmts rpmtsCreate(void);
+extern rpmts rpmtsFree(rpmts ts);
+extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag,
+ const void * keyp, size_t keylen);
+ ]]), [
+ LIBRPM_COMPAT=true
+ rpm_LIBS=-lrpm
+ AC_MSG_RESULT(yes)
+ ], [
+ LIBRPM_COMPAT=false
+ rpm_LIBS=
+ AC_MSG_RESULT(no)
+ ])
+ CFLAGS="$save_CFLAGS"
+ ])
+ AC_SUBST(rpm_LIBS)
+
+ if $HAVE_DLOPEN_LIBRPM; then
+ CHECK_LIBRPM_COMPAT
+ if ! $LIBRPM_COMPAT; then
+ HAVE_DLOPEN_LIBRPM=false
+ fi
+ fi
+
+ if $HAVE_DLOPEN_LIBRPM; then
+ DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"'
+ AC_DEFINE_UNQUOTED(DLOPEN_LIBRPM, $DLOPEN_LIBRPM_STRING, [librpm version specific library name to dlopen.])
+ AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.])
+ else
+ AC_MSG_RESULT(no)
+ LIBS="$save_LIBS"
+ if $DLOPEN_REQUIRE; then
+ AC_MSG_ERROR([Specific name $LIBRPM was requested but it could not be opened.])
+ fi
+ PKG_CHECK_MODULES(RPM, rpm, [HAVE_LIBRPM=true], [HAVE_LIBRPM=false])
+
+ if $HAVE_LIBRPM; then
+ CHECK_LIBRPM_COMPAT
+ if ! $LIBRPM_COMPAT; then
+ HAVE_LIBRPM=false
+ RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB"
+ fi
+ fi
+
+ if $HAVE_LIBRPM; then
+ AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.])
+ CFLAGS="$CFLAGS $RPM_CFLAGS"
+ LIBS="$LIBS $RPM_LIBS"
+ else
+ if $RPM_REQUIRE; then
+ AC_MSG_ERROR($RPM_PKG_ERRORS)
+ else
+ AC_MSG_WARN($RPM_PKG_ERRORS)
+ fi
+ fi
+ fi
+fi
+
+
dnl Handle elfutils. If '--with-elfutils=DIR' wasn't specified, used
dnl the system's elfutils.
build_elfutils=no
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 2f1683c1..728352a0 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -109,6 +109,8 @@ PIELDFLAGS = @PIELDFLAGS@
PKG_CONFIG = @PKG_CONFIG@
PROCFLAGS = @PROCFLAGS@
RANLIB = @RANLIB@
+RPM_CFLAGS = @RPM_CFLAGS@
+RPM_LIBS = @RPM_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@@ -158,6 +160,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+rpm_LIBS = @rpm_LIBS@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sqlite3_LIBS = @sqlite3_LIBS@
@@ -182,8 +185,8 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
exit 1;; \
esac; \
done; \
@@ -283,7 +286,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/doc/SystemTap_Tapset_Reference/Makefile.in b/doc/SystemTap_Tapset_Reference/Makefile.in
index ae0b2f59..a58bbc73 100644
--- a/doc/SystemTap_Tapset_Reference/Makefile.in
+++ b/doc/SystemTap_Tapset_Reference/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -112,6 +112,8 @@ PIELDFLAGS = @PIELDFLAGS@
PKG_CONFIG = @PKG_CONFIG@
PROCFLAGS = @PROCFLAGS@
RANLIB = @RANLIB@
+RPM_CFLAGS = @RPM_CFLAGS@
+RPM_LIBS = @RPM_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@@ -161,6 +163,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+rpm_LIBS = @rpm_LIBS@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sqlite3_LIBS = @sqlite3_LIBS@
@@ -187,8 +190,8 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
exit 1;; \
esac; \
done; \
@@ -246,7 +249,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/dwflpp.cxx b/dwflpp.cxx
index bfae1354..d05bdb97 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -21,6 +21,7 @@
#include "dwarf_wrappers.h"
#include "auto_free.h"
#include "hash.h"
+#include "rpm_finder.h"
#include <cstdlib>
#include <algorithm>
@@ -108,6 +109,9 @@ dwflpp::get_module_dwarf(bool required, bool report)
if (i)
msg += string(": ") + dwfl_errmsg (i);
+ /* add module_name to list to find rpm */
+ find_debug_rpms(sess, module_name.c_str());
+
if (required)
throw semantic_error (msg);
else
diff --git a/grapher/Makefile.in b/grapher/Makefile.in
index fc260d60..af2fecb5 100644
--- a/grapher/Makefile.in
+++ b/grapher/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -119,6 +119,8 @@ PIELDFLAGS = @PIELDFLAGS@
PKG_CONFIG = @PKG_CONFIG@
PROCFLAGS = @PROCFLAGS@
RANLIB = @RANLIB@
+RPM_CFLAGS = @RPM_CFLAGS@
+RPM_LIBS = @RPM_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@@ -168,6 +170,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+rpm_LIBS = @rpm_LIBS@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sqlite3_LIBS = @sqlite3_LIBS@
@@ -191,8 +194,8 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
exit 1;; \
esac; \
done; \
@@ -314,7 +317,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
diff --git a/main.cxx b/main.cxx
index 1f4f9812..9dc658ff 100644
--- a/main.cxx
+++ b/main.cxx
@@ -20,6 +20,7 @@
#include "util.h"
#include "coveragedb.h"
#include "git_version.h"
+#include "rpm_finder.h"
#include <iostream>
#include <fstream>
@@ -1069,6 +1070,9 @@ main (int argc, char * const argv [])
}
}
+ /* Print out list of missing files */
+ missing_rpm_list_print(s);
+
if (rc || s.listing_mode || s.last_pass == 2 || pending_interrupts) goto cleanup;
// PASS 3: TRANSLATION
diff --git a/rpm_finder.cxx b/rpm_finder.cxx
new file mode 100644
index 00000000..779a9c36
--- /dev/null
+++ b/rpm_finder.cxx
@@ -0,0 +1,203 @@
+// systemtap debuginfo rpm finder
+// Copyright (C) 2009 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+#include "config.h"
+#include "session.h"
+#include "rpm_finder.h"
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cerrno>
+#include <cstdlib>
+
+using namespace std;
+
+#ifdef HAVE_LIBRPM
+
+extern "C" {
+
+#define _RPM_4_4_COMPAT
+#include <string.h>
+#include <rpm/rpmlib.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmdb.h>
+#include <rpm/header.h>
+
+#ifndef xfree
+#define xfree free
+#endif
+
+}
+
+/* Returns the count of newly added rpms. */
+/* based on the code in F11 gdb-6.8.50.20090302 source rpm */
+
+static int
+missing_rpm_enlist (systemtap_session& sess, const char *filename)
+{
+ static int rpm_init_done = 0;
+ rpmts ts;
+ rpmdbMatchIterator mi;
+ int count = 0;
+
+ if (filename == NULL)
+ return 0;
+
+ if (!rpm_init_done)
+ {
+ static int init_tried;
+
+ /* Already failed the initialization before? */
+ if (init_tried)
+ return 0;
+ init_tried = 1;
+
+ if (rpmReadConfigFiles(NULL, NULL) != 0)
+ {
+ cerr << "Error reading the rpm configuration files" << endl;
+ return 0;
+ }
+
+ rpm_init_done = 1;
+ }
+
+ ts = rpmtsCreate();
+
+ mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
+ if (mi != NULL)
+ {
+ for (;;)
+ {
+ Header h;
+ char *debuginfo, *s, *s2;
+ errmsg_t err;
+ size_t srcrpmlen = sizeof (".src.rpm") - 1;
+ size_t debuginfolen = sizeof ("-debuginfo") - 1;
+ rpmdbMatchIterator mi_debuginfo;
+
+ h = rpmdbNextIterator(mi);
+ if (h == NULL)
+ break;
+
+ /* Verify the debuginfo file is not already installed. */
+
+ debuginfo = headerSprintf(h, "%{sourcerpm}-debuginfo.%{arch}",
+ rpmTagTable, rpmHeaderFormats, &err);
+
+ if (!debuginfo)
+ {
+ cerr << "Error querying the rpm file `" << filename << "': "
+ << err << endl;
+ continue;
+ }
+ /* s = `.src.rpm-debuginfo.%{arch}' */
+ s = strrchr (debuginfo, '-') - srcrpmlen;
+ s2 = NULL;
+ if (s > debuginfo && memcmp (s, ".src.rpm", srcrpmlen) == 0)
+ {
+ /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */
+ s2 = (char *) memrchr (debuginfo, '-', s - debuginfo);
+ }
+ if (s2)
+ {
+ /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
+ s2 = (char *) memrchr (debuginfo, '-', s2 - debuginfo);
+ }
+ if (!s2)
+ {
+ cerr << "Error querying the rpm file `" << filename
+ << "': " << debuginfo << endl;
+ xfree (debuginfo);
+ continue;
+ }
+ /* s = `.src.rpm-debuginfo.%{arch}' */
+ /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
+ memmove (s2 + debuginfolen, s2, s - s2);
+ memcpy (s2, "-debuginfo", debuginfolen);
+ /* s = `XXXX.%{arch}' */
+ /* strlen ("XXXX") == srcrpmlen + debuginfolen */
+ /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */
+ /* strlen ("XX") == srcrpmlen */
+ memmove (s + debuginfolen, s + srcrpmlen + debuginfolen,
+ strlen (s + srcrpmlen + debuginfolen) + 1);
+ /* s = `-debuginfo-%{version}-%{release}.%{arch}' */
+
+ /* RPMDBI_PACKAGES requires keylen == sizeof (int). */
+ /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */
+ mi_debuginfo = rpmtsInitIterator(ts, (rpmTag) RPMDBI_LABEL,
+ debuginfo, 0);
+ xfree (debuginfo);
+ if (mi_debuginfo)
+ {
+ rpmdbFreeIterator(mi_debuginfo);
+ count = 0;
+ break;
+ }
+
+ /* The allocated memory gets utilized below for MISSING_RPM_HASH. */
+ debuginfo = headerSprintf(h,
+ "%{name}-%{version}-%{release}.%{arch}",
+ rpmTagTable, rpmHeaderFormats, &err);
+ if (!debuginfo)
+ {
+ cerr << "Error querying the rpm file `" << filename
+ << "': " << err << endl;
+ continue;
+ }
+
+ /* Base package name for `debuginfo-install'. We do not use the
+ `yum' command directly as the line
+ yum --enablerepo='*-debuginfo' install NAME-debuginfo.ARCH
+ would be more complicated than just:
+ debuginfo-install NAME-VERSION-RELEASE.ARCH
+ Do not supply the rpm base name (derived from .src.rpm name) as
+ debuginfo-install is unable to install the debuginfo package if
+ the base name PKG binary rpm is not installed while for example
+ PKG-libs would be installed (RH Bug 467901).
+ FUTURE: After multiple debuginfo versions simultaneously installed
+ get supported the support for the VERSION-RELEASE tags handling
+ may need an update. */
+
+ sess.rpms_to_install.insert(debuginfo);
+ count++;
+ }
+
+ rpmdbFreeIterator(mi);
+ }
+
+ rpmtsFree(ts);
+
+ return count;
+}
+
+#endif /* HAVE_LIBRPM */
+
+void
+missing_rpm_list_print (systemtap_session &sess)
+{
+#ifdef HAVE_LIBRPM
+ if (sess.rpms_to_install.size() > 0) {
+ cerr << "Missing separate debuginfos, use: debuginfo-install ";
+ for (set<std::string>::iterator it=sess.rpms_to_install.begin();
+ it !=sess.rpms_to_install.end(); it++)
+ cerr << *it << " ";
+ cerr << endl;
+ }
+#endif
+}
+
+int
+find_debug_rpms (systemtap_session &sess, const char * filename)
+{
+#ifdef HAVE_LIBRPM
+ return missing_rpm_enlist (sess, filename);
+#else
+ return 0;
+#endif
+}
diff --git a/rpm_finder.h b/rpm_finder.h
new file mode 100644
index 00000000..a4ef5c05
--- /dev/null
+++ b/rpm_finder.h
@@ -0,0 +1,10 @@
+// systemtap debuginfo rpm finder
+// Copyright (C) 2009 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+extern void missing_rpm_list_print (systemtap_session &);
+extern int find_debug_rpms (systemtap_session &, const char *);
diff --git a/session.h b/session.h
index 151094b1..a617e47f 100644
--- a/session.h
+++ b/session.h
@@ -211,6 +211,8 @@ struct systemtap_session
std::set<std::string> seen_warnings;
unsigned num_errors () { return seen_errors.size(); }
+ std::set<std::string> rpms_to_install;
+
// void print_error (const parse_error& e);
const token* last_token;
void print_token (std::ostream& o, const token* tok);
diff --git a/systemtap.spec b/systemtap.spec
index c0864657..6e4e6abc 100644
--- a/systemtap.spec
+++ b/systemtap.spec
@@ -1,6 +1,7 @@
%{!?with_sqlite: %define with_sqlite 1}
%{!?with_docs: %define with_docs 1}
%{!?with_crash: %define with_crash 0}
+%{!?with_rpm: %define with_rpm 1}
%{!?with_bundled_elfutils: %define with_bundled_elfutils 0}
%{!?elfutils_version: %define elfutils_version 0.127}
%{!?pie_supported: %define pie_supported 1}
@@ -25,6 +26,9 @@ BuildRequires: sqlite-devel
%if %{with_crash}
BuildRequires: crash-devel zlib-devel
%endif
+%if %{with_rpm}
+BuildRequires: rpm-devel glibc-headers
+%endif
# Alternate kernel packages kernel-PAE-devel et al have a virtual
# provide for kernel-devel, so this requirement does the right thing.
Requires: kernel-devel
@@ -172,6 +176,13 @@ cd ..
%define crash_config --disable-crash
%endif
+# Enable/disable the code to find and suggest needed rpms
+%if %{with_rpm}
+%define rpm_config --with-rpm
+%else
+%define rpm_config --without-rpm
+%endif
+
%if %{with_docs}
%define docs_config --enable-docs
%else
@@ -192,7 +203,7 @@ cd ..
%endif
-%configure %{?elfutils_config} %{sqlite_config} %{crash_config} %{docs_config} %{pie_config} %{grapher_config}
+%configure %{?elfutils_config} %{sqlite_config} %{crash_config} %{docs_config} %{pie_config} %{grapher_config} %{rpm_config}
make %{?_smp_mflags}
%install