Module: sip-router
Branch: master
Commit: 72f1b495c42933fea96a019e140dc6333fda2eb3
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=72f1b495c42933fea96a019e140dc6333fda2eb3

Author: Daniel-Constantin Mierla <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
Date:   Fri May 17 09:58:19 2013 +0200

debugger: option to set debug level per module

- new parameters:
        - mod_hash_size - size of internal hash table to store levels per
          module (used to compute power of two with it)
        - mod_level_mode - enable/disable per module log level
        - mod_level - specify module log level
modparam("debugger", "mod_hash_size", 5)
modparam("debugger", "mod_level_mode", 1)
modparam("debugger", "mod_level", "core=3");
modparam("debugger", "mod_level", "usrloc=3");

---

 modules/debugger/debugger_api.c |  211 +++++++++++++++++++++++++++++++++++++++
 modules/debugger/debugger_api.h |    4 +
 modules/debugger/debugger_mod.c |   52 ++++++++++-
 3 files changed, 266 insertions(+), 1 deletions(-)

diff --git a/modules/debugger/debugger_api.c b/modules/debugger/debugger_api.c
index bbf31a0..7653c95 100644
--- a/modules/debugger/debugger_api.c
+++ b/modules/debugger/debugger_api.c
@@ -35,6 +35,7 @@
 #include "../../rpc_lookup.h"
 #include "../../route_struct.h"
 #include "../../mem/shm_mem.h"
+#include "../../locking.h"
                       
 #include "debugger_act.h"
 #include "debugger_api.h"
@@ -867,3 +868,213 @@ int dbg_init_rpc(void)
        return 0;
 }
 
