[PATCH] Patches to fix the debug system

Andreas Schneider asn at samba.org
Wed Nov 7 13:49:19 UTC 2018


Hello,

attached is a patchset to address some issues I've been running into when 
executing the testsuite locally.

The very nice bug was a segfault in the python glue test trying to set the 
debuglevel. I've opened:

https://bugzilla.samba.org/show_bug.cgi?id=13679

Please review and comment. Push if OK.


Thanks,


	Andreas


-- 
Andreas Schneider                      asn at samba.org
Samba Team                             www.samba.org
GPG-ID:     8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D
-------------- next part --------------
>From 46d4830bfa7add4e27cbb565710b097c1a46d800 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 7 Nov 2018 11:35:59 +0100
Subject: [PATCH 1/3] nsswitch:tests: Pass the envname to the script

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 nsswitch/tests/test_wbinfo_user_info.sh | 5 +++--
 source3/selftest/tests.py               | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/nsswitch/tests/test_wbinfo_user_info.sh b/nsswitch/tests/test_wbinfo_user_info.sh
index 8158ead5a4b..c699a30538f 100755
--- a/nsswitch/tests/test_wbinfo_user_info.sh
+++ b/nsswitch/tests/test_wbinfo_user_info.sh
@@ -4,7 +4,7 @@
 
 if [ $# -lt 6 ]; then
 cat <<EOF
-Usage: $(basename $0) DOMAIN REALM OWN_DOMAIN USERNAME1 UPN_NAME1 USERNAME2 UPN_NAME2
+Usage: $(basename $0) DOMAIN REALM OWN_DOMAIN USERNAME1 UPN_NAME1 USERNAME2 UPN_NAME2 ENVNAME
 EOF
 exit 1;
 fi
@@ -16,7 +16,8 @@ USERNAME1=$4
 UPN_NAME1=$5
 USERNAME2=$6
 UPN_NAME2=$7
-shift 6
+ENVNAME=$8
+shift 7
 
 failed=0
 
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 20b96762e7a..720485db7db 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -242,13 +242,13 @@ env = "ad_member:local"
 plantestsuite("samba3.wbinfo_user_info", env,
               [os.path.join(srcdir(),
                             "nsswitch/tests/test_wbinfo_user_info.sh"),
-               '$DOMAIN', '$REALM', '$DOMAIN', 'alice', 'alice', 'jane', 'jane.doe'])
+               '$DOMAIN', '$REALM', '$DOMAIN', 'alice', 'alice', 'jane', 'jane.doe', env])
 
 env = "fl2008r2dc:local"
 plantestsuite("samba3.wbinfo_user_info", env,
               [os.path.join(srcdir(),
                             "nsswitch/tests/test_wbinfo_user_info.sh"),
-               '$TRUST_DOMAIN', '$TRUST_REALM', '$DOMAIN', 'alice', 'alice', 'jane', 'jane.doe'])
+               '$TRUST_DOMAIN', '$TRUST_REALM', '$DOMAIN', 'alice', 'alice', 'jane', 'jane.doe', env])
 
 env = "ad_member"
 t = "WBCLIENT-MULTI-PING"
-- 
2.19.1


>From 352c76936749198c7a8b27af58b9051999ea8006 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 7 Nov 2018 14:32:29 +0100
Subject: [PATCH 2/3] lib:util: Fix DEBUGCLASS pointer initializiation

This fixes a segfault in pyglue:

