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>
|
||||
|
||||
* 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-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
|
||||
install-bin = pcprofiledump xtrace
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
distribute += catchsegv.sh
|
||||
ifeq ($(elf),yes)
|
||||
ifeq ($(build-shared),yes)
|
||||
install-bin = catchsegv
|
||||
install-bin += catchsegv
|
||||
endif
|
||||
endif
|
||||
generated = catchsegv
|
||||
@ -57,6 +59,15 @@ $(objpfx)catchsegv: catchsegv.sh $(common-objpfx)soversions.mk \
|
||||
chmod 555 $@.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.
|
||||
# This ensures they will load libc.so for needed symbols if loaded by
|
||||
# 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,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -39,10 +41,25 @@ install (void)
|
||||
|
||||
if (outfile != NULL && *outfile != '\0')
|
||||
{
|
||||
fd = open (outfile, O_RDWR);
|
||||
fd = open (outfile, O_RDWR | O_CREAT, 0666);
|
||||
|
||||
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