123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869 |
- /**
- * $Id$
- *
- * Copyright (C) 2010 Daniel-Constantin Mierla (asipto.com)
- *
- * This file is part of Kamailio, a free SIP server.
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version
- *
- * This file is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include "../../dprint.h"
- #include "../../ut.h"
- #include "../../pt.h"
- #include "../../events.h"
- #include "../../pvar.h"
- #include "../../rpc.h"
- #include "../../rpc_lookup.h"
- #include "../../route_struct.h"
- #include "../../mem/shm_mem.h"
-
- #include "debugger_act.h"
- #include "debugger_api.h"
- #define DBG_CMD_SIZE 256
- #define DBG_STATE_INIT 0
- #define DBG_STATE_WAIT 1
- #define DBG_STATE_NEXT 2
- static str _dbg_state_list[] = {
- str_init("unknown"),
- str_init("init"),
- str_init("wait"),
- str_init("next"),
- {0, 0}
- };
- str *dbg_get_state_name(int t)
- {
- switch(t) {
- case DBG_STATE_INIT:
- return &_dbg_state_list[1];
- case DBG_STATE_WAIT:
- return &_dbg_state_list[2];
- case DBG_STATE_NEXT:
- return &_dbg_state_list[3];
- }
- return &_dbg_state_list[0];
- }
- #define DBG_CFGTRACE_ON (1<<0)
- #define DBG_ABKPOINT_ON (1<<1)
- #define DBG_LBKPOINT_ON (1<<2)
- static str _dbg_status_list[] = {
- str_init("cfgtrace-on"),
- str_init("cfgtrace-off"),
- str_init("abkpoint-on"),
- str_init("abkpoint-off"),
- str_init("lbkpoint-on"),
- str_init("lbkpoint-off"),
- {0, 0}
- };
- str *dbg_get_status_name(int t)
- {
- if(t&DBG_CFGTRACE_ON)
- return &_dbg_status_list[0];
- if(t&DBG_ABKPOINT_ON)
- return &_dbg_status_list[2];
- if(t&DBG_LBKPOINT_ON)
- return &_dbg_status_list[4];
- return &_dbg_state_list[0];
- }
- #define DBG_CMD_NOP 0
- #define DBG_CMD_ERR 1
- #define DBG_CMD_READ 2
- #define DBG_CMD_NEXT 3
- #define DBG_CMD_MOVE 4
- #define DBG_CMD_SHOW 5
- #define DBG_CMD_PVEVAL 6
- #define DBG_CMD_PVLOG 7
- static str _dbg_cmd_list[] = {
- str_init("nop"),
- str_init("err"),
- str_init("read"),
- str_init("next"),
- str_init("move"),
- str_init("show"),
- str_init("pveval"),
- str_init("pvlog"),
- {0, 0}
- };
- str *dbg_get_cmd_name(int t)
- {
- switch(t) {
- case DBG_CMD_NOP:
- return &_dbg_cmd_list[0];
- case DBG_CMD_ERR:
- return &_dbg_cmd_list[1];
- case DBG_CMD_READ:
- return &_dbg_cmd_list[2];
- case DBG_CMD_NEXT:
- return &_dbg_cmd_list[3];
- case DBG_CMD_MOVE:
- return &_dbg_cmd_list[4];
- case DBG_CMD_SHOW:
- return &_dbg_cmd_list[5];
- case DBG_CMD_PVEVAL:
- return &_dbg_cmd_list[6];
- case DBG_CMD_PVLOG:
- return &_dbg_cmd_list[7];
- }
- return &_dbg_state_list[0];
- }
- /**
- *
- */
- int _dbg_cfgtrace = 0;
- /**
- *
- */
- int _dbg_breakpoint = 0;
- /**
- *
- */
- int _dbg_cfgtrace_level = L_ERR;
- /**
- *
- */
- int _dbg_cfgtrace_facility = DEFAULT_FACILITY;
- /**
- *
- */
- char *_dbg_cfgtrace_prefix = "*** cfgtrace:";
- /**
- *
- */
- int _dbg_step_usleep = 100000;
- /**
- *
- */
- int _dbg_step_loops = 200;
- /**
- *
- */
- typedef struct _dbg_cmd
- {
- unsigned int pid;
- unsigned int cmd;
- char buf[DBG_CMD_SIZE];
- } dbg_cmd_t;
- /**
- *
- */
- typedef struct _dbg_pid
- {
- unsigned int pid;
- unsigned int set;
- unsigned int state;
- dbg_cmd_t in;
- dbg_cmd_t out;
- } dbg_pid_t;
- /**
- *
- */
- static dbg_pid_t *_dbg_pid_list = NULL;
- /**
- *
- */
- static int _dbg_pid_no = 0;
- /**
- *
- */
- typedef struct _dbg_bp
- {
- str cfile;
- int cline;
- int set;
- struct _dbg_bp *next;
- } dbg_bp_t;
- /**
- *
- */
- static dbg_bp_t *_dbg_bp_list = NULL;
- /**
- * callback executed for each cfg action
- */
- int dbg_cfg_trace(void *data)
- {
- struct action *a;
- struct sip_msg *msg;
- int loop;
- int olen;
- str pvn;
- pv_spec_t pvs;
- pv_value_t val;
- void **srevp;
- str *an;
- srevp = (void**)data;
- a = (struct action *)srevp[0];
- msg = (struct sip_msg *)srevp[1];
- if(a==NULL || msg==NULL || _dbg_pid_list==NULL)
- return 0;
- an = dbg_get_action_name(a);
- if(_dbg_pid_list[process_no].set&DBG_CFGTRACE_ON)
- {
- if(is_printable(_dbg_cfgtrace_level))
- {
- LOG_(_dbg_cfgtrace_facility, _dbg_cfgtrace_level,
- _dbg_cfgtrace_prefix,
- " c=[%s] l=%d a=%d n=%.*s\n",
- ZSW(a->cfile), a->cline, a->type, an->len, ZSW(an->s)
- );
- }
- }
- if(!(_dbg_pid_list[process_no].set&DBG_ABKPOINT_ON))
- {
- /* no breakpoints to be considered */
- return 0;
- }
- if(_dbg_pid_list[process_no].state==DBG_STATE_INIT)
- {
- LOG(_dbg_cfgtrace_level,
- "breakpoint hit: p=[%u] c=[%s] l=%d a=%d n=%.*s\n",
- _dbg_pid_list[process_no].pid,
- ZSW(a->cfile), a->cline, a->type, an->len, ZSW(an->s)
- );
- _dbg_pid_list[process_no].in.cmd = DBG_CMD_NOP;
- _dbg_pid_list[process_no].state = DBG_STATE_WAIT;
- }
- loop = 1;
- while(loop)
- {
- switch(_dbg_pid_list[process_no].in.cmd)
- {
- case DBG_CMD_NOP:
- sleep_us(_dbg_step_usleep);
- break;
- case DBG_CMD_MOVE:
- loop = 0;
- _dbg_pid_list[process_no].state=DBG_STATE_INIT;
- _dbg_pid_list[process_no].in.cmd = DBG_CMD_NOP;
- _dbg_pid_list[process_no].in.pid = 0;
- break;
- case DBG_CMD_NEXT:
- loop = 0;
- if(_dbg_pid_list[process_no].state==DBG_STATE_WAIT)
- _dbg_pid_list[process_no].state=DBG_STATE_NEXT;
- _dbg_pid_list[process_no].in.cmd = DBG_CMD_NOP;
- olen = snprintf(_dbg_pid_list[process_no].out.buf,
- DBG_CMD_SIZE,
- "exec [%s:%d] a=%d n=%.*s",
- ZSW(a->cfile), a->cline, a->type, an->len, ZSW(an->s));
- if(olen<0)
- {
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_ERR;
- break;
- }
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_READ;
- break;
- case DBG_CMD_PVEVAL:
- case DBG_CMD_PVLOG:
- loop = _dbg_pid_list[process_no].in.cmd;
- _dbg_pid_list[process_no].in.cmd = DBG_CMD_NOP;
- pvn.s = _dbg_pid_list[process_no].in.buf;
- pvn.len = strlen(pvn.s);
- if(pvn.len<=0)
- {
- LM_ERR("no pv to eval\n");
- break;
- }
- LM_DBG("pv to eval: %s\n", pvn.s);
- if(pv_parse_spec(&pvn, &pvs)<0)
- {
- LM_ERR("unable to parse pv [%s]\n", pvn.s);
- break;
- }
- memset(&val, 0, sizeof(pv_value_t));
- if(pv_get_spec_value(msg, &pvs, &val) != 0)
- {
- LM_ERR("unable to get pv value for [%s]\n", pvn.s);
- break;
- }
- if(val.flags&PV_VAL_NULL)
- {
- if(loop==DBG_CMD_PVEVAL)
- {
- olen = snprintf(_dbg_pid_list[process_no].out.buf,
- DBG_CMD_SIZE,
- "%s : t=null",
- pvn.s);
- if(olen<0)
- {
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_ERR;
- break;
- }
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_READ;
- } else {
- LOG(_dbg_cfgtrace_level,
- "breakpoint eval: %s : t=null\n",
- pvn.s
- );
- }
- break;
- }
- if(val.flags&PV_TYPE_INT)
- {
- if(loop==DBG_CMD_PVEVAL)
- {
- olen = snprintf(_dbg_pid_list[process_no].out.buf,
- DBG_CMD_SIZE,
- "%s : t=int v=%d",
- pvn.s, val.ri);
- if(olen<0)
- {
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_ERR;
- break;
- }
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_READ;
- } else {
- LOG(_dbg_cfgtrace_level,
- "breakpoint eval: %s : t=int v=%d\n",
- pvn.s, val.ri
- );
- }
- break;
- }
-
- if(loop==DBG_CMD_PVEVAL)
- {
- olen = snprintf(_dbg_pid_list[process_no].out.buf,
- DBG_CMD_SIZE,
- "%s : t=str v=%.*s",
- pvn.s, val.rs.len, val.rs.s);
- if(olen<0)
- {
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_ERR;
- break;
- }
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_READ;
- } else {
- LOG(_dbg_cfgtrace_level,
- "breakpoint eval: %s : t=str v=%.*s\n",
- pvn.s, val.rs.len, val.rs.s
- );
- }
- break;
- case DBG_CMD_SHOW:
- _dbg_pid_list[process_no].in.cmd = DBG_CMD_NOP;
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_NOP;
- olen = snprintf(_dbg_pid_list[process_no].out.buf,
- DBG_CMD_SIZE,
- "at bkp [%s:%d] a=%d n=%.*s",
- a->cfile, a->cline, a->type, an->len, an->s);
- if(olen<0)
- {
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_ERR;
- break;
- }
- _dbg_pid_list[process_no].out.cmd = DBG_CMD_READ;
- break;
- default:
- /* unknown command?!? - exit loop */
- _dbg_pid_list[process_no].in.cmd = DBG_CMD_NOP;
- _dbg_pid_list[process_no].state=DBG_STATE_INIT;
- loop = 0;
- }
- }
- return 0;
- }
- /**
- *
- */
- int dbg_init_bp_list(void)
- {
- if(_dbg_bp_list!=NULL)
- return -1;
- _dbg_bp_list = (dbg_bp_t*)shm_malloc(sizeof(dbg_bp_t));
- if(_dbg_bp_list==NULL)
- return -1;
- memset(_dbg_bp_list, 0, sizeof(dbg_bp_t));
- if(_dbg_breakpoint==1)
- _dbg_bp_list->set |= DBG_ABKPOINT_ON;
- if(_dbg_cfgtrace==1)
- _dbg_bp_list->set |= DBG_CFGTRACE_ON;
- sr_event_register_cb(SREV_CFG_RUN_ACTION, dbg_cfg_trace);
- return 0;
- }
- /**
- *
- */
- int dbg_add_breakpoint(struct action *a, int bpon)
- {
- int len;
- dbg_bp_t *nbp = NULL;
- if(_dbg_bp_list==NULL)
- return -1;
- len = strlen(a->cfile);
- len += sizeof(dbg_bp_t) + 1;
- nbp = (dbg_bp_t*)shm_malloc(len);
- if(nbp==NULL)
- return -1;
- memset(nbp, 0, len);
- nbp->set |= (bpon)?DBG_ABKPOINT_ON:0;
- nbp->cline = a->cline;
- nbp->cfile.s = (char*)nbp + sizeof(dbg_bp_t);
- strcpy(nbp->cfile.s, a->cfile);
- nbp->cfile.len = strlen(nbp->cfile.s);
- nbp->next = _dbg_bp_list->next;
- _dbg_bp_list->next = nbp;
- return 0;
- }
- /**
- *
- */
- int dbg_init_pid_list(void)
- {
- _dbg_pid_no = get_max_procs();
- if(_dbg_pid_no<=0)
- return -1;
- if(_dbg_pid_list!=NULL)
- return -1;
- _dbg_pid_list = (dbg_pid_t*)shm_malloc(_dbg_pid_no*sizeof(dbg_pid_t));
- if(_dbg_pid_list==NULL)
- return -1;
- memset(_dbg_pid_list, 0, _dbg_pid_no*sizeof(dbg_pid_t));
- return 0;
- }
- /**
- *
- */
- int dbg_init_mypid(void)
- {
- if(_dbg_pid_list==NULL)
- return -1;
- if(process_no>=_dbg_pid_no)
- return -1;
- _dbg_pid_list[process_no].pid = (unsigned int)my_pid();
- if(_dbg_breakpoint==1)
- _dbg_pid_list[process_no].set |= DBG_ABKPOINT_ON;
- if(_dbg_cfgtrace==1)
- _dbg_pid_list[process_no].set |= DBG_CFGTRACE_ON;
- return 0;
- }
- /**
- *
- */
- int dbg_get_pid_index(unsigned int pid)
- {
- int i;
- for(i=0; i<_dbg_pid_no; i++)
- {
- if(_dbg_pid_list[i].pid == pid)
- return i;
- }
- return -1;
- }
- /**
- *
- */
- static const char* dbg_rpc_bp_doc[2] = {
- "Breakpoint command",
- 0
- };
- /**
- *
- */
- static void dbg_rpc_bp(rpc_t* rpc, void* ctx)
- {
- int i;
- int limit;
- int lpid;
- str cmd;
- str val;
- int loop;
- if(_dbg_pid_list==NULL)
- {
- rpc->fault(ctx, 500, "Not initialized");
- return;
- }
- if (rpc->scan(ctx, "S", &cmd) < 1)
- {
- rpc->fault(ctx, 500, "Config breakpoint command missing");
- return;
- }
- i = 0;
- limit = _dbg_pid_no;
- if (rpc->scan(ctx, "*d", &lpid) == 1)
- {
- i = dbg_get_pid_index((unsigned int)lpid);
- if(i<0)
- {
- rpc->fault(ctx, 500, "No such pid");
- return;
- }
- limit = i + 1;
- } else {
- lpid = -1;
- }
- if(cmd.len==2 && strncmp(cmd.s, "on", 2)==0)
- {
- for(; i<limit; i++)
- {
- _dbg_pid_list[i].set |= DBG_ABKPOINT_ON;
- _dbg_pid_list[i].state=DBG_STATE_INIT;
- }
- } else if(cmd.len==3 && strncmp(cmd.s, "off", 3)==0) {
- for(; i<limit; i++)
- {
- _dbg_pid_list[i].set &= ~DBG_ABKPOINT_ON;
- _dbg_pid_list[i].state=DBG_STATE_INIT;
- }
- } else if(cmd.len==7 && strncmp(cmd.s, "release", 7)==0) {
- for(; i<limit; i++)
- {
- if(_dbg_pid_list[i].state!=DBG_STATE_WAIT)
- {
- _dbg_pid_list[i].set &= ~DBG_ABKPOINT_ON;
- _dbg_pid_list[i].state=DBG_STATE_INIT;
- }
- }
- } else if(cmd.len==4 && strncmp(cmd.s, "keep", 4)==0) {
- if(lpid==-1)
- {
- rpc->fault(ctx, 500, "Missing pid parameter");
- return;
- }
- for(loop=0; loop<_dbg_pid_no; loop++)
- {
- if(i!=loop)
- {
- _dbg_pid_list[loop].set &= ~DBG_ABKPOINT_ON;
- if(_dbg_pid_list[loop].state!=DBG_STATE_INIT)
- {
- _dbg_pid_list[loop].in.pid = my_pid();
- _dbg_pid_list[loop].in.cmd = DBG_CMD_MOVE;
- }
- }
- }
- } else if(cmd.len==4 && strncmp(cmd.s, "move", 4)==0) {
- if(lpid==-1)
- {
- rpc->fault(ctx, 500, "Missing pid parameter");
- return;
- }
- for(; i<limit; i++)
- {
- if(_dbg_pid_list[i].state!=DBG_STATE_INIT)
- {
- _dbg_pid_list[i].set &= ~DBG_ABKPOINT_ON;
- _dbg_pid_list[i].in.pid = my_pid();
- _dbg_pid_list[i].in.cmd = DBG_CMD_MOVE;
- }
- }
- } else if(cmd.len==4 && strncmp(cmd.s, "next", 4)==0) {
- if(lpid==-1)
- {
- rpc->fault(ctx, 500, "Missing pid parameter");
- return;
- }
- _dbg_pid_list[i].in.pid = my_pid();
- _dbg_pid_list[i].in.cmd = DBG_CMD_NEXT;
- for(loop=0; loop<_dbg_step_loops; loop++)
- {
- sleep_us(_dbg_step_usleep);
- if(_dbg_pid_list[i].out.cmd == DBG_CMD_READ)
- {
- rpc->add(ctx, "s", _dbg_pid_list[i].out.buf);
- _dbg_pid_list[i].out.cmd = DBG_CMD_NOP;
- return;
- } else if(_dbg_pid_list[i].out.cmd == DBG_CMD_ERR) {
- rpc->add(ctx, "s", "cmd execution error");
- _dbg_pid_list[i].out.cmd = DBG_CMD_NOP;
- return;
- }
- }
- /* nothing to read ... err?!? */
- } else if(cmd.len==4 && strncmp(cmd.s, "show", 4)==0) {
- if(lpid==-1)
- {
- rpc->fault(ctx, 500, "Missing pid parameter");
- return;
- }
- _dbg_pid_list[i].in.pid = my_pid();
- _dbg_pid_list[i].in.cmd = DBG_CMD_SHOW;
- for(loop=0; loop<_dbg_step_loops; loop++)
- {
- sleep_us(_dbg_step_usleep);
- if(_dbg_pid_list[i].out.cmd == DBG_CMD_READ)
- {
- rpc->add(ctx, "s", _dbg_pid_list[i].out.buf);
- _dbg_pid_list[i].out.cmd = DBG_CMD_NOP;
- return;
- } else if(_dbg_pid_list[i].out.cmd == DBG_CMD_ERR) {
- rpc->add(ctx, "s", "cmd execution error");
- _dbg_pid_list[i].out.cmd = DBG_CMD_NOP;
- return;
- }
- }
- /* nothing to read ... err?!? */
- } else if(cmd.len==4 && strncmp(cmd.s, "eval", 4)==0) {
- if(lpid==-1)
- {
- rpc->fault(ctx, 500, "Missing pid parameter");
- return;
- }
- if (rpc->scan(ctx, "S", &val) < 1)
- {
- rpc->fault(ctx, 500, "pv param missing");
- return;
- }
- if (val.len < 2 || val.len>=DBG_CMD_SIZE)
- {
- rpc->fault(ctx, 500, "invalid pv param");
- return;
- }
- strncpy(_dbg_pid_list[i].in.buf, val.s, val.len);
- _dbg_pid_list[i].in.buf[val.len] = '\0';
- _dbg_pid_list[i].in.pid = my_pid();
- _dbg_pid_list[i].in.cmd = DBG_CMD_PVEVAL;
- for(loop=0; loop<_dbg_step_loops; loop++)
- {
- sleep_us(_dbg_step_usleep);
- if(_dbg_pid_list[i].out.cmd == DBG_CMD_READ)
- {
- rpc->add(ctx, "s", _dbg_pid_list[i].out.buf);
- _dbg_pid_list[i].out.cmd = DBG_CMD_NOP;
- return;
- } else if(_dbg_pid_list[i].out.cmd == DBG_CMD_ERR) {
- rpc->add(ctx, "s", "cmd execution error");
- _dbg_pid_list[i].out.cmd = DBG_CMD_NOP;
- return;
- }
- }
- /* nothing to read ... err?!? */
- } else if(cmd.len==3 && strncmp(cmd.s, "log", 3)==0) {
- if(lpid==-1)
- {
- rpc->fault(ctx, 500, "Missing pid parameter");
- return;
- }
- if (rpc->scan(ctx, "S", &val) < 1)
- {
- rpc->fault(ctx, 500, "pv param missing");
- return;
- }
- if (val.len < 2 || val.len>=DBG_CMD_SIZE)
- {
- rpc->fault(ctx, 500, "invalid pv param");
- return;
- }
- strncpy(_dbg_pid_list[i].in.buf, val.s, val.len);
- _dbg_pid_list[i].in.buf[val.len] = '\0';
- _dbg_pid_list[i].in.pid = my_pid();
- _dbg_pid_list[i].in.cmd = DBG_CMD_PVLOG;
- } else {
- rpc->fault(ctx, 500, "Unknown inner command");
- }
- rpc->add(ctx, "s", "200 ok");
- }
- /**
- *
- */
- static const char* dbg_rpc_list_doc[2] = {
- "List debugging process array",
- 0
- };
- /**
- *
- */
- static void dbg_rpc_list(rpc_t* rpc, void* ctx)
- {
- int i;
- int limit;
- int lpid;
- void* th;
- if(_dbg_pid_list==NULL)
- {
- rpc->fault(ctx, 500, "Not initialized");
- return;
- }
- i = 0;
- limit = _dbg_pid_no;
- if (rpc->scan(ctx, "*d", &lpid) == 1)
- {
- i = dbg_get_pid_index((unsigned int)lpid);
- if(i<0)
- {
- rpc->fault(ctx, 500, "No such pid");
- return;
- }
- limit = i + 1;
- }
- for(; i<limit; i++)
- {
- /* add entry node */
- if (rpc->add(ctx, "{", &th) < 0)
- {
- rpc->fault(ctx, 500, "Internal error creating rpc");
- return;
- }
- if(rpc->struct_add(th, "dddddd",
- "entry", i,
- "pid", _dbg_pid_list[i].pid,
- "set", _dbg_pid_list[i].set,
- "state", _dbg_pid_list[i].state,
- "in.pid", _dbg_pid_list[i].in.pid,
- "in.cmd", _dbg_pid_list[i].in.cmd
- )<0)
- {
- rpc->fault(ctx, 500, "Internal error creating rpc");
- return;
- }
- }
- }
- /**
- *
- */
- static const char* dbg_rpc_trace_doc[2] = {
- "Config trace command",
- 0
- };
- /**
- *
- */
- static void dbg_rpc_trace(rpc_t* rpc, void* ctx)
- {
- int i;
- int limit;
- int lpid;
- str cmd;
- if(_dbg_pid_list==NULL)
- {
- rpc->fault(ctx, 500, "Not initialized");
- return;
- }
- if (rpc->scan(ctx, "S", &cmd) < 1)
- {
- rpc->fault(ctx, 500, "Config trace command missing");
- return;
- }
- i = 0;
- limit = _dbg_pid_no;
- if (rpc->scan(ctx, "*d", &lpid) == 1)
- {
- i = dbg_get_pid_index((unsigned int)lpid);
- if(i<0)
- {
- rpc->fault(ctx, 500, "No such pid");
- return;
- }
- limit = i + 1;
- }
- if(cmd.len!=2 && cmd.len!=3)
- {
- rpc->fault(ctx, 500, "Unknown trace command");
- return;
- }
- if(cmd.len==2)
- {
- if(strncmp(cmd.s, "on", 2)!=0)
- {
- rpc->fault(ctx, 500, "Unknown trace command");
- return;
- }
- } else {
- if(strncmp(cmd.s, "off", 3)!=0)
- {
- rpc->fault(ctx, 500, "Unknown trace command");
- return;
- }
- }
- for(; i<limit; i++)
- {
- if(cmd.len==2)
- {
- _dbg_pid_list[i].set |= DBG_CFGTRACE_ON;
- } else {
- _dbg_pid_list[i].set &= ~DBG_CFGTRACE_ON;
- }
- }
- rpc->add(ctx, "s", "200 ok");
- }
- /**
- *
- */
- rpc_export_t dbg_rpc[] = {
- {"dbg.bp", dbg_rpc_bp, dbg_rpc_bp_doc, 0},
- {"dbg.ls", dbg_rpc_list, dbg_rpc_list_doc, 0},
- {"dbg.trace", dbg_rpc_trace, dbg_rpc_trace_doc, 0},
- {0, 0, 0, 0}
- };
- /**
- *
- */
- int dbg_init_rpc(void)
- {
- if (rpc_register_array(dbg_rpc)!=0)
- {
- LM_ERR("failed to register RPC commands\n");
- return -1;
- }
- return 0;
- }
|