Hi,
Consider the following test-case:
...
$ gcc -g src/gdb/testsuite/gdb.base/break-interp-*.c
...
When using:
- "set language c" to avoid loading the full symbol table for
break-interb-main.c, and
- using "set verbose" to be verbose about symbol table expansion:
...
$ gdb -batch \
-iex "set verbose" \
-iex "set language c" \
-ex r \
-ex bt \
--args ./a.out segv
Reading symbols from ./a.out...
Reading symbols from /lib64/ld-linux-x86-64.so.2...
(No debugging symbols found in /lib64/ld-linux-x86-64.so.2)
Reading symbols from system-supplied DSO at 0x7ffff7ffa000...
(No debugging symbols found in system-supplied DSO at 0x7ffff7ffa000)
Reading symbols from /lib64/libc.so.6...
(No debugging symbols found in /lib64/libc.so.6)
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a53160 in raise () from /lib64/libc.so.6
Reading in symbols for src/gdb/testsuite/gdb.base/break-interp-lib.c...done.
\#0 0x00007ffff7a53160 in raise () from /lib64/libc.so.6
\#1 0x0000000000400712 in libfunc (Reading in symbols for \
src/gdb/testsuite/gdb.base/break-interp-main.c...done.
action=0x7fffffffe0d6 "segv") at src/gdb/testsuite/gdb.base/break-interp-lib.c:34
\#2 0x00000000004007a4 in main (argc=2, argv=0x7fffffffdbd8) at \
src/gdb/testsuite/gdb.base/break-interp-main.c:27
...
we get the "Reading in symbols for break-interp-main.c...done" message
(triggered by verbose) in the middle of the libfunc backtrace line.
This patch attempts to get that message on its own line, like so:
...
\#0 0x00007ffff7a53160 in raise () from /lib64/libc.so.6
Reading in symbols for src/gdb/testsuite/gdb.base/break-interp-main.c...done.
\#1 0x0000000000400712 in libfunc (action=0x7fffffffe0d6 "segv") at \
src/gdb/testsuite/gdb.base/break-interp-lib.c:34
\#2 0x00000000004007a4 in main (argc=2, argv=0x7fffffffdbd8) at \
src/gdb/testsuite/gdb.base/break-interp-main.c:27...
It tries to achieve that by:
- printing the verbose message to gdb_stdlog instead of gdb_stdout
- capturing print_frame output in a string_file temporary, which is then
output as a single line
The latter caused regressions in annotate test-cases, which has been fixed by
replacing printf_filtered by current_uiout->message in the relevant annotate
functions.
The patch contains a test-case that passes.
The patch has been build and reg-tested on x86_64-linux, with the following
regressions:
...
FAIL: gdb.base/style-logging.exp: frame
FAIL: gdb.base/style.exp: frame
FAIL: gdb.base/style.exp: frame when width=20
FAIL: gdb.base/style.exp: frame when width=30
FAIL: gdb.opt/inline-cmds.exp: mi: step into inline call (timeout)
...
The gdb.opt/inline-cmds.exp failure probably means that the
current_uiout->is_mi_like_p () test in print_frame_info needs tweaking.
The first gdb.base/style.exp failure is related to missing styling, and I
assume to the other failures are likewise.
Any ideas on how to fix the FAILs?
Any other comments?
Thanks,
- Tom
[gdb] Make sure verbose output is on single line
---
gdb/annotate.c | 48 ++++++++++++++--------------
gdb/psymtab.c | 8 ++---
gdb/stack.c | 17 +++++++++-
gdb/testsuite/gdb.base/verbose-backtrace.exp | 38 ++++++++++++++++++++++
4 files changed, 82 insertions(+), 29 deletions(-)
@@ -52,9 +52,9 @@ static void
print_value_flags (struct type *t)
{
if (can_dereference (t))
- printf_filtered (("*"));
+ current_uiout->message (("*"));
else
- printf_filtered (("-"));
+ current_uiout->message (("-"));
}
static void
@@ -104,7 +104,7 @@ void
annotate_stopped (void)
{
if (annotation_level > 1)
- printf_filtered (("\n\032\032stopped\n"));
+ current_uiout->message (("\n\032\032stopped\n"));
}
void
@@ -207,7 +207,7 @@ annotate_frames_invalid (void)
target_terminal::scoped_restore_terminal_state term_state;
target_terminal::ours_for_output ();
- printf_unfiltered (("\n\032\032frames-invalid\n"));
+ current_uiout->message (("\n\032\032frames-invalid\n"));
frames_invalid_emitted = 1;
}
}
@@ -237,9 +237,9 @@ annotate_thread_exited (struct thread_info *t, int silent)
{
if (annotation_level > 1)
{
- printf_filtered(("\n\032\032thread-exited,"
- "id=\"%d\",group-id=\"i%d\"\n"),
- t->global_num, t->inf->num);
+ current_uiout->message(("\n\032\032thread-exited,"
+ "id=\"%d\",group-id=\"i%d\"\n"),
+ t->global_num, t->inf->num);
}
}
@@ -392,14 +392,14 @@ void
annotate_arg_begin (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032arg-begin\n"));
+ current_uiout->message (("\n\032\032arg-begin\n"));
}
void
annotate_arg_name_end (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032arg-name-end\n"));
+ current_uiout->message (("\n\032\032arg-name-end\n"));
}
void
@@ -407,9 +407,9 @@ annotate_arg_value (struct type *type)
{
if (annotation_level == 2)
{
- printf_filtered (("\n\032\032arg-value "));
+ current_uiout->message (("\n\032\032arg-value "));
print_value_flags (type);
- printf_filtered (("\n"));
+ current_uiout->message (("\n"));
}
}
@@ -417,7 +417,7 @@ void
annotate_arg_end (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032arg-end\n"));
+ current_uiout->message (("\n\032\032arg-end\n"));
}
static void
@@ -460,8 +460,8 @@ void
annotate_frame_begin (int level, struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (annotation_level > 1)
- printf_filtered (("\n\032\032frame-begin %d %s\n"),
- level, paddress (gdbarch, pc));
+ current_uiout->message (("\n\032\032frame-begin %d %s\n"),
+ level, paddress (gdbarch, pc));
}
void
@@ -482,70 +482,70 @@ void
annotate_frame_address (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-address\n"));
+ current_uiout->message (("\n\032\032frame-address\n"));
}
void
annotate_frame_address_end (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-address-end\n"));
+ current_uiout->message (("\n\032\032frame-address-end\n"));
}
void
annotate_frame_function_name (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-function-name\n"));
+ current_uiout->message (("\n\032\032frame-function-name\n"));
}
void
annotate_frame_args (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-args\n"));
+ current_uiout->message (("\n\032\032frame-args\n"));
}
void
annotate_frame_source_begin (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-source-begin\n"));
+ current_uiout->message (("\n\032\032frame-source-begin\n"));
}
void
annotate_frame_source_file (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-source-file\n"));
+ current_uiout->message (("\n\032\032frame-source-file\n"));
}
void
annotate_frame_source_file_end (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-source-file-end\n"));
+ current_uiout->message (("\n\032\032frame-source-file-end\n"));
}
void
annotate_frame_source_line (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-source-line\n"));
+ current_uiout->message (("\n\032\032frame-source-line\n"));
}
void
annotate_frame_source_end (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-source-end\n"));
+ current_uiout->message (("\n\032\032frame-source-end\n"));
}
void
annotate_frame_where (void)
{
if (annotation_level == 2)
- printf_filtered (("\n\032\032frame-where\n"));
+ current_uiout->message (("\n\032\032frame-where\n"));
}
void
@@ -760,16 +760,16 @@ psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
if (info_verbose)
{
- printf_filtered (_("Reading in symbols for %s..."),
- pst->filename);
- gdb_flush (gdb_stdout);
+ fprintf_filtered (gdb_stdlog, _("Reading in symbols for %s..."),
+ pst->filename);
+ gdb_flush (gdb_stdlog);
}
pst->read_symtab (objfile);
/* Finish up the debug error message. */
if (info_verbose)
- printf_filtered (_("done.\n"));
+ fprintf_filtered (gdb_stdlog, _("done.\n"));
}
return pst->get_compunit_symtab ();
@@ -1110,7 +1110,22 @@ print_frame_info (const frame_print_options &fp_opts,
|| print_what == LOC_AND_ADDRESS
|| print_what == SHORT_LOCATION);
if (location_print || !sal.symtab)
- print_frame (fp_opts, frame, print_level, print_what, print_args, sal);
+ {
+ if (current_uiout->is_mi_like_p ())
+ {
+ print_frame (fp_opts, frame, print_level, print_what, print_args, sal);
+ }
+ else
+ {
+ string_file tmp_stream (false);
+ {
+ current_uiout->redirect (&tmp_stream);
+ print_frame (fp_opts, frame, print_level, print_what, print_args, sal);
+ current_uiout->redirect (NULL);
+ }
+ gdb_stdout->printf ("%s", tmp_stream.string ().c_str());
+ }
+ }
source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC);
new file mode 100644
@@ -0,0 +1,38 @@
+# Copyright 2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile "break-interp-main.c break-interp-lib.c"
+
+if {[build_executable "failed to prepare" $testfile $srcfile debug]} {
+ return -1
+}
+
+clean_restart
+
+# Generate "Reading in symbols for" messages.
+gdb_test_no_output "set verbose"
+
+# Don't trigger psymtab expansion for break-interp-main.c
+gdb_test_no_output "set language c"
+
+gdb_load $binfile
+
+gdb_test "run segv"
+
+# Check that "Reading in symbols for" message has aline of its own.
+set filename "\[^\r\n\]*/gdb.base/break-interp-main.c"
+gdb_test "bt" \
+ "\r\nReading in symbols for $filename...done\.\r\n.*" \
+ "verbose message on own line"