Accepting request 746178 from home:tomdevries:branches:devel:gcc-gdb-two-l3s

- Fix for bsc#1146475 [bsc#1146475, swo#24971 ]
  * gdb-symtab-prefer-var-def-over-decl.patch
- Fix for bsc#1146167 [bsc#1146167, swo#24956]
  * gdb-only-force-interp_console-ui_out-for-breakpoint-commands-in-mi-mode.patch

OBS-URL: https://build.opensuse.org/request/show/746178
OBS-URL: https://build.opensuse.org/package/show/devel:gcc/gdb?expand=0&rev=235
This commit is contained in:
Michael Matz 2019-11-07 09:14:39 +00:00 committed by Git OBS Bridge
parent 7366c0f556
commit 58e41976fe
4 changed files with 427 additions and 0 deletions

View File

@ -0,0 +1,178 @@
[gdb] Only force INTERP_CONSOLE ui_out for breakpoint commands in MI mode
The problem reported in PR mi/25055 is that the output of the backtrace
command, when executed as breakpoint command does not show when executing
using the MI interpreter:
...
$ gdb a.out
Reading symbols from a.out...
(gdb) break main
Breakpoint 1 at 0x4003c0: file test.c, line 19.
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>bt
>end
(gdb) interpreter-exec mi "-exec-run"
^done
Breakpoint 1, main () at test.c:19
19 return foo (4);
(gdb)
...
Interestingly, the function print_frame is called twice during -exec-run:
- once during tui_on_normal_stop where the ui_out is temporarily set to
tui->interp_ui_out (), resulting in the part after the comma in
"Breakpoint 1, main () at test.c:19"
- once during execute_control_command, where the ui_out is the default for the
current interpreter: mi_ui_out, which ignores calls to output text.
The commit 3a87ae656c2 "Use console uiout when executing breakpoint commands"
fixes the problem by temporarily switching to the ui_out of INTERP_CONSOLE in
execute_control_command.
This however caused a regression in redirection (escaping '#' using '\' for
git commit message convenience):
...
$ rm -f gdb.txt; gdb a.out
Reading symbols from a.out...
(gdb) break main
Breakpoint 1 at 0x4003c0: file test.c, line 19.
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>bt
>end
(gdb) set logging redirect on
(gdb) set logging on
Redirecting output to gdb.txt.
Copying debug output to gdb.txt.
(gdb) run
\#0 main () at test.c:19
(gdb) q
A debugging session is active.
Inferior 1 [process 22428] will be killed.
Quit anyway? (y or n) y
$ cat gdb.txt
Starting program: /data/gdb_versions/devel/a.out
Breakpoint 1, main () at test.c:19
19 return foo (4);
...
The problem is that the '#0 main () at test.c:19' ends up in the gdb output
output rather than in gdb.txt. This is due to the fact that the redirect is
setup for the current ui_out (which is tui->interp_ui_out ()), while the
backtrace output is printed to the INTERP_CONSOLE ui_out.
Fix this by limiting switching to INTERP_CONSOLE ui_out to when INTERP_MI is
active.
Tested on x86_64-linux.
gdb/ChangeLog:
2019-10-02 Tom de Vries <tdevries@suse.de>
PR gdb/24956
* cli/cli-script.c (execute_control_command): Only switch to
INTERP_CONSOLE's ui_out when INTERP_MI is active.
gdb/testsuite/ChangeLog:
2019-10-02 Tom de Vries <tdevries@suse.de>
PR gdb/24956
* gdb.base/ui-redirect.exp: Test output of user-defined command.
Change-Id: Id1771e7fcc9496a7d97ec2b2ea6b1487596f1ef7
---
gdb/cli/cli-script.c | 3 +++
gdb/testsuite/gdb.base/ui-redirect.exp | 47 +++++++++++++++++++++++++++++++++-
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 85f00c75b3f..4d216f15dae 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -697,6 +697,9 @@ execute_control_command_1 (struct command_line *cmd, int from_tty)
enum command_control_type
execute_control_command (struct command_line *cmd, int from_tty)
{
+ if (!current_uiout->is_mi_like_p ())
+ return execute_control_command_1 (cmd, from_tty);
+
/* Make sure we use the console uiout. It's possible that we are executing
breakpoint commands while running the MI interpreter. */
interp *console = interp_lookup (current_ui, INTERP_CONSOLE);
diff --git a/gdb/testsuite/gdb.base/ui-redirect.exp b/gdb/testsuite/gdb.base/ui-redirect.exp
index 1ebff790e57..ab85eb059a0 100644
--- a/gdb/testsuite/gdb.base/ui-redirect.exp
+++ b/gdb/testsuite/gdb.base/ui-redirect.exp
@@ -17,7 +17,10 @@ if { [prepare_for_testing "failed to prepare" ui-redirect start.c] } {
return -1
}
-gdb_breakpoint main
+if ![runto_main] {
+ fail "can't run to main"
+ return -1
+}
set test "commands"
gdb_test_multiple $test $test {
@@ -34,8 +37,50 @@ gdb_test_multiple $test $test {
}
gdb_test_no_output "end"
+with_test_prefix "userdefined" {
+ set test "define userdefined"
+ gdb_test_multiple $test $test {
+ -re "End with a line saying just \"end\"\\.\r\n>$" {
+ pass $test
+ }
+ }
+
+ set test "bt"
+ gdb_test_multiple $test $test {
+ -re "\r\n>$" {
+ pass $test
+ }
+ }
+
+ gdb_test_no_output "end"
+}
+
gdb_test_no_output "set logging file /dev/null"
gdb_test "set logging on" "Copying output to /dev/null\\."
gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
+gdb_test "userdefined" "#0 main ().*"
gdb_test "set logging off" "Done logging to /dev/null\\."
gdb_test "help" "List of classes of commands:.*"
+
+with_test_prefix "redirect" {
+ gdb_test "set logging redirect on"
+ gdb_test "set logging on" \
+ "Redirecting output to /dev/null\\."
+ gdb_test_no_output "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
+ gdb_test_no_output "userdefined"
+ gdb_test "set logging off" "Done logging to /dev/null\\."
+ gdb_test "help" "List of classes of commands:.*"
+}
+
+with_test_prefix "redirect while already logging" {
+ gdb_test_no_output "set logging redirect off"
+ gdb_test "set logging on" \
+ "Copying output to /dev/null\\."
+ gdb_test "set logging redirect on" \
+ ".*warning: Currently logging .*Turn the logging off and on to make the new setting effective.*"
+ gdb_test "save breakpoints /dev/null" "Saved to file '/dev/null'\\."
+ gdb_test "userdefined" "#0 main ().*"
+ gdb_test "set logging off" "Done logging to /dev/null\\."
+ gdb_test "help" "List of classes of commands:.*"
+ gdb_test_no_output "set logging redirect off"
+}

View File

@ -0,0 +1,232 @@
[gdb/symtab] Prefer var def over decl
Consider the DWARF as generated by gcc with the tentative patch to fix gcc
PR91507 - "wrong debug for completed array with previous incomplete
declaration":
...
<1><f4>: Abbrev Number: 2 (DW_TAG_array_type)
<f5> DW_AT_type : <0xff>
<f9> DW_AT_sibling : <0xff>
<2><fd>: Abbrev Number: 3 (DW_TAG_subrange_type)
<2><fe>: Abbrev Number: 0
<1><ff>: Abbrev Number: 4 (DW_TAG_pointer_type)
<100> DW_AT_byte_size : 8
<101> DW_AT_type : <0x105>
<1><105>: Abbrev Number: 5 (DW_TAG_base_type)
<106> DW_AT_byte_size : 1
<107> DW_AT_encoding : 6 (signed char)
<108> DW_AT_name : (indirect string, offset: 0x19f): char
<1><10c>: Abbrev Number: 6 (DW_TAG_variable)
<10d> DW_AT_name : zzz
<111> DW_AT_decl_file : 1
<112> DW_AT_decl_line : 1
<113> DW_AT_decl_column : 14
<114> DW_AT_type : <0xf4>
<118> DW_AT_external : 1
<118> DW_AT_declaration : 1
<1><118>: Abbrev Number: 2 (DW_TAG_array_type)
<119> DW_AT_type : <0xff>
<11d> DW_AT_sibling : <0x128>
<1><12f>: Abbrev Number: 8 (DW_TAG_variable)
<130> DW_AT_specification: <0x10c>
<134> DW_AT_decl_line : 2
<135> DW_AT_decl_column : 7
<136> DW_AT_type : <0x118>
<13a> DW_AT_location : 9 byte block: 3 30 10 60 0 0 0 0 0 (DW_OP_addr: 601030)
...
The DWARF will result in two entries in the symbol table, a decl with type
char *[] and a def with type char*[2].
When trying to print the value of zzz:
...
$ gdb a.spec.out -batch -ex "p zzz"
...
the decl (rather than the def) will be found in the symbol table, which is
missing the location information, and consequently we get:
...
$1 = 0x601030 <zzz>
...
[ There is a fallback mechanism that finds the address of the variable in the
minimal symbol table, but that's not used here, because the type of the decl
does not specify a size. We could use the symbol size here to get the size
of the type, but that's currently not done: PR exp/24989. Still, fixing that
PR would not fix the generic case, where minimal symbol info is not
available. ]
Fix this by preferring defs over decls when searching in the symbol table.
Build and reg-tested on x86_64-linux.
[ The test-case is a bit simpler than the DWARF example listed above, because
the new variable varval3 that is used is not listed in the minimal symbols, so
there's no need to work around the fallback mechanism to trigger the problem. ]
gdb/ChangeLog:
2019-09-10 Tom de Vries <tdevries@suse.de>
PR symtab/24971
* block.c (best_symbol, better_symbol): New function.
(block_lookup_symbol_primary): Prefer def over decl.
gdb/testsuite/ChangeLog:
2019-09-10 Tom de Vries <tdevries@suse.de>
* gdb.dwarf2/varval.exp: Add decl before def test.
Change-Id: Id92326cb8ef9903b121ef9e320658eb565d0f5a9
---
gdb/block.c | 68 +++++++++++++++++++++++++++++++++++--
gdb/testsuite/gdb.dwarf2/varval.exp | 28 +++++++++++++--
2 files changed, 92 insertions(+), 4 deletions(-)
diff --git a/gdb/block.c b/gdb/block.c
index 3192b33e9e9..37f9d4f8d21 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -726,6 +726,43 @@ block_lookup_symbol (const struct block *block, const char *name,
}
}
+/* Return true if symbol A is the best match possible for DOMAIN. */
+
+static bool
+best_symbol (struct symbol *a, const domain_enum domain)
+{
+ return (SYMBOL_DOMAIN (a) == domain
+ && SYMBOL_CLASS (a) != LOC_UNRESOLVED);
+}
+
+/* Return symbol B if it is a better match than symbol A for DOMAIN.
+ Otherwise return A. */
+
+static struct symbol *
+better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain)
+{
+ if (a == NULL)
+ return b;
+ if (b == NULL)
+ return a;
+
+ if (SYMBOL_DOMAIN (a) == domain
+ && SYMBOL_DOMAIN (b) != domain)
+ return a;
+ if (SYMBOL_DOMAIN (b) == domain
+ && SYMBOL_DOMAIN (a) != domain)
+ return b;
+
+ if (SYMBOL_CLASS (a) != LOC_UNRESOLVED
+ && SYMBOL_CLASS (b) == LOC_UNRESOLVED)
+ return a;
+ if (SYMBOL_CLASS (b) != LOC_UNRESOLVED
+ && SYMBOL_CLASS (a) == LOC_UNRESOLVED)
+ return b;
+
+ return a;
+}
+
/* See block.h. */
struct symbol *
@@ -747,7 +784,34 @@ block_lookup_symbol_primary (const struct block *block, const char *name,
sym != NULL;
sym = mdict_iter_match_next (lookup_name, &mdict_iter))
{
- if (SYMBOL_DOMAIN (sym) == domain)
+ /* With the fix for PR gcc/debug/91507, we get for:
+ ...
+ extern char *zzz[];
+ char *zzz[ ] = {
+ "abc",
+ "cde"
+ };
+ ...
+ DWARF which will result in two entries in the symbol table, a decl
+ with type char *[] and a def with type char *[2].
+
+ If we return the decl here, we don't get the value of zzz:
+ ...
+ $ gdb a.spec.out -batch -ex "p zzz"
+ $1 = 0x601030 <zzz>
+ ...
+ because we're returning the symbol without location information, and
+ because the fallback that uses the address from the minimal symbols
+ doesn't work either because the type of the decl does not specify a
+ size.
+
+ To fix this, we prefer def over decl in best_symbol and
+ better_symbol.
+
+ In absence of the gcc fix, both def and decl have type char *[], so
+ the only option to make this work is improve the fallback to use the
+ size of the minimal symbol. Filed as PR exp/24989. */
+ if (best_symbol (sym, domain))
return sym;
/* This is a bit of a hack, but symbol_matches_domain might ignore
@@ -756,7 +820,7 @@ block_lookup_symbol_primary (const struct block *block, const char *name,
exactly the same domain. PR 16253. */
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
SYMBOL_DOMAIN (sym), domain))
- other = sym;
+ other = better_symbol (other, sym, domain);
}
return other;
diff --git a/gdb/testsuite/gdb.dwarf2/varval.exp b/gdb/testsuite/gdb.dwarf2/varval.exp
index 4711f4a24ae..fa3d90eb3d9 100644
--- a/gdb/testsuite/gdb.dwarf2/varval.exp
+++ b/gdb/testsuite/gdb.dwarf2/varval.exp
@@ -51,7 +51,7 @@ Dwarf::assemble ${asm_file} {
var_b_label var_c_label var_p_label var_bad_label \
varval_label var_s_label var_untyped_label \
var_a_abstract_label var_a_concrete_label \
- varval2_label
+ varval2_label varval3_decl_label varval3_def_label
set int_size [get_sizeof "int" -1]
@@ -165,6 +165,18 @@ Dwarf::assemble ${asm_file} {
{DW_AT_location {DW_OP_addr [gdb_target_symbol "var_b"]} SPECIAL_expr}
}
+ varval3_decl_label: DW_TAG_variable {
+ {DW_AT_name "varval3"}
+ {DW_AT_type :${int_label}}
+ {DW_AT_external 1 DW_FORM_flag}
+ {DW_AT_declaration 1 DW_FORM_flag}
+ }
+ varval3_def_label: DW_TAG_variable {
+ {DW_AT_name "varval3"}
+ {DW_AT_external 1 DW_FORM_flag}
+ {DW_AT_type :${int_label}}
+ {DW_AT_location {DW_OP_addr [gdb_target_symbol "var_a"]} SPECIAL_expr}
+ }
DW_TAG_subprogram {
{MACRO_AT_func { "main" "${srcdir}/${subdir}/${srcfile}" }}
{DW_AT_type :${int_label}}
@@ -274,7 +286,19 @@ if ![runto_main] {
}
gdb_test "print varval" "= 8"
-gdb_test "print varval2" "= 8"
+#gdb_test "print varval2" "= 8"
+set test "print varval2"
+set pass_pattern "= 8"
+set kfail_pattern "value has been optimized out"
+gdb_test_multiple $test "" {
+ -re "\[\r\n\]*(?:$pass_pattern)\[\r\n\]+$gdb_prompt $" {
+ pass $test
+ }
+ -re "\[\r\n\]*(?:$kfail_pattern)\[\r\n\]+$gdb_prompt $" {
+ kfail gdb/24515 $test
+ }
+}
+gdb_test "print varval3" "= 8"
gdb_test "print constval" "= 53"
gdb_test "print mixedval" "= 42"
gdb_test "print pointerval" "= \\(int \\*\\) $hex <var_b>"

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Wed Nov 6 21:18:46 UTC 2019 - Tom de Vries <tdevries@suse.com>
- Fix for bsc#1146475 [bsc#1146475, swo#24971 ]
* gdb-symtab-prefer-var-def-over-decl.patch
- Fix for bsc#1146167 [bsc#1146167, swo#24956]
* gdb-only-force-interp_console-ui_out-for-breakpoint-commands-in-mi-mode.patch
-------------------------------------------------------------------
Tue Oct 29 09:32:42 UTC 2019 - Tom de Vries <tdevries@suse.com>

View File

@ -247,6 +247,12 @@ Patch2009: gdb-s390-handle-arch13.diff
Patch2010: gdb-fix-heap-use-after-free-in-typename-concat.patch
Patch2011: gdb-dwarf-reader-reject-sections-with-invalid-sizes.patch
# Proposed patch for PR symtab/24971
Patch2500: gdb-symtab-prefer-var-def-over-decl.patch
# Proposed patch for PR gdb/24956
Patch2501: gdb-only-force-interp_console-ui_out-for-breakpoint-commands-in-mi-mode.patch
# Testsuite patches
Patch2600: gdb-testsuite-8.3-kfail-xfail-unsupported.patch
@ -591,6 +597,9 @@ find -name "*.info*"|xargs rm -f
%patch2010 -p1
%patch2011 -p1
%patch2500 -p1
%patch2501 -p1
%patch2600 -p1
#unpack libipt