+
+typedef struct _dbg_mod_level {
+       str name;
+       unsigned int hashid;
+       int level;
+       struct _dbg_mod_level *next;
+} dbg_mod_level_t;
+
+typedef struct _dbg_mod_slot
+{
+       dbg_mod_level_t *first;
+       gen_lock_t lock;
+} dbg_mod_slot_t;
+
+static dbg_mod_slot_t *_dbg_mod_table = NULL;
+static unsigned int _dbg_mod_table_size = 0;
+
+/**
+ *
+ */
+int dbg_init_mod_levels(int dbg_mod_level, int dbg_mod_hash_size)
+{
+       int i;
+       if(dbg_mod_level==0 || dbg_mod_hash_size<=0)
+               return 0;
+       if(_dbg_mod_table!=NULL)
+               return 0;
+       _dbg_mod_table_size = 1 << dbg_mod_hash_size;
+       _dbg_mod_table = 
(dbg_mod_slot_t*)shm_malloc(_dbg_mod_table_size*sizeof(dbg_mod_slot_t));
+       if(_dbg_mod_table==NULL)
+       {
+               LM_ERR("no more shm.\n");
+               return -1;
+       }
+       memset(_dbg_mod_table, 0, _dbg_mod_table_size*sizeof(dbg_mod_slot_t));
+
+       for(i=0; i<_dbg_mod_table_size; i++)
+       {
+               if(lock_init(&_dbg_mod_table[i].lock)==0)
+               {
+                       LM_ERR("cannot initalize lock[%d]\n", i);
+                       i--;
+                       while(i>=0)
+                       {
+                               lock_destroy(&_dbg_mod_table[i].lock);
+                               i--;
+                       }
+                       shm_free(_dbg_mod_table);
+                       _dbg_mod_table = NULL;
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * case insensitive hashing - clone here to avoid usage of LOG*()
+ * - s1 - str to hash
+ * - s1len - len of s1
+ * return computed hash id
+ */
+#define dbg_ch_h_inc h+=v^(v>>3)
+#define dbg_ch_icase(_c) (((_c)>='A'&&(_c)<='Z')?((_c)|0x20):(_c))
+static inline unsigned int dbg_compute_hash(char *s1, int s1len)
+{
+       char *p, *end;
+       register unsigned v;
+       register unsigned h;
+
+       h=0;
+
+       end=s1+s1len;
+       for ( p=s1 ; p<=(end-4) ; p+=4 ){
+               
v=(dbg_ch_icase(*p)<<24)+(dbg_ch_icase(p[1])<<16)+(dbg_ch_icase(p[2])<<8)
+                       + dbg_ch_icase(p[3]);
+               dbg_ch_h_inc;
+       }
+       v=0;
+       for (; p<end ; p++){ v<<=8; v+=dbg_ch_icase(*p);}
+       dbg_ch_h_inc;
+
+       h=((h)+(h>>11))+((h>>13)+(h>>23));
+       return h;
+}
+
+int dbg_set_mod_debug_level(char *mname, int mnlen, int *mlevel)
+{
+       unsigned int idx;
+       unsigned int hid;
+       dbg_mod_level_t *it;
+       dbg_mod_level_t *itp;
+       dbg_mod_level_t *itn;
+
+       if(_dbg_mod_table==NULL)
+               return -1;
+
+       hid = dbg_compute_hash(mname, mnlen);
+       idx = hid&(_dbg_mod_table_size-1);
+
+       lock_get(&_dbg_mod_table[idx].lock);
+       it = _dbg_mod_table[idx].first;
+       itp = NULL;
+       while(it!=NULL && it->hashid < hid) {
+               itp = it;
+               it = it->next;
+       }
+       while(it!=NULL && it->hashid==hid)
+       {
+               if(mnlen==it->name.len
+                               && strncmp(mname, it->name.s, mnlen)==0)
+               {
+                       /* found */
+                       if(mlevel==NULL) {
+                               /* remove */
+                               if(itp!=NULL) {
+                                       itp->next = it->next;
+                               } else {
+                                       _dbg_mod_table[idx].first = it->next;
+                               }
+                               shm_free(it);
+                       } else {
+                               /* set */
+                               it->level = *mlevel;
+                       }
+                       lock_release(&_dbg_mod_table[idx].lock);
+                       return 0;
+               }
+               itp = it;
+               it = it->next;
+       }
+       /* not found - add */
+       if(mlevel==NULL) {
+               lock_release(&_dbg_mod_table[idx].lock);
+               return 0;
+       }
+       itn = (dbg_mod_level_t*)shm_malloc(sizeof(dbg_mod_level_t) + 
(mnlen+1)*sizeof(char));
+       if(itn==NULL) {
+               LM_ERR("no more shm\n");
+               lock_release(&_dbg_mod_table[idx].lock);
+               return -1;
+       }
+       memset(itn, 0, sizeof(dbg_mod_level_t) + (mnlen+1)*sizeof(char));
+       itn->level    = *mlevel;
+       itn->hashid   = hid;
+       itn->name.s   = (char*)(itn) + sizeof(dbg_mod_level_t);
+       itn->name.len = mnlen;
+       strncpy(itn->name.s, mname, mnlen);
+       itn->name.s[itn->name.len] = '\0';
+
+       if(itp==NULL) {
+               itn->next = _dbg_mod_table[idx].first;
+               _dbg_mod_table[idx].first = itn;
+       } else {
+               itn->next = itp->next;
+               itp->next = itn;
+       }
+       lock_release(&_dbg_mod_table[idx].lock);
+       return 0;
+
+}
+
+static int _dbg_get_mod_debug_level = 0;
+int dbg_get_mod_debug_level(char *mname, int mnlen, int *mlevel)
+{
+       unsigned int idx;
+       unsigned int hid;
+       dbg_mod_level_t *it;
+       /* no LOG*() usage in this function and those executed insite it
+        * - use fprintf(stderr, ...) if need for troubleshooting
+        * - it will loop otherwise */
+       if(_dbg_mod_table==NULL)
+               return -1;
+
+       if(_dbg_get_mod_debug_level!=0)
+               return -1;
+       _dbg_get_mod_debug_level = 1;
+
+       hid = dbg_compute_hash(mname, mnlen);
+       idx = hid&(_dbg_mod_table_size-1);
+       lock_get(&_dbg_mod_table[idx].lock);
+       it = _dbg_mod_table[idx].first;
+       while(it!=NULL && it->hashid < hid)
+               it = it->next;
+       while(it!=NULL && it->hashid == hid)
+       {
+               if(mnlen==it->name.len
+                               && strncmp(mname, it->name.s, mnlen)==0)
+               {
+                       /* found */
+                       *mlevel = it->level;
+                       lock_release(&_dbg_mod_table[idx].lock);
+                       _dbg_get_mod_debug_level = 0;
+                       return 0;
+               }
+               it = it->next;
+       }
+       lock_release(&_dbg_mod_table[idx].lock);
+       _dbg_get_mod_debug_level = 0;
+       return -1;
+}
+
+/**
+ *
+ */
+void dbg_enable_mod_levels(void)
+{
+       if(_dbg_mod_table==NULL)
+               return;
+       set_module_debug_level_cb(dbg_get_mod_debug_level);
+}
diff --git a/modules/debugger/debugger_api.h b/modules/debugger/debugger_api.h
index e5a5ca2..9af8cf6 100644
--- a/modules/debugger/debugger_api.h
+++ b/modules/debugger/debugger_api.h
@@ -33,5 +33,9 @@ int dbg_init_pid_list(void);
 int dbg_init_mypid(void);
 int dbg_init_rpc(void);
 
+int dbg_init_mod_levels(int _dbg_mod_level, int _dbg_mod_hash_size);
+int dbg_set_mod_debug_level(char *mname, int mnlen, int *mlevel);
+void dbg_enable_mod_levels(void);
+
 #endif
 
diff --git a/modules/debugger/debugger_mod.c b/modules/debugger/debugger_mod.c
index 8b85afb..98d317b 100644
--- a/modules/debugger/debugger_mod.c
+++ b/modules/debugger/debugger_mod.c
@@ -44,6 +44,7 @@ static void mod_destroy(void);
 
 static int w_dbg_breakpoint(struct sip_msg* msg, char* point, char* str2);
 static int fixup_dbg_breakpoint(void** param, int param_no);
+static int dbg_mod_level_param(modparam_t type, void *val);
 
 /* parameters */
 extern int _dbg_cfgtrace;
@@ -56,6 +57,9 @@ extern int _dbg_step_loops;
 
 static char * _dbg_cfgtrace_facility_str = 0;
 
+static int _dbg_mod_hash_size = 0;
+static int _dbg_mod_level = 0;
+
 static cmd_export_t cmds[]={
        {"dbg_breakpoint", (cmd_function)w_dbg_breakpoint, 1,
                fixup_dbg_breakpoint, 0, ANY_ROUTE},
@@ -70,6 +74,9 @@ static param_export_t params[]={
        {"log_prefix",        STR_PARAM, &_dbg_cfgtrace_prefix},
        {"step_usleep",       INT_PARAM, &_dbg_step_usleep},
        {"step_loops",        INT_PARAM, &_dbg_step_loops},
+       {"mod_hash_size",     INT_PARAM, &_dbg_mod_hash_size},
+       {"mod_level_mode",    INT_PARAM, &_dbg_mod_level},
+       {"mod_level",         STR_PARAM|USE_FUNC_PARAM, 
(void*)dbg_mod_level_param},
        {0, 0, 0}
 };
 
@@ -113,6 +120,12 @@ static int mod_init(void)
                return -1;
        }
 
+       if(dbg_init_mod_levels(_dbg_mod_level, _dbg_mod_hash_size)<0)
+       {
+               LM_ERR("failed to init per module log level\n");
+               return -1;
+       }
+
        return dbg_init_bp_list();
 }
 
@@ -122,8 +135,10 @@ static int mod_init(void)
 static int child_init(int rank)
 {
        LM_DBG("rank is (%d)\n", rank);
-       if (rank==PROC_INIT)
+       if (rank==PROC_INIT) {
+               dbg_enable_mod_levels();
                return dbg_init_pid_list();
+       }
        return dbg_init_mypid();
 }
 
@@ -173,4 +188,39 @@ static int fixup_dbg_breakpoint(void** param, int param_no)
     return dbg_add_breakpoint(a, (*p=='0')?0:1);
 }
 
+static int dbg_mod_level_param(modparam_t type, void *val)
+{
+       char *p;
+       str s;
+       int l;
+       if(val==NULL)
+               return -1;
+
+       p = strchr((char*)val, '=');
+       if(p==NULL) {
+               LM_ERR("invalid parameter value: %s\n", (char*)val);
+               return -1;
+       }
+       s.s = p + 1;
+       s.len = strlen(s.s);
+
+       if(str2sint(&s, &l)<0) {
+               LM_ERR("invalid parameter - level value: %s\n", (char*)val);
+               return -1;
+       }
+       s.s = (char*)val;
+       s.len = p - s.s;
+       if(dbg_init_mod_levels(_dbg_mod_level, _dbg_mod_hash_size)<0)
+       {
+               LM_ERR("failed to init per module log level\n");
+               return -1;
+       }
+       if(dbg_set_mod_debug_level(s.s, s.len, &l)<0)
+       {
+               LM_ERR("cannot store parameter: %s\n", (char*)val);
+               return -1;
+       }
+       return 0;
+
+}
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to