This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 4/4] Test on solib load and unload


Hi.
A couple of nit, otherwise seems ok to me.

On Wed, Oct 16, 2013 at 12:09 AM, Yao Qi <yao@codesourcery.com> wrote:
> This patch is to add a test case to on the performance of GDB handling
> load and unload of shared library.
>
> In V3, there are some changes,
>
>  - Adapt to perf test framework changes.
>  - Measure load and unload separately.
>
> In V2, there are some changes,
>
>  - A new proc gdb_produce_source to produce source files.  I tried to
>    move all source file generation code out of solib.exp, but
>    compilation step still needs to know the generated file names.  I
>    have to hard-code the file names in compilation step, which is not
>    good to me, so I give up on this moving.
>  - SOLIB_NUMBER -> SOLIB_COUNT
>  - New variable SOLIB_DLCLOSE_REVERSED_ORDER to control the order of
>    iterating a list of shared libs to dlclose them.
>  - New variable GDB_PERFORMANCE to enable these perf test cases.
>  - Remove dlsym call in solib.c.
>  - Update solib.py for the updated framework.
>
> gdb/testsuite/
>
>         * lib/gdb.exp (gdb_produce_source): New procedure.
>         * gdb.perf/solib.c: New.
>         * gdb.perf/solib.exp: New.
>         * gdb.perf/solib.py: New.
> ---
>  gdb/testsuite/gdb.perf/solib.c   |   78 ++++++++++++++++++++++++++++++++++++++
>  gdb/testsuite/gdb.perf/solib.exp |   78 ++++++++++++++++++++++++++++++++++++++
>  gdb/testsuite/gdb.perf/solib.py  |   73 +++++++++++++++++++++++++++++++++++
>  gdb/testsuite/lib/gdb.exp        |   16 ++++++++
>  4 files changed, 245 insertions(+), 0 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.perf/solib.c
>  create mode 100644 gdb/testsuite/gdb.perf/solib.exp
>  create mode 100644 gdb/testsuite/gdb.perf/solib.py
>
> diff --git a/gdb/testsuite/gdb.perf/solib.c b/gdb/testsuite/gdb.perf/solib.c
> new file mode 100644
> index 0000000..42973d6
> --- /dev/null
> +++ b/gdb/testsuite/gdb.perf/solib.c
> @@ -0,0 +1,78 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright (C) 2013 Free Software Foundation, Inc.
> +
> +   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>
> +
> +#ifdef __WIN32__
> +#include <windows.h>
> +#define dlopen(name, mode) LoadLibrary (TEXT (name))
> +# define dlsym(handle, func) GetProcAddress (handle, func)
> +#define dlclose(handle) FreeLibrary (handle)
> +#else
> +#include <dlfcn.h>
> +#endif
> +
> +static void **handles;
> +
> +void
> +do_test_load (int number)
> +{
> +  char libname[40];
> +  int i;
> +
> +  handles = malloc (sizeof (void *) * number);

Check malloc result?

> +
> +  for (i = 0; i < number; i++)
> +    {
> +      sprintf (libname, "solib-lib%d", i);
> +      handles[i] = dlopen (libname, RTLD_LAZY);
> +      if (handles[i] == NULL)
> +       {
> +         printf ("ERROR on dlopen %s\n", libname);
> +         return;
> +       }
> +    }
> +}
> +
> +void
> +do_test_unload (int number)
> +{
> +  int i;
> +
> +  /* Unload shared libraries in different orders.  */
> +#ifndef SOLIB_DLCLOSE_REVERSED_ORDER
> +  for (i = 0; i < number; i++)
> +#else
> +  for (i = number - 1; i >= 0; i--)
> +#endif
> +    dlclose (handles[i]);
> +
> +  free (handles);
> +}
> +
> +static void
> +end (void)
> +{}
> +
> +int
> +main (void)
> +{
> +  end ();
> +
> +  return 0;
> +}
> diff --git a/gdb/testsuite/gdb.perf/solib.exp b/gdb/testsuite/gdb.perf/solib.exp
> new file mode 100644
> index 0000000..fc66f77
> --- /dev/null
> +++ b/gdb/testsuite/gdb.perf/solib.exp
> @@ -0,0 +1,78 @@
> +# Copyright (C) 2013 Free Software Foundation, Inc.
> +
> +# 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/>.
> +
> +# This test case is to test the performance of GDB when it is handling
> +# the shared libraries of inferior are loaded and unloaded.
> +load_lib perftest.exp
> +
> +if [skip_perf_tests] {
> +    return 0
> +}
> +
> +standard_testfile .c
> +set executable $testfile
> +set expfile $testfile.exp
> +
> +# make check-perf RUNTESTFLAGS='solib.exp SOLIB_COUNT=1024'
> +if ![info exists SOLIB_COUNT] {
> +    set SOLIB_COUNT 128
> +}
> +
> +PerfTest::assemble {
> +    compile {
> +       for {set i 0} {$i < $SOLIB_COUNT} {incr i} {
> +
> +           # Produce source files.
> +           set libname "solib-lib$i"
> +           set src [standard_output_file $libname.c]
> +           set exe [standard_output_file $libname]
> +
> +           gdb_produce_source $src { "int shr$i (void) {return 0;}" }
> +
> +           # Compile.
> +           if { [gdb_compile_shlib $src $exe {debug}] != "" } {
> +               untested "Couldn't compile $src."
> +               return -1
> +           }
> +
> +           # Delete object files to save some space.
> +           file delete [standard_output_file  "solib-lib$i.c.o"]
> +       }
> +
> +       set compile_flags {debug shlib_load}
> +       global SOLIB_DLCLOSE_REVERSED_ORDER


IWBN to have a convention to document all the test parameters in one
place, e.g. at the top of the .exp file or some such.
SOLIB_DLCLOSE_REVERSED_ORDER is kinda buried in the test.


> +
> +       if [info exists SOLIB_DLCLOSE_REVERSED_ORDER] {
> +           lappend compile_flags "additional_flags=-DSOLIB_DLCLOSE_REVERSED_ORDER"
> +       }
> +
> +       if { [gdb_compile "$srcdir/$subdir/$srcfile" ${binfile} executable  $compile_flags] == "" } {
> +           PerfTest::compiled
> +       }
> +    }
> +} {
> +   startup_gdb {
> +       clean_restart $binfile
> +
> +       if ![runto_main] {
> +           fail "Can't run to main"
> +           return -1
> +       }
> +    }
> +} {
> +    run {
> +       gdb_test_no_output "python SolibLoadUnload\($SOLIB_COUNT\).run()"
> +    }
> +}
> diff --git a/gdb/testsuite/gdb.perf/solib.py b/gdb/testsuite/gdb.perf/solib.py
> new file mode 100644
> index 0000000..91393b1
> --- /dev/null
> +++ b/gdb/testsuite/gdb.perf/solib.py
> @@ -0,0 +1,73 @@
> +# Copyright (C) 2013 Free Software Foundation, Inc.
> +
> +# 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/>.
> +
> +# This test case is to test the speed of GDB when it is handling the
> +# shared libraries of inferior are loaded and unloaded.
> +
> +from perftest import perftest
> +from perftest import measure
> +
> +class SolibLoadUnload1(perftest.TestCaseWithBasicMeasurements):
> +    def __init__(self, solib_count, measure_load):
> +        if measure_load:
> +            name = "solib_load"
> +        else:
> +            name = "solib_unload"
> +        # We want to measure time in this test.
> +        super (SolibLoadUnload1, self).__init__ (name)
> +        self.solib_count = solib_count
> +        self.measure_load = measure_load
> +
> +    def warm_up(self):
> +        do_test_load = "call do_test_load (%d)" % self.solib_count
> +        do_test_unload = "call do_test_unload (%d)" % self.solib_count
> +        gdb.execute(do_test_load)
> +        gdb.execute(do_test_unload)
> +
> +    def execute_test(self):
> +        num = self.solib_count
> +        iteration = 5;
> +
> +        while num > 0 and iteration > 0:
> +            # Do inferior calls to do_test_load and do_test_unload in pairs,
> +            # but measure differently.
> +            if self.measure_load:
> +                do_test_load = "call do_test_load (%d)" % num
> +                func = lambda: gdb.execute (do_test_load)
> +
> +                self.measure.measure(func, num)
> +
> +                do_test_unload = "call do_test_unload (%d)" % num
> +                gdb.execute (do_test_unload)
> +
> +            else:
> +                do_test_load = "call do_test_load (%d)" % num
> +                gdb.execute (do_test_load)
> +
> +                do_test_unload = "call do_test_unload (%d)" % num
> +                func = lambda: gdb.execute (do_test_unload)
> +
> +                self.measure.measure(func, num)
> +
> +            num = num / 2
> +            iteration -= 1
> +
> +class SolibLoadUnload(object):
> +    def __init__(self, solib_count):
> +        self.solib_count = solib_count;
> +
> +    def run(self):
> +        SolibLoadUnload1(self.solib_count, True).run()
> +        SolibLoadUnload1(self.solib_count, False).run()
> diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
> index 3efd539..28aca53 100644
> --- a/gdb/testsuite/lib/gdb.exp
> +++ b/gdb/testsuite/lib/gdb.exp
> @@ -1796,6 +1796,22 @@ proc supports_reverse {} {
>      return 0
>  }
>
> +# Produce source file NAME and write SOURCES into it.
> +
> +proc gdb_produce_source { name sources } {
> +    set index 0
> +    set f [open $name "w"]
> +
> +    while { ${index} < [llength ${sources}] } {
> +       set line [lindex ${sources} ${index}]
> +       set index [expr ${index} + 1]
> +
> +       set line [uplevel list $line]
> +       puts $f $line
> +    }
> +    close $f
> +}
> +
>  # Return 1 if target is ILP32.
>  # This cannot be decided simply from looking at the target string,
>  # as it might depend on externally passed compiler options like -m64.
> --
> 1.7.7.6
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]