0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <ndrx_config.h>
0039 #include <stdio.h>
0040 #include <stdlib.h>
0041 #include <time.h>
0042 #include <fcntl.h>
0043
0044 #include <unistd.h>
0045 #include <stdarg.h>
0046 #include <ctype.h>
0047 #include <memory.h>
0048 #include <errno.h>
0049 #include <signal.h>
0050 #include <limits.h>
0051 #include <pthread.h>
0052 #include <string.h>
0053
0054 #include <sys/time.h> /* purely for dbg_timer() */
0055 #include <sys/stat.h>
0056 #include <ndrstandard.h>
0057 #include <ndebug.h>
0058 #include <nstdutil.h>
0059 #include <limits.h>
0060 #include <sys_unix.h>
0061 #include <cconfig.h>
0062 #include <nstd_int.h>
0063 #include "nstd_tls.h"
0064 #include "userlog.h"
0065 #include "utlist.h"
0066 #include <expluginbase.h>
0067 #include <sys_test.h>
0068 #include <lcfint.h>
0069 #include <exregex.h>
0070
0071
0072
0073 #define BUFFER_CONTROL(dbg_p)\
0074 dbg_p->lines_written++;\
0075 if (dbg_p->lines_written >= dbg_p->buf_lines)\
0076 {\
0077 dbg_p->lines_written = 0;\
0078 fflush( ((ndrx_debug_file_sink_t*)dbg_p->dbg_f_ptr)->fp);\
0079 }
0080
0081 #define BUFFERED_PRINT_LINE(dbg_p, line)\
0082 fputs(line, ((ndrx_debug_file_sink_t*)dbg_p->dbg_f_ptr)->fp);\
0083 fputs("\n", ((ndrx_debug_file_sink_t*)dbg_p->dbg_f_ptr)->fp);\
0084 BUFFER_CONTROL(dbg_p)
0085
0086
0087 #define DEFAULT_BUFFER_SIZE 50000
0088
0089
0090
0091
0092 #define DEBUG_INITIALIZER(CODE, MODULE, FLAGS) \
0093 {\
0094 .level = 0,\
0095 .dbg_f_ptr = NULL,\
0096 .filename = "",\
0097 .filename_th_template="",\
0098 .pid = 0,\
0099 .buf_lines = 0,\
0100 .buffer_size = 0,\
0101 .lines_written = 0,\
0102 .module=MODULE,\
0103 .is_user=0,\
0104 .code=CODE,\
0105 .iflags="",\
0106 .is_threaded=0,\
0107 .threadnr=0,\
0108 .flags=FLAGS,\
0109 .memlog=NULL,\
0110 .hostnamecrc32=0x0,\
0111 .swait=NDRX_LOG_SWAIT_DEFAULT,\
0112 .version=0\
0113 }
0114
0115
0116
0117
0118
0119
0120
0121 typedef struct
0122 {
0123 char *binname;
0124 char *dbgstr;
0125 EX_hash_handle hh;
0126
0127 } ndrx_debug_rebins_t;
0128
0129
0130 ndrx_debug_t G_ubf_debug = DEBUG_INITIALIZER(LOG_CODE_UBF, "UBF ", (LOG_FACILITY_UBF|LOG_FACILITY_PROCESS));
0131 ndrx_debug_t G_ndrx_debug = DEBUG_INITIALIZER(LOG_CODE_NDRX, "NDRX", (LOG_FACILITY_NDRX|LOG_FACILITY_PROCESS));
0132 ndrx_debug_t G_tp_debug = DEBUG_INITIALIZER(LOG_CODE_TP, "USER", (LOG_FACILITY_TP|LOG_FACILITY_PROCESS));
0133
0134 ndrx_debug_t G_stdout_debug;
0135
0136 volatile int G_ndrx_debug_first = EXTRUE;
0137 volatile unsigned M_thread_nr = 0;
0138 exprivate int __thread M_is_initlock_owner = 0;
0139 exprivate MUTEX_LOCKDECL(M_dbglock);
0140 exprivate MUTEX_LOCKDECL(M_thread_nr_lock);
0141 exprivate MUTEX_LOCKDECL(M_memlog_lock);
0142
0143
0144 exprivate ndrx_debug_rebins_t *M_rebins = NULL;
0145
0146
0147
0148
0149
0150 expublic void ndrx_init_fail_banner(void)
0151 {
0152
0153 fprintf(stderr, "********************************************************************************\n");
0154 fprintf(stderr, "** CONFIGURATION ERROR ! **\n");
0155 fprintf(stderr, "** ... now worry **\n");
0156 fprintf(stderr, "** **\n");
0157 fprintf(stderr, "** Enduro/X Application server is not in proper environment or not configured **\n");
0158 fprintf(stderr, "** **\n");
0159 fprintf(stderr, "** Possible causes: **\n");
0160 fprintf(stderr, "** - Classical environment variables are not loaded (see ex_env(5) man page) **\n");
0161 fprintf(stderr, "** - Or Common-Config NDRX_CCONFIG env variable is not set **\n");
0162 fprintf(stderr, "** See \"Getting Started Tutorial\" in order to get system up-and-running **\n");
0163 fprintf(stderr, "** More info can be found here http://www.endurox.org/dokuwiki **\n");
0164 fprintf(stderr, "** **\n");
0165 fprintf(stderr, "** Process is now terminating with failure **\n");
0166 fprintf(stderr, "********************************************************************************\n");
0167 exit(EXFAIL);
0168 }
0169
0170
0171
0172
0173
0174 exprivate void ndrx_dbg_reply_memlog(ndrx_debug_t *dbg)
0175 {
0176 ndrx_memlogger_t *line, *tmp;
0177
0178
0179
0180
0181 DL_FOREACH_SAFE(dbg->memlog, line, tmp)
0182 {
0183
0184 if (line->level <= dbg->level)
0185 {
0186 BUFFERED_PRINT_LINE(dbg, line->line)
0187 }
0188
0189 DL_DELETE(dbg->memlog, line);
0190 NDRX_FREE(line);
0191 }
0192 }
0193
0194
0195
0196
0197 expublic void ndrx_dbg_reply_memlog_all(void)
0198 {
0199
0200
0201 NDRX_DBG_INIT_ENTRY;
0202 MUTEX_LOCK_V(M_memlog_lock);
0203
0204 if (NULL!=G_ubf_debug.memlog)
0205 {
0206 ndrx_dbg_reply_memlog(&G_ubf_debug);
0207 }
0208
0209 if (NULL!=G_ndrx_debug.memlog)
0210 {
0211 ndrx_dbg_reply_memlog(&G_ndrx_debug);
0212 }
0213
0214 if (NULL!=G_tp_debug.memlog)
0215 {
0216 ndrx_dbg_reply_memlog(&G_tp_debug);
0217 }
0218 MUTEX_UNLOCK_V(M_memlog_lock);
0219 }
0220
0221
0222
0223
0224
0225 expublic int ndrx_dbg_intlock_isset(void)
0226 {
0227 return M_is_initlock_owner;
0228 }
0229
0230
0231
0232
0233 expublic void ndrx_dbg_intlock_set(void)
0234 {
0235 M_is_initlock_owner++;
0236 }
0237
0238
0239
0240
0241
0242 expublic void ndrx_dbg_intlock_unset(int *do_reply)
0243 {
0244 M_is_initlock_owner--;
0245
0246 if (M_is_initlock_owner < 0)
0247 {
0248 M_is_initlock_owner = 0;
0249 }
0250
0251
0252
0253
0254
0255
0256
0257 if (0==M_is_initlock_owner)
0258 {
0259 *do_reply=EXTRUE;
0260 }
0261 }
0262
0263
0264
0265
0266
0267 expublic void ndrx_dbg_setthread(long threadnr)
0268 {
0269 NSTD_TLS_ENTRY;
0270 G_nstd_tls->M_threadnr = threadnr;
0271 }
0272
0273
0274
0275
0276 expublic void ndrx_dbg_lock(void)
0277 {
0278 MUTEX_LOCK_V(M_dbglock);
0279 }
0280
0281
0282
0283
0284 expublic void ndrx_dbg_unlock(void)
0285 {
0286 MUTEX_UNLOCK_V(M_dbglock);
0287 }
0288
0289
0290
0291
0292 expublic void ndrx_dbg_pid_update(void)
0293 {
0294 G_tp_debug.pid = G_ubf_debug.pid = G_ndrx_debug.pid = G_stdout_debug.pid = getpid();
0295 }
0296
0297
0298
0299
0300
0301
0302
0303 exprivate ndrx_debug_t * get_debug_ptr(ndrx_debug_t *dbg_ptr)
0304 {
0305 static __thread int recursive = EXFALSE;
0306 long flags = 0;
0307 char new_file[PATH_MAX];
0308
0309 if (NULL!=G_nstd_tls && !recursive)
0310 {
0311 if ( (LOG_THREADED_TEMPL & dbg_ptr->is_threaded) &&
0312 ((
0313 ((dbg_ptr->flags & LOG_FACILITY_NDRX)
0314
0315 && (flags = LOG_FACILITY_NDRX_THREAD)
0316 && NULL==G_nstd_tls->threadlog_ndrx.dbg_f_ptr ) ||
0317 ((dbg_ptr->flags & LOG_FACILITY_UBF)
0318
0319 && (flags = LOG_FACILITY_UBF_THREAD)
0320 && NULL==G_nstd_tls->threadlog_ubf.dbg_f_ptr) ||
0321 ((dbg_ptr->flags & LOG_FACILITY_TP)
0322
0323 && (flags = LOG_FACILITY_TP_THREAD)
0324 && NULL==G_nstd_tls->threadlog_tp.dbg_f_ptr )
0325 ) || (G_nstd_tls->M_threadnr_logopen != G_nstd_tls->M_threadnr)
0326 )
0327 )
0328 {
0329
0330 snprintf(new_file, sizeof(new_file), dbg_ptr->filename_th_template,
0331 (unsigned)G_nstd_tls->M_threadnr);
0332
0333
0334 G_nstd_tls->M_threadnr_logopen = G_nstd_tls->M_threadnr;
0335
0336 recursive = EXTRUE;
0337
0338 if (EXFAIL==tplogconfig(flags,
0339 dbg_ptr->level, NULL, dbg_ptr->module, new_file))
0340 {
0341 userlog("Failed to configure thread based logger for thread %d file %s: %s",
0342 G_nstd_tls->M_threadnr, new_file, Nstrerror(Nerror));
0343 }
0344
0345 recursive = EXFALSE;
0346
0347 }
0348
0349
0350
0351
0352 #define SYNC_LEVELS(X, Y) if (X.version!=Y.version)\
0353 {\
0354 X.version = Y.version;\
0355 X.level = Y.level;\
0356 }
0357
0358 if (NULL!=G_nstd_tls && !recursive)
0359 {
0360 if (dbg_ptr == &G_tp_debug && NULL!=G_nstd_tls->requestlog_tp.dbg_f_ptr)
0361 {
0362 SYNC_LEVELS(G_nstd_tls->requestlog_tp, G_tp_debug);
0363 return &G_nstd_tls->requestlog_tp;
0364 }
0365 else if (dbg_ptr == &G_tp_debug && NULL!=G_nstd_tls->threadlog_tp.dbg_f_ptr)
0366 {
0367 SYNC_LEVELS(G_nstd_tls->threadlog_tp, G_tp_debug);
0368 return &G_nstd_tls->threadlog_tp;
0369 }
0370 else if (dbg_ptr == &G_ndrx_debug && NULL!=G_nstd_tls->requestlog_ndrx.dbg_f_ptr)
0371 {
0372 SYNC_LEVELS(G_nstd_tls->requestlog_ndrx, G_ndrx_debug);
0373 return &G_nstd_tls->requestlog_ndrx;
0374 }
0375 else if (dbg_ptr == &G_ndrx_debug && NULL!=G_nstd_tls->threadlog_ndrx.dbg_f_ptr)
0376 {
0377 SYNC_LEVELS(G_nstd_tls->threadlog_ndrx, G_ndrx_debug);
0378 return &G_nstd_tls->threadlog_ndrx;
0379 }
0380 else if (dbg_ptr == &G_ubf_debug && NULL!=G_nstd_tls->requestlog_ubf.dbg_f_ptr)
0381 {
0382 SYNC_LEVELS(G_nstd_tls->requestlog_ubf, G_ubf_debug);
0383 return &G_nstd_tls->requestlog_ubf;
0384 }
0385 else if (dbg_ptr == &G_ubf_debug && NULL!=G_nstd_tls->threadlog_ubf.dbg_f_ptr)
0386 {
0387 SYNC_LEVELS(G_nstd_tls->threadlog_ubf, G_ubf_debug);
0388 return &G_nstd_tls->threadlog_ubf;
0389 }
0390 }
0391 }
0392
0393 return dbg_ptr;
0394 }
0395
0396
0397
0398
0399
0400
0401 exprivate int ndrx_dbg_rebins_load(char *binlist)
0402 {
0403 int ret = EXSUCCEED;
0404 ndrx_stdcfgstr_t* parsed2=NULL, *el2;
0405
0406
0407
0408
0409 if (EXSUCCEED!=ndrx_stdcfgstr_parse(binlist, &parsed2))
0410 {
0411 userlog("Failed to parse rebins [%s]", binlist);
0412 EXFAIL_OUT(ret);
0413 }
0414
0415 DL_FOREACH(parsed2, el2)
0416 {
0417 ndrx_debug_rebins_t *tmp=NULL;
0418
0419
0420
0421
0422 EXHASH_FIND_STR(M_rebins, el2->key, tmp);
0423 if (NULL==tmp)
0424 {
0425 ndrx_debug_rebins_t *tmp = NDRX_FPMALLOC(sizeof(ndrx_debug_rebins_t), 0);
0426
0427 if (NULL==tmp)
0428 {
0429 userlog("Failed to malloc ndrx_debug_rebins_t: %s", strerror(errno));
0430 EXFAIL_OUT(ret);
0431 }
0432
0433 memset(tmp, 0, sizeof(*tmp));
0434
0435 if (NULL==(tmp->binname = NDRX_STRDUP(el2->key)))
0436 {
0437 userlog("Failed to malloc binname for rebins: %s", strerror(errno));
0438 EXFAIL_OUT(ret);
0439 }
0440
0441
0442 EXHASH_ADD_KEYPTR(hh, M_rebins, tmp->binname,
0443 strlen(tmp->binname), tmp);
0444 }
0445 }
0446 out:
0447
0448 if (NULL!=parsed2)
0449 {
0450 ndrx_stdcfgstr_free(parsed2);
0451 }
0452
0453 return ret;
0454 }
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464 exprivate int ndrx_dbg_rebins_chkaddcfg(char *name, char *dbgstr)
0465 {
0466 int ret = EXSUCCEED;
0467 ndrx_debug_rebins_t *re_tmp=NULL;
0468
0469
0470
0471
0472 EXHASH_FIND_STR(M_rebins, name, re_tmp);
0473
0474 if (NULL!=re_tmp)
0475 {
0476
0477 re_tmp->dbgstr = NDRX_STRDUP(dbgstr);
0478
0479 if (NULL==re_tmp->dbgstr)
0480 {
0481 userlog("Failed to strdup: %s", strerror(errno));
0482 EXFAIL_OUT(ret);
0483 }
0484 }
0485
0486 out:
0487 return ret;
0488 }
0489
0490
0491
0492
0493
0494
0495 exprivate int ndrx_dbg_rebins_scancfg(ndrx_inicfg_section_keyval_t *conf)
0496 {
0497 int ret = EXSUCCEED;
0498 ndrx_inicfg_section_keyval_t *cc;
0499 ndrx_debug_rebins_t *el, *elt;
0500
0501 EXHASH_ITER(hh, M_rebins, el, elt)
0502 {
0503 if (NULL!=(cc=ndrx_keyval_hash_get(conf, el->binname)))
0504 {
0505 el->dbgstr = NDRX_STRDUP(cc->val);
0506
0507 if (NULL==el->dbgstr)
0508 {
0509 userlog("Failed to strdup: %s", strerror(errno));
0510 EXFAIL_OUT(ret);
0511 }
0512 }
0513 }
0514
0515 out:
0516 return ret;
0517 }
0518
0519
0520
0521
0522
0523
0524
0525
0526 exprivate int ndrx_dbg_rebins_apply(char *name, char *tmpfname, size_t tmpfnamesz)
0527 {
0528 ndrx_debug_rebins_t *el, *elt;
0529
0530 EXHASH_ITER(hh, M_rebins, el, elt)
0531 {
0532 int do_match;
0533
0534
0535 if (NULL!=el->dbgstr && EXSUCCEED==ndrx_init_parse_line(el->dbgstr, NULL,
0536 tmpfname, tmpfnamesz, &do_match, name))
0537 {
0538 if (EXTRUE==do_match)
0539 {
0540 return EXTRUE;
0541 }
0542 }
0543 }
0544
0545 return EXFALSE;
0546 }
0547
0548
0549
0550
0551 exprivate void ndrx_dbg_rebins_free(void)
0552 {
0553 ndrx_debug_rebins_t *el, *elt;
0554
0555 EXHASH_ITER(hh, M_rebins, el, elt)
0556 {
0557 EXHASH_DEL(M_rebins, el);
0558
0559 if (NULL!=el->binname)
0560 {
0561 NDRX_FREE(el->binname);
0562 }
0563
0564 if (NULL!=el->dbgstr)
0565 {
0566 NDRX_FREE(el->dbgstr);
0567 }
0568
0569 NDRX_FPFREE(el);
0570 }
0571 }
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587 expublic int ndrx_init_parse_line(const char *dbgstr, ndrx_debug_t *dbg_ptr,
0588 char *tmpfname, size_t tmpfnamesz, int *do_match, char *match_nm)
0589 {
0590 int ret = EXSUCCEED;
0591
0592 ndrx_stdcfgstr_t* parsed=NULL, *el;
0593 ndrx_debug_t *tmp_ptr;
0594
0595
0596 if (EXSUCCEED!=ndrx_stdcfgstr_parse(dbgstr, &parsed))
0597 {
0598 userlog("Failed to parse debug string [%s]", dbgstr);
0599 EXFAIL_OUT(ret);
0600 }
0601
0602 if (NULL!=do_match)
0603 {
0604 *do_match=EXFALSE;
0605
0606
0607 DL_FOREACH(parsed, el)
0608 {
0609 if (0==strcmp(el->key, "match"))
0610 {
0611 if (NULL==el->value)
0612 {
0613 userlog("Invalid debug string [%s] missing value for key [%s]",
0614 dbgstr, el->key);
0615 }
0616 else if (EXSUCCEED==ndrx_regqexec(el->value, match_nm))
0617 {
0618
0619 *do_match=EXTRUE;
0620 break;
0621 }
0622
0623 goto out;
0624 }
0625 }
0626 }
0627
0628 DL_FOREACH(parsed, el)
0629 {
0630 if (NULL==el->value)
0631 {
0632 userlog("Invalid debug string [%s] missing value for key [%s]",
0633 dbgstr, el->key);
0634 }
0635 else if (0==strcmp("ndrx", el->key))
0636 {
0637 int lev = atoi(el->value);
0638
0639 if (NULL!=dbg_ptr)
0640 {
0641 if ( (dbg_ptr->flags & LOG_FACILITY_NDRX) ||
0642 (dbg_ptr->flags & LOG_FACILITY_NDRX_THREAD) ||
0643 (dbg_ptr->flags & LOG_FACILITY_NDRX_REQUEST) )
0644 {
0645 dbg_ptr->level = lev;
0646 }
0647 }
0648 else
0649 {
0650 G_ndrx_debug.level = lev;
0651 }
0652 }
0653 else if (0==strcmp("ubf", el->key))
0654 {
0655 int lev = atoi(el->value);
0656
0657 if (NULL!=dbg_ptr)
0658 {
0659 if ( (dbg_ptr->flags & LOG_FACILITY_UBF) ||
0660 (dbg_ptr->flags & LOG_FACILITY_UBF_THREAD) ||
0661 (dbg_ptr->flags & LOG_FACILITY_UBF_REQUEST) )
0662 {
0663 dbg_ptr->level = lev;
0664 }
0665 }
0666 else
0667 {
0668 G_ubf_debug.level = lev;
0669 }
0670
0671 }
0672 else if (0==strcmp("tp", el->key))
0673 {
0674 int lev = atoi(el->value);
0675
0676 if (NULL!=dbg_ptr)
0677 {
0678 if ( (dbg_ptr->flags & LOG_FACILITY_TP) ||
0679 (dbg_ptr->flags & LOG_FACILITY_TP_THREAD) ||
0680 (dbg_ptr->flags & LOG_FACILITY_TP_REQUEST) )
0681 {
0682 dbg_ptr->level = lev;
0683 }
0684 }
0685 else
0686 {
0687 G_tp_debug.level = lev;
0688 }
0689 }
0690 else if (0==strcmp("iflags", el->key))
0691 {
0692
0693
0694
0695
0696 NDRX_STRCPY_SAFE(G_ndrx_debug.iflags, el->value);
0697 NDRX_STRCPY_SAFE(G_ubf_debug.iflags, el->value);
0698 NDRX_STRCPY_SAFE(G_tp_debug.iflags, el->value);
0699 }
0700 else if (0==strcmp("lines", el->key))
0701 {
0702 int lines = atoi(el->value);
0703
0704 if (lines < 0)
0705 {
0706 lines = 0;
0707 }
0708
0709 if (NULL!=dbg_ptr)
0710 {
0711 dbg_ptr->buf_lines = lines;
0712 }
0713 else
0714 {
0715 G_tp_debug.buf_lines =
0716 G_ndrx_debug.buf_lines =
0717 G_ubf_debug.buf_lines = lines;
0718 }
0719 }
0720 else if (0==strcmp("bufsz", el->key))
0721 {
0722 int bufsz = atoi(el->value);
0723
0724 if (bufsz<=0)
0725 {
0726 bufsz = DEFAULT_BUFFER_SIZE;
0727 }
0728
0729 if (NULL!=dbg_ptr)
0730 {
0731 dbg_ptr->buffer_size = bufsz;
0732 }
0733 else
0734 {
0735 G_tp_debug.buffer_size =
0736 G_ndrx_debug.buffer_size =
0737 G_ubf_debug.buffer_size = bufsz;
0738 }
0739 }
0740 else if (0==strcmp("file", el->key))
0741 {
0742 NDRX_STRCPY_SAFE_DST(tmpfname, el->value, tmpfnamesz);
0743 }
0744 else if (0==strcmp("threaded", el->key))
0745 {
0746 int val = 0;
0747
0748 if (el->value[0] == 'Y' || el->value[0] == 'y')
0749 {
0750 val = LOG_THREADED_TEMPL;
0751 }
0752 else if (el->value[0] == 'L' || el->value[0] == 'l')
0753 {
0754 val = LOG_THREADED_LINEL;
0755 }
0756
0757 if (NULL!=dbg_ptr)
0758 {
0759 dbg_ptr->is_threaded = val;
0760 }
0761 else
0762 {
0763 G_tp_debug.is_threaded = val;
0764 G_ubf_debug.is_threaded = val;
0765 G_ndrx_debug.is_threaded = val;
0766 }
0767 }
0768 else if (0==strcmp("mkdir", el->key))
0769 {
0770 int val = EXFALSE;
0771
0772 if (el->value[0] == 'Y' || el->value[0] == 'y')
0773 {
0774 val = EXTRUE;
0775 }
0776
0777 if (NULL!=dbg_ptr)
0778 {
0779 dbg_ptr->is_mkdir = val;
0780 }
0781 else
0782 {
0783 G_tp_debug.is_mkdir = val;
0784 G_ubf_debug.is_mkdir = val;
0785 G_ndrx_debug.is_mkdir = val;
0786 }
0787 }
0788 else if (0==strcmp("rebins", el->key))
0789 {
0790 if (EXSUCCEED!=ndrx_dbg_rebins_load(el->value))
0791 {
0792 EXFAIL_OUT(ret);
0793 }
0794 }
0795 }
0796
0797 ndrx_str_env_subs_len(tmpfname, tmpfnamesz);
0798
0799 if (NULL!=dbg_ptr)
0800 {
0801 tmp_ptr = dbg_ptr;
0802 }
0803 else
0804 {
0805 tmp_ptr = &G_ndrx_debug;
0806 }
0807
0808
0809
0810
0811 if ((tmp_ptr->is_threaded & LOG_THREADED_TEMPL) && EXEOS!=tmpfname[0])
0812 {
0813 int len;
0814 int len2;
0815 char *p;
0816
0817 len2 = 3;
0818
0819
0820
0821
0822 if (strchr(tmpfname, '%'))
0823 {
0824
0825
0826
0827
0828
0829 ndrx_str_fmtesc(tmp_ptr->filename_th_template,
0830 sizeof(tmp_ptr->filename_th_template), tmpfname);
0831 }
0832 else
0833 {
0834 NDRX_STRCPY_SAFE(tmp_ptr->filename_th_template, tmpfname);
0835 }
0836
0837 len = strlen(tmp_ptr->filename_th_template);
0838
0839
0840 if (len+len2+1 <= tmpfnamesz)
0841 {
0842
0843 if (NULL!=(p = strrchr(tmp_ptr->filename_th_template, '.')))
0844 {
0845
0846
0847 memmove(p+len2, p, strlen(p)+1);
0848 NDRX_STRNCPY(p, ".%u", len2);
0849 }
0850 else
0851 {
0852
0853 NDRX_STRCAT_S(tmp_ptr->filename_th_template,
0854 sizeof(tmp_ptr->filename_th_template), ".%u");
0855 }
0856
0857
0858 if (NULL==dbg_ptr)
0859 {
0860 NDRX_STRCPY_SAFE(G_ubf_debug.filename_th_template,
0861 G_ndrx_debug.filename_th_template);
0862
0863 NDRX_STRCPY_SAFE(G_tp_debug.filename_th_template,
0864 G_ndrx_debug.filename_th_template);
0865 }
0866 }
0867 }
0868
0869 out:
0870 if (NULL!=parsed)
0871 {
0872 ndrx_stdcfgstr_free(parsed);
0873 }
0874
0875 return ret;
0876 }
0877
0878
0879
0880
0881
0882
0883
0884
0885
0886
0887 expublic FILE *ndrx_dbg_fopen_mkdir(const char *filename, const char *mode,
0888 ndrx_debug_t *dbg_ptr, ndrx_debug_file_sink_t *fsink)
0889 {
0890 FILE *ret = NULL;
0891 int got_dir = EXFALSE;
0892 int fallbacks = 0;
0893
0894 int is_mkdir;
0895 int buffer_size;
0896
0897 ret = NDRX_FOPEN(filename, mode);
0898
0899
0900
0901 if (NULL!=dbg_ptr)
0902 {
0903 is_mkdir = dbg_ptr->is_mkdir;
0904 buffer_size = dbg_ptr->buffer_size;
0905 }
0906 else
0907 {
0908 is_mkdir = fsink->org_is_mkdir;
0909 buffer_size = fsink->org_buffer_size;
0910 }
0911
0912 if (!is_mkdir)
0913 {
0914 goto out;
0915 }
0916
0917
0918 if (NULL==ret && errno==ENOENT)
0919 {
0920
0921 char tmp[PATH_MAX+1];
0922 char *p;
0923
0924 NDRX_STRCPY_SAFE(tmp, filename);
0925
0926
0927
0928
0929 while (NULL!=(p=strrchr(tmp, '/')))
0930 {
0931 *p = EXEOS;
0932
0933
0934 if (EXSUCCEED!=mkdir(tmp, NDRX_DIR_PERM))
0935 {
0936 if (ENOENT!=errno)
0937 {
0938 break;
0939 }
0940 }
0941 else
0942 {
0943 got_dir = EXTRUE;
0944 break;
0945 }
0946
0947 fallbacks++;
0948 }
0949
0950 if (!got_dir)
0951 {
0952 goto out;
0953 }
0954
0955
0956
0957
0958
0959 while (fallbacks > 0)
0960 {
0961 tmp[strlen(tmp)]='/';
0962
0963 if (EXSUCCEED!=mkdir(tmp, NDRX_DIR_PERM))
0964 {
0965
0966 goto out;
0967 }
0968
0969 fallbacks--;
0970 }
0971
0972 ret = NDRX_FOPEN(filename, "a");
0973 }
0974
0975 out:
0976
0977 if (NULL!=ret)
0978 {
0979
0980 if (EXSUCCEED!=fcntl(fileno(ret), F_SETFD, FD_CLOEXEC))
0981 {
0982 userlog("WARNING: Failed to set FD_CLOEXEC: %s", strerror(errno));
0983 }
0984
0985
0986
0987 setvbuf(ret, NULL, _IOFBF, buffer_size);
0988
0989
0990 if (NULL!=dbg_ptr && NULL!=fsink)
0991 {
0992 fsink->org_is_mkdir = dbg_ptr->is_mkdir;
0993 fsink->org_buffer_size = dbg_ptr->buffer_size;
0994 }
0995 }
0996
0997 return ret;
0998 }
0999
1000
1001
1002
1003
1004
1005 expublic void ndrx_init_debug(void)
1006 {
1007 char *cfg_file = getenv(CONF_NDRX_DEBUG_CONF);
1008 char *inline_setting = getenv(CONF_NDRX_DEBUG_STR);
1009 FILE *f;
1010 ndrx_inicfg_section_keyval_t *conf = NULL, *cc;
1011 ndrx_inicfg_t *cconfig = NULL;
1012 char hostname[PATH_MAX];
1013 char buf[PATH_MAX*2];
1014 char *tmp;
1015 char tmpname[PATH_MAX+1]={EXEOS};
1016 int lcf_status=EXFAIL;
1017 int do_reply=EXFALSE;
1018 int did_match = EXFALSE;
1019 char *svname = getenv(CONF_NDRX_SVPROCNAME);
1020
1021 ndrx_dbg_intlock_set();
1022
1023
1024
1025
1026
1027
1028
1029
1030 ndrx_dbg_pid_update();
1031
1032 ndrx_sys_get_hostname(hostname, sizeof(hostname));
1033
1034
1035
1036 G_tp_debug.hostnamecrc32 = G_ubf_debug.hostnamecrc32 =
1037 G_ndrx_debug.hostnamecrc32 = G_stdout_debug.hostnamecrc32 =
1038 ndrx_Crc32_ComputeBuf(0, hostname, strlen(hostname));
1039
1040 cconfig = ndrx_get_G_cconfig();
1041
1042
1043
1044
1045 G_ndrx_debug.dbg_f_ptr = NULL;
1046 G_ubf_debug.dbg_f_ptr = NULL;
1047 G_tp_debug.dbg_f_ptr = NULL;
1048 G_stdout_debug.dbg_f_ptr = NULL;
1049
1050 G_ndrx_debug.version = 0;
1051 G_ubf_debug.version = 0;
1052 G_tp_debug.version = 0;
1053 G_stdout_debug.version = 0;
1054
1055
1056
1057
1058
1059
1060 #ifdef EX_USE_SYSVQ
1061 G_ndrx_debug.is_threaded = LOG_THREADED_LINEL;
1062 G_ubf_debug.is_threaded = LOG_THREADED_LINEL;
1063 G_tp_debug.is_threaded = LOG_THREADED_LINEL;
1064 G_stdout_debug.is_threaded = LOG_THREADED_LINEL;
1065 #endif
1066
1067
1068 G_stdout_debug.buf_lines = 1;
1069 G_stdout_debug.buffer_size = 1;
1070 G_stdout_debug.level = log_debug;
1071
1072
1073 G_tp_debug.buffer_size = G_ubf_debug.buffer_size = G_ndrx_debug.buffer_size = 50000;
1074
1075 G_tp_debug.buf_lines = G_ubf_debug.buf_lines = G_ndrx_debug.buf_lines = 1;
1076 G_ubf_debug.level = G_ndrx_debug.level = log_error;
1077
1078 G_tp_debug.level = log_debug;
1079
1080 if (NULL==cconfig)
1081 {
1082 if (NULL!=inline_setting)
1083 {
1084 ndrx_init_parse_line(inline_setting, NULL, tmpname, sizeof(tmpname),
1085 NULL, NULL);
1086 }
1087 else if (NULL!=cfg_file && EXEOS==cfg_file[0])
1088 {
1089
1090 G_tp_debug.level = G_ubf_debug.level = G_ndrx_debug.level = log_error;
1091 }
1092 else if (NULL!=cfg_file &&
1093 NULL!=(f=fopen(cfg_file, "r")))
1094 {
1095
1096
1097 while (NULL!=fgets(buf, sizeof(buf), f))
1098 {
1099 int offs;
1100
1101 if ('#'==buf[0] || '\n'==buf[0])
1102 {
1103
1104 continue;
1105 }
1106 if (buf[strlen(buf)-1]=='\n')
1107 {
1108 buf[strlen(buf)-1]=EXEOS;
1109 }
1110
1111 offs = strcspn(buf, "\t ");
1112
1113
1114 if (offs > 0)
1115 {
1116 *(buf + offs)=EXEOS;
1117
1118 if (0==strcmp(buf, (char *)EX_PROGNAME) ||
1119 NULL!=svname && 0==strcmp(buf, svname) ||
1120 0==strcmp(buf, "*"))
1121 {
1122 ndrx_init_parse_line((buf+offs+1), NULL,
1123 tmpname, sizeof(tmpname),
1124 NULL, NULL);
1125
1126
1127 if (0!=strcmp(buf, "*"))
1128 {
1129 did_match=EXTRUE;
1130 break;
1131 }
1132 }
1133
1134
1135 if (M_rebins)
1136 {
1137 ndrx_dbg_rebins_chkaddcfg(buf, (buf+offs+1));
1138 }
1139 }
1140
1141 }
1142
1143 fclose(f);
1144 }
1145 else if (NULL==f && NULL!=cfg_file)
1146 {
1147 fprintf(stderr, "Failed to to open [%s]: %d/%s\n", cfg_file,
1148 errno, strerror(errno));
1149 }
1150 }
1151 else
1152 {
1153
1154 ndrx_cconfig_load();
1155 if (EXSUCCEED==ndrx_cconfig_get(NDRX_CONF_SECTION_DEBUG, &conf))
1156 {
1157
1158
1159 if (NULL!=inline_setting)
1160 {
1161 ndrx_init_parse_line(inline_setting, NULL, tmpname, sizeof(tmpname),
1162 NULL, NULL);
1163 }
1164
1165 else
1166 {
1167
1168 if (NULL!=(cc=ndrx_keyval_hash_get(conf, "*")))
1169 {
1170 ndrx_init_parse_line(cc->val, NULL, tmpname, sizeof(tmpname),
1171 NULL, NULL);
1172 }
1173
1174
1175
1176
1177
1178 if (
1179 NULL!=svname && NULL!=(cc=ndrx_keyval_hash_get(conf, (char *)svname))
1180 ||
1181 NULL!=(cc=ndrx_keyval_hash_get(conf, (char *)EX_PROGNAME))
1182 )
1183 {
1184 ndrx_init_parse_line(cc->val, NULL, tmpname, sizeof(tmpname),
1185 NULL, NULL);
1186
1187 did_match=EXTRUE;
1188 }
1189
1190 if (!did_match && M_rebins)
1191 {
1192
1193 ndrx_dbg_rebins_scancfg(conf);
1194
1195 }
1196 }
1197 }
1198 }
1199
1200
1201
1202 if (!did_match && M_rebins)
1203 {
1204
1205 if (NULL!=svname && EXTRUE==ndrx_dbg_rebins_apply(svname, tmpname, sizeof(tmpname)))
1206 {
1207 did_match = EXTRUE;
1208 }
1209
1210 if (!did_match)
1211 {
1212 ndrx_dbg_rebins_apply((char *)EX_PROGNAME, tmpname, sizeof(tmpname));
1213 }
1214 }
1215
1216 ndrx_dbg_rebins_free();
1217 M_rebins=NULL;
1218
1219
1220 if (EXEOS==tmpname[0])
1221 {
1222
1223 tmp = getenv(CONF_NDRX_DFLTLOG);
1224
1225 if (NULL!=tmp)
1226 {
1227 NDRX_STRCPY_SAFE(tmpname, tmp);
1228 }
1229 }
1230
1231 if (EXEOS==tmpname[0])
1232 {
1233 NDRX_STRCPY_SAFE(tmpname, NDRX_LOG_OSSTDERR);
1234 }
1235
1236
1237 NDRX_STRCPY_SAFE(G_stdout_debug.filename, NDRX_LOG_OSSTDOUT);
1238
1239
1240 ndrx_debug_get_sink(tmpname, EXTRUE, &G_ndrx_debug, NULL);
1241 ndrx_debug_get_sink(tmpname, EXTRUE, &G_ubf_debug, NULL);
1242 ndrx_debug_get_sink(tmpname, EXTRUE, &G_tp_debug, NULL);
1243 ndrx_debug_get_sink(G_stdout_debug.filename, EXTRUE,
1244 &G_stdout_debug, NULL);
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256 if (NULL!=conf)
1257 {
1258
1259 ndrx_keyval_hash_free(conf);
1260 }
1261
1262
1263
1264 ndrx_systest_init();
1265
1266
1267
1268
1269
1270 lcf_status = ndrx_lcf_init();
1271
1272 G_ndrx_debug_first = EXFALSE;
1273
1274 ndrx_dbg_intlock_unset(&do_reply);
1275
1276
1277 if (do_reply)
1278 {
1279 ndrx_dbg_reply_memlog_all();
1280 }
1281
1282
1283 if (EXSUCCEED!=lcf_status)
1284 {
1285
1286 NDRX_LOG(log_warn, "LCF startup failed -> LCF commands will not be processed");
1287 }
1288
1289 }
1290
1291
1292
1293
1294
1295 expublic ndrx_debug_t * debug_get_ndrx_ptr(void)
1296 {
1297
1298 NDRX_DBG_INIT_ENTRY;
1299
1300 return get_debug_ptr(&G_ndrx_debug);
1301 }
1302
1303
1304
1305
1306
1307 expublic ndrx_debug_t * debug_get_tp_ptr(void)
1308 {
1309
1310 NDRX_DBG_INIT_ENTRY;
1311
1312 return get_debug_ptr(&G_tp_debug);
1313 }
1314
1315
1316
1317
1318
1319 expublic ndrx_debug_t * debug_get_ubf_ptr(void)
1320 {
1321 NDRX_DBG_INIT_ENTRY;
1322
1323 return get_debug_ptr(&G_ubf_debug);
1324 }
1325
1326
1327
1328
1329
1330 expublic int debug_get_ndrx_level(void)
1331 {
1332 NDRX_DBG_INIT_ENTRY;
1333 return G_ndrx_debug.level;
1334 }
1335
1336
1337
1338
1339
1340 expublic int debug_get_ubf_level(void)
1341 {
1342 NDRX_DBG_INIT_ENTRY;
1343 return G_ubf_debug.level;
1344 }
1345
1346
1347
1348
1349
1350 expublic int debug_get_tp_level(void)
1351 {
1352 NDRX_DBG_INIT_ENTRY;
1353 return G_tp_debug.level;
1354 }
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369 expublic void __ndrx_debug_dump_diff__(ndrx_debug_t *dbg_ptr, int lev, const char *file,
1370 long line, const char *func, const char *comment, void *ptr, void *ptr2, long len)
1371 {
1372
1373 int i;
1374 unsigned char buf[17];
1375 unsigned char buf2[17];
1376 unsigned char *cptr = (unsigned char*)ptr;
1377 unsigned char *cptr2 = (unsigned char*)ptr2;
1378 char print_line[256]={0};
1379 char print_line2[256]={0};
1380
1381
1382 dbg_ptr = get_debug_ptr(dbg_ptr);
1383
1384 if (dbg_ptr->level < lev)
1385 {
1386 return;
1387 }
1388
1389 __ndrx_debug__(dbg_ptr, lev, file, line, func, "%s", comment);
1390
1391 if (0==len)
1392 {
1393 __ndrx_debug__(dbg_ptr, lev, file, line, func, "Notice: Hex dump diff - "
1394 "nothing to dump: len=%d ptr=%p ptr2=%p", len, ptr, ptr2);
1395
1396 return;
1397 }
1398
1399 ndrx_debug_lock(dbg_ptr->dbg_f_ptr);
1400
1401 for (i = 0; i < len; i++)
1402 {
1403 if ((i % 16) == 0)
1404 {
1405 if (i != 0)
1406 {
1407 sprintf (print_line + strlen(print_line), " %s", buf);
1408 sprintf (print_line2 + strlen(print_line2), " %s", buf2);
1409
1410 if (0!=strcmp(print_line, print_line2))
1411 {
1412
1413 fputs("<", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1414 fputs(print_line, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1415 fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1416 BUFFER_CONTROL(dbg_ptr);
1417
1418
1419 fputs(">", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1420 fputs(print_line2, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1421 fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1422 BUFFER_CONTROL(dbg_ptr);
1423 }
1424
1425 print_line[0] = 0;
1426 print_line2[0] = 0;
1427 }
1428
1429 sprintf (print_line + strlen(print_line), " %04x ", i);
1430 sprintf (print_line2 + strlen(print_line2), " %04x ", i);
1431 }
1432
1433 sprintf (print_line + strlen(print_line), " %02x", cptr[i]);
1434 sprintf (print_line2 + strlen(print_line2), " %02x", cptr2[i]);
1435
1436 if ((cptr[i] < 0x20) || (cptr[i] > 0x7e))
1437 {
1438 buf[i % 16] = '.';
1439 }
1440 else
1441 {
1442 buf[i % 16] = cptr[i];
1443 }
1444 buf[(i % 16) + 1] = '\0';
1445
1446 if ((cptr2[i] < 0x20) || (cptr2[i] > 0x7e))
1447 {
1448 buf2[i % 16] = '.';
1449 }
1450 else
1451 {
1452 buf2[i % 16] = cptr2[i];
1453 }
1454 buf2[(i % 16) + 1] = '\0';
1455 }
1456
1457 while ((i % 16) != 0)
1458 {
1459 sprintf (print_line + strlen(print_line), " ");
1460 sprintf (print_line2 + strlen(print_line2), " ");
1461 i++;
1462 }
1463
1464 sprintf (print_line + strlen(print_line), " %s", buf);
1465 sprintf (print_line2 + strlen(print_line2), " %s", buf2);
1466
1467 if (0!=strcmp(print_line, print_line2))
1468 {
1469
1470 fputs("<", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1471 fputs(print_line, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1472 fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1473 BUFFER_CONTROL(dbg_ptr);
1474
1475
1476 fputs(">", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1477 fputs(print_line2, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1478 fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1479 BUFFER_CONTROL(dbg_ptr);
1480 }
1481 print_line[0] = 0;
1482 print_line2[0] = 0;
1483
1484 ndrx_debug_unlock(dbg_ptr->dbg_f_ptr);
1485 }
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499 expublic void __ndrx_debug_dump__(ndrx_debug_t *dbg_ptr, int lev, const char *file,
1500 long line, const char *func, const char *comment, void *ptr, long len)
1501 {
1502 int i;
1503 unsigned char buf[17];
1504 unsigned char *cptr = (unsigned char*)ptr;
1505 char print_line[256]={0};
1506 NSTD_TLS_ENTRY;
1507
1508
1509 dbg_ptr = get_debug_ptr(dbg_ptr);
1510
1511 if (dbg_ptr->level < lev)
1512 {
1513 return;
1514 }
1515
1516 __ndrx_debug__(dbg_ptr, lev, file, line, func, "%s (nr bytes: %ld)",
1517 comment, len);
1518
1519 if (0==len)
1520 {
1521 __ndrx_debug__(dbg_ptr, lev, file, line, func, "Notice: Hex dump - "
1522 "nothing to dump: len=%d ptr=%p", len, ptr);
1523
1524 return;
1525 }
1526
1527
1528
1529 ndrx_debug_lock(dbg_ptr->dbg_f_ptr);
1530
1531 for (i = 0; i < len; i++)
1532 {
1533 if ((i % 16) == 0)
1534 {
1535 if (i != 0)
1536 {
1537 sprintf (print_line + strlen(print_line), " %s", buf);
1538 BUFFERED_PRINT_LINE(dbg_ptr, print_line);
1539 print_line[0] = 0;
1540 }
1541
1542 sprintf (print_line + strlen(print_line), " %04x ", i);
1543 }
1544 sprintf (print_line + strlen(print_line), " %02x", cptr[i]);
1545
1546 if ((cptr[i] < 0x20) || (cptr[i] > 0x7e))
1547 {
1548 buf[i % 16] = '.';
1549 }
1550 else
1551 {
1552 buf[i % 16] = cptr[i];
1553 }
1554 buf[(i % 16) + 1] = '\0';
1555 }
1556
1557 while ((i % 16) != 0)
1558 {
1559 sprintf (print_line + strlen(print_line), " ");
1560 i++;
1561 }
1562
1563
1564 sprintf (print_line + strlen(print_line), " %s", buf);
1565 BUFFERED_PRINT_LINE(dbg_ptr, print_line);
1566 print_line[0] = 0;
1567
1568 ndrx_debug_unlock(dbg_ptr->dbg_f_ptr);
1569
1570 }
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583 expublic void __ndrx_debug__(ndrx_debug_t *dbg_ptr, int lev, const char *file,
1584 long line, const char *func, const char *fmt, ...)
1585 {
1586 va_list ap;
1587 char line_start[128];
1588 long ldate, ltime, lusec;
1589 char *line_print;
1590 char *func_last;
1591 int len;
1592 long thread_nr = 0;
1593 static __thread uint64_t ostid = 0;
1594 static __thread int first = EXTRUE;
1595
1596
1597
1598
1599 if (NULL!=G_nstd_tls)
1600 {
1601 thread_nr = G_nstd_tls->M_threadnr;
1602 }
1603
1604
1605 if (first)
1606 {
1607 ostid = ndrx_gettid();
1608 first = EXFALSE;
1609 }
1610
1611 if (!M_is_initlock_owner)
1612 {
1613 dbg_ptr = get_debug_ptr(dbg_ptr);
1614
1615 if (dbg_ptr->level < lev)
1616 {
1617 return;
1618 }
1619 }
1620
1621 if ((len=strlen(file)) > 8)
1622 {
1623 line_print = (char *)file+len-8;
1624 }
1625 else
1626 {
1627 line_print = (char *)file;
1628 }
1629
1630 if ((len=strlen(func)) > 12)
1631 {
1632 func_last = (char *)func+len-12;
1633 }
1634 else
1635 {
1636 func_last = (char *)func;
1637 }
1638
1639 ndrx_get_dt_local(&ldate, <ime, &lusec);
1640
1641 snprintf(line_start, sizeof(line_start),
1642 "%c:%s:%d:%08x:%05d:%08llx:%03ld:%08ld:%06ld%06d:%-12.12s:%-8.8s:%04ld:",
1643 dbg_ptr->code, dbg_ptr->module, lev, (unsigned int)dbg_ptr->hostnamecrc32,
1644 (int)dbg_ptr->pid, (unsigned long long)(ostid), thread_nr, ldate, ltime,
1645 (int)(lusec), func_last, line_print, line);
1646
1647
1648
1649 if (!M_is_initlock_owner)
1650 {
1651
1652
1653 ndrx_debug_lock((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr);
1654
1655 fputs(line_start, ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1656 va_start(ap, fmt);
1657 (void) vfprintf(((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp, fmt, ap);
1658 va_end(ap);
1659 fputs("\n", ((ndrx_debug_file_sink_t*)dbg_ptr->dbg_f_ptr)->fp);
1660
1661
1662 BUFFER_CONTROL(dbg_ptr);
1663
1664 ndrx_debug_unlock(dbg_ptr->dbg_f_ptr);
1665 }
1666 else
1667 {
1668 ndrx_memlogger_t *memline = NDRX_MALLOC(sizeof(ndrx_memlogger_t));
1669
1670 if (NULL==memline)
1671 {
1672 userlog("Failed to malloc mem debug line: %s - skipping log entry",
1673 strerror(errno));
1674 }
1675 else
1676 {
1677 int len;
1678 memline->line[0] = EXEOS;
1679 memline->level = lev;
1680
1681 NDRX_STRCPY_SAFE(memline->line, line_start);
1682
1683 len = strlen(memline->line);
1684
1685 va_start(ap, fmt);
1686 (void) vsnprintf(memline->line+len, sizeof(memline->line)-len, fmt, ap);
1687 va_end(ap);
1688
1689
1690
1691 MUTEX_LOCK_V(M_memlog_lock);
1692 DL_APPEND(dbg_ptr->memlog, memline);
1693 MUTEX_UNLOCK_V(M_memlog_lock);
1694
1695 }
1696 }
1697 }
1698
1699
1700
1701
1702
1703
1704
1705
1706 expublic void ndrx_dbg_init(char *module, char *config_key)
1707 {
1708 NDRX_DBG_INIT_ENTRY;
1709 }
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719 expublic void *ndrx_malloc_dbg(size_t size, long line, const char *file, const char *func)
1720 {
1721 void *ret;
1722 int errnosv;
1723
1724 ret=malloc(size);
1725 errnosv = errno;
1726
1727 userlog("[%p] <= malloc(size=%d):%s %s:%ld", ret, size, func, file, line);
1728
1729 errno = errnosv;
1730
1731 return ret;
1732 }
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742 expublic void ndrx_free_dbg(void *ptr, long line, const char *file, const char *func)
1743 {
1744 userlog("[%p] => free(ptr=%p):%s %s:%ld", ptr, ptr, func, file, line);
1745 free(ptr);
1746 }
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756 expublic void *ndrx_calloc_dbg(size_t nmemb, size_t size, long line, const char *file, const char *func)
1757 {
1758 void *ret;
1759 int errnosv;
1760
1761 ret=calloc(nmemb, size);
1762 errnosv = errno;
1763 userlog("[%p] <= calloc(nmemb=%d, size=%d):%s %s:%ld", ret, nmemb,
1764 size, func, file, line);
1765
1766 errno = errnosv;
1767
1768 return ret;
1769 }
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779 expublic void *ndrx_realloc_dbg(void *ptr, size_t size, long line, const char *file, const char *func)
1780 {
1781 void *ret;
1782 int errnosv;
1783
1784 ret= realloc(ptr, size);
1785
1786 errnosv = errno;
1787
1788 userlog("[%p] <= realloc(ptr=[%p], size=%d):%s %s:%ld", ret, ptr,
1789 size, func, file, line);
1790
1791 errno = errnosv;
1792 return ret;
1793 }
1794
1795
1796
1797
1798
1799
1800
1801
1802 expublic FILE *ndrx_fopen_dbg(const char *path, const char *mode,
1803 long line, const char *file, const char *func)
1804 {
1805 FILE *ret;
1806 int errnosv;
1807
1808 ret = fopen(path, mode);
1809 errnosv = errno;
1810
1811 userlog("[%p] <= fopen(path=%s, mode=%s):%s %s:%ld", ret, path, mode,
1812 func, file, line);
1813
1814 errno = errnosv;
1815
1816 return ret;
1817 }
1818
1819
1820
1821
1822
1823
1824
1825 expublic int ndrx_fclose_dbg(FILE *fp, long line, const char *file, const char *func)
1826 {
1827 int ret;
1828 int errnosv;
1829
1830 ret = fclose(fp);
1831
1832 errnosv = errno;
1833
1834 userlog("[%p] => fclose(fp=%p) => %d:%s %s:%ld", fp, fp, ret,
1835 func, file, line);
1836
1837 errno = errnosv;
1838
1839 return ret;
1840
1841 }
1842
1843
1844
1845
1846
1847 expublic char *ndrx_strdup_dbg(char *ptr, long line, const char *file, const char *func)
1848 {
1849 char *ret;
1850 int errnosv;
1851
1852 ret=strdup(ptr);
1853 errnosv = errno;
1854
1855 userlog("[%p] <= strdup(ptr=%p):%s %s:%ld", ret, ptr, func, file, line);
1856
1857 errno = errnosv;
1858
1859 return ret;
1860 }
1861
1862