Skip to content

Commit

Permalink
Fix gdb_interface: restore gdb's output streams at end of gdb_interface
Browse files Browse the repository at this point in the history
Currently for most gdb_interface call, in which a non-null file pointer
is passed, GDB's output stream is replaced with the passed file pointer

Due to this, 'info threads', which is a gdb passthrough, doesn't print any
thread, after support was added to get registers from crash_target:

    crash> info threads
      Id   Target Id         Frame

This empty output of 'info threads' was due to a subtle bug in
gdb_interface.

After this gdb passthrough is run, 'datatype_info' is called, with file
pointer set to null_fp (pointing to /dev/null). And after
'datatype_info' returns, any output by gdb goes to /dev/null, and hence
the output is lost.

Fix this by restoring the original output streams, after gdb_interface
has handled the output

After this patch:

    crash> info threads
      Id   Target Id         Frame
    * 1    2131 bash         0xc000000000051e40 in crash_fadump (regs=0x0, str=0xc000000002c60510 <buf> "sysrq triggered crash") at arch/powerpc/kernel/fadump.c:735

Cc: Sourabh Jain <[email protected]>
Cc: Hari Bathini <[email protected]>
Cc: Mahesh J Salgaonkar <[email protected]>
Cc: Naveen N. Rao <[email protected]>
Cc: Lianbo Jiang <[email protected]>
Cc: HAGIO KAZUHITO(萩尾 一仁) <[email protected]>
Cc: Tao Liu <[email protected]>
Cc: Alexey Makhalov <[email protected]>
Signed-off-by: Aditya Gupta <[email protected]>
Signed-off-by: Tao Liu <[email protected]>
  • Loading branch information
adi-g15-ibm committed Aug 27, 2024
1 parent e0c22aa commit 37399e5
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions gdb-10.2.patch
Original file line number Diff line number Diff line change
Expand Up @@ -16118,3 +16118,56 @@ exit 0
subclass (SYMBOL_NONE)
{
/* We can't use an initializer list for members of a base class, and
--- gdb-10.2/gdb/ui-file.h.orig
+++ gdb-10.2/gdb/ui-file.h
@@ -195,6 +195,7 @@ public:

bool can_emit_style_escape () override;

+ FILE *get_stream(void);
/* Sets the internal stream to FILE, and saves the FILE's file
descriptor in M_FD. */
void set_stream (FILE *file);
--- gdb-10.2/gdb/ui-file.c.orig
+++ gdb-10.2/gdb/ui-file.c
@@ -161,6 +161,12 @@ stdio_file::~stdio_file ()
fclose (m_file);
}

+FILE*
+stdio_file::get_stream(void)
+{
+ return m_file;
+}
+
void
stdio_file::set_stream (FILE *file)
{
--- gdb-10.2/gdb/symtab.c.orig
+++ gdb-10.2/gdb/symtab.c
@@ -6964,8 +6964,12 @@ void
gdb_command_funnel_1(struct gnu_request *req)
{
struct symbol *sym;
+ FILE *original_stdout_stream = nullptr;
+ FILE *original_stderr_stream = nullptr;

if (req->command != GNU_VERSION && req->command != GNU_USER_PRINT_OPTION) {
+ original_stdout_stream = (dynamic_cast< stdio_file * >gdb_stdout)->get_stream();
+ original_stderr_stream = (dynamic_cast< stdio_file * >gdb_stderr)->get_stream();
(dynamic_cast<stdio_file *>gdb_stdout)->set_stream(req->fp);
(dynamic_cast<stdio_file *>gdb_stderr)->set_stream(req->fp);
}
@@ -7068,6 +7072,12 @@ gdb_command_funnel_1(struct gnu_request *req)
req->flags |= GNU_COMMAND_FAILED;
break;
}
+
+ /* Restore the streams gdb output was using */
+ if (original_stdout_stream)
+ (dynamic_cast<stdio_file *>gdb_stdout)->set_stream(original_stdout_stream);
+ if (original_stderr_stream)
+ (dynamic_cast<stdio_file *>gdb_stderr)->set_stream(original_stderr_stream);
}

/*

0 comments on commit 37399e5

Please sign in to comment.