diff --git a/gdb-only-force-interp_console-ui_out-for-breakpoint-commands-in-mi-mode.patch b/gdb-only-force-interp_console-ui_out-for-breakpoint-commands-in-mi-mode.patch new file mode 100644 index 0000000..1e7aa41 --- /dev/null +++ b/gdb-only-force-interp_console-ui_out-for-breakpoint-commands-in-mi-mode.patch @@ -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 + + 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 + + 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" ++} diff --git a/gdb-symtab-prefer-var-def-over-decl.patch b/gdb-symtab-prefer-var-def-over-decl.patch new file mode 100644 index 0000000..5cd4b87 --- /dev/null +++ b/gdb-symtab-prefer-var-def-over-decl.patch @@ -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>: Abbrev Number: 2 (DW_TAG_array_type) + DW_AT_type : <0xff> + DW_AT_sibling : <0xff> + <2>: Abbrev Number: 3 (DW_TAG_subrange_type) + <2>: Abbrev Number: 0 + <1>: 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 +... + +[ 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 + + 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 + + * 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 ++ ... ++ 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 " diff --git a/gdb.changes b/gdb.changes index a2ab79d..4b5f2eb 100644 --- a/gdb.changes +++ b/gdb.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Wed Nov 6 21:18:46 UTC 2019 - Tom de Vries + +- 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 diff --git a/gdb.spec b/gdb.spec index 4052e3e..fdf1a3e 100644 --- a/gdb.spec +++ b/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