Enable runtime cwrapper debugging; add tests

* libltdl/config/ltmain.m4sh (func_emit_cwrapperexe_src):
Update comments. Initialize program_name. Eliminate _LENGTH
variables for string constants. In debug mode, print a
banner with known content before any other output. Remove
LTWRAPPER_DEBUGPRINTF macro. Add constants and variables
to support new --lt-debug option.
(func_emit_cwrapperexe_src:ltwrapper_debugprintf): Renamed to...
(func_emit_cwrapperexe_src:lt_debugprintf): this. Only print
messages if lt_debug != 0. Ensure appearance of messages
conforms to GCS.
(func_emit_cwrapperexe_src:lt_fatal): Ditto.
(func_emit_cwrapperexe_src:lt_error_core): Ditto.
(func_emit_cwrapperexe_src): Update all callers to lt_fatal.
Update all users of LTWRAPPER_DEBUGPRINTF (()) to call
lt_debugprintf () directly.
(func_emit_cwrapperexe_src:main): Consolidate option parsing.
Ensure first use of lt_debugprintf occurs after option parsing.
Add stanza to parse for --lt-debug and set lt_debug variable.
Use strcmp rather than strncmp, where safe.
* tests/cwrapper.at: Add new tests for --lt-debug and
-DLT_DEBUGWRAPPER.
This commit is contained in:
Charles Wilson 2009-07-12 14:30:44 -04:00
parent 7e8be90f48
commit 2613ea3ab2
3 changed files with 200 additions and 85 deletions

View File

@ -1,3 +1,28 @@
2010-02-21 Charles Wilson <libtool@cwilson.fastmail.fm>
Enable runtime cwrapper debugging; add tests
* libltdl/config/ltmain.m4sh (func_emit_cwrapperexe_src):
Update comments. Initialize program_name. Eliminate _LENGTH
variables for string constants. In debug mode, print a
banner with known content before any other output. Remove
LTWRAPPER_DEBUGPRINTF macro. Add constants and variables
to support new --lt-debug option.
(func_emit_cwrapperexe_src:ltwrapper_debugprintf): Renamed to...
(func_emit_cwrapperexe_src:lt_debugprintf): this. Only print
messages if lt_debug != 0. Ensure appearance of messages
conforms to GCS.
(func_emit_cwrapperexe_src:lt_fatal): Ditto.
(func_emit_cwrapperexe_src:lt_error_core): Ditto.
(func_emit_cwrapperexe_src): Update all callers to lt_fatal.
Update all users of LTWRAPPER_DEBUGPRINTF (()) to call
lt_debugprintf () directly.
(func_emit_cwrapperexe_src:main): Consolidate option parsing.
Ensure first use of lt_debugprintf occurs after option parsing.
Add stanza to parse for --lt-debug and set lt_debug variable.
Use strcmp rather than strncmp, where safe.
* tests/cwrapper.at: Add new tests for --lt-debug and
-DLT_DEBUGWRAPPER.
2010-01-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
Use --email with gendocs.sh.

View File

