Re: [PATCH] Re: libtool-2.4.2 is fine but libtool-2.4.6 very slow.

Pavel Raiskup <[email protected]>
Newsgroups gmane.comp.gnu.libtool.patches,gmane.comp.gnu.libtool.general
Message-ID <[email protected]>
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
0001-libtoolize-fix-infinite-recursion-in-m4.patch (text/x-patch, 8.2 KB)
From 5e8a4c5173f1aa0786e8eba15fb07bfe04b83862 Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <[email protected]>
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			[email protected]
 Erik van Pienbroek		[email protected]
 Ethan Mallove			[email protected]
 Fred Cox			[email protected]
+Hiroyuki Sato			[email protected]
 Jakub Bogusz			[email protected]
 James Su			[email protected]
 Jay Krell			[email protected]
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.