diff options
author | Tom de Vries <tdevries@suse.de> | 2021-11-22 09:14:15 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2021-11-22 09:14:15 +0100 |
commit | fc6a93854b3c9520259926891c3a5c559d3545d1 (patch) | |
tree | 4a951f6f82077c6c568c0d9575fbb8f7eb6a1e86 | |
parent | b4ab41207051793d280aeba47abe8e6ed3ac5861 (diff) | |
download | fsf-binutils-gdb-fc6a93854b3c9520259926891c3a5c559d3545d1.zip fsf-binutils-gdb-fc6a93854b3c9520259926891c3a5c559d3545d1.tar.gz fsf-binutils-gdb-fc6a93854b3c9520259926891c3a5c559d3545d1.tar.bz2 |
[gdb/testsuite] Speed up MACRO_AT_* calls
Currently, for each MACRO_AT_range or MACRO_AT_func in dwarf assembly the
following is done:
- $srcdir/$subdir/$srcfile is compiled to an executable using
flags "debug"
- a new gdb instance is started
- the new executable is loaded.
This is inefficient, because the executable is identical within the same
Dwarf::assemble call.
Share the gdb instance in the same Dwarf::assemble invocation, which speeds
up a make check with RUNTESTFLAGS like this to catch all dwarf assembly
test-cases:
...
rtf=$(echo $(cd src/gdb/testsuite; find gdb.* -type f -name "*.exp" \
| xargs grep -l Dwarf::assemble))
...
from:
...
real 1m39.916s
user 1m25.668s
sys 0m21.377s
...
to:
...
real 1m29.512s
user 1m17.316s
sys 0m19.100s
...
Tested on x86_64-linux.
-rw-r--r-- | gdb/testsuite/lib/dwarf.exp | 160 |
1 files changed, 148 insertions, 12 deletions
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 7dd82b8..22124f6 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -196,6 +196,145 @@ proc build_executable_and_dwo_files { testname executable options args } { return 0 } +# Utility function for procs shared_gdb_*. + +proc init_shared_gdb {} { + global shared_gdb_enabled + global shared_gdb_started + + if { ! [info exists shared_gdb_enabled] } { + set shared_gdb_enabled 0 + set shared_gdb_started 0 + } +} + +# Cluster of four procs: +# - shared_gdb_enable +# - shared_gdb_disable +# - shared_gdb_start_use SRC OPTIONS +# - shared_gdb_end_use +# +# Can be used like so: +# +# { +# if { $share } shared_gdb_enable +# ... +# shared_gdb_start_use $src $options +# ... +# shared_gdb_end_use +# ... +# shared_gdb_start_use $src $options +# ... +# shared_gdb_end_use +# ... +# if { $share } shared_gdb_disable +# } +# +# to write functionalty that could share ($share == 1) or could not +# share ($share == 0) a gdb session between two uses. + +proc shared_gdb_enable {} { + set me shared_gdb_enable + + init_shared_gdb + global shared_gdb_enabled + global shared_gdb_started + + if { $shared_gdb_enabled } { + error "$me: gdb sharing already enabled" + } + set shared_gdb_enabled 1 + + if { $shared_gdb_started } { + error "$me: gdb sharing not stopped" + } +} + +# See above. + +proc shared_gdb_disable {} { + init_shared_gdb + global shared_gdb_enabled + global shared_gdb_started + + if { ! $shared_gdb_enabled } { + error "$me: gdb sharing not enabled" + } + set shared_gdb_enabled 0 + + if { $shared_gdb_started } { + gdb_exit + set shared_gdb_started 0 + } +} + +# See above. + +proc shared_gdb_start_use { src options } { + set me shared_gdb_start_use + + init_shared_gdb + global shared_gdb_enabled + global shared_gdb_started + global shared_gdb_src + global shared_gdb_options + + set do_start 1 + if { $shared_gdb_enabled && $shared_gdb_started } { + if { $shared_gdb_src != $src + || $shared_gdb_options != $options } { + error "$me: gdb sharing inconsistent" + } + + set do_start 0 + } + + if { $do_start } { + set exe [standard_temp_file func_addr[pid].x] + + gdb_compile $src $exe executable $options + + gdb_exit + gdb_start + gdb_load "$exe" + + if { $shared_gdb_enabled } { + set shared_gdb_started 1 + set shared_gdb_src $src + set shared_gdb_options $options + } + } +} + +# See above. + +proc shared_gdb_end_use {} { + init_shared_gdb + global shared_gdb_enabled + + if { ! $shared_gdb_enabled } { + gdb_exit + } +} + +# Enable gdb session sharing within BODY. + +proc with_shared_gdb { body } { + shared_gdb_enable + set code [catch { uplevel 1 $body } result] + shared_gdb_disable + + # Return as appropriate. + if { $code == 1 } { + global errorInfo errorCode + return -code error -errorinfo $errorInfo -errorcode $errorCode $result + } elseif { $code > 1 } { + return -code $code $result + } + + return $result +} + # Return a list of expressions about function FUNC's address and length. # The first expression is the address of function FUNC, and the second # one is FUNC's length. SRC is the source file having function FUNC. @@ -227,13 +366,7 @@ proc build_executable_and_dwo_files { testname executable options args } { proc function_range { func src {options {debug}} } { global decimal gdb_prompt - set exe [standard_temp_file func_addr[pid].x] - - gdb_compile $src $exe executable $options - - gdb_exit - gdb_start - gdb_load "$exe" + shared_gdb_start_use $src $options # Compute the label offset, and we can get the function start address # by "${func}_label - $func_label_offset". @@ -271,7 +404,8 @@ proc function_range { func src {options {debug}} } { } } - gdb_exit + shared_gdb_end_use + return [list "${func}_label - $func_label_offset" $func_length] } @@ -2624,10 +2758,12 @@ namespace eval Dwarf { # the first in .debug_info. dummy_cu - # Not "uplevel" here, because we want to evaluate in this - # namespace. This is somewhat bad because it means we can't - # readily refer to outer variables. - eval $body + with_shared_gdb { + # Not "uplevel" here, because we want to evaluate in this + # namespace. This is somewhat bad because it means we can't + # readily refer to outer variables. + eval $body + } # Dummy CU at the end to ensure that the last CU in $body is not # the last in .debug_info. |