mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 10:50:07 +00:00
Update.
1999-10-07 Ulrich Drepper <drepper@cygnus.com> * debug/Makefile (install-bin): Add pcprofiledump and xtrace. Add rules for both programs. * debug/pcprofiledump.c: New file. * debug/xtrace.sh: New file. * debug/pcprofile.c: Allow creating output file. Add magic signature to let reader recognize file format.
This commit is contained in:
parent
42d7c59314
commit
cab30d75a3
@ -1,3 +1,12 @@
|
|||||||
|
1999-10-07 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* debug/Makefile (install-bin): Add pcprofiledump and xtrace.
|
||||||
|
Add rules for both programs.
|
||||||
|
* debug/pcprofiledump.c: New file.
|
||||||
|
* debug/xtrace.sh: New file.
|
||||||
|
* debug/pcprofile.c: Allow creating output file. Add magic signature
|
||||||
|
to let reader recognize file format.
|
||||||
|
|
||||||
1999-10-06 Ulrich Drepper <drepper@cygnus.com>
|
1999-10-06 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
* locale/programs/ld-ctype.c (ctype_read): Fix typos in last patch.
|
* locale/programs/ld-ctype.c (ctype_read): Fix typos in last patch.
|
||||||
|
@ -39,12 +39,14 @@ libSegFault-inhibit-o = $(filter-out .os,$(object-suffixes))
|
|||||||
libpcprofile-routines = pcprofile
|
libpcprofile-routines = pcprofile
|
||||||
libpcprofile-inhibit-o = $(filter-out .os,$(object-suffixes))
|
libpcprofile-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||||
|
|
||||||
|
install-bin = pcprofiledump xtrace
|
||||||
|
|
||||||
include ../Makeconfig
|
include ../Makeconfig
|
||||||
|
|
||||||
distribute += catchsegv.sh
|
distribute += catchsegv.sh
|
||||||
ifeq ($(elf),yes)
|
ifeq ($(elf),yes)
|
||||||
ifeq ($(build-shared),yes)
|
ifeq ($(build-shared),yes)
|
||||||
install-bin = catchsegv
|
install-bin += catchsegv
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
generated = catchsegv
|
generated = catchsegv
|
||||||
@ -57,6 +59,15 @@ $(objpfx)catchsegv: catchsegv.sh $(common-objpfx)soversions.mk \
|
|||||||
chmod 555 $@.new
|
chmod 555 $@.new
|
||||||
mv -f $@.new $@
|
mv -f $@.new $@
|
||||||
|
|
||||||
|
$(objpfx)pcprofiledump: $(objpfx)pcprofiledump.o
|
||||||
|
$(LINK.o) -o $@ $^
|
||||||
|
|
||||||
|
$(objpfx)xtrace: xtrace.sh
|
||||||
|
rm -f $@.new
|
||||||
|
sed -e 's|@BASH@|$(BASH)|' -e 's|@VERSION@|$(version)|' \
|
||||||
|
-e 's|@LIBDIR@|$(libdir)|' -e 's|@BINDIR@|$(bindir)|' $^ > $@.new \
|
||||||
|
&& rm -f $@ && mv $@.new $@ && chmod +x $@
|
||||||
|
|
||||||
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
|
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
|
||||||
# This ensures they will load libc.so for needed symbols if loaded by
|
# This ensures they will load libc.so for needed symbols if loaded by
|
||||||
# a statically-linked program that hasn't already loaded it.
|
# a statically-linked program that hasn't already loaded it.
|
||||||
|
@ -18,7 +18,9 @@
|
|||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -39,10 +41,25 @@ install (void)
|
|||||||
|
|
||||||
if (outfile != NULL && *outfile != '\0')
|
if (outfile != NULL && *outfile != '\0')
|
||||||
{
|
{
|
||||||
fd = open (outfile, O_RDWR);
|
fd = open (outfile, O_RDWR | O_CREAT, 0666);
|
||||||
|
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
active = 1;
|
{
|
||||||
|
uint32_t word;
|
||||||
|
|
||||||
|
active = 1;
|
||||||
|
|
||||||
|
/* Write a magic word which tells the reader about the byte
|
||||||
|
order and the size of the following entries. */
|
||||||
|
word = 0xdeb00000 | sizeof (void *);
|
||||||
|
if (TEMP_FAILURE_RETRY (write (fd, &word, 4)) != 4)
|
||||||
|
{
|
||||||
|
/* If even this fails we shouldn't try further. */
|
||||||
|
close (fd);
|
||||||
|
fd = -1;
|
||||||
|
active = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
187
debug/pcprofiledump.c
Normal file
187
debug/pcprofiledump.c
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/* Dump information generating by PC profiling.
|
||||||
|
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C 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
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||||
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
/* This is mainly and example. It shows how programs which want to use
|
||||||
|
the information should read the file. */
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <argp.h>
|
||||||
|
#include <byteswap.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <error.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <libintl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../version.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _
|
||||||
|
# define _(Str) gettext (Str)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef N_
|
||||||
|
# define N_(Str) Str
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Definitions of arguments for argp functions. */
|
||||||
|
static const struct argp_option options[] =
|
||||||
|
{
|
||||||
|
{ NULL, 0, NULL, 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Short description of program. */
|
||||||
|
static const char doc[] = N_("Dump information generating by PC profiling.");
|
||||||
|
|
||||||
|
/* Strings for arguments in help texts. */
|
||||||
|
static const char args_doc[] = N_("[FILE]");
|
||||||
|
|
||||||
|
/* Function to print some extra text in the help message. */
|
||||||
|
static char *more_help (int key, const char *text, void *input);
|
||||||
|
|
||||||
|
/* Data structure to communicate with argp functions. */
|
||||||
|
static struct argp argp =
|
||||||
|
{
|
||||||
|
options, NULL, args_doc, doc, NULL, more_help
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int remaining;
|
||||||
|
int must_swap;
|
||||||
|
uint32_t word;
|
||||||
|
|
||||||
|
/* Parse and process arguments. */
|
||||||
|
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||||
|
|
||||||
|
if (remaining == argc)
|
||||||
|
fd = STDIN_FILENO;
|
||||||
|
else if (remaining + 1 != argc)
|
||||||
|
{
|
||||||
|
argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
|
||||||
|
program_invocation_short_name);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Open the given file. */
|
||||||
|
fd = open (argv[remaining], O_RDONLY);
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
error (EXIT_FAILURE, errno, _("cannot open input file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the first 4-byte word. It contains the information about
|
||||||
|
the word size and the endianess. */
|
||||||
|
if (TEMP_FAILURE_RETRY (read (fd, &word, 4)) != 4)
|
||||||
|
error (EXIT_FAILURE, errno, _("cannot read header"));
|
||||||
|
|
||||||
|
/* Check whether we have to swap the byte order. */
|
||||||
|
must_swap = (word & 0xfffffff0) == bswap_32 (0xdeb00000);
|
||||||
|
if (must_swap)
|
||||||
|
word = bswap_32 (word);
|
||||||
|
|
||||||
|
/* We have two loops, one for 32 bit pointers, one for 64 bit pointers. */
|
||||||
|
if (word == 0xdeb00004)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t ptrs[2];
|
||||||
|
char bytes[8];
|
||||||
|
} pair;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
size_t len = sizeof (pair);
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
while (len > 0
|
||||||
|
&& (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len],
|
||||||
|
len))) != 0)
|
||||||
|
len -= n;
|
||||||
|
|
||||||
|
if (len != 0)
|
||||||
|
/* Nothing to read. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
printf ("this = %#010" PRIx32 ", caller = %#010" PRIx32 "\n",
|
||||||
|
must_swap ? bswap_32 (pair.ptrs[0]) : pair.ptrs[0],
|
||||||
|
must_swap ? bswap_32 (pair.ptrs[1]) : pair.ptrs[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (word == 0xdeb00008)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint64_t ptrs[2];
|
||||||
|
char bytes[16];
|
||||||
|
} pair;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
size_t len = sizeof (pair);
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
while (len > 0
|
||||||
|
&& (n = TEMP_FAILURE_RETRY (read (fd, &pair.bytes[8 - len],
|
||||||
|
len))) != 0)
|
||||||
|
len -= n;
|
||||||
|
|
||||||
|
if (len != 0)
|
||||||
|
/* Nothing to read. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
printf ("this = %#018" PRIx64 ", caller = %#018" PRIx64 "\n",
|
||||||
|
must_swap ? bswap_64 (pair.ptrs[0]) : pair.ptrs[0],
|
||||||
|
must_swap ? bswap_64 (pair.ptrs[1]) : pair.ptrs[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* This should not happen. */
|
||||||
|
error (EXIT_FAILURE, 0, _("invalid pointer size"));
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
more_help (int key, const char *text, void *input)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case ARGP_KEY_HELP_EXTRA:
|
||||||
|
/* We print some extra information. */
|
||||||
|
return strdup (gettext ("\
|
||||||
|
Report bugs using the `glibcbug' script to <bugs@gnu.org>.\n"));
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (char *) text;
|
||||||
|
}
|
168
debug/xtrace.sh
Executable file
168
debug/xtrace.sh
Executable file
@ -0,0 +1,168 @@
|
|||||||
|
#! @BASH@
|
||||||
|
# Copyright (C) 1999 Free Software Foundation, Inc.
|
||||||
|
# This file is part of the GNU C Library.
|
||||||
|
# Contributed by Ulrich Drepper <drepper@gnu.org>, 1999.
|
||||||
|
|
||||||
|
# The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU Library General Public License as
|
||||||
|
# published by the Free Software Foundation; either version 2 of the
|
||||||
|
# License, or (at your option) any later version.
|
||||||
|
|
||||||
|
# The GNU C 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
|
||||||
|
# Library General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Library General Public
|
||||||
|
# License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||||
|
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
# Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
pcprofileso=@LIBDIR@/libpcprofile.so
|
||||||
|
pcprofiledump=@BINDIR@/pcprofiledump
|
||||||
|
|
||||||
|
# Print usage message.
|
||||||
|
do_usage() {
|
||||||
|
echo >&2 $"Try \`xtrace --help' for more information."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Message for missing argument.
|
||||||
|
do_missing_arg() {
|
||||||
|
echo >&2 $"xtrace: option \`$1' requires an argument"
|
||||||
|
do_usage
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print help message
|
||||||
|
do_help() {
|
||||||
|
echo $"Usage: xtrace [OPTION]... PROGRAM [PROGRAMOPTION]...
|
||||||
|
Trace execution of program by printing currently executed function.
|
||||||
|
|
||||||
|
--data=FILE Don't run the program, just print the data from FILE.
|
||||||
|
|
||||||
|
-?,--help Print this help and exit
|
||||||
|
--usage Give a short usage message
|
||||||
|
-V,--version Print version information and exit
|
||||||
|
|
||||||
|
Mandatory arguments to long options are also mandatory for any corresponding
|
||||||
|
short options.
|
||||||
|
|
||||||
|
Report bugs using the \`glibcbug' script to <bugs@gnu.org>."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
do_version() {
|
||||||
|
echo 'xtrace (GNU libc) @VERSION@'
|
||||||
|
echo $"Copyright (C) 1999 Free Software Foundation, Inc.
|
||||||
|
This is free software; see the source for copying conditions. There is NO
|
||||||
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
Written by Ulrich Drepper."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print out function name, file, and line number is a nice formatted way.
|
||||||
|
format_line() {
|
||||||
|
fct=$1
|
||||||
|
file=${2%%:*}
|
||||||
|
line=${2##*:}
|
||||||
|
width=$(expr $COLUMNS - 30)
|
||||||
|
filelen=$(expr length $file)
|
||||||
|
if test "$filelen" -gt "$width"; then
|
||||||
|
rwidth=$(expr $width - 3)
|
||||||
|
file="...$(expr substr $file $(expr 1 + $filelen - $rwidth) $rwidth)"
|
||||||
|
fi
|
||||||
|
printf '%-20s %-*s %6s\n' $fct $width $file $line
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# If the variable COLUMNS is not set do this now.
|
||||||
|
COLUMNS=${COLUMNS:-80}
|
||||||
|
|
||||||
|
# If `TERM' is not set, set it to `xterm'.
|
||||||
|
TERM=${TERM:-xterm}
|
||||||
|
|
||||||
|
# Process arguments. But stop as soon as the program name is found.
|
||||||
|
while test $# -gt 0; do
|
||||||
|
case "$1" in
|
||||||
|
--d | --da | --dat | --data)
|
||||||
|
if test $# -eq 1; then
|
||||||
|
do_missing_arg $1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
data="$1"
|
||||||
|
;;
|
||||||
|
--d=* | --da=* | --dat=* | --data=*)
|
||||||
|
data=${1##*=}
|
||||||
|
;;
|
||||||
|
--)
|
||||||
|
# Stop processing arguments.
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
--*)
|
||||||
|
echo >&2 $"memprof: unrecognized option \`$1'"
|
||||||
|
do_usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Unknown option. This means the rest is the program name and parameters.
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# See whether any arguments are left.
|
||||||
|
if test $# -eq 0; then
|
||||||
|
echo >&2 $"No program name given"
|
||||||
|
do_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine the program name and check whether it exists.
|
||||||
|
program=$1
|
||||||
|
shift
|
||||||
|
if test ! -f "$program"; then
|
||||||
|
echo >2& $"\executable \`$program' not found"
|
||||||
|
do_usage
|
||||||
|
fi
|
||||||
|
if test ! -x "$program"; then
|
||||||
|
echo >&2 $"\`$program' is no executable"
|
||||||
|
do_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We have two modes. If a data file is given simply print the included data.
|
||||||
|
printf "%-20s %-*s %6s\n" Function $(expr $COLUMNS - 30) File Line
|
||||||
|
for i in $(seq 1 $COLUMNS); do echo -n -; done; echo
|
||||||
|
if test -n "$data"; then
|
||||||
|
eval $pcprofiledump $data |
|
||||||
|
sed 's/this = \([^,]*\).*/\1/' |
|
||||||
|
addr2line -fC -e $program |
|
||||||
|
while read fct; do
|
||||||
|
read file
|
||||||
|
if test "$fct" != '??' -a "$file" != '??:0'; then
|
||||||
|
format_line $fct $file
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
fifo=$(mktemp -u ${TMPDIR:-/tmp}/xprof.XXXXXX)
|
||||||
|
mkfifo -m 0600 $fifo || exit 1
|
||||||
|
# Now start the program and let it write to the FIFO.
|
||||||
|
eval $TERM -T "'xtrace - $program $*'" -e /bin/sh -c "'LD_PRELOAD=$pcprofileso PCPROFILE_OUTPUT=$fifo $program $*; read $fifo'" &
|
||||||
|
termpid=$!
|
||||||
|
eval $pcprofiledump $fifo |
|
||||||
|
sed 's/this = \([^,]*\).*/\1/' |
|
||||||
|
addr2line -fC -e $program |
|
||||||
|
while read fct; do
|
||||||
|
read file
|
||||||
|
if test "$fct" != '??' -a "$file" != '??:0'; then
|
||||||
|
format_line $fct $file
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
read -p "Press return to end the program."
|
||||||
|
echo > $fifo
|
||||||
|
rm $fifo
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
# Local Variables:
|
||||||
|
# mode:ksh
|
||||||
|
# End:
|
Loading…
Reference in New Issue
Block a user