aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2021-11-22 09:14:15 +0100
committerTom de Vries <tdevries@suse.de>2021-11-22 09:14:15 +0100
commitfc6a93854b3c9520259926891c3a5c559d3545d1 (patch)
tree4a951f6f82077c6c568c0d9575fbb8f7eb6a1e86
parentb4ab41207051793d280aeba47abe8e6ed3ac5861 (diff)
downloadfsf-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.exp160
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.