Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief Memory leak tracker
0003  *
0004  * @file xmemck.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <signal.h>
0039 #include <unistd.h>    /* for getopt */
0040 
0041 #include <atmi.h>
0042 #include <atmi_int.h>
0043 #include <ndrstandard.h>
0044 #include <Exfields.h>
0045 #include <ubf.h>
0046 #include <ubf_int.h>
0047 #include <fdatatype.h>
0048 #include <exmemck.h>
0049 #include <ndrx_config.h>
0050 #include <sys_unix.h>
0051 /*---------------------------Externs------------------------------------*/
0052 /*---------------------------Macros-------------------------------------*/    
0053 /*---------------------------Enums--------------------------------------*/
0054 /*---------------------------Typedefs-----------------------------------*/
0055 /*---------------------------Globals------------------------------------*/
0056 /*---------------------------Statics------------------------------------*/
0057 exprivate volatile int M_keep_running = EXTRUE;
0058 /*---------------------------Prototypes---------------------------------*/
0059 
0060 /**
0061  * Singnal handler for deinti
0062  */
0063 expublic void intHandler(int sig)
0064 {
0065     M_keep_running = EXFALSE;
0066 }
0067 
0068 /**
0069  * Print leaky info
0070  * @param proc
0071  */
0072 expublic void xmem_print_leaky(exmemck_process_t *proc)
0073 {
0074     fprintf(stdout, ">>> LEAK pid=%d! rss: %ld -> %ld (+%lf%%), vsz %ld -> %ld (+%lf%%): [%s]\n",
0075             proc->pid, proc->avg_first_halve_rss, proc->avg_second_halve_rss,
0076             proc->rss_increase_prcnt,
0077             proc->avg_first_halve_vsz, proc->avg_second_halve_vsz, 
0078             proc->vsz_increase_prcnt,
0079             proc->psout);
0080     
0081     fflush(stdout);
0082 }
0083 
0084 /**
0085  * Print process exit summary..
0086  * @param proc
0087  */
0088 expublic void xmem_print_exit(exmemck_process_t *proc)
0089 {
0090     NDRX_LOG(log_info, "Terminated: %d [%s]", proc->pid, proc->psout);
0091 }
0092 
0093 /**
0094  * Main entry point for `xmemck' utility
0095  */
0096 int main(int argc, char** argv)
0097 {
0098     int ret = EXSUCCEED;
0099     int c;
0100     int period = 1;
0101     int had_mask = EXFALSE;
0102     exmemck_settings_t settings;
0103     
0104     memset(&settings, 0, sizeof(settings));
0105     
0106     settings.pf_proc_exit = xmem_print_exit;
0107     settings.pf_proc_leaky = xmem_print_leaky;
0108     settings.percent_diff_allow = 5; /* Allow 5% incr */
0109     settings.interval_start_prcnt = 40;
0110     settings.interval_stop_prcnt = 90;
0111     settings.min_values = 20;
0112     
0113     signal(SIGINT, intHandler);
0114     signal(SIGTERM, intHandler);
0115     
0116     
0117     while ((c = getopt(argc, argv, "n:p:d:s:t:m:v:")) != -1)
0118     {
0119         NDRX_LOG(log_debug, "%c = [%s]", c, optarg);
0120         switch(c)
0121         {
0122             case 'p':
0123                 period = atoi(optarg);
0124                 NDRX_LOG(log_debug, "Period set to: %d", period);
0125                 break;
0126             case 'd':
0127                 settings.percent_diff_allow = atoi(optarg);
0128                 
0129                 NDRX_LOG(log_debug, "Percent diff allow: %d%%", 
0130                         settings.percent_diff_allow);
0131                 break;
0132             case 's':
0133                 settings.interval_start_prcnt = atoi(optarg);
0134                 
0135                 NDRX_LOG(log_debug, "Percent interval start: %d%%", 
0136                         settings.interval_start_prcnt);
0137                 break;
0138             case 't':
0139                 settings.interval_stop_prcnt = atoi(optarg);
0140                 
0141                 NDRX_LOG(log_debug, "Percent interval stop: %d%%", 
0142                         settings.interval_stop_prcnt);
0143                 break;
0144             case 'v':
0145                 settings.min_values = atoi(optarg);
0146                 
0147                 NDRX_LOG(log_debug, "Minimum values : %d", 
0148                         settings.min_values);
0149                 break;
0150             case 'n':
0151                 NDRX_STRCPY_SAFE(settings.negative_mask, optarg);
0152                 
0153                 NDRX_LOG(log_debug, "Negative mask set to [%s]", 
0154                         settings.negative_mask);
0155                 break;
0156             case 'm':
0157                 NDRX_LOG(log_debug, "Adding mask: [%s]", 
0158                         optarg);
0159                 
0160                 if (EXSUCCEED!=ndrx_memck_add(optarg,  NULL, &settings))
0161                 {
0162                     NDRX_LOG(log_error, "ndrx_memck_add() failed to add [%s]", 
0163                             optarg);
0164                     EXFAIL_OUT(ret);
0165                 }
0166                 
0167                 settings.negative_mask[0] = EXEOS; /* reset mask */
0168                 
0169                 had_mask = EXTRUE;
0170                 break;
0171         }
0172     }
0173     
0174     if (!had_mask)
0175     {
0176         NDRX_BANNER("");
0177         
0178         fprintf(stderr, "Enduro/X memory check usage:\n");
0179         fprintf(stderr, "%s [-p period in sec, default 1] [-d allow_increase_delta_percent, default 5] \\\n"
0180                 "[-s start_percent, default 40] [-t stop_percent, default 90] [-n negative_regex_mask] \\\n"
0181                 "[-v min_values, default 20] -m proc_mask_to_monitor1 [-m mask2] ... \n", argv[0]);
0182         exit(EXFAIL);
0183     }
0184     
0185     while (M_keep_running)
0186     {
0187         if (EXSUCCEED!=ndrx_memck_tick())
0188         {
0189             NDRX_LOG(log_error, "ndrx_memck_tick() failed");
0190             EXFAIL_OUT(ret);
0191         }
0192         
0193         sleep(period);
0194     }
0195     
0196     
0197 out:
0198                 
0199     ndrx_memck_rmall();
0200 
0201     return ret;
0202 }
0203 
0204 /* vim: set ts=4 sw=4 et smartindent: */