From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id ceKvNPOxfGl6rx0AWB0awg (envelope-from ) for ; Fri, 30 Jan 2026 08:28:19 -0500 Authentication-Results: simark.ca; dkim=fail reason="signature verification failed" (768-bit key; unprotected) header.d=tromey.com header.i=@tromey.com header.a=rsa-sha256 header.s=default header.b=b4XcK9CH; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id D32561E08D; Fri, 30 Jan 2026 08:28:19 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_INVALID,DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=no autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 2F4471E08D for ; Fri, 30 Jan 2026 08:28:19 -0500 (EST) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id C6AE64BA23CA for ; Fri, 30 Jan 2026 13:28:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C6AE64BA23CA Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (768-bit key, unprotected) header.d=tromey.com header.i=@tromey.com header.a=rsa-sha256 header.s=default header.b=b4XcK9CH Received: from omta038.useast.a.cloudfilter.net (omta038.useast.a.cloudfilter.net [44.202.169.37]) by sourceware.org (Postfix) with ESMTPS id 8845B4BB5884 for ; Fri, 30 Jan 2026 13:17:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8845B4BB5884 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tromey.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 8845B4BB5884 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=44.202.169.37 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1769779051; cv=none; b=xt1Q/c5BaybTRBJeHEfp8kSlNemkmj24mF1sRG68i15l5Y3J1ju0LvQ0yWlyIb0F3JuqaiThU0gIOjMxWsSgQ2h0aFwx6rZc/WgAeeQ2gjHEq1k8zgbUgcGXhogStlaOmpz/joZWmKDYHlhwcxHYJhSzzlm03oFNC13eKBB0cuI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1769779051; c=relaxed/simple; bh=Br/vKZZvFp3JleKdTb3j2NlYe+9N9uKSYUcQm/i8SRg=; h=DKIM-Signature:From:Date:Subject:MIME-Version:Message-Id:To; b=ambVpxwRnyip9s+G3la4Y0Zdw5rwF4bxdHDIdskTq+2VmCMSwjERSoNxAbR/GPOMTGp/p1fO9e6/YVgrI4YX9fyh+TALkX5iy/J/6k8vFVUBI7iXDqRxcjjaG9XYF4r6YJTbkuFxKuEaHriwRVsMfmNjxjSPS6F8TqCJSEQHmG0= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8845B4BB5884 Received: from eig-obgw-5001b.ext.cloudfilter.net ([10.0.29.181]) by cmsmtp with ESMTPS id lkZQvFGnhSkcfloNKvvWYE; Fri, 30 Jan 2026 13:17:26 +0000 Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with ESMTPS id loNJvfeErSqlVloNKvPsnZ; Fri, 30 Jan 2026 13:17:26 +0000 X-Authority-Analysis: v=2.4 cv=I7FlRMgg c=1 sm=1 tr=0 ts=697caf66 a=ApxJNpeYhEAb1aAlGBBbmA==:117 a=ApxJNpeYhEAb1aAlGBBbmA==:17 a=IkcTkHD0fZMA:10 a=vUbySO9Y5rIA:10 a=ItBw4LHWJt0A:10 a=mDV3o1hIAAAA:8 a=07VodR2oUPuVj-uC114A:9 a=QEXdDO2ut3YA:10 a=p2B7LCBIlYrZKF0eevq8:22 a=DCx65vhANUyCzuf5D8fC:22 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Cc:To:In-Reply-To:References:Message-Id: Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date:From:Sender: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=amEtsc+j/n3Vx/5l44RD9++4pl61Ch9VqybzCIqXaLM=; b=b4XcK9CHXjS0dB8eay3pjzsg8k qNYldcX97eIHtPY//j+Qo2p4UnMR+D2BJtf5YwCEl35A2KDCLQkj0ZcmrH0NNO8blnABeo52CR7fo ZamKLXt5GHWIoi9dcZgdyDQmm; Received: from 97-122-114-32.hlrn.qwest.net ([97.122.114.32]:33716 helo=[192.168.122.1]) by box5379.bluehost.com with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1vloNJ-00000001JjQ-1z5x; Fri, 30 Jan 2026 06:17:25 -0700 From: Tom Tromey Date: Fri, 30 Jan 2026 06:17:28 -0700 Subject: [PATCH v3 14/21] Add a new logging_file implementation MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260130-pr-28948-logging-5-v3-14-3eec47ef3cba@tromey.com> References: <20260130-pr-28948-logging-5-v3-0-3eec47ef3cba@tromey.com> In-Reply-To: <20260130-pr-28948-logging-5-v3-0-3eec47ef3cba@tromey.com> To: gdb-patches@sourceware.org Cc: Tom Tromey X-Mailer: b4 0.14.3 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - sourceware.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 97.122.114.32 X-Source-L: No X-Exim-ID: 1vloNJ-00000001JjQ-1z5x X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 97-122-114-32.hlrn.qwest.net ([192.168.122.1]) [97.122.114.32]:33716 X-Source-Auth: tom+tromey.com X-Email-Count: 24 X-Org: HG=bhshared;ORG=bluehost; X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-CMAE-Envelope: MS4xfI+75bU3XvczbiKVty3WMPGp6u7GY3NYBkAeJKMXWGBB1ScRY9olnz4glhOwknH17l7IQVd+SM0VldxikGG3vG7zfLOhVNY86547lyanvJUonrg2yG3j +x5Jz1HRFBQ6dGjJmZfCoaiivqjOkDn8XgPg0BiM9JfrKTwdgKf3q9K2GD6RAeu1og9tyz6jI44fSw+x7ngsDQSjlWTAvZ1xyto= X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org This adds a new logging_file subclass of ui_file. This new subclass handles the details of logging, by consulting the relevant globals. I think a dependency on globals is warranted here, because the logging settings themselves are global. The idea of this approach is that rather than modifying the output pipeline in response to logging commands, a logging_file will simply always be in the pipeline, and will then react to the appropriate settings. ("Appropriate" because there are tests that the logger doesn't immediately react to changes, so it captures settings at the moment logging starts.) The new code isn't actually used yet -- nothing in this patch constructs a logging_file. It's separate for easier review. --- gdb/cli/cli-logging.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/logging-file.h | 82 ++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+) diff --git a/gdb/cli/cli-logging.c b/gdb/cli/cli-logging.c index c00c6bf0488..6f2a6287700 100644 --- a/gdb/cli/cli-logging.c +++ b/gdb/cli/cli-logging.c @@ -20,6 +20,7 @@ #include "cli/cli-cmds.h" #include "ui-out.h" #include "interps.h" +#include "logging-file.h" #include "cli/cli-style.h" #include "cli/cli-decode.h" @@ -61,6 +62,9 @@ show_logging_overwrite (struct ui_file *file, int from_tty, gdb_printf (file, _("off: Logging appends to the log file.\n")); } +/* The current log file, or nullptr if none. */ +static ui_file_up log_file; + /* Value as configured by the user. */ static bool logging_redirect; static bool debug_redirect; @@ -96,6 +100,119 @@ show_logging_debug_redirect (struct ui_file *file, int from_tty, _("off: Debug output will go to both the screen and the log file.\n")); } +/* Values as used by the logging_file implementation. These are + separate and only set when logging is enabled, because historically + gdb required you to disable and re-enable logging to change these + settings. */ + +static bool logging_redirect_for_file; +static bool debug_redirect_for_file; + +/* See logging-file.h. */ + +template +bool +logging_file::ordinary_output () const +{ + if (log_file == nullptr) + return true; + if (logging_redirect_for_file) + return false; + if (debug_redirect_for_file) + return !m_for_stdlog; + return true; +} + +/* See logging-file.h. */ + +template +void +logging_file::flush () +{ + if (log_file != nullptr) + log_file->flush (); + /* Always flushing seems fine. */ + m_out->flush (); +} + +/* See logging-file.h. */ + +template +bool +logging_file::can_page () const +{ + /* If all output is redirected, do not page. */ + if (!ordinary_output ()) + return false; + /* In other cases, paging happens if the underlying stream can + page. */ + return m_out->can_page (); +} + +/* See logging-file.h. */ + +template +void +logging_file::write (const char *buf, long length_buf) +{ + if (log_file != nullptr) + log_file->write (buf, length_buf); + if (ordinary_output ()) + m_out->write (buf, length_buf); +} + +/* See logging-file.h. */ + +template +void +logging_file::write_async_safe (const char *buf, long length_buf) +{ + if (log_file != nullptr) + log_file->write_async_safe (buf, length_buf); + if (ordinary_output ()) + m_out->write_async_safe (buf, length_buf); +} + +/* See logging-file.h. */ + +template +void +logging_file::puts (const char *linebuffer) +{ + if (log_file != nullptr) + log_file->puts (linebuffer); + if (ordinary_output ()) + m_out->puts (linebuffer); +} + +/* See logging-file.h. */ + +template +void +logging_file::emit_style_escape (const ui_file_style &style) +{ + if (log_file != nullptr) + log_file->emit_style_escape (style); + if (ordinary_output ()) + m_out->emit_style_escape (style); +} + +/* See logging-file.h. */ + +template +void +logging_file::puts_unfiltered (const char *str) +{ + if (log_file != nullptr) + log_file->puts_unfiltered (str); + if (ordinary_output ()) + m_out->puts_unfiltered (str); +} + +/* The available instantiations of logging_file. */ +template class logging_file; +template class logging_file; + /* If we've pushed output files, close them and pop them. */ static void pop_output_files (void) @@ -141,6 +258,8 @@ handle_redirections (int from_tty) } saved_filename = logging_filename; + logging_redirect_for_file = logging_redirect; + debug_redirect_for_file = debug_redirect; /* Let the interpreter do anything it needs. */ current_interp_set_logging (std::move (log), logging_redirect, diff --git a/gdb/logging-file.h b/gdb/logging-file.h new file mode 100644 index 00000000000..5dfe1118494 --- /dev/null +++ b/gdb/logging-file.h @@ -0,0 +1,82 @@ +/* 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 . */ + +#ifndef GDB_LOGGING_FILE_H +#define GDB_LOGGING_FILE_H + +#include "ui-file.h" + +/* A ui_file implementation that optionally writes its output to a + second logging stream. Whether logging is actually done depends on + the user's logging settings. The precise underlying ui_file type + is a template parameter, so that either owning or non-owning + instances can be made. */ + +template +class logging_file : public ui_file +{ +public: + /* This wraps another stream. Whether or not output actually goes + to that stream depends on the redirection settings. FOR_STDLOG + should only be set for a stream intended by use as gdb_stdlog; + this is used to implement the "debug redirect" feature. */ + logging_file (T out, bool for_stdlog = false) + : m_out (std::move (out)), + m_for_stdlog (for_stdlog) + { + } + + void write (const char *buf, long length_buf) override; + void write_async_safe (const char *buf, long length_buf) override; + void puts (const char *) override; + void flush () override; + bool can_page () const override; + void emit_style_escape (const ui_file_style &style) override; + void puts_unfiltered (const char *str) override; + + bool isatty () override + { + /* Defer to the wrapped file. */ + return m_out->isatty (); + } + + bool term_out () override + { + /* Defer to the wrapped file. */ + return m_out->term_out (); + } + + bool can_emit_style_escape () override + { + /* Defer to the wrapped file. */ + return m_out->can_emit_style_escape (); + } + +private: + /* A helper function that returns true if output should go to + M_OUT. */ + bool ordinary_output () const; + + /* The underlying file. */ + T m_out; + + /* True if this stream is used for gdb_stdlog. This is used to + implement the debug redirect feature. */ + bool m_for_stdlog; +}; + +#endif /* GDB_LOGGING_FILE_H */ -- 2.49.0