==10142== Process terminating with default action of signal 11 (SIGSEGV)
==10142==  Bad permissions for mapped region at address 0x6F00A20
==10142==    at 0x6F1074B: py_set_debug_level (pyglue.c:165)

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13679

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 lib/util/debug.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/util/debug.c b/lib/util/debug.c
index d41e0f99c77..847ec1f0a0c 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -557,10 +557,10 @@ static const char *default_classname_table[] = {
  * This is to allow reading of DEBUGLEVEL_CLASS before the debug
  * system has been initialized.
  */
-static const int debug_class_list_initial[ARRAY_SIZE(default_classname_table)];
+static int debug_class_list_initial[ARRAY_SIZE(default_classname_table)];
 
 static size_t debug_num_classes = 0;
-int     *DEBUGLEVEL_CLASS = discard_const_p(int, debug_class_list_initial);
+int     *DEBUGLEVEL_CLASS = debug_class_list_initial;
 
 
 /* -------------------------------------------------------------------------- **
-- 
2.19.1


>From 4ba9ac3532a68221dd9d8c7cacdf2d9f9603acc8 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn at samba.org>
Date: Wed, 7 Nov 2018 14:14:05 +0100
Subject: [PATCH 3/3] debug: Use debuglevel_(get|set) function

Signed-off-by: Andreas Schneider <asn at samba.org>
---
 ctdb/common/conf_tool.c              |  6 ++++--
 ctdb/common/logging.c                |  4 +++-
 ctdb/common/path_tool.c              |  2 +-
 ctdb/event/event_tool.c              |  6 ++++--
 ctdb/server/ctdb_control.c           | 11 ++++++++--
 ctdb/server/ctdb_recoverd.c          |  2 +-
 ctdb/tests/src/ctdb_takeover_tests.c |  2 +-
 ctdb/tests/src/dummy_client.c        |  2 +-
 ctdb/tests/src/test_options.c        |  2 +-
 ctdb/tools/ctdb.c                    |  9 +++++----
 ctdb/tools/ctdb_killtcp.c            |  9 +++++----
 lib/util/debug.c                     | 12 ++++++++++-
 lib/util/debug.h                     | 30 ++++++++++++++--------------
 python/pyglue.c                      |  5 +++--
 source3/nmbd/asyncdns.c              |  2 +-
 source4/param/pyparam.c              |  2 +-
 16 files changed, 66 insertions(+), 40 deletions(-)

diff --git a/ctdb/common/conf_tool.c b/ctdb/common/conf_tool.c
index e6020c504e6..8e0753eb787 100644
--- a/ctdb/common/conf_tool.c
+++ b/ctdb/common/conf_tool.c
@@ -276,6 +276,7 @@ int main(int argc, const char **argv)
 	TALLOC_CTX *mem_ctx;
 	struct conf_tool_context *ctx;
 	int ret, result;
+	int level;
 	bool ok;
 
 	mem_ctx = talloc_new(NULL);
@@ -297,10 +298,11 @@ int main(int argc, const char **argv)
 	}
 
 	setup_logging("ctdb-config", DEBUG_STDERR);
-	ok = debug_level_parse(conf_data.debug, &DEBUGLEVEL);
+	ok = debug_level_parse(conf_data.debug, &level);
 	if (!ok) {
-		DEBUGLEVEL = DEBUG_ERR;
+		level = DEBUG_ERR;
 	}
+	debuglevel_set(level);
 
 	ret = conf_tool_run(ctx, &result);
 	if (ret != 0) {
diff --git a/ctdb/common/logging.c b/ctdb/common/logging.c
index dc8c4f75058..aaa93216ef5 100644
--- a/ctdb/common/logging.c
+++ b/ctdb/common/logging.c
@@ -674,6 +674,7 @@ int logging_init(TALLOC_CTX *mem_ctx, const char *logging,
 {
 	struct log_backend *backend = NULL;
 	char *option = NULL;
+	int level;
 	int ret;
 
 	setup_logging(app_name, DEBUG_STDERR);
@@ -681,9 +682,10 @@ int logging_init(TALLOC_CTX *mem_ctx, const char *logging,
 	if (debug_level == NULL) {
 		debug_level = getenv("CTDB_DEBUGLEVEL");
 	}
-	if (! debug_level_parse(debug_level, &DEBUGLEVEL)) {
+	if (! debug_level_parse(debug_level, &level)) {
 		return EINVAL;
 	}
+	debuglevel_set(level);
 
 	if (logging == NULL) {
 		logging = getenv("CTDB_LOGGING");
diff --git a/ctdb/common/path_tool.c b/ctdb/common/path_tool.c
index 1c60b023c42..a19afa9b0c3 100644
--- a/ctdb/common/path_tool.c
+++ b/ctdb/common/path_tool.c
@@ -365,7 +365,7 @@ int main(int argc, const char **argv)
 	}
 
 	setup_logging("ctdb-path", DEBUG_STDERR);
-	DEBUGLEVEL = DEBUG_ERR;
+	debuglevel_set(DEBUG_ERR);
 
 	ret = path_tool_run(ctx, &result);
 	if (ret != 0) {
diff --git a/ctdb/event/event_tool.c b/ctdb/event/event_tool.c
index f18deb8d5b1..8350f202cea 100644
--- a/ctdb/event/event_tool.c
+++ b/ctdb/event/event_tool.c
@@ -717,6 +717,7 @@ int main(int argc, const char **argv)
 	TALLOC_CTX *mem_ctx;
 	struct event_tool_context *ctx;
 	int ret, result = 0;
+	int level;
 	bool ok;
 
 	mem_ctx = talloc_new(NULL);
@@ -738,10 +739,11 @@ int main(int argc, const char **argv)
 	}
 
 	setup_logging("ctdb-event", DEBUG_STDERR);
-	ok = debug_level_parse(event_data.debug, &DEBUGLEVEL);
+	ok = debug_level_parse(event_data.debug, &level);
 	if (!ok) {
-		DEBUGLEVEL = DEBUG_ERR;
+		level = DEBUG_ERR;
 	}
+	debuglevel_set(level);
 
 	ret = event_tool_run(ctx, &result);
 	if (ret != 0) {
diff --git a/ctdb/server/ctdb_control.c b/ctdb/server/ctdb_control.c
index c260b924529..6c91e211660 100644
--- a/ctdb/server/ctdb_control.c
+++ b/ctdb/server/ctdb_control.c
@@ -100,6 +100,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 	uint32_t opcode = c->opcode;
 	uint64_t srvid = c->srvid;
 	uint32_t client_id = c->client_id;
+	static int level = DEBUG_ERR;
 
 	switch (opcode) {
 	case CTDB_CONTROL_PROCESS_EXISTS: {
@@ -108,14 +109,20 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 	}
 
 	case CTDB_CONTROL_SET_DEBUG: {
+		union {
+			uint8_t *ptr;
+			int32_t *level;
+		} debug;
 		CHECK_CONTROL_DATA_SIZE(sizeof(int32_t));
-		DEBUGLEVEL = *(int32_t *)indata.dptr;
+		debug.ptr = indata.dptr;
+		debuglevel_set(*debug.level);
 		return 0;
 	}
 
 	case CTDB_CONTROL_GET_DEBUG: {
 		CHECK_CONTROL_DATA_SIZE(0);
-		outdata->dptr = (uint8_t *)&(DEBUGLEVEL);
+		level = debuglevel_get();
+		outdata->dptr = (uint8_t *)&(level);
 		outdata->dsize = sizeof(DEBUGLEVEL);
 		return 0;
 	}
diff --git a/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c
index 673c99c3d34..f000538bae2 100644
--- a/ctdb/server/ctdb_recoverd.c
+++ b/ctdb/server/ctdb_recoverd.c
@@ -2637,7 +2637,7 @@ static void main_loop(struct ctdb_context *ctdb, struct ctdb_recoverd *rec,
 		DEBUG(DEBUG_ERR, (__location__ " Failed to read debuglevel from parent\n"));
 		return;
 	}
-	DEBUGLEVEL = debug_level;
+	debuglevel_set(debug_level);
 
 	/* get relevant tunables */
 	ret = ctdb_ctrl_get_all_tunables(ctdb, CONTROL_TIMEOUT(), CTDB_CURRENT_NODE, &ctdb->tunable);
diff --git a/ctdb/tests/src/ctdb_takeover_tests.c b/ctdb/tests/src/ctdb_takeover_tests.c
index e9958ce205a..cc6b4416dd9 100644
--- a/ctdb/tests/src/ctdb_takeover_tests.c
+++ b/ctdb/tests/src/ctdb_takeover_tests.c
@@ -257,7 +257,7 @@ int main(int argc, const char *argv[])
 	if (! debug_level_parse(debuglevelstr, &loglevel)) {
                 loglevel = DEBUG_DEBUG;
         }
-	DEBUGLEVEL = loglevel;
+	debuglevel_set(loglevel);
 
 	if (argc < 2) {
 		usage();
diff --git a/ctdb/tests/src/dummy_client.c b/ctdb/tests/src/dummy_client.c
index 22ba40f6e3b..13e069180a3 100644
--- a/ctdb/tests/src/dummy_client.c
+++ b/ctdb/tests/src/dummy_client.c
@@ -104,7 +104,7 @@ int main(int argc, const char *argv[])
 	}
 
 	setup_logging("dummy_client", DEBUG_STDERR);
-	DEBUGLEVEL = log_level;
+	debuglevel_set(log_level);
 
 	if (options.sockpath == NULL) {
 		options.sockpath = path_socket(mem_ctx, "ctdbd");
diff --git a/ctdb/tests/src/test_options.c b/ctdb/tests/src/test_options.c
index cfce51aeeb6..ba9c4961771 100644
--- a/ctdb/tests/src/test_options.c
+++ b/ctdb/tests/src/test_options.c
@@ -98,7 +98,7 @@ static bool verify_options_basic(struct test_options *opts)
 		return false;
 	}
 
-	DEBUGLEVEL = log_level;
+	debuglevel_set(log_level);
 
 	return true;
 }
diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c
index 8fa1ce63203..f96167f9366 100644
--- a/ctdb/tools/ctdb.c
+++ b/ctdb/tools/ctdb.c
@@ -6188,6 +6188,7 @@ int main(int argc, const char *argv[])
 	int extra_argc;
 	const struct ctdb_cmd *cmd;
 	int loglevel;
+	bool ok;
 	int ret;
 
 	setlinebuf(stdout);
@@ -6246,11 +6247,11 @@ int main(int argc, const char *argv[])
 
 	/* Enable logging */
 	setup_logging("ctdb", DEBUG_STDERR);
-	if (debug_level_parse(options.debuglevelstr, &loglevel)) {
-		DEBUGLEVEL = loglevel;
-	} else {
-		DEBUGLEVEL = DEBUG_ERR;
+	ok = debug_level_parse(options.debuglevelstr, &loglevel);
+	if (!ok) {
+		loglevel = DEBUG_ERR;
 	}
+	debuglevel_set(loglevel);
 
 	signal(SIGALRM, alarm_handler);
 	alarm(options.maxruntime);
diff --git a/ctdb/tools/ctdb_killtcp.c b/ctdb/tools/ctdb_killtcp.c
index 8537a579670..fc443bd08e2 100644
--- a/ctdb/tools/ctdb_killtcp.c
+++ b/ctdb/tools/ctdb_killtcp.c
@@ -330,16 +330,17 @@ int main(int argc, char **argv)
 	struct tevent_req *req;
 	int debug_level;
 	bool status;
+	bool ok;
 	int ret;
 
 	/* Set the debug level */
 	t = getenv("CTDB_DEBUGLEVEL");
 	if (t != NULL) {
-		if (debug_level_parse(t, &debug_level)) {
-			DEBUGLEVEL = debug_level;
-		} else {
-			DEBUGLEVEL = DEBUG_ERR;
+		ok = debug_level_parse(t, &debug_level);
+		if (!ok) {
+			debug_level = DEBUG_ERR;
 		}
+		debuglevel_set(debug_level);
 	}
 
 	if (argc != 2 && argc != 4) {
diff --git a/lib/util/debug.c b/lib/util/debug.c
index 847ec1f0a0c..b5f120bb3a4 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -560,7 +560,17 @@ static const char *default_classname_table[] = {
 static int debug_class_list_initial[ARRAY_SIZE(default_classname_table)];
 
 static size_t debug_num_classes = 0;
-int     *DEBUGLEVEL_CLASS = debug_class_list_initial;
+static int    *DEBUGLEVEL_CLASS = debug_class_list_initial;
+
+int debuglevel_get_class(size_t idx)
+{
+	return DEBUGLEVEL_CLASS[idx];
+}
+
+void debuglevel_set_class(size_t idx, int level)
+{
+	DEBUGLEVEL_CLASS[idx] = level;
+}
 
 
 /* -------------------------------------------------------------------------- **
diff --git a/lib/util/debug.h b/lib/util/debug.h
index 2895d157887..e6f54a7657f 100644
--- a/lib/util/debug.h
+++ b/lib/util/debug.h
@@ -47,12 +47,6 @@ bool dbgtext( const char *, ... ) PRINTF_ATTRIBUTE(1,2);
 bool dbghdrclass( int level, int cls, const char *location, const char *func);
 bool dbghdr( int level, const char *location, const char *func);
 
-/*
- * Redefine DEBUGLEVEL because so we don't have to change every source file
- * that *unnecessarily* references it.
- */
-#define DEBUGLEVEL DEBUGLEVEL_CLASS[DBGC_ALL]
-
 /*
  * Define all new debug classes here. A class is represented by an entry in
  * the DEBUGLEVEL_CLASS array. Index zero of this arrray is equivalent to the
@@ -109,7 +103,10 @@ bool dbghdr( int level, const char *location, const char *func);
 #define DBGC_CLASS            0     /* override as shown above */
 #endif
 
-extern int  *DEBUGLEVEL_CLASS;
+#define DEBUGLEVEL debuglevel_get()
+
+#define debuglevel_get() debuglevel_get_class(DBGC_ALL)
+#define debuglevel_set(lvl) debuglevel_set_class(DBGC_ALL, (lvl))
 
 /* Debugging macros
  *
@@ -176,13 +173,16 @@ extern int  *DEBUGLEVEL_CLASS;
 #endif
 #endif
 
+int debuglevel_get_class(size_t idx);
+void debuglevel_set_class(size_t idx, int level);
+
 #define CHECK_DEBUGLVL( level ) \
   ( ((level) <= MAX_DEBUG_LEVEL) && \
-    unlikely(DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level)))
+    unlikely(debuglevel_get_class(DBGC_CLASS) >= (level)))
 
 #define CHECK_DEBUGLVLC( dbgc_class, level ) \
   ( ((level) <= MAX_DEBUG_LEVEL) && \
-    unlikely(DEBUGLEVEL_CLASS[ dbgc_class ] >= (level)))
+    unlikely(debuglevel_get_class(dbgc_class) >= (level)))
 
 #define DEBUGLVL( level ) \
   ( CHECK_DEBUGLVL(level) \
@@ -194,24 +194,24 @@ extern int  *DEBUGLEVEL_CLASS;
 
 #define DEBUG( level, body ) \
   (void)( ((level) <= MAX_DEBUG_LEVEL) && \
-	  unlikely(DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))		\
+       unlikely(debuglevel_get_class(DBGC_CLASS) >= (level))             \
        && (dbghdrclass( level, DBGC_CLASS, __location__, __FUNCTION__ )) \
        && (dbgtext body) )
 
 #define DEBUGC( dbgc_class, level, body ) \
   (void)( ((level) <= MAX_DEBUG_LEVEL) && \
-	  unlikely(DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))		\
+       unlikely(debuglevel_get_class(dbgc_class) >= (level))             \
        && (dbghdrclass( level, DBGC_CLASS, __location__, __FUNCTION__ )) \
        && (dbgtext body) )
 
 #define DEBUGADD( level, body ) \
   (void)( ((level) <= MAX_DEBUG_LEVEL) && \
-	  unlikely(DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))	\
+	  unlikely(debuglevel_get_class(DBGC_CLASS) >= (level))	\
        && (dbgtext body) )
 
 #define DEBUGADDC( dbgc_class, level, body ) \
   (void)( ((level) <= MAX_DEBUG_LEVEL) && \
-          unlikely((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))) \
+          unlikely((debuglevel_get_class(dbgc_class) >= (level))) \
        && (dbgtext body) )
 
 /* Print a separator to the debug log. */
@@ -221,7 +221,7 @@ extern int  *DEBUGLEVEL_CLASS;
 /* Prefix messages with the function name */
 #define DBG_PREFIX(level, body ) \
 	(void)( ((level) <= MAX_DEBUG_LEVEL) &&			\
-		unlikely(DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))	\
+		unlikely(debuglevel_get_class(DBGC_CLASS) >= (level))	\
 		&& (dbghdrclass(level, DBGC_CLASS, __location__, __func__ )) \
 		&& (dbgtext("%s: ", __func__))				\
 		&& (dbgtext body) )
@@ -229,7 +229,7 @@ extern int  *DEBUGLEVEL_CLASS;
 /* Prefix messages with the function name - class specific */
 #define DBGC_PREFIX(dbgc_class, level, body ) \
 	(void)( ((level) <= MAX_DEBUG_LEVEL) &&			\
-		unlikely(DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))	\
+		unlikely(debuglevel_get_class(dbgc_class) >= (level))	\
 		&& (dbghdrclass(level, dbgc_class, __location__, __func__ )) \
 		&& (dbgtext("%s: ", __func__))				\
 		&& (dbgtext body) )
diff --git a/python/pyglue.c b/python/pyglue.c
index 04efa14d051..22ac53f3c66 100644
--- a/python/pyglue.c
+++ b/python/pyglue.c
@@ -23,6 +23,7 @@
 #include "version.h"
 #include "param/pyparam.h"
 #include "lib/socket/netif.h"
+#include "lib/util/debug.h"
 
 void init_glue(void);
 static PyObject *PyExc_NTSTATUSError;
@@ -161,13 +162,13 @@ static PyObject *py_set_debug_level(PyObject *self, PyObject *args)
 	unsigned level;
 	if (!PyArg_ParseTuple(args, "I", &level))
 		return NULL;
-	(DEBUGLEVEL) = level;
+	debuglevel_set(level);
 	Py_RETURN_NONE;
 }
 
 static PyObject *py_get_debug_level(PyObject *self)
 {
-	return PyInt_FromLong(DEBUGLEVEL);
+	return PyInt_FromLong(debuglevel_get());
 }
 
 static PyObject *py_fault_setup(PyObject *self)
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c
index b4532fa4840..e52380b03f0 100644
--- a/source3/nmbd/asyncdns.c
+++ b/source3/nmbd/asyncdns.c
@@ -86,7 +86,7 @@ static void asyncdns_process(void)
 	struct query_record r;
 	unstring qname;
 
-	DEBUGLEVEL = -1;
+	debuglevel_set(-1);
 
 	while (1) {
 		NTSTATUS status;
diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c
index 7f69d7b3c8b..e71bb469eee 100644
--- a/source4/param/pyparam.c
+++ b/source4/param/pyparam.c
@@ -347,7 +347,7 @@ static PyObject *py_lp_dump_a_parameter(PyObject *self, PyObject *args)
 
 static PyObject *py_lp_log_level(PyObject *self, PyObject *unused)
 {
-	int ret = DEBUGLEVEL_CLASS[DBGC_CLASS];
+	int ret = debuglevel_get();
 	return PyInt_FromLong(ret);
 }
 
-- 
2.19.1



More information about the samba-technical mailing list