Hi Eric, thanks for your review!

On Saturday 19 of September 2015 15:05:07 Eric Blake wrote:
> On 09/19/2015 02:09 AM, Pavel Raiskup wrote:
> > Hi Hiroyuki Sato,
> > 
> > On Wednesday 02 of September 2015 16:00:34 Hiroyuki Sato wrote:
> >> This configure.ac is extreme slow on libtool-2.4.6.
> >> But It run smoothly on libtool-2.4.2.
> >> https://github.com/groonga/groonga/blob/master/configure.ac
> > 
> > thanks for reproducer!
> > 
> > This _really_ looks like issue mentioned [1], though the thread is
> > believed to be resolved (with existing small slowdown between
> > libtool-2.4.5 and 2.4.2).  Let me CC Robert whether this patch does not
> > actually fix the "1 sec" slowdown of libtoolize.
> 
> This looks very much like the same bug that gettext had:
> http://git.savannah.gnu.org/cgit/gettext.git/commit/?id=d75090f2
> https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=764580

Indeed, I missed that report.

> Your proposed solution doesn't seem quite right:
> 
> >          # Disable these macros.
> >          m4_undefine([m4_dnl])
> > -        m4_undefine([m4_include])
> >          m4_undefine([m4_m4exit])
> >          m4_undefine([m4_m4wrap])
> >          m4_undefine([m4_maketemp])
> > +        # Rather do not use undefine here because people tend to define
> > +        # macros of the same name as file included in their bodies - which
> > +        # results in infinite recursion.
> > +        m4_define([m4_include], [])
> 
> I'd recommend that you use the same fix as gettext, and define ALL of
> these macros to an empty string, rather than special-casing m4_include
> as the only one that does not get undefined.

Agreed, m4_pushdef([trace_breaking_macro]) should not cause any harm.
I fixed the patch (attached).

Pavel
>From 5e8a4c5173f1aa0786e8eba15fb07bfe04b83862 Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <prais...@redhat.com>
Date: Fri, 18 Sep 2015 23:17:07 +0200
Subject: [PATCH] libtoolize: fix infinite recursion in m4

Some projects use this construct in configure.ac:

  m4_define([version], m4_include([version])
  pkg_version=version

When the m4_include builtin is undefined (as was done in
libtoolize and extract-trace scripts), the call to this 'version'
macro gone to infinite recursion (until ENOMEM).  So rather
re-define all potentially dangerous macros by empty strings,
suggested by Eric Blake.

While we are on it, merge the macro-"blacklist" with similar list
implemented in gettext, except the 'm4_esyscmd'.  It's kept
defined because we already trace AC_INIT macro for package
version, while it is often specified by
m4_esyscmd(git-version-gen).  Similarly to m4_include, m4_esyscmd
might be opt-in-blacklisted in future.

References:
http://lists.gnu.org/archive/html/libtool/2015-09/msg00000.html
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=764580

* gl/build-aux/extract-trace (_G_mini): Redefine trace-breaking
macros to empty strings rather than undefining those.  Use 'dnl'
for comments.
* bootstrap: Likewise, sync with extract-trace.
* NEWS: Document.
* NO-THANKS: Mention Hiroyuki Sato.
---
 NEWS                       |  4 ++++
 NO-THANKS                  |  1 +
 bootstrap                  | 44 ++++++++++++++++++++++++++++----------------
 gl/build-aux/extract-trace | 44 ++++++++++++++++++++++++++++----------------
 4 files changed, 61 insertions(+), 32 deletions(-)

diff --git a/NEWS b/NEWS
index c5c9023..82dd037 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ NEWS - list of user-visible changes between releases of GNU Libtool
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Bug fixes:
+
+  - Fix significant slowdown of libtoolize for certain projects (regression
+    introduced in 2.4.3 release) caused by infinite m4 macro recursion.
 
 * Noteworthy changes in release 2.4.6 (2015-02-15) [stable]
 
diff --git a/NO-THANKS b/NO-THANKS
index 10de16b..51ec8eb 100644
--- a/NO-THANKS
+++ b/NO-THANKS
@@ -82,6 +82,7 @@ Donn Washburn			n5...@comcast.net
 Erik van Pienbroek		erik-...@vanpienbroek.nl
 Ethan Mallove			ethan.mall...@sun.com
 Fred Cox			sailorf...@yahoo.com
+Hiroyuki Sato			hiroys...@gmail.com
 Jakub Bogusz			qbo...@pld-linux.org
 James Su			james...@gmail.com
 Jay Krell			jay.kr...@cornell.edu
diff --git a/bootstrap b/bootstrap
index 4596413..17fb169 100755
--- a/bootstrap
+++ b/bootstrap
@@ -2472,29 +2472,41 @@ func_extract_trace ()
     # arguments to Autocof functions, but without following
     # 'm4_s?include' files.
     _G_mini='
-        # Initialisation.
+        dnl  Initialisation.
         m4_changequote([,])
         m4_define([m4_copy],   [m4_define([$2], m4_defn([$1]))])
         m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])])
 