@ -2727,10 +2727,6 @@ func_emit_cwrapperexe_src ()
This wrapper executable should never be moved out of the build directory.
If it is, it will not operate correctly.
Currently, it simply execs the wrapper *script* "$SHELL $output",
but could eventually absorb all of the scripts functionality and
exec $objdir/$outputname directly.
*/
EOF
cat <<"EOF"
@ -2855,22 +2851,13 @@ int setenv (const char *, const char *, int);
if (stale) { free ((void *) stale); stale = 0; } \
} while (0)
#undef LTWRAPPER_DEBUGPRINTF
#if defined LT_DEBUGWRAPPER
# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
static void
ltwrapper_debugprintf (const char *fmt, ...)
{
va_list args;
va_start (args, fmt);
(void) vfprintf (stderr, fmt, args);
va_end (args);
}
#if defined(LT_DEBUGWRAPPER)
static int lt_debug = 1;
#else
# define LTWRAPPER_DEBUGPRINTF(args)
static int lt_debug = 0;
#endif
const char *program_name = NULL;
const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
void *xmalloc (size_t num);
char *xstrdup (const char *string);
@ -2880,7 +2867,10 @@ char *chase_symlinks (const char *pathspec);
int make_executable (const char *path);
int check_executable (const char *path);
char *strendzap (char *str, const char *pat);
void lt_fatal (const char *message, ...);
void lt_debugprintf (const char *file, int line, const char *fmt, ...);
void lt_fatal (const char *file, int line, const char *message, ...);
static const char *nonnull (const char *s);
static const char *nonempty (const char *s);
void lt_setenv (const char *name, const char *value);
char *lt_extend_str (const char *orig_value, const char *add, int to_end);
void lt_update_exe_path (const char *name, const char *value);
@ -2932,12 +2922,10 @@ EOF
cat <<"EOF"
#define LTWRAPPER_OPTION_PREFIX "--lt-"
#define LTWRAPPER_OPTION_PREFIX_LENGTH 5
static const size_t opt_prefix_len = LTWRAPPER_OPTION_PREFIX_LENGTH;
static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug";
int
main (int argc, char *argv[])
@ -2954,10 +2942,13 @@ main (int argc, char *argv[])
int i;
program_name = (char *) xstrdup (base_name (argv[0]));
LTWRAPPER_DEBUGPRINTF (("(main) argv[0] : %s\n", argv[0]));
LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
newargz = XMALLOC (char *, argc + 1);
/* very simple arg parsing; don't want to rely on getopt */
/* very simple arg parsing; don't want to rely on getopt
* also, copy all non cwrapper options to newargz, except
* argz[0], which is handled differently
*/
newargc=0;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], dumpscript_opt) == 0)
@ -2974,21 +2965,54 @@ EOF
lt_dump_script (stdout);
return 0;
}
if (strcmp (argv[i], debug_opt) == 0)
{
lt_debug = 1;
continue;
}
if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
{
/* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
namespace, but it is not one of the ones we know about and
have already dealt with, above (inluding dump-script), then
report an error. Otherwise, targets might begin to believe
they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
namespace. The first time any user complains about this, we'll
need to make LTWRAPPER_OPTION_PREFIX a configure-time option
or a configure.ac-settable value.
*/
lt_fatal (__FILE__, __LINE__,
"unrecognized %s option: '%s'",
ltwrapper_option_prefix, argv[i]);
}
/* otherwise ... */
newargz[++newargc] = xstrdup (argv[i]);
}
newargz[++newargc] = NULL;
EOF
cat <<EOF
/* The GNU banner must be the first non-error debug message */
lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
EOF
cat <<"EOF"
lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
newargz = XMALLOC (char *, argc + 1);
tmp_pathspec = find_executable (argv[0]);
if (tmp_pathspec == NULL)
lt_fatal ("Couldn't find %s", argv[0]);
LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
tmp_pathspec));
lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
lt_debugprintf (__FILE__, __LINE__,
"(main) found exe (before symlink chase) at: %s\n",
tmp_pathspec);
actual_cwrapper_path = chase_symlinks (tmp_pathspec);
LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
actual_cwrapper_path));
lt_debugprintf (__FILE__, __LINE__,
"(main) found exe (after symlink chase) at: %s\n",
actual_cwrapper_path);
XFREE (tmp_pathspec);
actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
strendzap (actual_cwrapper_path, actual_cwrapper_name);
/* wrapper name transforms */
@ -3006,8 +3030,9 @@ EOF
target_name = tmp_pathspec;
tmp_pathspec = 0;
LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
target_name));
lt_debugprintf (__FILE__, __LINE__,
"(main) libtool target name: %s\n",
target_name);
EOF
cat <<EOF
@ -3060,32 +3085,12 @@ EOF
lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
newargc=0;
for (i = 1; i < argc; i++)
{
if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
{
/* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
namespace, but it is not one of the ones we know about and
have already dealt with, above (inluding dump-script), then
report an error. Otherwise, targets might begin to believe
they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
namespace. The first time any user complains about this, we'll
need to make LTWRAPPER_OPTION_PREFIX a configure-time option
or a configure.ac-settable value.
*/
lt_fatal ("Unrecognized option in %s namespace: '%s'",
ltwrapper_option_prefix, argv[i]);
}
/* otherwise ... */
newargz[++newargc] = xstrdup (argv[i]);
}
newargz[++newargc] = NULL;
LTWRAPPER_DEBUGPRINTF (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
nonnull (lt_argv_zero));
for (i = 0; i < newargc; i++)
{
LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
i, nonnull (newargz[i]));
}
EOF
@ -3099,7 +3104,9 @@ EOF
if (rval == -1)
{
/* failed to start process */
LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
lt_debugprintf (__FILE__, __LINE__,
"(main) failed to launch target \"%s\": %s\n",
lt_argv_zero, strerror (errno));
return 127;
}
return rval;
@ -3121,7 +3128,7 @@ xmalloc (size_t num)
{
void *p = (void *) malloc (num);
if (!p)
lt_fatal ("Memory exhausted");
lt_fatal (__FILE__, __LINE__, "memory exhausted");
return p;
}
@ -3155,8 +3162,8 @@ check_executable (const char *path)
{
struct stat st;
LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n",
path ? (*path ? path : "EMPTY!") : "NULL!"));
lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
nonempty (path));
if ((!path) || (!*path))
return 0;
@ -3173,8 +3180,8 @@ make_executable (const char *path)
int rval = 0;
struct stat st;
LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n",
path ? (*path ? path : "EMPTY!") : "NULL!"));
lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
nonempty (path));
if ((!path) || (!*path))
return 0;
@ -3200,8 +3207,8 @@ find_executable (const char *wrapper)
int tmp_len;
char *concat_name;
LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n",
wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
nonempty (wrapper));
if ((wrapper == NULL) || (*wrapper == '\0'))
return NULL;
@ -3254,7 +3261,8 @@ find_executable (const char *wrapper)
{
/* empty path: current directory */
if (getcwd (tmp, LT_PATHMAX) == NULL)
lt_fatal ("getcwd failed");
lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
strerror (errno));
tmp_len = strlen (tmp);
concat_name =
XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
@ -3279,7 +3287,7 @@ find_executable (const char *wrapper)
}
/* Relative path | not found in path: prepend cwd */
if (getcwd (tmp, LT_PATHMAX) == NULL)
lt_fatal ("getcwd failed");
lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", strerror (errno));
tmp_len = strlen (tmp);
concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
memcpy (concat_name, tmp, tmp_len);
@ -3305,8 +3313,9 @@ chase_symlinks (const char *pathspec)
int has_symlinks = 0;
while (strlen (tmp_pathspec) && !has_symlinks)
{
LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
tmp_pathspec));
lt_debugprintf (__FILE__, __LINE__,
"checking path component for symlinks: %s\n",
tmp_pathspec);
if (lstat (tmp_pathspec, &s) == 0)
{
if (S_ISLNK (s.st_mode) != 0)
@ -3328,8 +3337,9 @@ chase_symlinks (const char *pathspec)
}
else
{
char *errstr = strerror (errno);
lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
lt_fatal (__FILE__, __LINE__,
"error accessing file \"%s\": %s",
tmp_pathspec, strerror (errno));
}
}
XFREE (tmp_pathspec);
@ -3342,7 +3352,8 @@ chase_symlinks (const char *pathspec)
tmp_pathspec = realpath (pathspec, buf);
if (tmp_pathspec == 0)
{
lt_fatal ("Could not follow symlinks for %s", pathspec);
lt_fatal (__FILE__, __LINE__,
"could not follow symlinks for %s", pathspec);
}
return xstrdup (tmp_pathspec);
#endif
@ -3368,11 +3379,25 @@ strendzap (char *str, const char *pat)
return str;
}
void
lt_debugprintf (const char *file, int line, const char *fmt, ...)
{
va_list args;
if (lt_debug)
{
(void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
va_start (args, fmt);
(void) vfprintf (stderr, fmt, args);
va_end (args);
}
}
static void
lt_error_core (int exit_status, const char *mode,
lt_error_core (int exit_status, const char *file,
int line, const char *mode,
const char *message, va_list ap)
{
fprintf (stderr, "%s: %s: ", program_name, mode);
fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
vfprintf (stderr, message, ap);
fprintf (stderr, ".\n");
@ -3381,20 +3406,32 @@ lt_error_core (int exit_status, const char *mode,
}
void
lt_fatal (const char *message, ...)
lt_fatal (const char *file, int line, const char *message, ...)
{
va_list ap;
va_start (ap, message);
lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
va_end (ap);
}
static const char *
nonnull (const char *s)
{
return s ? s : "(null)";
}
static const char *
nonempty (const char *s)
{
return (s && !*s) ? "(empty)" : nonnull (s);
}
void
lt_setenv (const char *name, const char *value)
{
LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
(name ? name : "<NULL>"),
(value ? value : "<NULL>")));
lt_debugprintf (__FILE__, __LINE__,
"(lt_setenv) setting '%s' to '%s'\n",
nonnull (name), nonnull (value));
{
#ifdef HAVE_SETENV
/* always make a copy, for consistency with !HAVE_SETENV */
@ -3442,9 +3479,9 @@ lt_extend_str (const char *orig_value, const char *add, int to_end)
void
lt_update_exe_path (const char *name, const char *value)
{
LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
(name ? name : "<NULL>"),
(value ? value : "<NULL>")));
lt_debugprintf (__FILE__, __LINE__,
"(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
nonnull (name), nonnull (value));
if (name && *name && value && *value)
{
@ -3463,9 +3500,9 @@ lt_update_exe_path (const char *name, const char *value)
void
lt_update_lib_path (const char *name, const char *value)
{
LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
(name ? name : "<NULL>"),
(value ? value : "<NULL>")));
lt_debugprintf (__FILE__, __LINE__,
"(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
nonnull (name), nonnull (value));
if (name && *name && value && *value)
{

View File

@ -79,5 +79,58 @@ for restrictive_flags in '-Wall -Werror' '-std=c89 -Wall -Werror' '-std=c99 -Wal
LT_AT_EXEC_CHECK([./usea], [0], [ignore], [ignore], [])
done
# Test run-time activation of wrapper debugging.
# This is not part of the loop above, because we
# need to check, not ignore, the output.
CFLAGS="$orig_CFLAGS"
LIBTOOL=$orig_LIBTOOL
AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c liba.c],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -no-undefined -o liba.la -rpath /foo liba.lo],
[], [ignore], [ignore])
AT_CHECK([test -f liba.la])
AT_CHECK([$CC $CPPFLAGS $CFLAGS -c usea.c],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o usea$EXEEXT usea.$OBJEXT liba.la],
[], [ignore], [ignore])
LT_AT_EXEC_CHECK([./usea], [0], [ignore], [stderr], [--lt-debug])
LT_AT_UNIFY_NL([stderr])
AT_CHECK([grep 'libtool wrapper' stderr], [0], [ignore], [ignore])
# Test compile-time activation of wrapper debugging.
# We structure this test as a loop, so that we can 'break' out of it
# if necessary -- even though the loop by design executes only once.
for debugwrapper_flags in '-DLT_DEBUGWRAPPER'; do
CFLAGS="$orig_CFLAGS $debugwrapper_flags"
sed -e "s/LTCFLAGS=.*/&' $debugwrapper_flags'/" \
-e "s/^lt_option_debug=/lt_option_debug=1/" \
< "$orig_LIBTOOL" > ./libtool
LIBTOOL=./libtool
# make sure $debugwrapper_flags do not cause a failure
# themselves (e.g. because a non-gcc compiler doesn't
# understand them)
$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c trivial.c || continue
AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c liba.c],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -no-undefined -o liba.la -rpath /foo liba.lo],
[], [ignore], [ignore])
AT_CHECK([test -f liba.la])
AT_CHECK([$CC $CPPFLAGS $CFLAGS -c usea.c],
[], [ignore], [ignore])
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o usea$EXEEXT usea.$OBJEXT liba.la],
[], [ignore], [ignore])
LT_AT_EXEC_CHECK([./usea], [0], [ignore], [stderr], [])
LT_AT_UNIFY_NL([stderr])
AT_CHECK([grep 'libtool wrapper' stderr], [0], [ignore], [ignore])
done
AT_CLEANUP