From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>, Andrew Burgess <aburgess@redhat.com>
Subject: [PATCH v3 05/21] Move buffered stream to new files
Date: Fri, 30 Jan 2026 06:17:19 -0700 [thread overview]
Message-ID: <20260130-pr-28948-logging-5-v3-5-3eec47ef3cba@tromey.com> (raw)
In-Reply-To: <20260130-pr-28948-logging-5-v3-0-3eec47ef3cba@tromey.com>
The buffered stream code is currently in ui-out.h and ui-out.c, which
seems weird because it seems more like a low-level ui-file idea (for
the most part, it does also affect some ui_out).
This patch moves the declarations to a new header file,
buffered-streams.h and the implementation to buffered-streams.c. This
seems cleaner to me.
Approved-By: Andrew Burgess <aburgess@redhat.com>
---
gdb/Makefile.in | 2 +
gdb/buffered-streams.c | 155 +++++++++++++++++++++++++++++++++++
gdb/buffered-streams.h | 205 +++++++++++++++++++++++++++++++++++++++++++++++
gdb/cli-out.c | 1 +
gdb/debuginfod-support.c | 1 +
gdb/infrun.c | 1 +
gdb/stack.c | 1 +
gdb/thread.c | 1 +
gdb/ui-out.c | 137 +------------------------------
gdb/ui-out.h | 180 -----------------------------------------
10 files changed, 368 insertions(+), 316 deletions(-)
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index fc76925344f..9aa46f8b1fa 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1071,6 +1071,7 @@ COMMON_SFILES = \
breakpoint.c \
bt-utils.c \
btrace.c \
+ buffered-streams.c \
build-id.c \
buildsym.c \
c-lang.c \
@@ -1346,6 +1347,7 @@ HFILES_NO_SRCDIR = \
bsd-uthread.h \
btrace.h \
bt-utils.h \
+ buffered-streams.h \
build-id.h \
buildsym.h \
c-exp.h \
diff --git a/gdb/buffered-streams.c b/gdb/buffered-streams.c
new file mode 100644
index 00000000000..a9d3fcf4f5d
--- /dev/null
+++ b/gdb/buffered-streams.c
@@ -0,0 +1,155 @@
+/* Copyright (C) 2025, 2026 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+#include "buffered-streams.h"
+#include "ui-out.h"
+
+/* See buffered-streams.h. */
+
+void
+buffer_group::output_unit::flush () const
+{
+ if (!m_msg.empty ())
+ m_stream->puts (m_msg.c_str ());
+
+ if (m_wrap_hint >= 0)
+ m_stream->wrap_here (m_wrap_hint);
+
+ if (m_flush)
+ m_stream->flush ();
+}
+
+/* See buffered-streams.h. */
+
+void
+buffer_group::write (const char *buf, long length_buf, ui_file *stream)
+{
+ /* Record each line separately. */
+ for (size_t prev = 0, cur = 0; cur < length_buf; ++cur)
+ if (buf[cur] == '\n' || cur == length_buf - 1)
+ {
+ std::string msg (buf + prev, cur - prev + 1);
+
+ if (m_buffered_output.size () > 0
+ && m_buffered_output.back ().m_wrap_hint == -1
+ && m_buffered_output.back ().m_stream == stream
+ && m_buffered_output.back ().m_msg.size () > 0
+ && m_buffered_output.back ().m_msg.back () != '\n')
+ m_buffered_output.back ().m_msg.append (msg);
+ else
+ m_buffered_output.emplace_back (msg).m_stream = stream;
+ prev = cur + 1;
+ }
+}
+
+/* See buffered-streams.h. */
+
+void
+buffer_group::wrap_here (int indent, ui_file *stream)
+{
+ m_buffered_output.emplace_back ("", indent).m_stream = stream;
+}
+
+/* See buffered-streams.h. */
+
+void
+buffer_group::flush_here (ui_file *stream)
+{
+ m_buffered_output.emplace_back ("", -1, true).m_stream = stream;
+}
+
+/* See buffered-streams.h. */
+
+ui_file *
+get_unbuffered (ui_file *stream)
+{
+ while (true)
+ {
+ buffering_file *buf = dynamic_cast<buffering_file *> (stream);
+
+ if (buf == nullptr)
+ return stream;
+
+ stream = buf->stream ();
+ }
+}
+
+buffered_streams::buffered_streams (buffer_group *group, ui_out *uiout)
+ : m_buffered_stdout (group, gdb_stdout),
+ m_buffered_stderr (group, gdb_stderr),
+ m_buffered_stdlog (group, gdb_stdlog),
+ m_buffered_stdtarg (group, gdb_stdtarg),
+ m_uiout (uiout)
+{
+ gdb_stdout = &m_buffered_stdout;
+ gdb_stderr = &m_buffered_stderr;
+ gdb_stdlog = &m_buffered_stdlog;
+ gdb_stdtarg = &m_buffered_stdtarg;
+
+ ui_file *stream = current_uiout->current_stream ();
+ if (stream != nullptr)
+ {
+ m_buffered_current_uiout.emplace (group, stream);
+ current_uiout->redirect (&(*m_buffered_current_uiout));
+ }
+
+ stream = m_uiout->current_stream ();
+ if (stream != nullptr && current_uiout != m_uiout)
+ {
+ m_buffered_uiout.emplace (group, stream);
+ m_uiout->redirect (&(*m_buffered_uiout));
+ }
+
+ m_buffers_in_place = true;
+}
+
+/* See buffered-streams.h. */
+
+void
+buffered_streams::remove_buffers ()
+{
+ if (!m_buffers_in_place)
+ return;
+
+ m_buffers_in_place = false;
+
+ gdb_stdout = m_buffered_stdout.stream ();
+ gdb_stderr = m_buffered_stderr.stream ();
+ gdb_stdlog = m_buffered_stdlog.stream ();
+ gdb_stdtarg = m_buffered_stdtarg.stream ();
+
+ if (m_buffered_current_uiout.has_value ())
+ current_uiout->redirect (nullptr);
+
+ if (m_buffered_uiout.has_value ())
+ m_uiout->redirect (nullptr);
+}
+
+buffer_group::buffer_group (ui_out *uiout)
+ : m_buffered_streams (new buffered_streams (this, uiout))
+{ /* Nothing. */ }
+
+/* See buffered-streams.h. */
+
+void
+buffer_group::flush () const
+{
+ m_buffered_streams->remove_buffers ();
+
+ for (const output_unit &ou : m_buffered_output)
+ ou.flush ();
+}
diff --git a/gdb/buffered-streams.h b/gdb/buffered-streams.h
new file mode 100644
index 00000000000..0da2d8a8f43
--- /dev/null
+++ b/gdb/buffered-streams.h
@@ -0,0 +1,205 @@
+/* Copyright (C) 2025, 2026 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ 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/>. */
+
+#ifndef GDB_BUFFERED_STREAMS_H
+#define GDB_BUFFERED_STREAMS_H
+
+#include <optional>
+#include "ui-file.h"
+
+struct buffered_streams;
+class ui_out;
+
+/* Organizes writes to a collection of buffered output streams
+ so that when flushed, output is written to all streams in
+ chronological order. */
+
+struct buffer_group
+{
+ buffer_group (ui_out *uiout);
+
+ /* Flush all buffered writes to the underlying output streams. */
+ void flush () const;
+
+ /* Record contents of BUF and associate it with STREAM. */
+ void write (const char *buf, long length_buf, ui_file *stream);
+
+ /* Record a wrap_here and associate it with STREAM. */
+ void wrap_here (int indent, ui_file *stream);
+
+ /* Record a call to flush and associate it with STREAM. */
+ void flush_here (ui_file *stream);
+
+private:
+
+ struct output_unit
+ {
+ output_unit (std::string msg, int wrap_hint = -1, bool flush = false)
+ : m_msg (msg), m_wrap_hint (wrap_hint), m_flush (flush)
+ {}
+
+ /* Write contents of this output_unit to the underlying stream. */
+ void flush () const;
+
+ /* Underlying stream for which this output unit will be written to. */
+ ui_file *m_stream;
+
+ /* String to be written to underlying buffer. */
+ std::string m_msg;
+
+ /* Argument to wrap_here. -1 indicates no wrap. Used to call wrap_here
+ during buffer flush. */
+ int m_wrap_hint;
+
+ /* Indicate that the underlying output stream's flush should be called. */
+ bool m_flush;
+ };
+
+ /* Output_units to be written to buffered output streams. */
+ std::vector<output_unit> m_buffered_output;
+
+ /* Buffered output streams. */
+ std::unique_ptr<buffered_streams> m_buffered_streams;
+};
+
+/* If FILE is a buffering_file, return its underlying stream. */
+
+extern ui_file *get_unbuffered (ui_file *file);
+
+/* Buffer output to gdb_stdout and gdb_stderr for the duration of FUNC. */
+
+template<typename F, typename... Arg>
+void
+do_with_buffered_output (F func, ui_out *uiout, Arg... args)
+{
+ buffer_group g (uiout);
+
+ try
+ {
+ func (uiout, std::forward<Arg> (args)...);
+ }
+ catch (gdb_exception &ex)
+ {
+ /* Ideally flush would be called in the destructor of buffer_group,
+ however flushing might cause an exception to be thrown. Catch it
+ and ensure the first exception propagates. */
+ try
+ {
+ g.flush ();
+ }
+ catch (const gdb_exception &)
+ {
+ }
+
+ throw_exception (std::move (ex));
+ }
+
+ /* Try was successful. Let any further exceptions propagate. */
+ g.flush ();
+}
+
+/* Accumulate writes to an underlying ui_file. Output to the
+ underlying file is deferred until required. */
+
+struct buffering_file : public ui_file
+{
+ buffering_file (buffer_group *group, ui_file *stream)
+ : m_group (group),
+ m_stream (stream)
+ { /* Nothing. */ }
+
+ /* Return the underlying output stream. */
+ ui_file *stream () const
+ {
+ return m_stream;
+ }
+
+ /* Record the contents of BUF. */
+ void write (const char *buf, long length_buf) override
+ {
+ m_group->write (buf, length_buf, m_stream);
+ }
+
+ /* Record a wrap_here call with argument INDENT. */
+ void wrap_here (int indent) override
+ {
+ m_group->wrap_here (indent, m_stream);
+ }
+
+ /* Return true if the underlying stream is a tty. */
+ bool isatty () override
+ {
+ return m_stream->isatty ();
+ }
+
+ /* Return true if ANSI escapes can be used on the underlying stream. */
+ bool can_emit_style_escape () override
+ {
+ return m_stream->can_emit_style_escape ();
+ }
+
+ /* Flush the underlying output stream. */
+ void flush () override
+ {
+ return m_group->flush_here (m_stream);
+ }
+
+private:
+
+ /* Coordinates buffering across multiple buffering_files. */
+ buffer_group *m_group;
+
+ /* The underlying output stream. */
+ ui_file *m_stream;
+};
+
+/* Attaches and detaches buffers for each of the gdb_std* streams. */
+
+struct buffered_streams
+{
+ buffered_streams (buffer_group *group, ui_out *uiout);
+
+ ~buffered_streams ()
+ {
+ this->remove_buffers ();
+ }
+
+ /* Remove buffering_files from all underlying streams. */
+ void remove_buffers ();
+
+private:
+
+ /* True if buffers are still attached to each underlying output stream. */
+ bool m_buffers_in_place;
+
+ /* Buffers for each gdb_std* output stream. */
+ buffering_file m_buffered_stdout;
+ buffering_file m_buffered_stderr;
+ buffering_file m_buffered_stdlog;
+ buffering_file m_buffered_stdtarg;
+
+ /* Buffer for current_uiout's output stream. */
+ std::optional<buffering_file> m_buffered_current_uiout;
+
+ /* Additional ui_out being buffered. */
+ ui_out *m_uiout;
+
+ /* Buffer for m_uiout's output stream. */
+ std::optional<buffering_file> m_buffered_uiout;
+};
+
+#endif /* GDB_BUFFERED_STREAMS_H */
diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index 0f4dbc7768d..b1ea9560fcf 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -27,6 +27,7 @@
#include "cli/cli-style.h"
#include "ui.h"
#include "cli/cli-cmds.h"
+#include "buffered-streams.h"
/* These are the CLI output functions */
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
index 16012f826ce..3da3edc432d 100644
--- a/gdb/debuginfod-support.c
+++ b/gdb/debuginfod-support.c
@@ -26,6 +26,7 @@
#include "cli/cli-style.h"
#include "cli-out.h"
#include "target.h"
+#include "buffered-streams.h"
/* Set/show debuginfod commands. */
static cmd_list_element *set_debuginfod_prefix_list;
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 6bcd8ec5cc0..422b4728477 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -76,6 +76,7 @@
#include "disasm.h"
#include "interps.h"
#include "finish-thread-state.h"
+#include "buffered-streams.h"
/* Prototypes for local functions */
diff --git a/gdb/stack.c b/gdb/stack.c
index 732d525083e..919cbf73642 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -50,6 +50,7 @@
#include "linespec.h"
#include "cli/cli-utils.h"
#include "objfiles.h"
+#include "buffered-streams.h"
#include "symfile.h"
#include "extension.h"
diff --git a/gdb/thread.c b/gdb/thread.c
index 0788bea235a..96e3bb7b50f 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -50,6 +50,7 @@
#include "stack.h"
#include "interps.h"
#include "record-full.h"
+#include "buffered-streams.h"
/* Print notices when new threads are attached and detached. */
static bool print_thread_events = true;
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 00c2055f492..8a41d9897fa 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -26,6 +26,7 @@
#include "gdbsupport/format.h"
#include "cli/cli-style.h"
#include "diagnostics.h"
+#include "buffered-streams.h"
#include <vector>
#include <memory>
@@ -847,139 +848,3 @@ ui_out::ui_out (ui_out_flags flags)
ui_out::~ui_out ()
{
}
-
-/* See ui-out.h. */
-
-void
-buffer_group::output_unit::flush () const
-{
- if (!m_msg.empty ())
- m_stream->puts (m_msg.c_str ());
-
- if (m_wrap_hint >= 0)
- m_stream->wrap_here (m_wrap_hint);
-
- if (m_flush)
- m_stream->flush ();
-}
-
-/* See ui-out.h. */
-
-void
-buffer_group::write (const char *buf, long length_buf, ui_file *stream)
-{
- /* Record each line separately. */
- for (size_t prev = 0, cur = 0; cur < length_buf; ++cur)
- if (buf[cur] == '\n' || cur == length_buf - 1)
- {
- std::string msg (buf + prev, cur - prev + 1);
-
- if (m_buffered_output.size () > 0
- && m_buffered_output.back ().m_wrap_hint == -1
- && m_buffered_output.back ().m_stream == stream
- && m_buffered_output.back ().m_msg.size () > 0
- && m_buffered_output.back ().m_msg.back () != '\n')
- m_buffered_output.back ().m_msg.append (msg);
- else
- m_buffered_output.emplace_back (msg).m_stream = stream;
- prev = cur + 1;
- }
-}
-
-/* See ui-out.h. */
-
-void
-buffer_group::wrap_here (int indent, ui_file *stream)
-{
- m_buffered_output.emplace_back ("", indent).m_stream = stream;
-}
-
-/* See ui-out.h. */
-
-void
-buffer_group::flush_here (ui_file *stream)
-{
- m_buffered_output.emplace_back ("", -1, true).m_stream = stream;
-}
-
-/* See ui-out.h. */
-
-ui_file *
-get_unbuffered (ui_file *stream)
-{
- while (true)
- {
- buffering_file *buf = dynamic_cast<buffering_file *> (stream);
-
- if (buf == nullptr)
- return stream;
-
- stream = buf->stream ();
- }
-}
-
-buffered_streams::buffered_streams (buffer_group *group, ui_out *uiout)
- : m_buffered_stdout (group, gdb_stdout),
- m_buffered_stderr (group, gdb_stderr),
- m_buffered_stdlog (group, gdb_stdlog),
- m_buffered_stdtarg (group, gdb_stdtarg),
- m_uiout (uiout)
-{
- gdb_stdout = &m_buffered_stdout;
- gdb_stderr = &m_buffered_stderr;
- gdb_stdlog = &m_buffered_stdlog;
- gdb_stdtarg = &m_buffered_stdtarg;
-
- ui_file *stream = current_uiout->current_stream ();
- if (stream != nullptr)
- {
- m_buffered_current_uiout.emplace (group, stream);
- current_uiout->redirect (&(*m_buffered_current_uiout));
- }
-
- stream = m_uiout->current_stream ();
- if (stream != nullptr && current_uiout != m_uiout)
- {
- m_buffered_uiout.emplace (group, stream);
- m_uiout->redirect (&(*m_buffered_uiout));
- }
-
- m_buffers_in_place = true;
-}
-
-/* See ui-out.h. */
-
-void
-buffered_streams::remove_buffers ()
-{
- if (!m_buffers_in_place)
- return;
-
- m_buffers_in_place = false;
-
- gdb_stdout = m_buffered_stdout.stream ();
- gdb_stderr = m_buffered_stderr.stream ();
- gdb_stdlog = m_buffered_stdlog.stream ();
- gdb_stdtarg = m_buffered_stdtarg.stream ();
-
- if (m_buffered_current_uiout.has_value ())
- current_uiout->redirect (nullptr);
-
- if (m_buffered_uiout.has_value ())
- m_uiout->redirect (nullptr);
-}
-
-buffer_group::buffer_group (ui_out *uiout)
- : m_buffered_streams (new buffered_streams (this, uiout))
-{ /* Nothing. */ }
-
-/* See ui-out.h. */
-
-void
-buffer_group::flush () const
-{
- m_buffered_streams->remove_buffers ();
-
- for (const output_unit &ou : m_buffered_output)
- ou.flush ();
-}
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index ee5e68fa233..69d9910443e 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -475,184 +475,4 @@ class ui_out_redirect_pop
struct ui_out *m_uiout;
};
-struct buffered_streams;
-
-/* Organizes writes to a collection of buffered output streams
- so that when flushed, output is written to all streams in
- chronological order. */
-
-struct buffer_group
-{
- buffer_group (ui_out *uiout);
-
- /* Flush all buffered writes to the underlying output streams. */
- void flush () const;
-
- /* Record contents of BUF and associate it with STREAM. */
- void write (const char *buf, long length_buf, ui_file *stream);
-
- /* Record a wrap_here and associate it with STREAM. */
- void wrap_here (int indent, ui_file *stream);
-
- /* Record a call to flush and associate it with STREAM. */
- void flush_here (ui_file *stream);
-
-private:
-
- struct output_unit
- {
- output_unit (std::string msg, int wrap_hint = -1, bool flush = false)
- : m_msg (msg), m_wrap_hint (wrap_hint), m_flush (flush)
- {}
-
- /* Write contents of this output_unit to the underlying stream. */
- void flush () const;
-
- /* Underlying stream for which this output unit will be written to. */
- ui_file *m_stream;
-
- /* String to be written to underlying buffer. */
- std::string m_msg;
-
- /* Argument to wrap_here. -1 indicates no wrap. Used to call wrap_here
- during buffer flush. */
- int m_wrap_hint;
-
- /* Indicate that the underlying output stream's flush should be called. */
- bool m_flush;
- };
-
- /* Output_units to be written to buffered output streams. */
- std::vector<output_unit> m_buffered_output;
-
- /* Buffered output streams. */
- std::unique_ptr<buffered_streams> m_buffered_streams;
-};
-
-/* If FILE is a buffering_file, return its underlying stream. */
-
-extern ui_file *get_unbuffered (ui_file *file);
-
-/* Buffer output to gdb_stdout and gdb_stderr for the duration of FUNC. */
-
-template<typename F, typename... Arg>
-void
-do_with_buffered_output (F func, ui_out *uiout, Arg... args)
-{
- buffer_group g (uiout);
-
- try
- {
- func (uiout, std::forward<Arg> (args)...);
- }
- catch (gdb_exception &ex)
- {
- /* Ideally flush would be called in the destructor of buffer_group,
- however flushing might cause an exception to be thrown. Catch it
- and ensure the first exception propagates. */
- try
- {
- g.flush ();
- }
- catch (const gdb_exception &)
- {
- }
-
- throw_exception (std::move (ex));
- }
-
- /* Try was successful. Let any further exceptions propagate. */
- g.flush ();
-}
-
-/* Accumulate writes to an underlying ui_file. Output to the
- underlying file is deferred until required. */
-
-struct buffering_file : public ui_file
-{
- buffering_file (buffer_group *group, ui_file *stream)
- : m_group (group),
- m_stream (stream)
- { /* Nothing. */ }
-
- /* Return the underlying output stream. */
- ui_file *stream () const
- {
- return m_stream;
- }
-
- /* Record the contents of BUF. */
- void write (const char *buf, long length_buf) override
- {
- m_group->write (buf, length_buf, m_stream);
- }
-
- /* Record a wrap_here call with argument INDENT. */
- void wrap_here (int indent) override
- {
- m_group->wrap_here (indent, m_stream);
- }
-
- /* Return true if the underlying stream is a tty. */
- bool isatty () override
- {
- return m_stream->isatty ();
- }
-
- /* Return true if ANSI escapes can be used on the underlying stream. */
- bool can_emit_style_escape () override
- {
- return m_stream->can_emit_style_escape ();
- }
-
- /* Flush the underlying output stream. */
- void flush () override
- {
- return m_group->flush_here (m_stream);
- }
-
-private:
-
- /* Coordinates buffering across multiple buffering_files. */
- buffer_group *m_group;
-
- /* The underlying output stream. */
- ui_file *m_stream;
-};
-
-/* Attaches and detaches buffers for each of the gdb_std* streams. */
-
-struct buffered_streams
-{
- buffered_streams (buffer_group *group, ui_out *uiout);
-
- ~buffered_streams ()
- {
- this->remove_buffers ();
- }
-
- /* Remove buffering_files from all underlying streams. */
- void remove_buffers ();
-
-private:
-
- /* True if buffers are still attached to each underlying output stream. */
- bool m_buffers_in_place;
-
- /* Buffers for each gdb_std* output stream. */
- buffering_file m_buffered_stdout;
- buffering_file m_buffered_stderr;
- buffering_file m_buffered_stdlog;
- buffering_file m_buffered_stdtarg;
-
- /* Buffer for current_uiout's output stream. */
- std::optional<buffering_file> m_buffered_current_uiout;
-
- /* Additional ui_out being buffered. */
- ui_out *m_uiout;
-
- /* Buffer for m_uiout's output stream. */
- std::optional<buffering_file> m_buffered_uiout;
-};
-
#endif /* GDB_UI_OUT_H */
--
2.49.0
next prev parent reply other threads:[~2026-01-30 13:22 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-30 13:17 [PATCH v3 00/21] Rework gdb logging and output redirection Tom Tromey
2026-01-30 13:17 ` [PATCH v3 01/21] Remove unnecessary override of write_async_safe Tom Tromey
2026-01-30 13:17 ` [PATCH v3 02/21] Move stdtarg to ui Tom Tromey
2026-01-30 13:17 ` [PATCH v3 03/21] Turn wrapped_file into a template Tom Tromey
2026-01-30 13:17 ` [PATCH v3 04/21] Small rewrite of get_unbuffered Tom Tromey
2026-01-30 13:17 ` Tom Tromey [this message]
2026-01-30 13:17 ` [PATCH v3 06/21] Remove TYPE_FN_FIELD_STUB and associated code Tom Tromey
2026-01-30 13:17 ` [PATCH v3 07/21] Change how stdin is handled in the UI Tom Tromey
2026-01-30 13:17 ` [PATCH v3 08/21] Remove gdb_stdtargin Tom Tromey
2026-01-30 13:17 ` [PATCH v3 09/21] Improve fputs_highlighted by using ui_file::write Tom Tromey
2026-01-30 13:17 ` [PATCH v3 10/21] Add stream to buffer_group::output_unit constructor Tom Tromey
2026-01-30 13:17 ` [PATCH v3 11/21] Restore ui_file::can_page Tom Tromey
2026-01-30 13:17 ` [PATCH v3 12/21] Rewrite cli-style.c:do_show Tom Tromey
2026-01-30 13:17 ` [PATCH v3 13/21] Remove m_applied_style from ui_file Tom Tromey
2026-01-30 13:17 ` [PATCH v3 14/21] Add a new logging_file implementation Tom Tromey
2026-01-30 13:17 ` [PATCH v3 15/21] Rewrite output redirection and logging Tom Tromey
2026-01-30 13:17 ` [PATCH v3 16/21] Remove tee_file Tom Tromey
2026-01-30 13:17 ` [PATCH v3 17/21] Warn if log file changed while logging Tom Tromey
2026-01-30 13:17 ` [PATCH v3 18/21] Fix leaks with timestamped_file Tom Tromey
2026-01-30 13:17 ` [PATCH v3 19/21] Use std::make_unique with ui_files Tom Tromey
2026-01-30 13:17 ` [PATCH v3 20/21] Style filenames in cli-logging.c Tom Tromey
2026-01-30 13:17 ` [PATCH v3 21/21] Update gdb.execute documentation Tom Tromey
2026-01-30 13:35 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260130-pr-28948-logging-5-v3-5-3eec47ef3cba@tromey.com \
--to=tom@tromey.com \
--cc=aburgess@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox