public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@polymtl.ca>
To: gdb-patches@sourceware.org
Cc: Michael Weghorn <m.weghorn@posteo.de>,
	Simon Marchi <simon.marchi@polymtl.ca>
Subject: [PATCH 3/4] gdbsupport: allow passing format string to scoped_debug_start_end
Date: Fri, 23 Apr 2021 22:10:05 -0400	[thread overview]
Message-ID: <20210424021006.22779-4-simon.marchi@polymtl.ca> (raw)
In-Reply-To: <20210424021006.22779-1-simon.marchi@polymtl.ca>

A little thing that bothers me with scoped_debug_start_end is that it's
not possible to pass a format string to add context to the messages: the
start and end messages are fixed.

It was done like this at the time because there's the risk that debug
output is not enabled on entry (when the constructor runs) but is
enabled on exit (when the destructor runs).  For example, a user
debugging from a top-gdb may manually enable a debug_foo variable.  If
debug output is disabled while the constructor runs, we won't render the
format string (to minimize overhead) so it won't be available in the
destructor.

I think it would be nice to be able to use a format string along with
scoped_debug_start_end, and I think it's unfortunate that such a narrow
use case prevents it.  So with this patch, I propose that we allow
passing a format string to scoped_debug_start_end, and if the rare
situation described above happens, then we just show a "sorry, message
not available" kind of message.

The following patch makes use of this.

gdbsupport/ChangeLog:

	* common-debug.h (struct scoped_debug_start_end)
	<scoped_debug_start_end>: Change start_msg/end_msg for
	start_prefix/end_prefix.  Add format string parameter and make
	variadic.
	<~scoped_debug_start_end>: Adjust.
	<m_end_msg>: Rename to...
	<m_end_prefix>: ... this.
	<m_with_format>: New.
	<m_msg>: New.
	(scoped_debug_start_end): Make variadic.
	(scoped_debug_enter_exit): Adjust.

Change-Id: I9427ce8877a246a46694b3a1fec3837dc6954d6e
---
 gdbsupport/common-debug.h | 65 +++++++++++++++++++++++++++++++--------
 1 file changed, 53 insertions(+), 12 deletions(-)

diff --git a/gdbsupport/common-debug.h b/gdbsupport/common-debug.h
index 7288b694d595..06f60f4d4af1 100644
--- a/gdbsupport/common-debug.h
+++ b/gdbsupport/common-debug.h
@@ -20,8 +20,11 @@
 #ifndef COMMON_COMMON_DEBUG_H
 #define COMMON_COMMON_DEBUG_H
 
+#include "gdbsupport/gdb_optional.h"
 #include "gdbsupport/preprocessor.h"
 
+#include <stdarg.h>
+
 /* Set to true to enable debugging of hardware breakpoint/
    watchpoint support code.  */
 
@@ -94,20 +97,38 @@ struct scoped_debug_start_end
 
      MODULE and FUNC are forwarded to debug_prefixed_printf.
 
-     START_MSG and END_MSG are the statements to print on construction and
-     destruction, respectively.  */
+     START_PREFIX and END_PREFIX are the statements to print on construction and
+     destruction, respectively.
+
+     If the FMT format string is non-nullptr, then a `: ` is appended to the
+     messages, followed by the rendering of that format string.  The format
+     string is rendered during construction and is re-used as is for the
+     message on exit.  */
 
   scoped_debug_start_end (bool &debug_enabled, const char *module,
-			  const char *func, const char *start_msg,
-			  const char *end_msg)
+			  const char *func, const char *start_prefix,
+			  const char *end_prefix, const char *fmt, ...)
     : m_debug_enabled (debug_enabled),
       m_module (module),
       m_func (func),
