瀏覽代碼

modules/debugger: new parameter log_assign

This parameter enables logging every single assign action on the config.
Victor Seva 12 年之前
父節點
當前提交
2312e2adc6

+ 18 - 2
modules/debugger/README

@@ -35,6 +35,7 @@ Daniel-Constantin Mierla
               3.8. mod_hash_size (int)
               3.9. mod_level_mode (int)
               3.10. mod_level (str)
+              3.11. log_assign (int)
 
         4. Functions
 
@@ -61,7 +62,8 @@ Daniel-Constantin Mierla
    1.8. Set mod_hash_size parameter
    1.9. Set mod_level_mode parameter
    1.10. Set mod_level parameter
-   1.11. dbg_breakpoint usage
+   1.11. Set log_assign parameter
+   1.12. dbg_breakpoint usage
 
 Chapter 1. Admin Guide
 
@@ -85,6 +87,7 @@ Chapter 1. Admin Guide
         3.8. mod_hash_size (int)
         3.9. mod_level_mode (int)
         3.10. mod_level (str)
+        3.11. log_assign (int)
 
    4. Functions
 
@@ -150,6 +153,7 @@ Chapter 1. Admin Guide
    3.8. mod_hash_size (int)
    3.9. mod_level_mode (int)
    3.10. mod_level (str)
+   3.11. log_assign (int)
 
 3.1. cfgtrace (int)
 
@@ -275,6 +279,18 @@ modparam("debugger", "mod_level", "core=3")
 modparam("debugger", "mod_level", "tm=3")
 ...
 
+3.11. log_assign (int)
+
+   Enable or disable log assign actions on config (0 - disabled, 1 -
+   enabled).
+
+   Default value is "0".
+
+   Example 1.11. Set log_assign parameter
+...
+modparam("debugger", "log_assign", 1)
+...
+
 4. Functions
 
    4.1. dbg_breakpoint(mode)
@@ -288,7 +304,7 @@ modparam("debugger", "mod_level", "tm=3")
    Note that this version of the module does not export this anchors to
    RPC for interactive debugging (temporarily disabled).
 
-   Example 1.11. dbg_breakpoint usage
+   Example 1.12. dbg_breakpoint usage
 ...
 if($si=="10.0.0.10")
         dbg_breakpoint("1");

+ 165 - 1
modules/debugger/debugger_api.c

@@ -36,6 +36,8 @@
 #include "../../route_struct.h"
 #include "../../mem/shm_mem.h"
 #include "../../locking.h"
+#include "../../lvalue.h"
+#include "../../hashes.h"
 
 #include "debugger_act.h"
 #include "debugger_api.h"
@@ -895,7 +897,6 @@ int dbg_init_rpc(void)
 	return 0;
 }
 
-
 typedef struct _dbg_mod_level {
 	str name;
 	unsigned int hashid;
@@ -1109,6 +1110,169 @@ void dbg_enable_mod_levels(void)
 	set_module_debug_level_cb(dbg_get_mod_debug_level);
 }
 
