Ian Lance Taylor wrote: > On Tue, Aug 12, 2014 at 10:11 AM, Gary Benson <gben...@redhat.com> wrote: > > Ian Lance Taylor wrote: > > > I think that by default the program should stop. That will make > > > it possible to eventually run as part of "make check". Give it > > > some number of iterations that stops it in a second or so. You > > > can still have it run forever by using -m -1. > > > > On my machine it usually fails in 3-5 seconds, so a 1 second run > > seems a little too short. How does 10 seconds sound? > > OK, we can start with that, I suppose.
I have committed the patch inlined below. By default it tries 7.5 million symbols, which takes roughly 10 seconds on my box. A good seed for testing is 1407772345 which manages 30,123,441 symbols before crashing (about 45 seconds). Cheers, Gary -- 2014-08-13 Gary Benson <gben...@redhat.com> * testsuite/demangler-fuzzer.c: New file. * testsuite/Makefile.in (fuzz-demangler): New rule. (demangler-fuzzer): Likewise. (mostlyclean): Clean up demangler fuzzer. Index: libiberty/testsuite/Makefile.in =================================================================== --- libiberty/testsuite/Makefile.in (revision 213911) +++ libiberty/testsuite/Makefile.in (revision 213912) @@ -59,6 +59,10 @@ check-expandargv: test-expandargv ./test-expandargv +# Run the demangler fuzzer +fuzz-demangler: demangler-fuzzer + ./demangler-fuzzer + TEST_COMPILE = $(CC) @DEFS@ $(LIBCFLAGS) -I.. -I$(INCDIR) $(HDEFINES) test-demangle: $(srcdir)/test-demangle.c ../libiberty.a $(TEST_COMPILE) -o test-demangle \ @@ -72,6 +76,10 @@ $(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-expandargv \ $(srcdir)/test-expandargv.c ../libiberty.a +demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a + $(TEST_COMPILE) -o demangler-fuzzer \ + $(srcdir)/demangler-fuzzer.c ../libiberty.a + # Standard (either GNU or Cygnus) rules we don't use. html install-html info install-info clean-info dvi pdf install-pdf \ install etags tags installcheck: @@ -81,6 +89,7 @@ rm -f test-demangle rm -f test-pexecute rm -f test-expandargv + rm -f demangler-fuzzer rm -f core clean: mostlyclean distclean: clean Index: libiberty/testsuite/demangler-fuzzer.c =================================================================== --- libiberty/testsuite/demangler-fuzzer.c (revision 0) +++ libiberty/testsuite/demangler-fuzzer.c (revision 213912) @@ -0,0 +1,108 @@ +/* Demangler fuzzer. + + Copyright (C) 2014 Free Software Foundation, Inc. + + This file is part of GNU libiberty. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include "demangle.h" + +#define MAXLEN 253 +#define ALPMIN 33 +#define ALPMAX 127 + +static char *program_name; + +#define DEFAULT_MAXCOUNT 7500000 + +static void +print_usage (FILE *fp, int exit_value) +{ + fprintf (fp, "Usage: %s [OPTION]...\n", program_name); + fprintf (fp, "Options:\n"); + fprintf (fp, " -h Display this message.\n"); + fprintf (fp, " -s SEED Select the random seed to be used.\n"); + fprintf (fp, " The default is to base one on the"); + fprintf (fp, " current time.\n"); + fprintf (fp, " -m MAXCOUNT Exit after MAXCOUNT symbols.\n"); + fprintf (fp, " The default is %d.", DEFAULT_MAXCOUNT); + fprintf (fp, " Set to `-1' for no limit.\n"); + + exit (exit_value); +} + +int +main (int argc, char *argv[]) +{ + char symbol[2 + MAXLEN + 1] = "_Z"; + int seed = -1, seed_set = 0; + int count = 0, maxcount = DEFAULT_MAXCOUNT; + int optchr; + + program_name = argv[0]; + + do + { + optchr = getopt (argc, argv, "hs:m:t:"); + switch (optchr) + { + case '?': /* Unrecognized option. */ + print_usage (stderr, 1); + break; + + case 'h': + print_usage (stdout, 0); + break; + + case 's': + seed = atoi (optarg); + seed_set = 1; + break; + + case 'm': + maxcount = atoi (optarg); + break; + } + } + while (optchr != -1); + + if (!seed_set) + seed = time (NULL); + srand (seed); + printf ("%s: seed = %d\n", program_name, seed); + + while (maxcount < 0 || count < maxcount) + { + char *buffer = symbol + 2; + int length, i; + + length = rand () % MAXLEN; + for (i = 0; i < length; i++) + *buffer++ = (rand () % (ALPMAX - ALPMIN)) + ALPMIN; + + *buffer++ = '\0'; + + cplus_demangle (symbol, DMGL_AUTO | DMGL_ANSI | DMGL_PARAMS); + + count++; + } + + printf ("%s: successfully demangled %d symbols\n", program_name, count); + exit (0); +}