-      m_end_msg (end_msg)
+      m_end_prefix (end_prefix),
+      m_with_format (fmt != nullptr)
   {
     if (m_debug_enabled)
       {
-	debug_prefixed_printf (m_module, m_func, "%s", start_msg);
+	if (fmt != nullptr)
+	  {
+	    va_list args;
+	    va_start (args, fmt);
+	    m_msg = string_vprintf (fmt, args);
+	    va_end (args);
+
+	    debug_prefixed_printf (m_module, m_func, "%s: %s",
+				   start_prefix, m_msg->c_str ());
+	  }
+	else
+	  debug_prefixed_printf (m_module, m_func, "%s", start_prefix);
+
 	++debug_print_depth;
 	m_must_decrement_print_depth = true;
       }
@@ -125,7 +146,22 @@ struct scoped_debug_start_end
 
     if (m_debug_enabled)
       {
-	debug_prefixed_printf (m_module, m_func, "%s", m_end_msg);
+	if (m_with_format)
+	  {
+	    if (m_msg.has_value ())
+	      debug_prefixed_printf (m_module, m_func, "%s: %s",
+				     m_end_prefix, m_msg->c_str ());
+	    else
+	      {
+		/* A format string was passed to the constructor, but debug
+		   control variable wasn't set at the time, so we don't have the
+		   rendering of the format string.  */
+		debug_prefixed_printf (m_module, m_func, "%s: <%s debugging was not enabled on entry>",
+				       m_end_prefix, m_module);
+	      }
+	  }
+	else
+	  debug_prefixed_printf (m_module, m_func, "%s", m_end_prefix);
       }
   }
 
@@ -133,20 +169,25 @@ struct scoped_debug_start_end
   bool &m_debug_enabled;
   const char *m_module;
   const char *m_func;
-  const char *m_end_msg;
+  const char *m_end_prefix;
+
+  /* The result of formatting the format string in the constructor.  */
+  gdb::optional<std::string> m_msg;
+
+  /* True is a non-nullptr format was passed to the constructor.  */
+  bool m_with_format;
 
   /* This is used to handle the case where debugging is enabled during
      construction but not during destruction, or vice-versa.  We want to make
      sure there are as many increments are there are decrements.  */
-
   bool m_must_decrement_print_depth = false;
 };
 
 /* Helper to define a module-specific start/end debug macro.  */
 
-#define scoped_debug_start_end(debug_enabled, module, msg) \
+#define scoped_debug_start_end(debug_enabled, module, fmt, ...) \
   scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
-    (debug_enabled, module, __func__, "start: " msg, "end: " msg)
+    (debug_enabled, module, __func__, "start", "end", fmt, ##__VA_ARGS__)
 
 /* Helper to define a module-specific enter/exit debug macro.  This is a special
    case of `scoped_debug_start_end` where the start and end messages are "enter"
@@ -154,6 +195,6 @@ struct scoped_debug_start_end
 
 #define scoped_debug_enter_exit(debug_enabled, module) \
   scoped_debug_start_end CONCAT(scoped_debug_start_end, __LINE__) \
-    (debug_enabled, module, __func__, "enter", "exit")
+    (debug_enabled, module, __func__, "enter", "exit", nullptr)
 
 #endif /* COMMON_COMMON_DEBUG_H */
-- 
2.30.1


  parent reply	other threads:[~2021-04-24  2:10 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-24  2:10 [PATCH 0/4] Improvements to observer debug output Simon Marchi
2021-04-24  2:10 ` [PATCH 1/4] gdbsupport: introduce struct observer Simon Marchi
2021-04-24  2:10 ` [PATCH 2/4] gdbsupport, gdb: give names to observers Simon Marchi
2021-04-24 21:14   ` Tom Tromey
2021-04-24 23:11     ` Simon Marchi
2021-04-24  2:10 ` Simon Marchi [this message]
2021-04-24 21:17   ` [PATCH 3/4] gdbsupport: allow passing format string to scoped_debug_start_end Tom Tromey
2021-04-24 23:21     ` Simon Marchi
2021-04-24  2:10 ` [PATCH 4/4] gdbsupport: add observer_debug_printf, OBSERVER_SCOPED_DEBUG_ENTER_EXIT Simon Marchi
2021-04-24 21:19 ` [PATCH 0/4] Improvements to observer debug output Tom Tromey
2021-04-24 23:34   ` Simon Marchi

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=20210424021006.22779-4-simon.marchi@polymtl.ca \
    --to=simon.marchi@polymtl.ca \
    --cc=gdb-patches@sourceware.org \
    --cc=m.weghorn@posteo.de \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).