+#define DBG_PVCACHE_SIZE 32
+
+typedef struct _dbg_pvcache {
+	pv_spec_t *spec;
+	str *pvname;
+	struct _dbg_pvcache *next;
+} dbg_pvcache_t;
+
+static dbg_pvcache_t **_dbg_pvcache = NULL;
+
+void dbg_init_pvcache()
+{
+	_dbg_pvcache = (dbg_pvcache_t**)pkg_malloc(sizeof(dbg_pvcache_t*)*DBG_PVCACHE_SIZE);
+	memset(_dbg_pvcache, 0, sizeof(dbg_pvcache_t*)*DBG_PVCACHE_SIZE);
+}
+
+int dbg_assign_add(str *name, pv_spec_t *spec)
+{
+	dbg_pvcache_t *pvn, *last, *next;
+	unsigned int pvid;
+	//unsigned i = 0;
+
+	if(name==NULL||spec==NULL)
+		return -1;
+
+	if(_dbg_pvcache==NULL)
+		return -1;
+
+	pvid = get_hash1_raw((char *)&spec, sizeof(pv_spec_t*));
+	pvn = (dbg_pvcache_t*)pkg_malloc(sizeof(dbg_pvcache_t));
+	if(pvn==0)
+	{
+		LM_ERR("no more memory\n");
+		return -1;
+	}
+	memset(pvn, 0, sizeof(dbg_pvcache_t));
+	pvn->pvname = name;
+	pvn->spec = spec;
+	next = _dbg_pvcache[pvid%DBG_PVCACHE_SIZE];
+	if(next==NULL)
+	{
+		_dbg_pvcache[pvid%DBG_PVCACHE_SIZE] = pvn;
+	}
+	else
+	{
+		while(next)
+		{
+			//i++;
+			last = next;
+			next = next->next;
+		}
+		last->next = pvn;
+	}
+	/*LM_DBG("spec[%p] pvar[%.*s] added in cache[%d][%d]\n", spec,
+		name->len, name->s, pvid%DBG_PVCACHE_SIZE, i);*/
+	return 0;
+}
+
+str *_dbg_pvcache_lookup(pv_spec_t *spec)
+{
+	dbg_pvcache_t *pvi;
+	unsigned int pvid;
+	str *name = NULL;
+	//unsigned int i = 0;
+
+	if(spec==NULL)
+		return NULL;
+
+	if(_dbg_pvcache==NULL)
+		return NULL;
+
+	pvid = get_hash1_raw((char *)&spec, sizeof(pv_spec_t*));
+	pvi = _dbg_pvcache[pvid%DBG_PVCACHE_SIZE];
+	while(pvi)
+	{
+		if(pvi->spec==spec) {
+			/*LM_DBG("spec[%p] pvar[%.*s] found in cache[%d][%d]\n", spec,
+				pvi->pvname->len, pvi->pvname->s, pvid%DBG_PVCACHE_SIZE, i);*/
+			return pvi->pvname;
+		}
+		//i++;
+		pvi = pvi->next;
+	}
+	name = pv_cache_get_name(spec);
+	if(name!=NULL)
+	{
+		/*LM_DBG("Add name[%.*s] to pvcache\n", name->len, name->s);*/
+		dbg_assign_add(name, spec);
+	}
+	return name;
+}
+
+int _dbg_log_assign_action_avp(struct sip_msg* msg, struct lvalue* lv)
+{
+	int_str avp_val;
+	avp_t* avp;
+	avp_spec_t* avp_s = &lv->lv.avps;
+	avp = search_avp_by_index(avp_s->type, avp_s->name,
+				&avp_val, avp_s->index);
+	if (likely(avp)){
+		if (avp->flags&(AVP_VAL_STR)){
+			LM_DBG("%.*s:\"%.*s\"\n", avp_s->name.s.len, avp_s->name.s.s,
+				avp_val.s.len, avp_val.s.s);
+		}else{
+			LM_DBG("%.*s:%d\n", avp_s->name.s.len, avp_s->name.s.s,
+				avp_val.n);
+		}
+	}
+	return 0;
+}
+
+int _dbg_log_assign_action_pvar(struct sip_msg* msg, struct lvalue* lv)
+{
+	pv_value_t value;
+	pv_spec_t* pvar = lv->lv.pvs;
+	str def_name = {"unknown", 7};
+	str *name = _dbg_pvcache_lookup(pvar);
+
+	if(name==NULL)
+		name = &def_name;
+	if(pv_get_spec_value(msg, pvar, &value)!=0)
+	{
+		LM_ERR("can't get value\n");
+		return -1;
+	}
+
+	if(value.flags&(PV_VAL_NULL|PV_VAL_EMPTY|PV_VAL_NONE)){
+		LM_DBG("%.*s: $null\n", name->len, name->s);
+	}else if(value.flags&(PV_VAL_INT)){
+		LM_DBG("%.*s:%d\n", name->len, name->s, value.ri);
+	}else if(value.flags&(PV_VAL_STR)){
+		LM_DBG("%.*s:\"%.*s\"\n", name->len, name->s, value.rs.len, value.rs.s);
+	}
+	return 0;
+}
+
+int dbg_log_assign(struct sip_msg* msg, struct lvalue *lv)
+{
+	if(lv==NULL)
+	{
+		LM_ERR("left value is NULL\n");
+		return -1;
+	}
+	switch(lv->type){
+		case LV_AVP:
+			return _dbg_log_assign_action_avp(msg, lv);
+			break;
+		case LV_PVAR:
+			return _dbg_log_assign_action_pvar(msg, lv);
+			break;
+		case LV_NONE:
+			break;
+	}
+	return 0;
+}
+
+void dbg_enable_log_assign(void)
+{
+	if(_dbg_pvcache==NULL)
+		return;
+	set_log_assign_action_cb(dbg_log_assign);
+}
+
 int dbg_level_mode_fixup(void *temp_handle,
 	str *group_name, str *var_name, void **value){
 	if(_dbg_mod_table==NULL)

+ 2 - 0
modules/debugger/debugger_api.h

@@ -37,5 +37,7 @@ int dbg_init_mod_levels(int _dbg_mod_hash_size);
 int dbg_set_mod_debug_level(char *mname, int mnlen, int *mlevel);
 void dbg_enable_mod_levels(void);
 
+void dbg_init_pvcache(void);
+void dbg_enable_log_assign(void);
 #endif
 

+ 7 - 0
modules/debugger/debugger_mod.c

@@ -57,6 +57,7 @@ extern int _dbg_step_usleep;
 extern int _dbg_step_loops;
 
 static char * _dbg_cfgtrace_facility_str = 0;
+static int _dbg_log_assign = 0;
 
 static cmd_export_t cmds[]={
 	{"dbg_breakpoint", (cmd_function)w_dbg_breakpoint, 1,
@@ -70,6 +71,7 @@ static param_export_t params[]={
 	{"log_level",         INT_PARAM, &_dbg_cfgtrace_level},
 	{"log_facility",      STR_PARAM, &_dbg_cfgtrace_facility_str},
 	{"log_prefix",        STR_PARAM, &_dbg_cfgtrace_prefix},
+	{"log_assign",        INT_PARAM, &_dbg_log_assign},
 	{"step_usleep",       INT_PARAM, &_dbg_step_usleep},
 	{"step_loops",        INT_PARAM, &_dbg_step_loops},
 	{"mod_hash_size",     INT_PARAM, &default_dbg_cfg.mod_hash_size},
@@ -133,6 +135,10 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if(_dbg_log_assign>0)
+	{
+		dbg_init_pvcache();
+	}
 	return dbg_init_bp_list();
 }
 
@@ -144,6 +150,7 @@ static int child_init(int rank)
 	LM_DBG("rank is (%d)\n", rank);
 	if (rank==PROC_INIT) {
 		dbg_enable_mod_levels();
+		dbg_enable_log_assign();
 		return dbg_init_pid_list();
 	}
 	return dbg_init_mypid();

+ 22 - 1
modules/debugger/doc/debugger_admin.xml

@@ -281,8 +281,29 @@ modparam("debugger", "mod_level", "tm=3")
 </programlisting>
 	    </example>
 	</section>
+
+	<section>
+	    <title><varname>log_assign</varname> (int)</title>
+	    <para>
+		Enable or disable log assign actions on config (0 - disabled, 1 - enabled).
+	    </para>
+		<para>
+		<emphasis>
+		    Default value is <quote>0</quote>.
+		</emphasis>
+	    </para>
+	    <example>
+		<title>Set <varname>log_assign</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("debugger", "log_assign", 1)
+...
+</programlisting>
+	    </example>
 	</section>
-	
+
+	</section>
+
     <section>
 	<title>Functions</title>
  	<section>