]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
debug: add DBG_DEV()
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Thu, 26 May 2022 03:55:12 +0000 (15:55 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 17 Jun 2022 01:28:30 +0000 (01:28 +0000)
This can be a useful macro when you are trying to track the behaviour
of one process out of the dozens that samba starts up, and when your
interest is in following it over time, not necessarily in a single
stack.

In DEVELOPER mode, if you call 'debug_developer_enable()' in the
process you're following, then any instances of DBG_DEV() will work
like DBG_ERR(), also adding ":DEV:12345:" where "12345" is the pid of
th current process.

Within debug.c itself, the macro always writes to stderr, because the
debug.c functions are not all reentrant.

When not in DEVELOPER MODE, the macro evaluates to nothing.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/util/debug.c
lib/util/debug.h

index 2f583f90f0af2da6449587c9ed838185c919f0ff..4ec5766a292e03ee213b965835f95286461ac530 100644 (file)
@@ -179,6 +179,72 @@ static struct debug_class *dbgc_config = debug_class_list_initial;
 static int current_msg_level = 0;
 static int current_msg_class = 0;
 
+/*
+ * DBG_DEV(): when and how to user it.
+ *
+ * As a developer, you sometimes want verbose logging between point A and
+ * point B, where the relationship between these points is not easily defined
+ * in terms of the call stack.
+ *
+ * For example, you might be interested in what is going on in functions in
+ * lib/util/util_str.c in an ldap worker process after a particular query. If
+ * you use gdb, something will time out and you won't get the full
+ * conversation. If you add fprintf() or DBG_ERR()s to util_str.c, you'll get
+ * a massive flood, and there's a chance one will accidentally slip into a
+ * release and the whole world will flood. DBG_DEV is a solution.
+ *
+ * On start-up, DBG_DEV() is switched OFF. Nothing is printed.
+ *
+ * 1. Add `DBG_DEV("formatted msg %d, etc\n", i);` where needed.
+ *
+ * 2. At each point you want to start debugging, add `debug_developer_enable()`.
+ *
+ * 3. At each point you want debugging to stop, add `debug_developer_disable()`.
+ *
+ * In DEVELOPER builds, the message will be printed at level 0, as with
+ * DBG_ERR(). In production builds, the macro resolves to nothing.
+ *
+ * The messages are printed with a "<function_name>:DEV:<pid>:" prefix.
+ */
+
+static bool debug_developer_is_enabled = false;
+
+bool debug_developer_enabled(void)
+{
+       return debug_developer_is_enabled;
+}
+
+/*
+ * debug_developer_disable() will turn DBG_DEV() on in the current
+ * process and children.
+ */
+void debug_developer_enable(void)
+{
+       debug_developer_is_enabled = true;
+}
+
+/*
+ * debug_developer_disable() will make DBG_DEV() do nothing in the current
+ * process (and children).
+ */
+void debug_developer_disable(void)
+{
+       debug_developer_is_enabled = false;
+}
+
+/*
+ * Within debug.c, DBG_DEV() always writes to stderr, because some functions
+ * here will attempt infinite recursion with normal DEBUG macros.
+ */
+#ifdef DEVELOPER
+#undef DBG_DEV
+#define DBG_DEV(fmt, ...)                                              \
+       (void)((debug_developer_enabled())                              \
+              && (fprintf(stderr, "%s:DEV:%d: " fmt "%s",              \
+                          __func__, getpid(), ##__VA_ARGS__, "")) )
+#endif
+
+
 #if defined(WITH_SYSLOG) || defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
 static int debug_level_to_priority(int level)
 {
index 9aeec853e6484c7798007329f35a2089f055496c..9f902863527ac0821008e2b603a423a0500887df 100644 (file)
@@ -237,6 +237,16 @@ void debuglevel_set_class(size_t idx, int level);
                && (dbgtext("%s: ", __func__))                          \
                && (dbgtext body) )
 
+
+#ifdef DEVELOPER
+#define DBG_DEV(...) \
+  (void)( (debug_developer_enabled())                          \
+         && (dbgtext("%s:DEV:%d: ", __func__, getpid()))       \
+         && (dbgtext(__VA_ARGS__)) )
+#else
+#define DBG_DEV(...) /* DBG_DEV was here */
+#endif
+
 /*
  * Debug levels matching RFC 3164
  */
@@ -329,6 +339,9 @@ bool debug_get_output_is_stderr(void);
 bool debug_get_output_is_stdout(void);
 void debug_schedule_reopen_logs(void);
 char *debug_list_class_names_and_levels(void);
+bool debug_developer_enabled(void);
+void debug_developer_enable(void);
+void debug_developer_disable(void);
 
 typedef void (*debug_callback_fn)(void *private_ptr, int level, const char *msg);