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:
parent
7366c0f556
commit
58e41976fe
@ -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"
|
||||
+}
|
232
gdb-symtab-prefer-var-def-over-decl.patch
Normal file
232
gdb-symtab-prefer-var-def-over-decl.patch
Normal 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>"
|
@ -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>
|
||||
|
||||
|
9
gdb.spec
9
gdb.spec
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user