[前][次][番号順一覧][スレッド一覧]

ruby-changes:62509

From: Koichi <ko1@a...>
Date: Sun, 2 Aug 2020 09:00:04 +0900 (JST)
Subject: [ruby-changes:62509] b4f58ea300 (master): support multiple filters by RUBY_DEBUG_LOG_FILTER

https://git.ruby-lang.org/ruby.git/commit/?id=b4f58ea300

From b4f58ea3008e3e86bdc931407c68c6e0497ef078 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Sun, 2 Aug 2020 04:24:47 +0900
Subject: support multiple filters by RUBY_DEBUG_LOG_FILTER

Now you can specify multiple filters for RUBY_DEBUG_LOG output
by RUBY_DEBUG_LOG_FILTER=a,b,c (in this case, logs that the
function name contains a, b or c).

diff --git a/debug.c b/debug.c
index 7241d37..1dd7eeb 100644
--- a/debug.c
+++ b/debug.c
@@ -266,14 +266,14 @@ ruby_set_debug_option(const char *str) https://github.com/ruby/ruby/blob/trunk/debug.c#L266
 
 #define MAX_DEBUG_LOG             0x1000
 #define MAX_DEBUG_LOG_MESSAGE_LEN 0x0200
-#define MAX_DEBUG_LOG_FILTER      0x0001
+#define MAX_DEBUG_LOG_FILTER      0x0010
 
 enum ruby_debug_log_mode ruby_debug_log_mode;
 
 static struct {
     char *mem;
     unsigned int cnt;
-    const char *filters[MAX_DEBUG_LOG_FILTER];
+    char filters[MAX_DEBUG_LOG_FILTER][MAX_DEBUG_LOG_FILTER];
     unsigned int filters_num;
     rb_nativethread_lock_t lock;
     FILE *output;
@@ -292,6 +292,7 @@ setup_debug_log(void) https://github.com/ruby/ruby/blob/trunk/debug.c#L292
     const char *log_config = getenv("RUBY_DEBUG_LOG");
     if (log_config) {
         fprintf(stderr, "RUBY_DEBUG_LOG=%s\n", log_config);
+        unsetenv("RUBY_DEBUG_LOG");
         if  (strcmp(log_config, "mem")    == 0) {
             debug_log.mem = (char *)malloc(MAX_DEBUG_LOG * MAX_DEBUG_LOG_MESSAGE_LEN);
             if (debug_log.mem == NULL) {
@@ -317,12 +318,49 @@ setup_debug_log(void) https://github.com/ruby/ruby/blob/trunk/debug.c#L318
 
     // check RUBY_DEBUG_LOG_FILTER
     const char *filter_config = getenv("RUBY_DEBUG_LOG_FILTER");
-    if (filter_config) {
-        fprintf(stderr, "RUBY_DEBUG_LOG_FILTER=%s\n", filter_config);
+    if (filter_config && strlen(filter_config) > 0) {
+        unsigned int i;
+        for (i=0; i<MAX_DEBUG_LOG_FILTER; i++) {
+            const char *p;
+            if ((p = strchr(filter_config, ',')) == NULL) {
+                if (strlen(filter_config) >= MAX_DEBUG_LOG_FILTER) {
+                    fprintf(stderr, "too long: %s (max:%d)\n", filter_config, MAX_DEBUG_LOG_FILTER);
+                    exit(1);
+                }
+                strncpy(debug_log.filters[i], filter_config, MAX_DEBUG_LOG_FILTER - 1);
+                i++;
+                break;
+            }
+            else {
+                size_t n = p - filter_config;
+                if (n >= MAX_DEBUG_LOG_FILTER) {
+                    fprintf(stderr, "too long: %s (max:%d)\n", filter_config, MAX_DEBUG_LOG_FILTER);
+                    exit(1);
+                }
+                strncpy(debug_log.filters[i], filter_config, n);
+                filter_config = p+1;
+            }
+        }
+        debug_log.filters_num = i;
+        for (i=0; i<debug_log.filters_num; i++) {
+            fprintf(stderr, "RUBY_DEBUG_LOG_FILTER[%d]=%s\n", i, debug_log.filters[i]);
+        }
+    }
+}
 
-        // TODO: multiple filters
-        debug_log.filters[0] = filter_config;
-        debug_log.filters_num = 1;
+bool
+ruby_debug_log_filter(const char *func_name)
+{
+    if (debug_log.filters_num > 0) {
+        for (unsigned int i = 0; i<debug_log.filters_num; i++) {
+            if (strstr(func_name, debug_log.filters[i]) != NULL) {
+                return true;
+            }
+        }
+        return false;
+    }
+    else {
+        return true;
     }
 }
 
@@ -346,15 +384,6 @@ ruby_debug_log(const char *file, int line, const char *func_name, const char *fm https://github.com/ruby/ruby/blob/trunk/debug.c#L384
 
     // message title
     if (func_name && len < MAX_DEBUG_LOG_MESSAGE_LEN) {
-        // filter on func_name
-        if (debug_log.filters_num > 0) {
-            int hit = 0;
-            for (unsigned int i = 0; i<debug_log.filters_num; i++) {
-                if (strstr(func_name, debug_log.filters[i]) != NULL) hit++;
-            }
-            if (hit != 0) return;
-        }
-
         r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "%s\t", func_name);
         if (r < 0) rb_bug("ruby_debug_log returns %d\n", r);
         len += r;
diff --git a/vm_debug.h b/vm_debug.h
index 9b4fb3d..a3631c0 100644
--- a/vm_debug.h
+++ b/vm_debug.h
@@ -89,14 +89,24 @@ extern enum ruby_debug_log_mode { https://github.com/ruby/ruby/blob/trunk/vm_debug.h#L89
 
 void ruby_debug_log(const char *file, int line, const char *func_name, const char *fmt, ...);
 void ruby_debug_log_print(unsigned int n);
+bool ruby_debug_log_filter(const char *func_name);
 
 // convenient macro to log even if the USE_RUBY_DEBUG_LOG macro is not specified.
 // You can use this macro for temporary usage (you should not commit it).
 #define _RUBY_DEBUG_LOG(fmt, ...) ruby_debug_log(__FILE__, __LINE__, __func__, fmt, __VA_ARGS__)
 
 #if USE_RUBY_DEBUG_LOG
-#define RUBY_DEBUG_LOG(fmt, ...) do { if (ruby_debug_log_mode) ruby_debug_log(__FILE__, __LINE__, __func__, fmt, __VA_ARGS__); } while (0)
-#define RUBY_DEBUG_LOG2(file, line, fmt, ...) do { if (ruby_debug_log_mode) ruby_debug_log(file, line, __func__, fmt, __VA_ARGS__); } while (0)
+
+#define RUBY_DEBUG_LOG(fmt, ...) do { \
+  if (ruby_debug_log_mode && ruby_debug_log_filter(__func__)) \
+    ruby_debug_log(__FILE__, __LINE__, __func__, fmt, __VA_ARGS__); \
+} while (0)
+
+#define RUBY_DEBUG_LOG2(file, line, fmt, ...) do { \
+  if (ruby_debug_log_mode && ruby_debug_log_filter(__func__)) \
+    ruby_debug_log(file, line, __func__, fmt, __VA_ARGS__); \
+} while (0)
+
 #else
 // do nothing
 #define RUBY_DEBUG_LOG(fmt, ...)
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]