-        # Disable these macros.
-        m4_undefine([m4_dnl])
-        m4_undefine([m4_include])
-        m4_undefine([m4_m4exit])
-        m4_undefine([m4_m4wrap])
-        m4_undefine([m4_maketemp])
-
-        # Copy and rename macros not handled by "m4 --prefix".
+        dnl  Replace macros which may abort m4 with a no-op variant.
+        m4_pushdef([m4_assert])
+        m4_pushdef([m4_exit])
+        m4_pushdef([m4_fatal])
+        m4_pushdef([m4_m4exit])
+
+        dnl  Replace macros that might break stderr of m4.
+        m4_pushdef([m4_errprint])
+        m4_pushdef([m4_errprintn])
+        m4_pushdef([m4_include])
+        m4_pushdef([m4_warn])
+
+        dnl  Avoid side-effects of tracing by extract-trace.
+        m4_pushdef([m4_maketemp])
+        m4_pushdef([m4_mkstemp])
+
+        dnl  TODO: reasons for this
+        m4_pushdef([m4_dnl])
+        m4_pushdef([m4_m4wrap])
+
+        dnl  Copy and rename macros not handled by "m4 --prefix".
         m4_define([dnl],         [m4_builtin([dnl])])
         m4_copy([m4_define],     [m4_defun])
         m4_rename([m4_ifelse],   [m4_if])
-        m4_ifdef([m4_mkstemp],   [m4_undefine([m4_mkstemp])])
         m4_rename([m4_patsubst], [m4_bpatsubst])
         m4_rename([m4_regexp],   [m4_bregexp])
 
-        # "m4sugar.mini" - useful m4-time macros for dynamic arguments.
-        # If we discover packages that need more m4 macros defined in
-        # order to bootstrap correctly, add them here:
+        dnl  "m4sugar.mini" - useful m4-time macros for dynamic arguments.
+        dnl  If we discover packages that need more m4 macros defined in
+        dnl  order to bootstrap correctly, add them here:
         m4_define([m4_bmatch],
             [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2],
                    [m4_if(m4_bregexp([$1], [$2]), -1,
@@ -2505,11 +2517,11 @@ func_extract_trace ()
         m4_define([m4_require], [$1])
         m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))])
 
-        # "autoconf.mini" - things from autoconf macros we care about.
+        dnl  "autoconf.mini" - things from autoconf macros we care about.
         m4_copy([m4_defun], [AC_DEFUN])
 
-        # Dummy definitions for the macros we want to trace.
-        # AM_INIT_AUTOMAKE at least produces no trace without this.
+        dnl  Dummy definitions for the macros we want to trace.
+        dnl  AM_INIT_AUTOMAKE at least produces no trace without this.
     '
 
     _G_save=$IFS
diff --git a/gl/build-aux/extract-trace b/gl/build-aux/extract-trace
index 315a32a..c6abd21 100755
--- a/gl/build-aux/extract-trace
+++ b/gl/build-aux/extract-trace
@@ -329,29 +329,41 @@ func_extract_trace ()
     # arguments to Autocof functions, but without following
     # 'm4_s?include' files.
     _G_mini='
-        # Initialisation.
+        dnl  Initialisation.
         m4_changequote([,])
         m4_define([m4_copy],   [m4_define([$2], m4_defn([$1]))])
         m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])])
 
-        # Disable these macros.
-        m4_undefine([m4_dnl])
-        m4_undefine([m4_include])
-        m4_undefine([m4_m4exit])
-        m4_undefine([m4_m4wrap])
-        m4_undefine([m4_maketemp])
-
-        # Copy and rename macros not handled by "m4 --prefix".
+        dnl  Replace macros which may abort m4 with a no-op variant.
+        m4_pushdef([m4_assert])
+        m4_pushdef([m4_exit])
+        m4_pushdef([m4_fatal])
+        m4_pushdef([m4_m4exit])
+
+        dnl  Replace macros that might break stderr of m4.
+        m4_pushdef([m4_errprint])
+        m4_pushdef([m4_errprintn])
+        m4_pushdef([m4_include])
+        m4_pushdef([m4_warn])
+
+        dnl  Avoid side-effects of tracing by extract-trace.
+        m4_pushdef([m4_maketemp])
+        m4_pushdef([m4_mkstemp])
+
+        dnl  TODO: reasons for this
+        m4_pushdef([m4_dnl])
+        m4_pushdef([m4_m4wrap])
+
+        dnl  Copy and rename macros not handled by "m4 --prefix".
         m4_define([dnl],         [m4_builtin([dnl])])
         m4_copy([m4_define],     [m4_defun])
         m4_rename([m4_ifelse],   [m4_if])
-        m4_ifdef([m4_mkstemp],   [m4_undefine([m4_mkstemp])])
         m4_rename([m4_patsubst], [m4_bpatsubst])
         m4_rename([m4_regexp],   [m4_bregexp])
 
-        # "m4sugar.mini" - useful m4-time macros for dynamic arguments.
-        # If we discover packages that need more m4 macros defined in
-        # order to bootstrap correctly, add them here:
+        dnl  "m4sugar.mini" - useful m4-time macros for dynamic arguments.
+        dnl  If we discover packages that need more m4 macros defined in
+        dnl  order to bootstrap correctly, add them here:
         m4_define([m4_bmatch],
             [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2],
                    [m4_if(m4_bregexp([$1], [$2]), -1,
@@ -362,11 +374,11 @@ func_extract_trace ()
         m4_define([m4_require], [$1])
         m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))])
 
-        # "autoconf.mini" - things from autoconf macros we care about.
+        dnl  "autoconf.mini" - things from autoconf macros we care about.
         m4_copy([m4_defun], [AC_DEFUN])
 
-        # Dummy definitions for the macros we want to trace.
-        # AM_INIT_AUTOMAKE at least produces no trace without this.
+        dnl  Dummy definitions for the macros we want to trace.
+        dnl  AM_INIT_AUTOMAKE at least produces no trace without this.
     '
 
     _G_save=$IFS
-- 
2.5.0

_______________________________________________
https://lists.gnu.org/mailman/listinfo/libtool

Reply via email to